/* Demo of three interpenetrating quads, to show transparency. Implemented Fall 2003 Scott D. Anderson */ #include #include bool BgBlack = true; bool MidTrans = false; bool DepthMask = true; bool DepthTest = true; bool OpaqueFirst = true; float TextLeft = -0.2; // X coordinate for left end of text // I'm trying to make the cross section have an equilateral triangle, in // the unit square, so this constant is useful, since it's the slope of // the non-horizontal lines. const float C=1.7320508075688772; // sqrt(3); void opaqueRedQuad() { glBegin(GL_QUADS); glColor4f(1,0,0,1); // solid red glVertex3f(0,C/2,-1); // back left glVertex3f(0,C/2,1); // front left glVertex3f(1,C/2,1); // front right glVertex3f(1,C/2,-1); // back right glEnd(); } void transparentGreenBlueQuads() { glBegin(GL_QUADS); if(MidTrans) glColor4f(0,1,0,0.5); // middle opaque green else glColor4f(0,1,0,0.7); // fairly opaque green glVertex3f(0,1,-1); // back left glVertex3f(0,1,1); // front left glVertex3f(1/C,0,1); // front right glVertex3f(1/C,0,-1); // back right if(MidTrans) glColor4f(0,0,1,0.5); // middle opaque blue else glColor4f(0,0,1,0.3); // fairly transparent blue glVertex3f(1-1/C,0,-1); // back left glVertex3f(1-1/C,0,1); // front left glVertex3f(1,1,1); // front right glVertex3f(1,1,-1); // back right glEnd(); } void depthMask() { twColorName(BgBlack?TW_WHITE:TW_BLACK); glDepthMask(DepthMask ? GL_TRUE : GL_FALSE); twDrawString(TextLeft,-0.1,1, "Depth Mask %s - 'm' to toggle", DepthMask? "TRUE" : "FALSE"); } void depthTest() { twColorName(BgBlack?TW_WHITE:TW_BLACK); if(DepthTest) { glEnable(GL_DEPTH_TEST); twDrawString(TextLeft,-0.2,1, "Depth Test ON - 'd' toggles"); } else { glDisable(GL_DEPTH_TEST); twDrawString(TextLeft,-0.2,1, "Depth Test OFF - 'd' toggles"); } } void display(void) { if(BgBlack) glClearColor(0,0,0,0); // transparent black else glClearColor(1,1,1,1); // opaque white glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); twCamera(); depthTest(); if(OpaqueFirst) { twColorName(BgBlack?TW_WHITE:TW_BLACK); twDrawString(TextLeft,0,1,"Opaque First: red, then green and blue - 'o' to toggle"); // Normal settings for opaque objects glDepthMask(GL_TRUE); // this is the default glDisable(GL_BLEND); opaqueRedQuad(); // Settings for transparent objects glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); depthMask(); transparentGreenBlueQuads(); glDepthMask(GL_TRUE); glDisable(GL_BLEND); } else { twColorName(BgBlack?TW_WHITE:TW_BLACK); twDrawString(TextLeft,0,1,"Opaque Last: green and blue, then red - 'o' to toggle"); // Settings for transparent objects glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); depthMask(); transparentGreenBlueQuads(); // Normal settings for opaque objects glDepthMask(GL_TRUE); // this is the default glDisable(GL_BLEND); opaqueRedQuad(); } glFlush(); glutSwapBuffers(); } void keys(unsigned char k, int, int) { switch(k) { case 'b': BgBlack = !BgBlack; break; case 'd': DepthTest = !DepthTest; break; case 'm': DepthMask = !DepthMask; break; case 'M': MidTrans = !MidTrans; break; case 'o': OpaqueFirst = !OpaqueFirst; break; } glutPostRedisplay(); } int main(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); twInitWindowSize(500,500); glutCreateWindow(argv[0]); glutDisplayFunc(display); twBoundingBox(0,1,0,1,-1,1); twMainInit(); twKeyCallback('b',keys,"toggle black/white background"); twKeyCallback('d',keys,"toggle depth test"); twKeyCallback('m',keys,"toggle depth mask"); twKeyCallback('M',keys,"toggle middle transparency: 0.7/0.3 vs 0.5/0.5"); twKeyCallback('o',keys,"toggle opaque first/last"); glutMainLoop(); return 0; }