标签:failed rest buffer tor main orm local amp make
代码即关键注释如下:
static GLfloat vGreen[] = { 0.0f, 1.0f, 0.0f, 1.0f }; static GLfloat vWhite[] = { 1.0f, 1.0f, 1.0f, 1.0f }; static GLfloat vLightPos[] = { 0.0f, 3.0f, 0.0f, 1.0f }; GLsizei screenWidth; // Desired window or desktop width GLsizei screenHeight; // Desired window or desktop height GLboolean bFullScreen; // Request to run full screen GLboolean bAnimated; // Request for continual updates GLShaderManager shaderManager; // Shader Manager GLMatrixStack modelViewMatrix; // Modelview Matrix GLMatrixStack projectionMatrix; // Projection Matrix M3DMatrix44f orthoMatrix; GLFrustum viewFrustum; // View Frustum GLGeometryTransform transformPipeline; // Geometry Transform Pipeline GLFrame cameraFrame; // Camera frame GLTriangleBatch torusBatch; GLBatch floorBatch; GLBatch screenQuad; GLuint textures[1]; GLuint blurTextures[6]; GLuint pixBuffObjs[1]; GLuint curBlurTarget; bool bUsePBOPath; GLfloat speedFactor; GLuint blurProg; void *pixelData; GLuint pixelDataSize; //void MoveCamera(void); void DrawWorld(GLfloat yRot, GLfloat xPos); bool LoadBMPTexture(const char *szFileName, GLenum minFilter, GLenum magFilter, GLenum wrapMode); void SetupBlurProg(void); // returns 1 - 6 for blur texture units // curPixBuf is always between 0 and 5 void AdvanceBlurTaget() { curBlurTarget = ((curBlurTarget + 1) % 6); } GLuint GetBlurTarget0() { return (1 + ((curBlurTarget + 5) % 6)); } GLuint GetBlurTarget1() { return (1 + ((curBlurTarget + 4) % 6)); } GLuint GetBlurTarget2() { return (1 + ((curBlurTarget + 3) % 6)); } GLuint GetBlurTarget3() { return (1 + ((curBlurTarget + 2) % 6)); } GLuint GetBlurTarget4() { return (1 + ((curBlurTarget + 1) % 6)); } GLuint GetBlurTarget5() { return (1 + ((curBlurTarget) % 6)); } void UpdateFrameCount() { static int iFrames = 0; // Frame count static CStopWatch frameTimer; // Render time // Reset the stopwatch on first time if(iFrames == 0) { frameTimer.Reset(); iFrames++; } // Increment the frame count iFrames++; // Do periodic frame rate calculation if (iFrames == 101) { float fps; fps = 100.0f / frameTimer.GetElapsedSeconds(); if (bUsePBOPath) printf("Pix_buffs - Using PBOs %.1f fps\n", fps); else printf("Pix_buffs - Using Client mem copies %.1f fps\n", fps); frameTimer.Reset(); iFrames = 1; } } /////////////////////////////////////////////////////////////////////////////////////////////////////// // Load in a BMP file as a texture. Allows specification of the filters and the wrap mode bool LoadBMPTexture(const char *szFileName, GLenum minFilter, GLenum magFilter, GLenum wrapMode) { GLbyte *pBits; GLint iWidth, iHeight; pBits = gltReadBMPBits(szFileName, &iWidth, &iHeight); if(pBits == NULL) return false; // Set Wrap modes glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapMode); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapMode); // Do I need to generate mipmaps? if(minFilter == GL_LINEAR_MIPMAP_LINEAR || minFilter == GL_LINEAR_MIPMAP_NEAREST || minFilter == GL_NEAREST_MIPMAP_LINEAR || minFilter == GL_NEAREST_MIPMAP_NEAREST) glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minFilter); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magFilter); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, iWidth, iHeight, 0, GL_BGR, GL_UNSIGNED_BYTE, pBits); return true; } /////////////////////////////////////////////////////////////////////////////// // OpenGL related startup code is safe to put here. Load textures, etc. void SetupRC(void) { GLenum err = glewInit(); if (GLEW_OK != err) { /* Problem: glewInit failed, something is seriously wrong. */ fprintf(stderr, "Error: %s\n", glewGetErrorString(err)); } // Initialze Shader Manager shaderManager.InitializeStockShaders(); glEnable(GL_DEPTH_TEST); // Black glClearColor(0.0f, 0.0f, 0.0f, 1.0f); gltMakeTorus(torusBatch, 0.4f, 0.15f, 35, 35); GLfloat alpha = 0.25f; floorBatch.Begin(GL_TRIANGLE_FAN, 4, 1); floorBatch.Color4f(0.0f, 1.0f, 0.0f, alpha); floorBatch.MultiTexCoord2f(0, 0.0f, 0.0f); floorBatch.Normal3f(0.0, 1.0f, 0.0f); floorBatch.Vertex3f(-20.0f, -0.41f, 20.0f); floorBatch.Color4f(0.0f, 1.0f, 0.0f, alpha); floorBatch.MultiTexCoord2f(0, 10.0f, 0.0f); floorBatch.Normal3f(0.0, 1.0f, 0.0f); floorBatch.Vertex3f(20.0f, -0.41f, 20.0f); floorBatch.Color4f(0.0f, 1.0f, 0.0f, alpha); floorBatch.MultiTexCoord2f(0, 10.0f, 10.0f); floorBatch.Normal3f(0.0, 1.0f, 0.0f); floorBatch.Vertex3f(20.0f, -0.41f, -20.0f); floorBatch.Color4f(0.0f, 1.0f, 0.0f, alpha); floorBatch.MultiTexCoord2f(0, 0.0f, 10.0f); floorBatch.Normal3f(0.0, 1.0f, 0.0f); floorBatch.Vertex3f(-20.0f, -0.41f, -20.0f); floorBatch.End(); glGenTextures(1, textures); glBindTexture(GL_TEXTURE_2D, textures[0]); LoadBMPTexture("marble.bmp", GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR, GL_REPEAT); // Create blur program blurProg = gltLoadShaderPairWithAttributes("blur.vs", "blur.fs", 2, GLT_ATTRIBUTE_VERTEX, "vVertex", GLT_ATTRIBUTE_TEXTURE0, "texCoord0"); // Create blur textures glGenTextures(6, blurTextures); // ☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆ // XXX I don‘t think this is necessary. Should set texture data to NULL // Allocate a pixel buffer to initialize textures and PBOs // 计算 像素数据的字节数 pixelDataSize = screenWidth * screenHeight * 3 * sizeof(unsigned int); // XXX This should be unsigned byte // 可以直接用 NULL 初始化 Texture //void *data = (void *)malloc(pixelDataSize); //memset(data, 0x00, pixelDataSize); // Setup 6 texture units for blur effect // Initialize texture data for (int i = 0; i < 6; i++) { glActiveTexture(GL_TEXTURE1 + i); glBindTexture(GL_TEXTURE_2D, blurTextures[i]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, screenWidth, screenHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL/*data*/); } // Alloc space for copying pixels so we dont call malloc on every draw // 创建分配 PBO,并绑定为Pack Buffer,类型为GL_DYNAMIC_COPY glGenBuffers(1, pixBuffObjs); glBindBuffer(GL_PIXEL_PACK_BUFFER, pixBuffObjs[0]); glBufferData(GL_PIXEL_PACK_BUFFER, pixelDataSize, pixelData, GL_DYNAMIC_COPY); glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); // ☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆ // Create geometry and a matrix for screen aligned drawing gltGenerateOrtho2DMat(screenWidth, screenHeight, orthoMatrix, screenQuad); // Make sure all went well gltCheckErrors(); } /////////////////////////////////////////////////////////////////////////////// // Do your cleanup here. Free textures, display lists, buffer objects, etc. void ShutdownRC(void) { // Make sure default FBO is bound // 确保绑定默认的 FBO glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); // Cleanup textures for (int i = 0; i < 7; i++) { glActiveTexture(GL_TEXTURE0 + i); glBindTexture(GL_TEXTURE_2D, 0); } // Now delete detached textures glDeleteTextures(1, textures); glDeleteTextures(6, blurTextures); // delete PBO // ☆ 删除 PBO glDeleteBuffers(1, pixBuffObjs); } /////////////////////////////////////////////////////////////////////////////// // This is called at least once and before any rendering occurs. If the screen // is a resizeable window, then this will also get called whenever the window // is resized. void ChangeSize(int nWidth, int nHeight) { glViewport(0, 0, nWidth, nHeight); transformPipeline.SetMatrixStacks(modelViewMatrix, projectionMatrix); viewFrustum.SetPerspective(35.0f, float(nWidth) / float(nHeight), 1.0f, 100.0f); projectionMatrix.LoadMatrix(viewFrustum.GetProjectionMatrix()); modelViewMatrix.LoadIdentity(); // update screen sizes screenWidth = nWidth; screenHeight = nHeight; // reset screen aligned quad gltGenerateOrtho2DMat(screenWidth, screenHeight, orthoMatrix, screenQuad); // ☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆ free(pixelData); pixelDataSize = screenWidth * screenHeight * 3 * sizeof(unsigned int); pixelData = (void *)malloc(pixelDataSize); // Resize PBOs // 如果窗口大小发生变化,则重新分配 PBO glBindBuffer(GL_PIXEL_PACK_BUFFER, pixBuffObjs[0]); glBufferData(GL_PIXEL_PACK_BUFFER, pixelDataSize, pixelData, GL_DYNAMIC_COPY); glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); // ☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆ gltCheckErrors(); } /////////////////////////////////////////////////////////////////////////////// // Update the camera based on user input, toggle display modes // void ProccessKeys(unsigned char key, int x, int y) { static CStopWatch cameraTimer; float fTime = cameraTimer.GetElapsedSeconds(); float linear = fTime * 12.0f; cameraTimer.Reset(); // Alternate between PBOs and local memory when ‘P‘ is pressed // 按 P键 切换 PBO和内存 if(key == ‘P‘ || key == ‘p‘) bUsePBOPath = (bUsePBOPath) ? GL_FALSE : GL_TRUE; // Speed up movement if(key == ‘+‘) { speedFactor += linear / 2; if(speedFactor > 6) speedFactor = 6; } // Slow down moement if(key == ‘-‘) { speedFactor -= linear / 2; if(speedFactor < 0.5) speedFactor = 0.5; } } /////////////////////////////////////////////////////////////////////////////// // Load and setup program for blur effect // void SetupBlurProg(void) { // Set the blur program as the current one glUseProgram(blurProg); // Set MVP matrix glUniformMatrix4fv(glGetUniformLocation(blurProg, "mvpMatrix"), 1, GL_FALSE, transformPipeline.GetModelViewProjectionMatrix()); // Setup the textue units for the blur targets, these rotate every frame glUniform1i(glGetUniformLocation(blurProg, "textureUnit0"), GetBlurTarget0()); glUniform1i(glGetUniformLocation(blurProg, "textureUnit1"), GetBlurTarget1()); glUniform1i(glGetUniformLocation(blurProg, "textureUnit2"), GetBlurTarget2()); glUniform1i(glGetUniformLocation(blurProg, "textureUnit3"), GetBlurTarget3()); glUniform1i(glGetUniformLocation(blurProg, "textureUnit4"), GetBlurTarget4()); glUniform1i(glGetUniformLocation(blurProg, "textureUnit5"), GetBlurTarget5()); } /////////////////////////////////////////////////////////////////////////////// // Draw the scene // void DrawWorld(GLfloat yRot, GLfloat xPos) { M3DMatrix44f mCamera; modelViewMatrix.GetMatrix(mCamera); // Need light position relative to the Camera M3DVector4f vLightTransformed; m3dTransformVector4(vLightTransformed, vLightPos, mCamera); // Draw stuff relative to the camera modelViewMatrix.PushMatrix(); modelViewMatrix.Translate(0.0f, 0.2f, -2.5f); modelViewMatrix.Translate(xPos, 0.0f, 0.0f); modelViewMatrix.Rotate(yRot, 0.0f, 1.0f, 0.0f); shaderManager.UseStockShader(GLT_SHADER_POINT_LIGHT_DIFF, modelViewMatrix.GetMatrix(), transformPipeline.GetProjectionMatrix(), vLightTransformed, vGreen, 0); torusBatch.Draw(); modelViewMatrix.PopMatrix(); } /////////////////////////////////////////////////////////////////////////////// // Render a frame. The owning framework is responsible for buffer swaps, // flushes, etc. void RenderScene(void) { static CStopWatch animationTimer; static float totalTime = 6; // To go back and forth static float halfTotalTime = totalTime / 2; float seconds = animationTimer.GetElapsedSeconds() * speedFactor; float xPos = 0; // Calculate the next postion of the moving object // First perform a mod-like operation on the time as a float while(seconds > totalTime) seconds -= totalTime; // Move object position, if it‘s gone half way across // start bringing it back if(seconds < halfTotalTime) xPos = seconds - halfTotalTime * 0.5f; else xPos = totalTime - seconds - halfTotalTime * 0.5f; // First draw world to screen modelViewMatrix.PushMatrix(); M3DMatrix44f mCamera; cameraFrame.GetCameraMatrix(mCamera); modelViewMatrix.MultMatrix(mCamera); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, textures[0]); // Marble glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); shaderManager.UseStockShader(GLT_SHADER_TEXTURE_MODULATE, transformPipeline.GetModelViewProjectionMatrix(), vWhite, 0); floorBatch.Draw(); DrawWorld(0.0f, xPos); modelViewMatrix.PopMatrix(); if(bUsePBOPath) { // First bind the PBO as the pack buffer, then read the pixels directly to the PBO // ☆ 首先绑定 PBO 为 Pack Buffer,再直接从 Frame Buffer 中读取像素到 PBO ☆ glBindBuffer(GL_PIXEL_PACK_BUFFER, pixBuffObjs[0]); glReadPixels(0, 0, screenWidth, screenHeight, GL_RGB, GL_UNSIGNED_BYTE, NULL); glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); // 解绑 PBO // Next bind the PBO as the unpack buffer, then push the pixels straight into the texture // ☆ 接着绑定 PBO 为 Unpack Buffer,再把 PBO 中的像素直接推送到纹理当中 ☆ glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pixBuffObjs[0]); // Setup texture unit for new blur, this gets imcremented every frame glActiveTexture(GL_TEXTURE0 + GetBlurTarget0() ); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, screenWidth, screenHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); // 解绑 PBO } else { // Grab the screen pixels and copy into local memory // 从FrameBuffer中获取屏幕像素,并拷贝到客户端内存中 glReadPixels(0, 0, screenWidth, screenHeight, GL_RGB, GL_UNSIGNED_BYTE, pixelData); // Push pixels from client memory into texture // Setup texture unit for new blur, this gets imcremented every frame // 推送客户端内存中的像素到纹理中 glActiveTexture(GL_TEXTURE0 + GetBlurTarget0() ); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, screenWidth, screenHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, pixelData); } // Draw full screen quad with blur shader and all blur textures projectionMatrix.PushMatrix(); projectionMatrix.LoadIdentity(); projectionMatrix.LoadMatrix(orthoMatrix); modelViewMatrix.PushMatrix(); modelViewMatrix.LoadIdentity(); glDisable(GL_DEPTH_TEST); SetupBlurProg(); screenQuad.Draw(); glEnable(GL_DEPTH_TEST); modelViewMatrix.PopMatrix(); projectionMatrix.PopMatrix(); // Move to the next blur texture for the next frame AdvanceBlurTaget(); // Do the buffer Swap glutSwapBuffers(); // Do it again glutPostRedisplay(); UpdateFrameCount(); } int main(int argc, char *argv[]) { screenWidth = 800; screenHeight = 600; bFullScreen = false; bAnimated = true; bUsePBOPath = false; // true blurProg = 0; speedFactor = 1.0f; gltSetWorkingDirectory(argv[0]); glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); glutInitWindowSize(screenWidth, screenHeight); glutCreateWindow("Pix Buffs"); glutReshapeFunc(ChangeSize); glutDisplayFunc(RenderScene); glutKeyboardFunc(ProccessKeys); SetupRC(); glutMainLoop(); ShutdownRC(); return 0; }
执行效果图:
相关阅读:OpenGL深入探索——像素缓冲区对象 (PBO)
《OpenGL 超级宝典(Super Bible)第五版》 有关 PBO 的 Example
标签:failed rest buffer tor main orm local amp make
原文地址:http://blog.csdn.net/panda1234lee/article/details/53248556