diff options
Diffstat (limited to 'progs/tests')
-rw-r--r-- | progs/tests/bufferobj.c | 36 | ||||
-rw-r--r-- | progs/tests/fbotest1.c | 15 | ||||
-rw-r--r-- | progs/tests/fbotexture.c | 380 |
3 files changed, 302 insertions, 129 deletions
diff --git a/progs/tests/bufferobj.c b/progs/tests/bufferobj.c index 50ab5cdfa89..d1a85392e1e 100644 --- a/progs/tests/bufferobj.c +++ b/progs/tests/bufferobj.c @@ -22,6 +22,8 @@ struct object GLuint NumVerts; GLuint VertexOffset; GLuint ColorOffset; + GLuint VertexStride; + GLuint ColorStride; GLuint NumElements; }; @@ -46,7 +48,7 @@ static void CheckError(int line) static void DrawObject( const struct object *obj ) { glBindBufferARB(GL_ARRAY_BUFFER_ARB, obj->BufferID); - glVertexPointer(3, GL_FLOAT, 0, (void *) obj->VertexOffset); + glVertexPointer(3, GL_FLOAT, obj->VertexStride, (void *) obj->VertexOffset); glEnable(GL_VERTEX_ARRAY); /* test push/pop attrib */ @@ -60,7 +62,7 @@ static void DrawObject( const struct object *obj ) glPopClientAttrib(); } #endif - glColorPointer(3, GL_FLOAT, 0, (void *) obj->ColorOffset); + glColorPointer(3, GL_FLOAT, obj->ColorStride, (void *) obj->ColorOffset); glEnable(GL_COLOR_ARRAY); if (obj->NumElements > 0) { @@ -241,6 +243,8 @@ static void MakeObject1(struct object *obj) obj->NumVerts = 4; obj->VertexOffset = 0; obj->ColorOffset = 3 * sizeof(GLfloat) * obj->NumVerts; + obj->VertexStride = 0; + obj->ColorStride = 0; obj->NumElements = 0; glUnmapBufferARB(GL_ARRAY_BUFFER_ARB); @@ -255,24 +259,28 @@ static void MakeObject1(struct object *obj) static void MakeObject2(struct object *obj) { - GLfloat *v, *c; + GLfloat *v; + int start = 40; /* bytes, to test non-zero array offsets */ glGenBuffersARB(1, &obj->BufferID); glBindBufferARB(GL_ARRAY_BUFFER_ARB, obj->BufferID); glBufferDataARB(GL_ARRAY_BUFFER_ARB, 1000, NULL, GL_STATIC_DRAW_ARB); v = (GLfloat *) glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB); - /* Make triangle */ - v[0] = -1; v[1] = -1; v[2] = 0; - v[3] = 1; v[4] = -1; v[5] = 0; - v[6] = 0; v[7] = 1; v[8] = 0; - c = v + 9; - c[0] = 0; c[1] = 1; c[2] = 0; - c[3] = 0; c[4] = 1; c[5] = 0; - c[6] = 1; c[7] = 1; c[8] = 0; + v += start / sizeof(GLfloat); + + /* Make triangle: interleaved colors, then positions */ + /* R G B X Y Z */ + v[0] = 0; v[1] = 1; v[2] = 0; v[3] = -1; v[4] = -1; v[5] = 0; + v[6] = 0; v[7] = 1; v[8] = 0; v[9] = 1; v[10] = -1; v[11] = 0; + v[12] = 1; v[13] = 1; v[14] = 0; v[15] = 0; v[16] = 1; v[17] = 0; + obj->NumVerts = 3; - obj->VertexOffset = 0; - obj->ColorOffset = 3 * sizeof(GLfloat) * obj->NumVerts; + obj->VertexOffset = start + 3 * sizeof(GLfloat); + obj->ColorOffset = start; + obj->VertexStride = 6 * sizeof(GLfloat); + obj->ColorStride = 6 * sizeof(GLfloat); + obj->NumElements = 0; glUnmapBufferARB(GL_ARRAY_BUFFER_ARB); @@ -300,6 +308,8 @@ static void MakeObject3(struct object *obj) obj->NumVerts = 4; obj->VertexOffset = 0; obj->ColorOffset = 3 * sizeof(GLfloat) * obj->NumVerts; + obj->VertexStride = 0; + obj->ColorStride = 0; bytes = obj->NumVerts * (3 + 3) * sizeof(GLfloat); diff --git a/progs/tests/fbotest1.c b/progs/tests/fbotest1.c index 8f4569ff3b4..ab2757c3c3d 100644 --- a/progs/tests/fbotest1.c +++ b/progs/tests/fbotest1.c @@ -122,6 +122,7 @@ Key( unsigned char key, int x, int y ) static void Init( void ) { + GLboolean ARB_fbo = glutExtensionSupported("GL_ARB_framebuffer_object"); GLint i; if (!glutExtensionSupported("GL_EXT_framebuffer_object")) { @@ -133,16 +134,20 @@ Init( void ) glGenFramebuffersEXT(1, &MyFB); assert(MyFB); assert(!glIsFramebufferEXT(MyFB)); - glDeleteFramebuffersEXT(1, &MyFB); - assert(!glIsFramebufferEXT(MyFB)); + if (!ARB_fbo) { + glDeleteFramebuffersEXT(1, &MyFB); + assert(!glIsFramebufferEXT(MyFB)); + } /* Note, continue to use MyFB below */ glGenRenderbuffersEXT(1, &MyRB); assert(MyRB); assert(!glIsRenderbufferEXT(MyRB)); - glDeleteRenderbuffersEXT(1, &MyRB); - assert(!glIsRenderbufferEXT(MyRB)); - MyRB = 42; /* an arbitrary ID */ + if (!ARB_fbo) { + glDeleteRenderbuffersEXT(1, &MyRB); + assert(!glIsRenderbufferEXT(MyRB)); + MyRB = 42; /* an arbitrary ID */ + } glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, MyFB); assert(glIsFramebufferEXT(MyFB)); diff --git a/progs/tests/fbotexture.c b/progs/tests/fbotexture.c index 88d0549c808..1f7c45fc794 100644 --- a/progs/tests/fbotexture.c +++ b/progs/tests/fbotexture.c @@ -32,11 +32,13 @@ static int TexWidth = 512, TexHeight = 512; static GLuint MyFB; static GLuint TexObj; -static GLuint DepthRB, StencilRB; +static GLuint DepthRB = 0, StencilRB = 0; static GLboolean Anim = GL_FALSE; static GLfloat Rot = 0.0; static GLboolean UsePackedDepthStencil = GL_FALSE; -static GLuint TextureLevel = 1; /* which texture level to render to */ +static GLboolean UsePackedDepthStencilBoth = GL_FALSE; +static GLboolean Use_ARB_fbo = GL_FALSE; +static GLuint TextureLevel = 0; /* which texture level to render to */ static GLenum TexIntFormat = GL_RGB; /* either GL_RGB or GL_RGBA */ static GLboolean Cull = GL_FALSE; static GLboolean Wireframe = GL_FALSE; @@ -248,8 +250,7 @@ CleanUp(void) glDeleteRenderbuffersEXT(1, &DepthRB); #endif #if STENCIL - if (!UsePackedDepthStencil) - glDeleteRenderbuffersEXT(1, &StencilRB); + glDeleteRenderbuffersEXT(1, &StencilRB); #endif glDeleteFramebuffersEXT(1, &MyFB); @@ -294,140 +295,294 @@ Key(unsigned char key, int x, int y) } -static void -Usage(void) +/** + * Attach depth and stencil renderbuffer(s) to the given framebuffer object. + * \param tryDepthStencil if true, try to use a combined depth+stencil buffer + * \param bindDepthStencil if true, and tryDepthStencil is true, bind with + * the GL_DEPTH_STENCIL_ATTACHMENT target. + * \return GL_TRUE for success, GL_FALSE for failure + */ +static GLboolean +AttachDepthAndStencilBuffers(GLuint fbo, + GLsizei width, GLsizei height, + GLboolean tryDepthStencil, + GLboolean bindDepthStencil, + GLuint *depthRbOut, GLuint *stencilRbOut) { - printf("Usage:\n"); - printf(" a Toggle animation\n"); - printf(" s/s Step/rotate\n"); - printf(" c Toggle back-face culling\n"); - printf(" w Toggle wireframe mode (front-face only)\n"); - printf(" Esc Exit\n"); -} + GLenum status; + *depthRbOut = *stencilRbOut = 0; -static void -Init(int argc, char *argv[]) -{ - static const GLfloat mat[4] = { 1.0, 0.5, 0.5, 1.0 }; - GLint i; + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo); - if (!glutExtensionSupported("GL_EXT_framebuffer_object")) { - printf("GL_EXT_framebuffer_object not found!\n"); - exit(0); - } + if (tryDepthStencil) { + GLuint rb; - if (argc > 1 && strcmp(argv[1], "-ds") == 0) { - if (!glutExtensionSupported("GL_EXT_packed_depth_stencil")) { - printf("GL_EXT_packed_depth_stencil not found!\n"); - exit(0); + glGenRenderbuffersEXT(1, &rb); + glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, rb); + glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, + GL_DEPTH24_STENCIL8_EXT, + width, height); + if (glGetError()) + return GL_FALSE; + + if (bindDepthStencil) { + /* attach to both depth and stencil at once */ + glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, + GL_DEPTH_STENCIL_ATTACHMENT, + GL_RENDERBUFFER_EXT, rb); + if (glGetError()) + return GL_FALSE; + } + else { + /* attach to depth attachment point */ + glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, + GL_DEPTH_ATTACHMENT_EXT, + GL_RENDERBUFFER_EXT, rb); + if (glGetError()) + return GL_FALSE; + + /* and attach to stencil attachment point */ + glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, + GL_STENCIL_ATTACHMENT_EXT, + GL_RENDERBUFFER_EXT, rb); + if (glGetError()) + return GL_FALSE; } - UsePackedDepthStencil = GL_TRUE; - printf("Using GL_EXT_packed_depth_stencil\n"); + + status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); + if (status != GL_FRAMEBUFFER_COMPLETE_EXT) + return GL_FALSE; + + *depthRbOut = *stencilRbOut = rb; + return GL_TRUE; } - printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER)); + /* just depth renderbuffer */ + { + GLuint rb; - /* gen framebuffer id, delete it, do some assertions, just for testing */ - glGenFramebuffersEXT(1, &MyFB); - assert(MyFB); - assert(!glIsFramebufferEXT(MyFB)); - glDeleteFramebuffersEXT(1, &MyFB); - assert(!glIsFramebufferEXT(MyFB)); - /* Note, continue to use MyFB below */ + glGenRenderbuffersEXT(1, &rb); + glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, rb); + glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, + GL_DEPTH_COMPONENT, + width, height); + if (glGetError()) + return GL_FALSE; - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, MyFB); - assert(glIsFramebufferEXT(MyFB)); - glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, &i); - assert(i == MyFB); + /* attach to depth attachment point */ + glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, + GL_DEPTH_ATTACHMENT_EXT, + GL_RENDERBUFFER_EXT, rb); + if (glGetError()) + return GL_FALSE; - /* Make texture object/image */ - glGenTextures(1, &TexObj); - glBindTexture(TexTarget, TexObj); - /* make two image levels */ - glTexImage2D(TexTarget, 0, TexIntFormat, TexWidth, TexHeight, 0, - GL_RGBA, GL_UNSIGNED_BYTE, NULL); - glTexImage2D(TexTarget, 1, TexIntFormat, TexWidth/2, TexHeight/2, 0, - GL_RGBA, GL_UNSIGNED_BYTE, NULL); - TexWidth = TexWidth >> TextureLevel; - TexHeight = TexHeight >> TextureLevel; - - glTexParameteri(TexTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(TexTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - glTexParameteri(TexTarget, GL_TEXTURE_BASE_LEVEL, TextureLevel); - glTexParameteri(TexTarget, GL_TEXTURE_MAX_LEVEL, TextureLevel); + status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); + if (status != GL_FRAMEBUFFER_COMPLETE_EXT) + return GL_FALSE; - CheckError(__LINE__); + *depthRbOut = rb; + } + + /* just stencil renderbuffer */ + { + GLuint rb; + + glGenRenderbuffersEXT(1, &rb); + glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, rb); + glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, + GL_STENCIL_INDEX, + width, height); + if (glGetError()) + return GL_FALSE; + + /* attach to depth attachment point */ + glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, + GL_STENCIL_ATTACHMENT_EXT, + GL_RENDERBUFFER_EXT, rb); + if (glGetError()) + return GL_FALSE; + + status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); + if (status != GL_FRAMEBUFFER_COMPLETE_EXT) + return GL_FALSE; + + *stencilRbOut = rb; + } + + return GL_TRUE; +} + + +static void +ParseArgs(int argc, char *argv[]) +{ + GLint i; + for (i = 1; i < argc; i++) { + if (strcmp(argv[i], "-ds") == 0) { + if (!glutExtensionSupported("GL_EXT_packed_depth_stencil")) { + printf("GL_EXT_packed_depth_stencil not found!\n"); + exit(0); + } + UsePackedDepthStencil = GL_TRUE; + printf("Using GL_EXT_packed_depth_stencil\n"); + } + else if (strcmp(argv[i], "-ds2") == 0) { + if (!glutExtensionSupported("GL_EXT_packed_depth_stencil")) { + printf("GL_EXT_packed_depth_stencil not found!\n"); + exit(0); + } + if (!glutExtensionSupported("GL_ARB_framebuffer_object")) { + printf("GL_ARB_framebuffer_object not found!\n"); + exit(0); + } + UsePackedDepthStencilBoth = GL_TRUE; + printf("Using GL_EXT_packed_depth_stencil and GL_DEPTH_STENCIL attachment point\n"); + } + else if (strcmp(argv[i], "-arb") == 0) { + if (!glutExtensionSupported("GL_ARB_framebuffer_object")) { + printf("Sorry, GL_ARB_framebuffer object not supported!\n"); + } + else { + Use_ARB_fbo = GL_TRUE; + } + } + else { + printf("Unknown option: %s\n", argv[i]); + } + } +} + + +/* + * Make FBO to render into given texture. + */ +static GLuint +MakeFBO_RenderTexture(GLuint TexObj) +{ + GLuint fb; + GLint sizeFudge = 0; + glGenFramebuffersEXT(1, &fb); + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb); /* Render color to texture */ glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, TexTarget, TexObj, TextureLevel); + if (Use_ARB_fbo) { + /* use a smaller depth buffer to see what happens */ + sizeFudge = 90; + } -#if DEPTH - /* make depth renderbuffer */ - glGenRenderbuffersEXT(1, &DepthRB); - assert(DepthRB); - assert(!glIsRenderbufferEXT(DepthRB)); - glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, DepthRB); - assert(glIsRenderbufferEXT(DepthRB)); - if (UsePackedDepthStencil) - glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_STENCIL_EXT, - TexWidth, TexHeight); - else - glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, - TexWidth, TexHeight); - CheckError(__LINE__); - glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT, - GL_RENDERBUFFER_DEPTH_SIZE_EXT, &i); - CheckError(__LINE__); - printf("Depth renderbuffer size = %d bits\n", i); - assert(i > 0); + /* Setup depth and stencil buffers */ + { + GLboolean b; + b = AttachDepthAndStencilBuffers(fb, + TexWidth - sizeFudge, + TexHeight - sizeFudge, + UsePackedDepthStencil, + UsePackedDepthStencilBoth, + &DepthRB, &StencilRB); + if (!b) { + /* try !UsePackedDepthStencil */ + b = AttachDepthAndStencilBuffers(fb, + TexWidth - sizeFudge, + TexHeight - sizeFudge, + !UsePackedDepthStencil, + UsePackedDepthStencilBoth, + &DepthRB, &StencilRB); + } + if (!b) { + printf("Unable to create/attach depth and stencil renderbuffers " + " to FBO!\n"); + exit(1); + } + } - /* attach DepthRB to MyFB */ - glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, - GL_RENDERBUFFER_EXT, DepthRB); -#endif + /* queries */ + { + GLint bits, w, h; - CheckError(__LINE__); + glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, DepthRB); + glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT, + GL_RENDERBUFFER_WIDTH_EXT, &w); + glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT, + GL_RENDERBUFFER_HEIGHT_EXT, &h); + printf("Color/Texture size: %d x %d\n", TexWidth, TexHeight); + printf("Depth buffer size: %d x %d\n", w, h); + + glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT, + GL_RENDERBUFFER_DEPTH_SIZE_EXT, &bits); + printf("Depth renderbuffer size = %d bits\n", bits); -#if STENCIL - if (UsePackedDepthStencil) { - /* DepthRb is a combined depth/stencil renderbuffer */ - glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, - GL_STENCIL_ATTACHMENT_EXT, - GL_RENDERBUFFER_EXT, DepthRB); - } - else { - /* make stencil renderbuffer */ - glGenRenderbuffersEXT(1, &StencilRB); - assert(StencilRB); - assert(!glIsRenderbufferEXT(StencilRB)); glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, StencilRB); - assert(glIsRenderbufferEXT(StencilRB)); - glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_STENCIL_INDEX, - TexWidth, TexHeight); - /* attach StencilRB to MyFB */ - glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, - GL_STENCIL_ATTACHMENT_EXT, - GL_RENDERBUFFER_EXT, StencilRB); + glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT, + GL_RENDERBUFFER_STENCIL_SIZE_EXT, &bits); + printf("Stencil renderbuffer size = %d bits\n", bits); } - glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT, - GL_RENDERBUFFER_STENCIL_SIZE_EXT, &i); - CheckError(__LINE__); - printf("Stencil renderbuffer size = %d bits\n", i); - assert(i > 0); -#endif - CheckError(__LINE__); - - /* bind regular framebuffer */ + /* bind the regular framebuffer */ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); + return fb; +} + + +static void +Init(void) +{ + if (!glutExtensionSupported("GL_EXT_framebuffer_object")) { + printf("GL_EXT_framebuffer_object not found!\n"); + exit(0); + } + + printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER)); /* lighting */ - glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat); + { + static const GLfloat mat[4] = { 1.0, 0.5, 0.5, 1.0 }; + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat); + } + + /* + * Make texture object/image (we'll render into this texture) + */ + { + glGenTextures(1, &TexObj); + glBindTexture(TexTarget, TexObj); + + /* make two image levels */ + glTexImage2D(TexTarget, 0, TexIntFormat, TexWidth, TexHeight, 0, + GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glTexImage2D(TexTarget, 1, TexIntFormat, TexWidth/2, TexHeight/2, 0, + GL_RGBA, GL_UNSIGNED_BYTE, NULL); + TexWidth = TexWidth >> TextureLevel; + TexHeight = TexHeight >> TextureLevel; + + glTexParameteri(TexTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(TexTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(TexTarget, GL_TEXTURE_BASE_LEVEL, TextureLevel); + glTexParameteri(TexTarget, GL_TEXTURE_MAX_LEVEL, TextureLevel); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + } + + MyFB = MakeFBO_RenderTexture(TexObj); +} + + +static void +Usage(void) +{ + printf("Usage:\n"); + printf(" -ds Use combined depth/stencil renderbuffer\n"); + printf(" -arb Try GL_ARB_framebuffer_object's mismatched buffer sizes\n"); + printf(" -ds2 Tye GL_ARB_framebuffer_object's GL_DEPTH_STENCIL_ATTACHMENT\n"); + printf("Keys:\n"); + printf(" a Toggle animation\n"); + printf(" s/s Step/rotate\n"); + printf(" c Toggle back-face culling\n"); + printf(" w Toggle wireframe mode (front-face only)\n"); + printf(" Esc Exit\n"); } @@ -444,8 +599,11 @@ main(int argc, char *argv[]) glutDisplayFunc(Display); if (Anim) glutIdleFunc(Idle); - Init(argc, argv); + + ParseArgs(argc, argv); + Init(); Usage(); + glutMainLoop(); return 0; } |