#include #include #include #include #include #define WINDSIZEX 100 #define WINDSIZEY 100 void init (void) { int i; GLfloat white[] = { 1.0, 1.0, 1.0, 1.0 }; glClearColor (0.0, 0.0, 0.0, 1.0); glColor4fv (white); glDisable (GL_DITHER); // Check if GL_EXT_framebuffer_object is supported if (!strstr (glGetString (GL_EXTENSIONS), "GL_EXT_framebuffer_object")) { printf ("GL_EXT_framebuffer_object is not supported\n"); exit(0); } else { printf ("GL_EXT_framebuffer_object is supported\n"); } } #define CHECK_FRAMEBUFFER_STATUS() \ { \ GLenum status; \ status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); \ switch(status) { \ case GL_FRAMEBUFFER_COMPLETE_EXT: \ printf("GL_FRAMEBUFFER_COMPLETE_EXT\n"); \ break; \ case GL_FRAMEBUFFER_UNSUPPORTED_EXT: \ printf("GL_FRAMEBUFFER_UNSUPPORTED_EXT\n"); \ /* choose different formats */ \ break; \ case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT: \ printf("GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT\n"); \ break; \ case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT: \ printf("GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT\n"); \ break; \ case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT: \ printf("GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT\n"); \ break; \ case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT: \ printf("%d:GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT\n", __LINE__);\ break; \ case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT: \ printf("GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT\n");\ break; \ default: \ /* programming error; will fail on all hardware */ \ printf("programming error\n"); \ break; \ } \ } enum { BLACK, RED, GREEN, BLUE, WHITE }; GLfloat colors[][4] = { {0.0, 0.0, 0.0, 0.0}, {1.0, 0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0}, {0.0, 0.0, 1.0, 1.0}, {1.0, 1.0, 1.0, 1.0} }; #define TEXSIZE 64 static void test (void) { GLfloat red[] = { 1.0, 0.0, 0.0, 1.0 }; GLfloat white[] = { 1.0, 1.0, 1.0, 1.0 }; GLfloat green[] = { 0.0, 1.0, 0.0, 1.0 }; GLuint fbs[1]; GLuint textures[1]; GLint t[TEXSIZE * TEXSIZE * 3]; int i, j, level; glClearColor (0.0, 0.0, 0.0, 1.0); glClear (GL_COLOR_BUFFER_BIT); glGenTextures (1, textures); glBindTexture (GL_TEXTURE_2D, textures[0]); glGenFramebuffersEXT (1, fbs); glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, fbs[0]); // Render to the texture glDisable (GL_TEXTURE_2D); level = 0; for (i=TEXSIZE; i>0; i/=2, level++) { printf("level = %d\n", level); glTexImage2D(GL_TEXTURE_2D, level, GL_RGB, i, i, 0, GL_RGB, GL_INT, NULL); glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, textures[0], level); CHECK_FRAMEBUFFER_STATUS(); glColor4fv(colors[RED + (level % (WHITE - RED))]); glClearColor(0.0, 0.0, 0.0, 0.0); glClear(GL_COLOR_BUFFER_BIT); glBegin(GL_POLYGON); glVertex3f(0, 0, 1); glVertex3f(TEXSIZE, 0, 1); glVertex3f(TEXSIZE, TEXSIZE, 1); glVertex3f(0, TEXSIZE, 1); glEnd(); } // Render to the window glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, 0); glColor4fv (colors[GREEN]); glClearColor (0.0, 0.0, 0.0, 0.0); glClear (GL_COLOR_BUFFER_BIT); glBindTexture (GL_TEXTURE_2D, textures[0]); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); glEnable (GL_TEXTURE_2D); glBegin (GL_POLYGON); glTexCoord2f (0.0, 0.0); glVertex2f (0, 0); glTexCoord2f (1.0, 0.0); glVertex2f (TEXSIZE/2, 0); glTexCoord2f (1.0, 1.0); glVertex2f (TEXSIZE/2, TEXSIZE/2); glTexCoord2f (0.0, 1.0); glVertex2f (0, TEXSIZE/2); glEnd (); GLfloat buf[WINDSIZEX * WINDSIZEY * 3]; printf ("read out non-black pixels:\n"); glReadPixels (0, 0, WINDSIZEX, WINDSIZEY, GL_RGB, GL_FLOAT, buf); #if 1 for (j = 0; j < WINDSIZEY; j++) { for (i = 0; i < WINDSIZEY; i++) { if (buf[(j * WINDSIZEX + i) * 3] != 0 || buf[(j * WINDSIZEX + i) * 3 + 1] != 0 || buf[(j * WINDSIZEX + i) * 3 + 2] != 0) { printf ("(%d, %d) = [%f, %f, %f]\n", i, j, buf[(j * WINDSIZEX + i) * 3], buf[(j * WINDSIZEX + i) * 3 + 1], buf[(j * WINDSIZEX + i) * 3 + 2]); } } } #endif glFlush (); glDeleteTextures(1, textures); glDeleteFramebuffersEXT(1, fbs); } void display (void) { glMatrixMode (GL_PROJECTION); glLoadIdentity (); gluOrtho2D (0, WINDSIZEX, 0, WINDSIZEX); test (); } int main (int argc, char **argv) { glutInit (&argc, argv); glutInitDisplayMode (GLUT_SINGLE | GLUT_RGBA); glutInitWindowSize (WINDSIZEX, WINDSIZEY); glutInitWindowPosition (100, 100); glutCreateWindow (argv[0]); init (); glutDisplayFunc (display); glutMainLoop (); return 0; }