2 * Demonstration of doing triangle rasterization with a fragment program.
4 * 1. Draw screen-aligned quad / bounding box around the triangle verts.
5 * 2. For each pixel in the quad, determine if pixel is inside/outside
20 #include "shaderutil.h"
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
= GL_TRUE
;
31 static GLfloat Zrot
= 0.0f
;
32 static GLint uv0
, uv1
, uv2
;
35 static const GLfloat TriVerts
[3][2] = {
43 RotateVerts(GLfloat a
,
44 GLuint n
, const GLfloat vertsIn
[][2], GLfloat vertsOut
[][2])
47 GLfloat cx
= WinWidth
/ 2, cy
= WinHeight
/ 2;
48 for (i
= 0; i
< n
; i
++) {
49 float x
= vertsIn
[i
][0] - cx
;
50 float y
= vertsIn
[i
][1] - cy
;
52 vertsOut
[i
][0] = x
* cos(a
) + y
* sin(a
) + cx
;
53 vertsOut
[i
][1] = -x
* sin(a
) + y
* cos(a
) + cy
;
58 ComputeBounds(GLuint n
, GLfloat vertsIn
[][2],
59 GLfloat
*xmin
, GLfloat
*ymin
,
60 GLfloat
*xmax
, GLfloat
*ymax
)
63 *xmin
= *xmax
= vertsIn
[0][0];
64 *ymin
= *ymax
= vertsIn
[0][1];
65 for (i
= 1; i
< n
; i
++) {
66 if (vertsIn
[i
][0] < *xmin
)
67 *xmin
= vertsIn
[i
][0];
68 else if (vertsIn
[i
][0] > *xmax
)
69 *xmax
= vertsIn
[i
][0];
70 if (vertsIn
[i
][1] < *ymin
)
71 *ymin
= vertsIn
[i
][1];
72 else if (vertsIn
[i
][1] > *ymax
)
73 *ymax
= vertsIn
[i
][1];
81 GLfloat v
[3][2], xmin
, ymin
, xmax
, ymax
;
83 RotateVerts(Zrot
, 3, TriVerts
, v
);
84 ComputeBounds(3, v
, &xmin
, &ymin
, &xmax
, &ymax
);
86 glUniform2fv(uv0
, 1, v
[0]);
87 glUniform2fv(uv1
, 1, v
[1]);
88 glUniform2fv(uv2
, 1, v
[2]);
90 glClear(GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
);
94 glVertex2f(xmin
, ymin
);
95 glVertex2f(xmax
, ymin
);
96 glVertex2f(xmax
, ymax
);
97 glVertex2f(xmin
, ymax
);
109 Zrot
= glutGet(GLUT_ELAPSED_TIME
) * 0.0005;
118 Reshape(int width
, int height
)
120 glViewport(0, 0, width
, height
);
121 glMatrixMode(GL_PROJECTION
);
123 glOrtho(0, width
, 0, height
, -1, 1);
125 glMatrixMode(GL_MODELVIEW
);
133 glDeleteShader(fragShader
);
134 glDeleteShader(vertShader
);
135 glDeleteProgram(program
);
136 glutDestroyWindow(win
);
141 Key(unsigned char key
, int x
, int y
)
173 static const char *fragShaderText
=
174 "uniform vec2 v0, v1, v2; \n"
175 "float crs(const vec2 u, const vec2 v) \n"
177 " return u.x * v.y - u.y * v.x; \n"
181 " vec2 p = gl_FragCoord.xy; \n"
182 " if (crs(v1 - v0, p - v0) >= 0.0 && \n"
183 " crs(v2 - v1, p - v1) >= 0.0 && \n"
184 " crs(v0 - v2, p - v2) >= 0.0) \n"
185 " gl_FragColor = vec4(1.0); \n"
187 " gl_FragColor = vec4(0.5); \n"
189 static const char *vertShaderText
=
191 " gl_Position = ftransform(); \n"
194 if (!ShadersSupported())
197 vertShader
= CompileShaderText(GL_VERTEX_SHADER
, vertShaderText
);
198 fragShader
= CompileShaderText(GL_FRAGMENT_SHADER
, fragShaderText
);
199 program
= LinkShaders(vertShader
, fragShader
);
201 glUseProgram(program
);
203 uv0
= glGetUniformLocation(program
, "v0");
204 uv1
= glGetUniformLocation(program
, "v1");
205 uv2
= glGetUniformLocation(program
, "v2");
206 printf("Uniforms: %d %d %d\n", uv0
, uv1
, uv2
);
208 /*assert(glGetError() == 0);*/
210 glClearColor(0.3f
, 0.3f
, 0.3f
, 0.0f
);
211 glEnable(GL_DEPTH_TEST
);
213 printf("GL_RENDERER = %s\n",(const char *) glGetString(GL_RENDERER
));
215 assert(glIsProgram(program
));
216 assert(glIsShader(fragShader
));
217 assert(glIsShader(vertShader
));
224 ParseOptions(int argc
, char *argv
[])
227 for (i
= 1; i
< argc
; i
++) {
228 if (strcmp(argv
[i
], "-fs") == 0) {
229 FragProgFile
= argv
[i
+1];
231 else if (strcmp(argv
[i
], "-vs") == 0) {
232 VertProgFile
= argv
[i
+1];
239 main(int argc
, char *argv
[])
241 glutInit(&argc
, argv
);
242 glutInitWindowSize(WinWidth
, WinHeight
);
243 glutInitDisplayMode(GLUT_RGB
| GLUT_DOUBLE
| GLUT_DEPTH
);
244 win
= glutCreateWindow(argv
[0]);
246 glutReshapeFunc(Reshape
);
247 glutKeyboardFunc(Key
);
248 glutDisplayFunc(Redisplay
);
251 ParseOptions(argc
, argv
);