2 * Test two-sided lighting with shaders.
3 * Both GL_VERTEX_PROGRAM_TWO_SIDE and gl_FrontFacing can be tested
19 #include "shaderutil.h"
22 static GLint WinWidth
= 300, WinHeight
= 300;
23 static char *FragProgFile
= NULL
;
24 static char *VertProgFile
= NULL
;
25 static GLuint fragShader
;
26 static GLuint vertShader
;
27 static GLuint program
;
29 static GLboolean anim
;
30 static GLboolean DetermineFacingInFragProg
;
32 static GLint u_fragface
;
33 static GLenum FrontWinding
;
34 static int prevTime
= 0;
37 static const GLfloat Red
[4] = {1, 0, 0, 1};
38 static const GLfloat Green
[4] = {0, 1, 0, 0};
44 DetermineFacingInFragProg
= GL_TRUE
;
45 FrontWinding
= GL_CCW
;
55 const int sections
= 20;
59 glFrontFace(FrontWinding
);
61 if (DetermineFacingInFragProg
) {
62 glUniform1i_func(u_fragface
, 1);
63 glDisable(GL_VERTEX_PROGRAM_TWO_SIDE
);
66 glUniform1i_func(u_fragface
, 0);
67 glEnable(GL_VERTEX_PROGRAM_TWO_SIDE
);
70 glClear(GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
);
73 glRotatef(Xrot
, 1, 0, 0);
75 /* Draw a tristrip ring */
76 glBegin(GL_TRIANGLE_STRIP
);
78 glSecondaryColor3fv_func(Green
);
79 for (i
= 0; i
<= sections
; i
++) {
80 float a
= (float) i
/ (sections
) * M_PI
* 2.0;
81 float x
= radius
* cos(a
);
82 float y
= radius
* sin(a
);
97 int curTime
= glutGet(GLUT_ELAPSED_TIME
);
98 int dt
= curTime
- prevTime
;
112 Reshape(int width
, int height
)
114 float ar
= (float) width
/ height
;
115 glViewport(0, 0, width
, height
);
116 glMatrixMode(GL_PROJECTION
);
118 glFrustum(-ar
, ar
, -1, 1, 3, 25);
119 glMatrixMode(GL_MODELVIEW
);
121 glTranslatef(0, 0, -10);
128 glDeleteShader_func(fragShader
);
129 glDeleteShader_func(vertShader
);
130 glDeleteProgram_func(program
);
131 glutDestroyWindow(win
);
136 Key(unsigned char key
, int x
, int y
)
146 prevTime
= glutGet(GLUT_ELAPSED_TIME
);
153 printf("Using frag shader gl_FrontFacing\n");
154 DetermineFacingInFragProg
= GL_TRUE
;
157 printf("Using vert shader Two-sided lighting\n");
158 DetermineFacingInFragProg
= GL_FALSE
;
171 if (FrontWinding
== GL_CCW
) {
172 FrontWinding
= GL_CW
;
173 printf("FrontFace = GL_CW\n");
176 FrontWinding
= GL_CCW
;
177 printf("FrontFace = GL_CCW\n");
192 static const char *fragShaderText
=
193 "uniform bool fragface; \n"
196 " if (!fragface || gl_FrontFacing) { \n"
197 " gl_FragColor = gl_Color; \n"
200 " // note: dim green to help debug \n"
201 " gl_FragColor = 0.8 * gl_SecondaryColor; \n"
205 " bool f = gl_FrontFacing; \n"
207 " gl_FragColor = vec4(1.0, 0.0, 0.0, 0.0); \n"
210 " gl_FragColor = vec4(0.0, 1.0, 0.0, 0.0); \n"
214 static const char *vertShaderText
=
215 "uniform bool fragface; \n"
217 " gl_FrontColor = gl_Color; \n"
218 " if (fragface) { \n"
219 " // front/back chosen in frag prog \n"
220 " gl_FrontSecondaryColor = gl_SecondaryColor; \n"
223 " // front/back chosen in prim setup \n"
224 " gl_BackColor = gl_SecondaryColor; \n"
226 " gl_Position = ftransform(); \n"
229 if (!ShadersSupported())
234 vertShader
= CompileShaderText(GL_VERTEX_SHADER
, vertShaderText
);
235 fragShader
= CompileShaderText(GL_FRAGMENT_SHADER
, fragShaderText
);
236 program
= LinkShaders(vertShader
, fragShader
);
238 glUseProgram_func(program
);
240 u_fragface
= glGetUniformLocation_func(program
, "fragface");
241 printf("Uniforms: %d\n", u_fragface
);
243 /*assert(glGetError() == 0);*/
245 glClearColor(0.3f
, 0.3f
, 0.3f
, 0.0f
);
247 printf("GL_RENDERER = %s\n",(const char *) glGetString(GL_RENDERER
));
249 assert(glIsProgram_func(program
));
250 assert(glIsShader_func(fragShader
));
251 assert(glIsShader_func(vertShader
));
253 glEnable(GL_DEPTH_TEST
);
260 ParseOptions(int argc
, char *argv
[])
263 for (i
= 1; i
< argc
; i
++) {
264 if (strcmp(argv
[i
], "-fs") == 0) {
265 FragProgFile
= argv
[i
+1];
267 else if (strcmp(argv
[i
], "-vs") == 0) {
268 VertProgFile
= argv
[i
+1];
278 printf(" f - do front/back determination in fragment shader\n");
279 printf(" v - do front/back determination in vertex shader\n");
280 printf(" r - reset, show front\n");
281 printf(" a - toggle animation\n");
282 printf(" s - step rotation\n");
283 printf(" w - toggle CW, CCW front-face winding\n");
284 printf("NOTE: red = front face, green = back face.\n");
289 main(int argc
, char *argv
[])
291 glutInit(&argc
, argv
);
292 glutInitWindowPosition( 0, 0);
293 glutInitWindowSize(WinWidth
, WinHeight
);
294 glutInitDisplayMode(GLUT_RGB
| GLUT_DEPTH
| GLUT_DOUBLE
);
295 win
= glutCreateWindow(argv
[0]);
296 glutReshapeFunc(Reshape
);
297 glutKeyboardFunc(Key
);
298 glutDisplayFunc(Redisplay
);
301 ParseOptions(argc
, argv
);