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);