1/** 2 * Test glPolygonMode w/ different front/back face modes. 3 * 4 * The left half of the window draws a torus with different front/back 5 * polygon modes. 6 * 7 * The right half of the windows tries to draw the same thing, but with 8 * a different approach: 9 * glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); 10 * glEnable(GL_CULL_FACE); 11 * glCullFace(GL_FRONT); 12 * draw_object(); 13 * glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); 14 * glEnable(GL_CULL_FACE); 15 * glCullFace(GL_BACK); 16 * draw_object(); 17 * 18 * The outcome is often the same, but not always (turn on blending with 'b'). 19 * 20 * Brian Paul 21 * 2 Feb 2016 22 */ 23 24 25#include <stdio.h> 26#include <stdlib.h> 27#include <math.h> 28#include "glut_wrap.h" 29 30static int Win; 31static int WinWidth = 800, WinHeight = 400; 32static GLfloat Xrot = 0; 33static GLboolean Anim = GL_TRUE; 34static double t0; 35static GLboolean Blend = GL_TRUE; 36 37 38static void 39Idle(void) 40{ 41 double t1 = glutGet(GLUT_ELAPSED_TIME) / 1000.0; 42 Xrot += (t1 - t0) * 20; /* 20 degrees per second */ 43 t0 = t1; 44 glutPostRedisplay(); 45} 46 47 48static void 49Draw(void) 50{ 51 int hw = WinWidth / 2; 52 53 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 54 55 if (Blend) { 56 glEnable(GL_BLEND); 57 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 58 glBlendFunc(GL_ONE, GL_ONE); 59 } 60 else { 61 glDisable(GL_BLEND); 62 } 63 64 glPushMatrix(); 65 glRotatef(Xrot, 1, 0, 0); 66 67 /* draw left half */ 68 glViewport(0, 0, hw, WinHeight); 69 70 glPolygonMode(GL_FRONT, GL_LINE); 71 glPolygonMode(GL_BACK, GL_FILL); 72 glDisable(GL_CULL_FACE); 73 glutSolidTorus(0.75, 2.0, 10, 20); 74 75 /* draw right half */ 76 glViewport(hw, 0, WinWidth - hw, WinHeight); 77 78 /* draw back faces */ 79 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); 80 glEnable(GL_CULL_FACE); 81 glCullFace(GL_FRONT); 82 glutSolidTorus(0.75, 2.0, 10, 20); 83 84 /* draw front faces */ 85 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); 86 glEnable(GL_CULL_FACE); 87 glCullFace(GL_BACK); 88 glutSolidTorus(0.75, 2.0, 10, 20); 89 90 glPopMatrix(); 91 92 glutSwapBuffers(); 93} 94 95 96static void 97Reshape(int width, int height) 98{ 99 WinWidth = width; 100 WinHeight = height; 101 glMatrixMode(GL_PROJECTION); 102 glLoadIdentity(); 103 glFrustum(-1.0, 1.0, -1.0, 1.0, 3.0, 25.0); 104 glMatrixMode(GL_MODELVIEW); 105 glLoadIdentity(); 106 glTranslatef(0.0, 0.0, -10.0); 107 glutPostRedisplay(); 108} 109 110 111static void 112Key(unsigned char key, int x, int y) 113{ 114 (void) x; 115 (void) y; 116 switch (key) { 117 case 'a': 118 Anim = !Anim; 119 if (Anim) { 120 t0 = glutGet(GLUT_ELAPSED_TIME) / 1000.0; 121 glutIdleFunc(Idle); 122 } 123 else 124 glutIdleFunc(NULL); 125 break; 126 case 'b': 127 Blend = !Blend; 128 break; 129 case 27: 130 glutDestroyWindow(Win); 131 exit(0); 132 break; 133 } 134 glutPostRedisplay(); 135} 136 137 138static void 139SpecialKey(int key, int x, int y) 140{ 141 const GLfloat step = 3.0; 142 (void) x; 143 (void) y; 144 switch (key) { 145 case GLUT_KEY_UP: 146 Xrot -= step; 147 break; 148 case GLUT_KEY_DOWN: 149 Xrot += step; 150 break; 151 } 152 glutPostRedisplay(); 153} 154 155 156static void 157Init(void) 158{ 159 static const float yellow[4] = {1, 1, 0, 0.5}; 160 static const float blue[4] = {0.2, 0.2, 1, 0.5}; 161 static const float gray[4] = {0.2, 0.2, 0.2, 1.0}; 162 163 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, gray); 164 glMaterialfv(GL_FRONT, GL_DIFFUSE, yellow); 165 glMaterialfv(GL_BACK, GL_DIFFUSE, blue); 166 glEnable(GL_DEPTH_TEST); 167 glEnable(GL_LIGHTING); 168 glEnable(GL_LIGHT0); 169 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 1); 170 glShadeModel(GL_FLAT); 171 172 glClearColor(0.25, 0.25, 0.25, 1.0); 173} 174 175 176int 177main(int argc, char *argv[]) 178{ 179 glutInit(&argc, argv); 180 glutInitWindowSize(WinWidth, WinHeight); 181 glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); 182 Win = glutCreateWindow(argv[0]); 183 glutReshapeFunc(Reshape); 184 glutKeyboardFunc(Key); 185 glutSpecialFunc(SpecialKey); 186 glutDisplayFunc(Draw); 187 if (Anim) 188 glutIdleFunc(Idle); 189 Init(); 190 glutMainLoop(); 191 return 0; 192} 193