#include #include #include #include #include GLuint fb,depth_rb,tex; #define CHECK_FRAMEBUFFER_STATUS() \ {\ GLenum status; \ status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); \ fprintf(stderr, "%x\n", status);\ switch(status) { \ case GL_FRAMEBUFFER_COMPLETE_EXT: \ fprintf(stderr,"framebuffer complete!\n");\ break; \ case GL_FRAMEBUFFER_UNSUPPORTED_EXT: \ fprintf(stderr,"framebuffer GL_FRAMEBUFFER_UNSUPPORTED_EXT\n");\ /* you gotta choose different formats */ \ assert(0); \ break; \ case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT: \ fprintf(stderr,"framebuffer INCOMPLETE_ATTACHMENT\n");\ break; \ case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT: \ fprintf(stderr,"framebuffer FRAMEBUFFER_MISSING_ATTACHMENT\n");\ break; \ case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT: \ fprintf(stderr,"framebuffer FRAMEBUFFER_DIMENSIONS\n");\ break; \ case GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT: \ fprintf(stderr,"framebuffer INCOMPLETE_DUPLICATE_ATTACHMENT\n");\ break; \ case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT: \ fprintf(stderr,"framebuffer INCOMPLETE_FORMATS\n");\ break; \ case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT: \ fprintf(stderr,"framebuffer INCOMPLETE_DRAW_BUFFER\n");\ break; \ case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT: \ fprintf(stderr,"framebuffer INCOMPLETE_READ_BUFFER\n");\ break; \ case GL_FRAMEBUFFER_BINDING_EXT: \ fprintf(stderr,"framebuffer BINDING_EXT\n");\ break; \ /* case GL_FRAMEBUFFER_STATUS_ERROR_EXT: \ fprintf(stderr,"framebuffer STATUS_ERROR\n");\ break; \ */ \ default: \ /* programming error; will fail on all hardware */ \ assert(0); \ }\ } int imageWinWidth = 256; int imageWinHeight = 256; void reshape(int w, int h) { glClearColor (0.0, 0.0, 0.0, 0.0); glViewport(0, 0, (GLsizei) w, (GLsizei) h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glFrustum(0.0, 1.0, 1.0, 0.0, 1.0, 100.0); gluLookAt(0.0,0.0,0.0, 0.0, 0.0, -1.0, 0.0, 1.0, 0.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glutPostRedisplay(); } static GLenum errCode; const GLubyte *errString; void errcheck() { if ((errCode = glGetError()) != GL_NO_ERROR) { errString = gluErrorString(errCode); fprintf (stderr, "OpenGL Error: %s\n", errString); exit(1); } } void myIdle(){ glutPostRedisplay(); } void keyboard (unsigned char key, int x, int y) { switch (key) { case 27: exit(0); break; default: break; } } void MouseFunc( int button, int state, int x, int y) { switch(button) { case GLUT_LEFT_BUTTON : break; case GLUT_RIGHT_BUTTON : break; } } void render_redirect() { //bind the FBO, and the associated texture. glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb); // draw a scene. the results are being // written into the associated texture,'tex' glClearColor(0.0, 0.0, 1.0, 1.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glColor4f( 1.0, 1.0, 1.0, 1.0); glLineWidth(5.0); glBegin(GL_LINES); glColor4f( 1.0, 1.0, 1.0, 1.0); glVertex3f( 0.0, 0.0, -1.0); glVertex3f( 1.0, 1.0, -1.0); glEnd(); // 'unbind' the FBO. things will now be drawn to screen as usual glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); glClearColor(0.0, 1.0, 0.0, 1.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glColor3f(1.0, 1.0, 1.0); glEnable(GL_TEXTURE_RECTANGLE_NV); glBindTexture(GL_TEXTURE_RECTANGLE_NV, tex); // draw the 'tex' texture containing the framebuffer rendered drawing. glBegin(GL_QUADS); glTexCoord2f(0, 0); glVertex3f(0.0, 0.0, -1.0); glTexCoord2f(0, 256); glVertex3f(0.0, .5, -1.0); glTexCoord2f(256,256); glVertex3f(.5,.5, -1.0); glTexCoord2f(256,0); glVertex3f(.5, 0.0, -1.0); glEnd(); glDisable(GL_TEXTURE_RECTANGLE_NV); glutSwapBuffers(); } int main(int argc, char *argv[] ) { glutInit( &argc, argv ); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH); glutInitWindowSize(imageWinWidth, imageWinHeight); glutCreateWindow(argv[0]); //gen the frambuffer object (FBO), similar manner as a texture glGenFramebuffersEXT(1, &fb); errcheck(); // make a texture glGenTextures(1, &tex); // texture //bind the framebuffer, fb, so operations will now occur on it glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb); // initialize texture that will store the framebuffer image glBindTexture(GL_TEXTURE_RECTANGLE_NV, tex); glTexImage2D(GL_TEXTURE_RECTANGLE_NV, 0, GL_RGBA, 256,256, 0, GL_RGBA, GL_UNSIGNED_BYTE,NULL); errcheck(); // bind this texture to the current framebuffer obj. as // color_attachement_0 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_NV, tex, 0); errcheck(); //see if everything is OK CHECK_FRAMEBUFFER_STATUS() //'unbind' the frambuffer object, so subsequent drawing ops are not // drawn into the FBO. // '0' means "windowing system provided framebuffer glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); glutDisplayFunc(render_redirect); glutIdleFunc(myIdle); glutReshapeFunc(reshape); glutKeyboardFunc(keyboard); glutMouseFunc(MouseFunc); glutMainLoop(); return 0; }