FBO

来源:互联网 发布:软件无线电相关项目 编辑:程序博客网 时间:2024/05/09 07:17

简介:

OpenGL默认的帧缓存包括:颜色缓存、深度缓存、模板缓存、累积缓存。

OpenGL扩展帧缓存(即FBO)包括:颜色缓存、深度缓存、模板缓存。


用途:

1、渲染到纹理:将纹理图像关联到帧缓存,opengl执行渲染到纹理
2、离线渲染:将renderbuffer关联到帧缓存,opengl执行离线渲染

下面这幅图显示了帧缓存对象、纹理对象和渲染缓存对象之间的联系。多多个纹理对象或者渲染缓存对象能够通过关联点关联到一个帧缓存对象上。

OpenGL Frame Buffer Object (FBO)


使用方法:

具体的创建使用过程参见

http://blog.csdn.net/xiajun07061225/article/details/7283929

http://www.cnblogs.com/lizhengjin/archive/2010/12/23/1914795.html


代码:

#include <iostream>#include <gl/glew.h>#include <gl/glut.h>using namespace std; GLuint textureId;   // Storage For 6 face Textures GLuint fboId;GLuint rboId;//camerafloat cameraAngleX;float cameraAngleY;float cameraDistance = -6.0;//mousebool mouseLeftDown;bool mouseRightDown;float LastXPos;float LastYPos;const int    IMAGE_WIDTH = 256;const int    IMAGE_HEIGHT = 256;bool checkFramebufferStatus(){// check FBO statusGLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);switch(status){case GL_FRAMEBUFFER_COMPLETE:std::cout << "Framebuffer complete." << std::endl;return true;case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:std::cout << "[ERROR] Framebuffer incomplete: Attachment is NOT complete." << std::endl;return false;case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:std::cout << "[ERROR] Framebuffer incomplete: No image is attached to FBO." << std::endl;return false;/*case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS:std::cout << "[ERROR] Framebuffer incomplete: Attached images have different dimensions." << std::endl;return false;case GL_FRAMEBUFFER_INCOMPLETE_FORMATS:std::cout << "[ERROR] Framebuffer incomplete: Color attached images have different internal formats." << std::endl;return false;*/case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER:std::cout << "[ERROR] Framebuffer incomplete: Draw buffer." << std::endl;return false;case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER:std::cout << "[ERROR] Framebuffer incomplete: Read buffer." << std::endl;return false;case GL_FRAMEBUFFER_UNSUPPORTED:std::cout << "[ERROR] Framebuffer incomplete: Unsupported by FBO implementation." << std::endl;return false;default:std::cout << "[ERROR] Framebuffer incomplete: Unknown error." << std::endl;return false;}}void initGL(){glEnable(GL_DEPTH_TEST);glEnable(GL_TEXTURE_2D);       // Enable Texture MappingglShadeModel(GL_SMOOTH);       // Enable Smooth ShadingglClearColor(0.0f, 0.0f, 0.0f, 0.5f);    // Black BackgroundglClearDepth(1.0f);                         // 0 is near, 1 is farglDepthFunc(GL_LEQUAL);glGenTextures(1, &textureId);glBindTexture(GL_TEXTURE_2D, textureId);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, IMAGE_WIDTH, IMAGE_HEIGHT, 0, GL_BGRA, GL_UNSIGNED_BYTE, 0);glBindTexture(GL_TEXTURE_2D, 0);glGenFramebuffers(1, &fboId);glBindFramebuffer(GL_FRAMEBUFFER, fboId);// create a renderbuffer object to store depth info// NOTE: A depth renderable image should be attached the FBO for depth test.// If we don't attach a depth renderable image to the FBO, then// the rendering output will be corrupted because of missing depth test.// If you also need stencil test for your rendering, then you must// attach additional image to the stencil attachement point, too.glGenRenderbuffers(1, &rboId);glBindRenderbuffer(GL_RENDERBUFFER, rboId);glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, IMAGE_WIDTH, IMAGE_HEIGHT);glBindRenderbuffer(GL_RENDERBUFFER, 0); // attach a texture to FBO color attachement pointglFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureId, 0);// attach a renderbuffer to depth attachment pointglFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rboId);checkFramebufferStatus();glBindFramebuffer(GL_FRAMEBUFFER, 0);}void draw(){glBindTexture(GL_TEXTURE_2D, textureId);glColor4f(1, 1, 1, 1);// Front FaceglBegin(GL_QUADS);glNormal3f( 0.0f, 0.0f, 1.0f);glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f,  1.0f);glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f);glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,  1.0f,  1.0f);glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,  1.0f,  1.0f);glEnd();// Back FaceglBegin(GL_QUADS);glNormal3f( 0.0f, 0.0f,-1.0f);glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f,  1.0f, -1.0f);glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f,  1.0f, -1.0f);glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);glEnd();// Top FaceglBegin(GL_QUADS);glNormal3f( 0.0f, 1.0f, 0.0f);glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,  1.0f, -1.0f);glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f,  1.0f,  1.0f);glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f,  1.0f,  1.0f);glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,  1.0f, -1.0f);glEnd();// Bottom FaceglBegin(GL_QUADS);glNormal3f( 0.0f,-1.0f, 0.0f);glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, -1.0f);glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, -1.0f, -1.0f);glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f);glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f,  1.0f);glEnd();// Right faceglBegin(GL_QUADS);glNormal3f( 1.0f, 0.0f, 0.0f);glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,  1.0f, -1.0f);glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f,  1.0f,  1.0f);glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f);glEnd();// Left FaceglBegin(GL_QUADS);glNormal3f(-1.0f, 0.0f, 0.0f);glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f,  1.0f);glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f,  1.0f,  1.0f);glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,  1.0f, -1.0f);glEnd();glBindTexture(GL_TEXTURE_2D, 0);}void display(){glLoadIdentity();glTranslatef(0, 0, cameraDistance);glBindFramebuffer(GL_FRAMEBUFFER, fboId);glClearColor(1.0, 1.0, 1.0, 1.0);glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);glPushMatrix();glTranslatef(-1.1, -1.875f, 0);glColor4f(1.0f, 0.0f, 0.0f, 0.5f);glutWireTeapot(0.7f);glPopMatrix();glBindFramebuffer(GL_FRAMEBUFFER, 0); // unbind// trigger mipmaps generation explicitly// NOTE: If GL_GENERATE_MIPMAP is set to GL_TRUE, then glCopyTexSubImage2D()// triggers mipmap generation automatically. However, the texture attached// onto a FBO should generate mipmaps manually via glGenerateMipmap().glBindTexture(GL_TEXTURE_2D, textureId);glGenerateMipmap(GL_TEXTURE_2D);glBindTexture(GL_TEXTURE_2D, 0);glLoadIdentity();glTranslatef(0, 0, cameraDistance);glRotatef(cameraAngleX, 1, 0, 0);   // pitchglRotatef(cameraAngleY, 0, 1, 0);   // heading// clear framebufferglClearColor(0, 0, 0, 0);glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);glPushMatrix();// draw a cube with the dynamic texturedraw();glPopMatrix();glutSwapBuffers();}void reshape(int w, int h){glViewport(0, 0, w, h);glMatrixMode(GL_PROJECTION);glLoadIdentity();gluPerspective(60.0f, (GLfloat)w/(GLfloat)h, 0.01f, 100.0f);glMatrixMode(GL_MODELVIEW);glLoadIdentity();}void mouse(int button, int state, int x, int y){if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN){mouseLeftDown = true;LastXPos = x;LastYPos = y;}if (button == GLUT_RIGHT_BUTTON && state == GLUT_UP){mouseRightDown = true;}}void mouseMotion(int x, int y){if (mouseLeftDown){cameraAngleX += GLfloat(y - LastYPos)/GLfloat(20.0);cameraAngleY += GLfloat(x - LastXPos)/GLfloat(20.0);LastYPos = y;LastXPos = x;}}int main(int argc, char **argv){glutInit(&argc, argv);glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);glutInitWindowSize(480, 640);glutInitWindowPosition(100, 100);glutCreateWindow("FBO");glewInit();if(!glewIsSupported("GL_VERSION_2_0")){fprintf(stderr, "ERROR: Support for necessary OpengGL extensions missing.");}initGL();glutDisplayFunc(display);glutIdleFunc(display);  glutReshapeFunc(reshape);glutMouseFunc(mouse);glutMotionFunc(mouseMotion);glutMainLoop();glDeleteTextures(1, &textureId);glDeleteFramebuffers(1, &fboId);glDeleteRenderbuffers(1, &rboId);return 0;}




