/* * Exercise LLVM stencil bug # 41787 * Command extracted from the GL api trace attached to that bug. */ #include #include #include #include "glut_wrap.h" static int Win; static int WinWidth = 403, WinHeight = 302; static GLfloat Xrot = -70, Yrot = 0, Zrot = 0; static GLboolean Anim = GL_FALSE; static void Idle(void) { Zrot += .2; glutPostRedisplay(); } static void draw_floor(void) { float z = -0.22; glColor3f(.5, .5, 0); glPushMatrix(); glScalef(2, 2, 2); glBegin(GL_TRIANGLE_FAN); #if 0 /* irregular floor */ glColor3f(0, .5, 0); glVertex3f(0, 0, 0); glColor3f(.5, .5, 0); glVertex3f(-1, -1, z); glColor3f(0, .5, 0); glVertex3f(0, -1, z); glColor3f(.5, .5, 0); glVertex3f(1, -1, z); glColor3f(0, .5, 0); glVertex3f(1, 0, z); glColor3f(.5, .5, 0); glVertex3f(1, 1, z); glColor3f(0, .5, 0); glVertex3f(0, 1, z); glColor3f(.5, .5, 0); glVertex3f(-1, 1, z); glColor3f(0, .5, 0); glVertex3f(-1, 0, z); glColor3f(.5, .5, 0); glVertex3f(-1, -1, z); #else /* flat floor */ glVertex3f(-1, -1, z); glVertex3f( 1, -1, z); glVertex3f( 1, 1, z); glVertex3f(-1, 1, z); #endif glEnd(); glPopMatrix(); } /* * Draw a closed shape to represent a shadow volume. */ static void draw_shadow_volume(void) { glPushMatrix(); if (0) { glScalef(1, 1, 4); glutSolidCube(2.0); } else if (0) { glScalef(1, 1, 4); glutSolidDodecahedron(); } else if (1) { /* XXX more tessellation = more artifacts */ glutSolidSphere(1.0, 20*3, 10*3); } else { glutSolidTeapot(1.0); } glPopMatrix(); } static void draw_scene(void) { /*130*/ /*glDepthFunc(GL_LEQUAL);*/ /*220*/ glEnable(GL_DEPTH_TEST); /*247*/ /*glFogi(pname = GL_FOG_COORD_SRC, param = GL_FRAGMENT_DEPTH);*/ /* draw scene */ #if 0 /*387*/ glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); #else glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); #endif #if 0 /*531*/ glDrawElements(GL_TRIANGLES, 468, GL_UNSIGNED_SHORT, blob(936)); /*622*/ glDrawElements(GL_TRIANGLES, 9600, GL_UNSIGNED_SHORT, blob(19200)); /*708*/ glDrawElements(GL_TRIANGLES, 696, GL_UNSIGNED_SHORT, blob(1392)); /*776*/ glDrawElements(GL_TRIANGLES, 4992, GL_UNSIGNED_SHORT, blob(9984)); #else draw_floor(); #endif /*786*/ glPushAttrib(GL_POLYGON_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT); /*789*/ /*glDepthFunc(GL_LEQUAL);*/ /*790*/ glDepthMask(GL_FALSE); #if 1 /*791*/ glColorMask(0, 0, 0, 0); #endif /*792*/ glEnable(GL_STENCIL_TEST); /*793*/ glEnable(GL_POLYGON_OFFSET_FILL); /*794*/ glPolygonOffset(0, 1); /*796*/ glStencilMask(~0); /*797*/ glStencilFunc(GL_ALWAYS, 0, ~0); #if 1 /* XXX WE ONLY SEE CORRUPTION WHEN CULLING IS ENABLED */ /*798*/ glEnable(GL_CULL_FACE); #endif /*799*/ glStencilOp(GL_KEEP, GL_INCR_WRAP, GL_KEEP); /*800*/ glCullFace(GL_FRONT); #if 0 /*802*/ glDrawArrays(GL_TRIANGLES, 0, 23424); #else draw_shadow_volume(); #endif /*803*/ glStencilOp(GL_KEEP, GL_DECR_WRAP, GL_KEEP); /*804*/ glCullFace(GL_BACK); #if 0 /*806*/ glDrawArrays(GL_TRIANGLES, 0, 23424); #else draw_shadow_volume(); #endif /*808*/ glPopAttrib(); /* * draw blended shadow where stencil != 0 */ /*811*/ glPushAttrib(GL_POLYGON_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT); /*814*/ glDepthMask(GL_FALSE); /*815*/ glShadeModel(GL_FLAT); /*816*/ glColorMask(1, 1, 1, 1); /*817*/ glEnable(GL_BLEND); /*818*/ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); /*819*/ glEnable(GL_STENCIL_TEST); /*820*/ glStencilFunc(GL_NOTEQUAL, 0, ~0); /*821*/ glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); /*822*/ glMatrixMode(GL_MODELVIEW); /*823*/ glPushMatrix(); /*824*/ glLoadIdentity(); /*825*/ glMatrixMode(GL_PROJECTION); /*826*/ glPushMatrix(); /*827*/ glLoadIdentity(); /*828*/ glBegin(GL_QUADS); /*829*/ glColor4ub(0, 0, 0, 150); /*830*/ glVertex3f( -1, -1, -0.9); /*831*/ glColor4ub(0, 0, 0, 150); /*832*/ glVertex3f( -1, 1, -0.9); /*833*/ glColor4ub(0, 0, 0, 150); /*834*/ glVertex3f( 1, 1, -0.9); /*835*/ glColor4ub(0, 0, 0, 150); /*836*/ glVertex3f( 1, -1, -0.9); /*837*/ glEnd(); /*838*/ glClear(GL_STENCIL_BUFFER_BIT); /*839*/ glPopMatrix(); /*840*/ glMatrixMode(GL_MODELVIEW); /*841*/ glPopMatrix(); /*842*/ glPopAttrib(); /*890*/ /*glEnable(GL_DEPTH_TEST);*/ /*891*/ /*glDepthFunc(GL_LEQUAL);*/ /*892*/ /*glDepthMask(GL_FALSE);*/ glDisable(GL_BLEND); glDisable(GL_STENCIL_TEST); glDisable(GL_CULL_FACE); glDepthMask(GL_TRUE); } static void Draw(void) { glPushMatrix(); glRotatef(Xrot, 1, 0, 0); glRotatef(Yrot, 0, 1, 0); glRotatef(Zrot, 0, 0, 1); draw_scene(); glPopMatrix(); glutSwapBuffers(); } static void Reshape(int width, int height) { WinWidth = width; WinHeight = height; glViewport(0, 0, width, height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 25.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatef(0.0, 0.0, -15.0); } static void Key(unsigned char key, int x, int y) { const GLfloat step = 3.0; (void) x; (void) y; switch (key) { case 'a': Anim = !Anim; if (Anim) glutIdleFunc(Idle); else glutIdleFunc(NULL); break; case 'z': Zrot -= step; break; case 'Z': Zrot += step; break; case 27: glutDestroyWindow(Win); exit(0); break; } glutPostRedisplay(); } static void SpecialKey(int key, int x, int y) { const GLfloat step = 3.0; (void) x; (void) y; switch (key) { case GLUT_KEY_UP: Xrot -= step; break; case GLUT_KEY_DOWN: Xrot += step; break; case GLUT_KEY_LEFT: Yrot -= step; break; case GLUT_KEY_RIGHT: Yrot += step; break; } glutPostRedisplay(); } static void Init(void) { glShadeModel(GL_FLAT); glClearColor(0, 0.25, 0, 0); } int main(int argc, char *argv[]) { glutInit(&argc, argv); glutInitWindowSize(WinWidth, WinHeight); glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH | GLUT_STENCIL); Win = glutCreateWindow(argv[0]); glutReshapeFunc(Reshape); glutKeyboardFunc(Key); glutSpecialFunc(SpecialKey); glutDisplayFunc(Draw); if (Anim) glutIdleFunc(Idle); Init(); glutMainLoop(); return 0; }