//#undef GL_EXT_framebuffer_object #if defined GL_EXT_framebuffer_object && GL_EXT_framebuffer_object static const char *framebuffer_status_to_string(GLenum status) { switch (status) { case GL_FRAMEBUFFER_COMPLETE_EXT : return "FRAMEBUFFER_COMPLETE_EXT 0x8CD5"; case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT : return "FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT 0x8CD6"; case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT : return "FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT 0x8CD7"; //case GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT : return "FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT 0x8CD8"; case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT : return "FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT 0x8CD9"; case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT : return "FRAMEBUFFER_INCOMPLETE_FORMATS_EXT 0x8CDA"; case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT : return "FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT 0x8CDB"; case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT : return "FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT 0x8CDC"; case GL_FRAMEBUFFER_UNSUPPORTED_EXT : return "FRAMEBUFFER_UNSUPPORTED_EXT 0x8CDD"; } abort(); } #endif static float cube_vertices[8 * 3] = { -1, -1, -1, -1, -1, 1, -1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, -1, 1, 1, 1 }; static float cube_texcoords[8 * 2] = { 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1 }; static GLuint cube_indices[6 * 4] = { 0, 1, 3, 2, 4, 5, 7, 6, 0, 1, 5, 4, 2, 3, 7, 6, 0, 2, 6, 4, 1, 3, 7, 5 }; static void draw_cube(void) { glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glVertexPointer(3, GL_FLOAT, 0, cube_vertices); glTexCoordPointer(2, GL_FLOAT, 0, cube_texcoords); glDrawElements(GL_QUADS, 6 * 4, GL_UNSIGNED_INT, cube_indices); glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); } static GLuint texture_id; #if defined GL_EXT_framebuffer_object && GL_EXT_framebuffer_object static GLuint framebuffer_id; #endif static int use_fbo = 0; static void display(void) { unsigned width = glutGet(GLUT_WINDOW_WIDTH); unsigned height = glutGet(GLUT_WINDOW_HEIGHT); static int last_frame_time = 0; if (last_frame_time == 0) { last_frame_time = glutGet(GLUT_ELAPSED_TIME); } int now = glutGet(GLUT_ELAPSED_TIME); double dt = (now - last_frame_time) * 0.001; last_frame_time = now; static double angle = 0.0; angle += M_PI * dt; if (angle > M_PI) { angle -= 2.0 * M_PI; } if (use_fbo) { #if defined GL_EXT_framebuffer_object && GL_EXT_framebuffer_object glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, framebuffer_id); #endif } glClear(GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(-1.0, 1.0, -1.0, 1.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glBegin(GL_QUADS); glColor3f(sin(angle), cos(angle), 0.0f); glVertex2f(-1.0f, -1.0f); glColor3f(0.0f, sin(angle), cos(angle)); glVertex2f(1.0f, -1.0f); glColor3f(cos(angle), 0.0f, sin(angle)); glVertex2f(1.0f, 1.0f); glColor3f(1.0f, 1.0f, 1.0f); glVertex2f(-1.0f, 1.0f); glEnd(); glColor3f(1.0f, 1.0f, 1.0f); if (use_fbo) { #if defined GL_EXT_framebuffer_object && GL_EXT_framebuffer_object glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); #endif } else { glBindTexture(GL_TEXTURE_2D, texture_id); glCopyTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, 0, 0, width, height); glBindTexture(GL_TEXTURE_2D, 0); } glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(45.0, (double)width / (double)height, 1.0, 100.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(6.0 * cos(angle), 0.0, 6.0 * sin(angle), 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, texture_id); draw_cube(); glBindTexture(GL_TEXTURE_2D, 0); glDisable(GL_TEXTURE_2D); glutSwapBuffers(); glutReportErrors(); } static void reshape(int width, int height) { glViewport(0, 0, width, height); #if defined(GL_ATI_texture_float) && GL_ATI_texture_float && 0 GLenum internal_format = GL_RGBA_FLOAT32_ATI; printf("Using float FBO\n"); #else GLenum internal_format = GL_RGBA; printf("Not using float FBO\n"); #endif glBindTexture(GL_TEXTURE_2D, texture_id); glTexImage2D( GL_TEXTURE_2D, 0, internal_format, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glBindTexture(GL_TEXTURE_2D, 0); #if defined GL_EXT_framebuffer_object && GL_EXT_framebuffer_object glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, framebuffer_id); glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, texture_id, 0); printf("framebuffer completeness: %s\n", framebuffer_status_to_string( glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT))); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); #endif } static void idle(void) { glutPostRedisplay(); } static void keyboard(unsigned char k, int x, int y) { #if defined GL_EXT_framebuffer_object && GL_EXT_framebuffer_object if (k == 'f') { use_fbo = !use_fbo; printf("%susing fbo\n", use_fbo ? "" : "not "); } #endif } int main(int argc, char **argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH); glutInitWindowSize(512, 512); glutCreateWindow("GL_EXT_framebuffer_object Test"); glEnable(GL_DEPTH_TEST); glReadBuffer(GL_BACK); glGenTextures(1, &texture_id); #if defined GL_EXT_framebuffer_object && GL_EXT_framebuffer_object glGenFramebuffersEXT(1, &framebuffer_id); #endif glutDisplayFunc(display); glutReshapeFunc(reshape); glutIdleFunc(idle); glutKeyboardFunc(keyboard); glutMainLoop(); return EXIT_SUCCESS; }