2 * Test two-sided lighting with shaders.
3 * Both GL_VERTEX_PROGRAM_TWO_SIDE and gl_FrontFacing can be tested
17 #include "shaderutil.h"
20 #define M_PI 3.1415926535
23 static GLint WinWidth
= 300, WinHeight
= 300;
24 static char *FragProgFile
= NULL
;
25 static char *VertProgFile
= NULL
;
26 static GLuint fragShader
;
27 static GLuint vertShader
;
28 static GLuint program
;
30 static GLboolean anim
;
31 static GLboolean DetermineFacingInFragProg
;
33 static GLint u_fragface
;
34 static GLenum FrontWinding
;
35 static int prevTime
= 0;
38 static const GLfloat Red
[4] = {1, 0, 0, 1};
39 static const GLfloat Green
[4] = {0, 1, 0, 0};
45 DetermineFacingInFragProg
= GL_TRUE
;
46 FrontWinding
= GL_CCW
;
56 const int sections
= 20;
60 glFrontFace(FrontWinding
);
62 if (DetermineFacingInFragProg
) {
63 glUniform1i(u_fragface
, 1);
64 glDisable(GL_VERTEX_PROGRAM_TWO_SIDE
);
67 glUniform1i(u_fragface
, 0);
68 glEnable(GL_VERTEX_PROGRAM_TWO_SIDE
);
71 glClear(GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
);
74 glRotatef(Xrot
, 1, 0, 0);
76 /* Draw a tristrip ring */
77 glBegin(GL_TRIANGLE_STRIP
);
79 glSecondaryColor3fv(Green
);
80 for (i
= 0; i
<= sections
; i
++) {
81 float a
= (float) i
/ (sections
) * M_PI
* 2.0;
82 float x
= radius
* cos(a
);
83 float y
= radius
* sin(a
);
98 int curTime
= glutGet(GLUT_ELAPSED_TIME
);
99 int dt
= curTime
- prevTime
;
113 Reshape(int width
, int height
)
115 float ar
= (float) width
/ height
;
116 glViewport(0, 0, width
, height
);
117 glMatrixMode(GL_PROJECTION
);
119 glFrustum(-ar
, ar
, -1, 1, 3, 25);
120 glMatrixMode(GL_MODELVIEW
);
122 glTranslatef(0, 0, -10);
129 glDeleteShader(fragShader
);
130 glDeleteShader(vertShader
);
131 glDeleteProgram(program
);
132 glutDestroyWindow(win
);
137 Key(unsigned char key
, int x
, int y
)
147 prevTime
= glutGet(GLUT_ELAPSED_TIME
);
154 printf("Using frag shader gl_FrontFacing\n");
155 DetermineFacingInFragProg
= GL_TRUE
;
158 printf("Using vert shader Two-sided lighting\n");
159 DetermineFacingInFragProg
= GL_FALSE
;
172 if (FrontWinding
== GL_CCW
) {
173 FrontWinding
= GL_CW
;
174 printf("FrontFace = GL_CW\n");
177 FrontWinding
= GL_CCW
;
178 printf("FrontFace = GL_CCW\n");
193 static const char *fragShaderText
=
194 "uniform bool fragface; \n"
197 " if (!fragface || gl_FrontFacing) { \n"
198 " gl_FragColor = gl_Color; \n"
201 " // note: dim green to help debug \n"
202 " gl_FragColor = 0.8 * gl_SecondaryColor; \n"
206 " bool f = gl_FrontFacing; \n"
208 " gl_FragColor = vec4(1.0, 0.0, 0.0, 0.0); \n"
211 " gl_FragColor = vec4(0.0, 1.0, 0.0, 0.0); \n"
215 static const char *vertShaderText
=
216 "uniform bool fragface; \n"
218 " gl_FrontColor = gl_Color; \n"
219 " if (fragface) { \n"
220 " // front/back chosen in frag prog \n"
221 " gl_FrontSecondaryColor = gl_SecondaryColor; \n"
224 " // front/back chosen in prim setup \n"
225 " gl_BackColor = gl_SecondaryColor; \n"
227 " gl_Position = ftransform(); \n"
230 if (!ShadersSupported())
233 vertShader
= CompileShaderText(GL_VERTEX_SHADER
, vertShaderText
);
234 fragShader
= CompileShaderText(GL_FRAGMENT_SHADER
, fragShaderText
);
235 program
= LinkShaders(vertShader
, fragShader
);
237 glUseProgram(program
);
239 u_fragface
= glGetUniformLocation(program
, "fragface");
240 printf("Uniforms: %d\n", u_fragface
);
242 /*assert(glGetError() == 0);*/
244 glClearColor(0.3f
, 0.3f
, 0.3f
, 0.0f
);
246 printf("GL_RENDERER = %s\n",(const char *) glGetString(GL_RENDERER
));
248 assert(glIsProgram(program
));
249 assert(glIsShader(fragShader
));
250 assert(glIsShader(vertShader
));
252 glEnable(GL_DEPTH_TEST
);
259 ParseOptions(int argc
, char *argv
[])
262 for (i
= 1; i
< argc
; i
++) {
263 if (strcmp(argv
[i
], "-fs") == 0) {
264 FragProgFile
= argv
[i
+1];
266 else if (strcmp(argv
[i
], "-vs") == 0) {
267 VertProgFile
= argv
[i
+1];
277 printf(" f - do front/back determination in fragment shader\n");
278 printf(" v - do front/back determination in vertex shader\n");
279 printf(" r - reset, show front\n");
280 printf(" a - toggle animation\n");
281 printf(" s - step rotation\n");
282 printf(" w - toggle CW, CCW front-face winding\n");
283 printf("NOTE: red = front face, green = back face.\n");
288 main(int argc
, char *argv
[])
290 glutInit(&argc
, argv
);
291 glutInitWindowSize(WinWidth
, WinHeight
);
292 glutInitDisplayMode(GLUT_RGB
| GLUT_DEPTH
| GLUT_DOUBLE
);
293 win
= glutCreateWindow(argv
[0]);
295 glutReshapeFunc(Reshape
);
296 glutKeyboardFunc(Key
);
297 glutDisplayFunc(Redisplay
);
300 ParseOptions(argc
, argv
);