another sample

#include <iostream>#include <gl/glew.h>#include <gl/glut.h>using namespace std; GLuint textureId;   // Storage For 6 face Textures GLuint fboId;GLuint rboId;//camerafloat cameraAngleX;float cameraAngleY;float cameraDistance = -6.0;//mousebool mouseLeftDown;bool mouseRightDown;float LastXPos;float LastYPos;const int    IMAGE_WIDTH = 256;const int    IMAGE_HEIGHT = 256;bool checkFramebufferStatus(){// check FBO statusGLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);switch(status){case GL_FRAMEBUFFER_COMPLETE:std::cout << "Framebuffer complete." << std::endl;return true;case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:std::cout << "[ERROR] Framebuffer incomplete: Attachment is NOT complete." << std::endl;return false;case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:std::cout << "[ERROR] Framebuffer incomplete: No image is attached to FBO." << std::endl;return false;/*case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS:std::cout << "[ERROR] Framebuffer incomplete: Attached images have different dimensions." << std::endl;return false;case GL_FRAMEBUFFER_INCOMPLETE_FORMATS:std::cout << "[ERROR] Framebuffer incomplete: Color attached images have different internal formats." << std::endl;return false;*/case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER:std::cout << "[ERROR] Framebuffer incomplete: Draw buffer." << std::endl;return false;case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER:std::cout << "[ERROR] Framebuffer incomplete: Read buffer." << std::endl;return false;case GL_FRAMEBUFFER_UNSUPPORTED:std::cout << "[ERROR] Framebuffer incomplete: Unsupported by FBO implementation." << std::endl;return false;default:std::cout << "[ERROR] Framebuffer incomplete: Unknown error." << std::endl;return false;}}void createFBO(){glGenTextures(1, &textureId);glBindTexture(GL_TEXTURE_2D, textureId);glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, IMAGE_WIDTH, IMAGE_HEIGHT, 0, GL_BGRA, GL_UNSIGNED_BYTE, 0);glGenFramebuffers(1, &fboId);glBindFramebuffer(GL_FRAMEBUFFER, fboId);glGenRenderbuffers(1, &rboId);glBindRenderbuffer(GL_RENDERBUFFER, rboId);glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, IMAGE_WIDTH, IMAGE_HEIGHT);glBindRenderbuffer(GL_RENDERBUFFER, 0);//attach a texture to FBO color attachment pointglFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureId, 0);//attach a renderbuffer to depth attachment pointglFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rboId);checkFramebufferStatus();glBindFramebuffer(GL_FRAMEBUFFER, 0);}void deleteFBO(){if (textureId)glDeleteTextures(1, &textureId);if (fboId)glDeleteFramebuffers(1, &fboId);if (rboId)glDeleteFramebuffers(1, &rboId);}void initGL(){glEnable(GL_DEPTH_TEST);glEnable(GL_TEXTURE_2D);       // Enable Texture MappingglShadeModel(GL_SMOOTH);       // Enable Smooth ShadingglClearColor(0.0f, 0.0f, 0.0f, 0.5f);    // Black BackgroundglClearDepth(1.0f);                         // 0 is near, 1 is farglDepthFunc(GL_LEQUAL);createFBO();}void draw(){glBindTexture(GL_TEXTURE_2D, textureId);glColor4f(1, 1, 0, 1);glBegin(GL_QUADS);{glTexCoord2f( 0.0f, 0.0f);glVertex2f(-1, -1);glTexCoord2f( 1.0f, 0.0f);glVertex2f( 1, -1);glTexCoord2f( 1.0f, 1.0f);glVertex2f( 1,  1);glTexCoord2f( 0.0f, 1.0f);glVertex2f(-1,  1);}glEnd();glBindTexture(GL_TEXTURE_2D, 0);}void display(){glLoadIdentity();glTranslatef(0, 0, cameraDistance);glBindFramebuffer(GL_FRAMEBUFFER, fboId);glClearColor(1.0, 1.0, 1.0, 1.0);glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);glPushMatrix();glTranslatef(-1.1, -1.875f, 0);glColor4f(1.0f, 0.0f, 0.0f, 0.5f);//glutWireTeapot(0.7f);glutSolidTeapot(0.7);glPopMatrix();glBindFramebuffer(GL_FRAMEBUFFER, 0); // unbind// trigger mipmaps generation explicitly// NOTE: If GL_GENERATE_MIPMAP is set to GL_TRUE, then glCopyTexSubImage2D()// triggers mipmap generation automatically. However, the texture attached// onto a FBO should generate mipmaps manually via glGenerateMipmap().glBindTexture(GL_TEXTURE_2D, textureId);glGenerateMipmap(GL_TEXTURE_2D);glBindTexture(GL_TEXTURE_2D, 0);glLoadIdentity();glTranslatef(0, 0, cameraDistance);glRotatef(cameraAngleX, 1, 0, 0);   // pitchglRotatef(cameraAngleY, 0, 1, 0);   // heading// clear framebufferglClearColor(0, 0, 0, 0);glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);glPushMatrix();// draw a cube with the dynamic texturedraw();glPopMatrix();glutSwapBuffers();}void reshape(int w, int h){glViewport(0, 0, w, h);glMatrixMode(GL_PROJECTION);glLoadIdentity();gluPerspective(60.0f, (GLfloat)w/(GLfloat)h, 0.01f, 100.0f);glMatrixMode(GL_MODELVIEW);glLoadIdentity();}void mouse(int button, int state, int x, int y){if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN){mouseLeftDown = true;LastXPos = x;LastYPos = y;}if (button == GLUT_RIGHT_BUTTON && state == GLUT_UP){mouseRightDown = true;}}void mouseMotion(int x, int y){if (mouseLeftDown){cameraAngleX += GLfloat(y - LastYPos)/GLfloat(20.0);cameraAngleY += GLfloat(x - LastXPos)/GLfloat(20.0);LastYPos = y;LastXPos = x;}}int main(int argc, char **argv){glutInit(&argc, argv);glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);glutInitWindowSize(480, 640);glutInitWindowPosition(100, 100);glutCreateWindow("FBO");glewInit();if(!glewIsSupported("GL_VERSION_2_0")){fprintf(stderr, "ERROR: Support for necessary OpengGL extensions missing.");}initGL();glutDisplayFunc(display);glutIdleFunc(display);  glutReshapeFunc(reshape);glutMouseFunc(mouse);glutMotionFunc(mouseMotion);glutMainLoop();deleteFBO();return 0;}



原创粉丝点击