1/* 2 * Test GL_EXT_framebuffer_object 3 * Like fbotest2.c but use a texture for the Z buffer / renderbuffer. 4 * Note: the Z texture is never resized so that limits what can be 5 * rendered if the window is resized. 6 * 7 * This tests a bug reported by Christoph Bumiller on 1 Feb 2010 8 * on mesa3d-dev. 9 * 10 * XXX this should be made into a piglit test. 11 * 12 * Brian Paul 13 * 1 Feb 2010 14 */ 15 16 17#include <assert.h> 18#include <stdio.h> 19#include <stdlib.h> 20#include <math.h> 21#include <GL/glew.h> 22#include "glut_wrap.h" 23 24 25static int Win = 0; 26static int Width = 400, Height = 400; 27static GLuint Tex = 0; 28static GLuint MyFB, ColorRb, DepthRb; 29static GLboolean Animate = GL_FALSE; 30static GLfloat Rotation = 0.0; 31 32 33static void 34CheckError(int line) 35{ 36 GLenum err = glGetError(); 37 if (err) { 38 printf("fbotest3: GL Error 0x%x at line %d\n", (int) err, line); 39 } 40} 41 42 43static void 44Display( void ) 45{ 46 GLubyte *buffer = malloc(Width * Height * 4); 47 GLenum status; 48 49 CheckError(__LINE__); 50 51 /* draw to user framebuffer */ 52 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, MyFB); 53 glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); 54 glReadBuffer(GL_COLOR_ATTACHMENT0_EXT); 55 56 status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); 57 if (status != GL_FRAMEBUFFER_COMPLETE_EXT) { 58 printf("fbotest3: Error: Framebuffer is incomplete!!!\n"); 59 } 60 61 CheckError(__LINE__); 62 63 glClearColor(0.5, 0.5, 1.0, 0.0); 64 glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); 65 66 glEnable(GL_DEPTH_TEST); 67 glEnable(GL_LIGHTING); 68 glEnable(GL_LIGHT0); 69 70 glPushMatrix(); 71 glRotatef(30.0, 1, 0, 0); 72 glRotatef(Rotation, 0, 1, 0); 73 glutSolidTeapot(2.0); 74 glPopMatrix(); 75 76 /* read from user framebuffer */ 77 glReadPixels(0, 0, Width, Height, GL_RGBA, GL_UNSIGNED_BYTE, buffer); 78 79 /* draw to window */ 80 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); 81 glDisable(GL_DEPTH_TEST); /* in case window has depth buffer */ 82 glWindowPos2iARB(0, 0); 83 glDrawPixels(Width, Height, GL_RGBA, GL_UNSIGNED_BYTE, buffer); 84 85 free(buffer); 86 glutSwapBuffers(); 87 CheckError(__LINE__); 88} 89 90 91static void 92Reshape( int width, int height ) 93{ 94 float ar = (float) width / (float) height; 95 96 glViewport( 0, 0, width, height ); 97 glMatrixMode( GL_PROJECTION ); 98 glLoadIdentity(); 99 glFrustum( -ar, ar, -1.0, 1.0, 5.0, 25.0 ); 100 101 glMatrixMode( GL_MODELVIEW ); 102 glLoadIdentity(); 103 glTranslatef( 0.0, 0.0, -15.0 ); 104 105 glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, ColorRb); 106 glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGB, width, height); 107 108 Width = width; 109 Height = height; 110} 111 112 113static void 114CleanUp(void) 115{ 116 glDeleteFramebuffersEXT(1, &MyFB); 117 glDeleteRenderbuffersEXT(1, &ColorRb); 118 glDeleteRenderbuffersEXT(1, &DepthRb); 119 glDeleteTextures(1, &Tex); 120 assert(!glIsFramebufferEXT(MyFB)); 121 assert(!glIsRenderbufferEXT(ColorRb)); 122 assert(!glIsRenderbufferEXT(DepthRb)); 123 glutDestroyWindow(Win); 124 exit(0); 125} 126 127 128static void 129Idle(void) 130{ 131 Rotation = glutGet(GLUT_ELAPSED_TIME) * 0.1; 132 glutPostRedisplay(); 133} 134 135 136static void 137Key( unsigned char key, int x, int y ) 138{ 139 (void) x; 140 (void) y; 141 switch (key) { 142 case 'a': 143 Animate = !Animate; 144 if (Animate) 145 glutIdleFunc(Idle); 146 else 147 glutIdleFunc(NULL); 148 break; 149 case 27: 150 CleanUp(); 151 break; 152 } 153 glutPostRedisplay(); 154} 155 156 157static void 158Init( void ) 159{ 160 if (!glutExtensionSupported("GL_EXT_framebuffer_object")) { 161 printf("fbotest3: GL_EXT_framebuffer_object not found!\n"); 162 exit(0); 163 } 164 printf("fbotest3: GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER)); 165 166 /* create initial tex obj as an RGBA texture */ 167 glGenTextures(1, &Tex); 168 glBindTexture(GL_TEXTURE_2D, Tex); 169 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, 170 GL_RGBA, GL_UNSIGNED_BYTE, NULL); 171 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 172 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 173 glEnable(GL_TEXTURE_2D); 174 175 /* draw something to make sure the texture is used */ 176 glBegin(GL_POINTS); 177 glVertex2f(0, 0); 178 glEnd(); 179 180 /* done w/ texturing */ 181 glDisable(GL_TEXTURE_2D); 182 183 /* Create my Framebuffer Object */ 184 glGenFramebuffersEXT(1, &MyFB); 185 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, MyFB); 186 assert(glIsFramebufferEXT(MyFB)); 187 188 /* Setup color renderbuffer */ 189 glGenRenderbuffersEXT(1, &ColorRb); 190 glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, ColorRb); 191 assert(glIsRenderbufferEXT(ColorRb)); 192 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, 193 GL_RENDERBUFFER_EXT, ColorRb); 194 glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGB, Width, Height); 195 196 /* Setup depth renderbuffer (a texture) */ 197 glGenRenderbuffersEXT(1, &DepthRb); 198 glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, DepthRb); 199 assert(glIsRenderbufferEXT(DepthRb)); 200 /* replace RGBA texture with Z texture */ 201 glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, Width, Height, 0, 202 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL); 203 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, 204 GL_TEXTURE_2D, Tex, 0); 205 206 CheckError(__LINE__); 207 208 /* restore to default */ 209 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); 210 CheckError(__LINE__); 211} 212 213 214int 215main( int argc, char *argv[] ) 216{ 217 glutInit( &argc, argv ); 218 glutInitWindowPosition( 0, 0 ); 219 glutInitWindowSize(Width, Height); 220 glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE ); 221 Win = glutCreateWindow(argv[0]); 222 glewInit(); 223 glutReshapeFunc( Reshape ); 224 glutKeyboardFunc( Key ); 225 glutDisplayFunc( Display ); 226 if (Animate) 227 glutIdleFunc(Idle); 228 Init(); 229 glutMainLoop(); 230 return 0; 231} 232