gallivm: Ensure PIPE_OS_xxx are defined.
[mesa.git] / progs / glsl / trirast.c
1 /**
2 * Demonstration of doing triangle rasterization with a fragment program.
3 * Basic idea:
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
6 * the triangle edges.
7 *
8 * Brian Paul
9 * 1 Aug 2007
10 */
11
12
13 #include <assert.h>
14 #include <string.h>
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <math.h>
18 #include <GL/glew.h>
19 #include <GL/glut.h>
20 #include "shaderutil.h"
21
22
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;
29 static GLint win = 0;
30 static GLboolean anim = GL_TRUE;
31 static GLfloat Zrot = 0.0f;
32 static GLint uv0, uv1, uv2;
33
34
35 static const GLfloat TriVerts[3][2] = {
36 { 50, 50 },
37 { 250, 50 },
38 { 150, 250 }
39 };
40
41
42 static void
43 RotateVerts(GLfloat a,
44 GLuint n, const GLfloat vertsIn[][2], GLfloat vertsOut[][2])
45 {
46 GLuint i;
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;
51
52 vertsOut[i][0] = x * cos(a) + y * sin(a) + cx;
53 vertsOut[i][1] = -x * sin(a) + y * cos(a) + cy;
54 }
55 }
56
57 static void
58 ComputeBounds(GLuint n, GLfloat vertsIn[][2],
59 GLfloat *xmin, GLfloat *ymin,
60 GLfloat *xmax, GLfloat *ymax)
61 {
62 GLuint i;
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];
74 }
75 }
76
77
78 static void
79 Redisplay(void)
80 {
81 GLfloat v[3][2], xmin, ymin, xmax, ymax;
82
83 RotateVerts(Zrot, 3, TriVerts, v);
84 ComputeBounds(3, v, &xmin, &ymin, &xmax, &ymax);
85
86 glUniform2fv(uv0, 1, v[0]);
87 glUniform2fv(uv1, 1, v[1]);
88 glUniform2fv(uv2, 1, v[2]);
89
90 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
91
92 glPushMatrix();
93 glBegin(GL_POLYGON);
94 glVertex2f(xmin, ymin);
95 glVertex2f(xmax, ymin);
96 glVertex2f(xmax, ymax);
97 glVertex2f(xmin, ymax);
98 glEnd();
99 glPopMatrix();
100
101 glutSwapBuffers();
102 }
103
104
105 static void
106 Idle(void)
107 {
108 if (anim) {
109 Zrot = glutGet(GLUT_ELAPSED_TIME) * 0.0005;
110 glutPostRedisplay();
111 }
112 else
113 abort();
114 }
115
116
117 static void
118 Reshape(int width, int height)
119 {
120 glViewport(0, 0, width, height);
121 glMatrixMode(GL_PROJECTION);
122 glLoadIdentity();
123 glOrtho(0, width, 0, height, -1, 1);
124
125 glMatrixMode(GL_MODELVIEW);
126 glLoadIdentity();
127 }
128
129
130 static void
131 CleanUp(void)
132 {
133 glDeleteShader(fragShader);
134 glDeleteShader(vertShader);
135 glDeleteProgram(program);
136 glutDestroyWindow(win);
137 }
138
139
140 static void
141 Key(unsigned char key, int x, int y)
142 {
143 (void) x;
144 (void) y;
145
146 switch(key) {
147 case ' ':
148 case 'a':
149 anim = !anim;
150 if (anim)
151 glutIdleFunc(Idle);
152 else
153 glutIdleFunc(NULL);
154 break;
155 case 'z':
156 Zrot = 0;
157 break;
158 case 's':
159 Zrot += 0.05;
160 break;
161 case 27:
162 CleanUp();
163 exit(0);
164 break;
165 }
166 glutPostRedisplay();
167 }
168
169
170 static void
171 Init(void)
172 {
173 static const char *fragShaderText =
174 "uniform vec2 v0, v1, v2; \n"
175 "float crs(const vec2 u, const vec2 v) \n"
176 "{ \n"
177 " return u.x * v.y - u.y * v.x; \n"
178 "} \n"
179 "\n"
180 "void main() {\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"
186 " else \n"
187 " gl_FragColor = vec4(0.5); \n"
188 "}\n";
189 static const char *vertShaderText =
190 "void main() {\n"
191 " gl_Position = ftransform(); \n"
192 "}\n";
193
194 if (!ShadersSupported())
195 exit(1);
196
197 vertShader = CompileShaderText(GL_VERTEX_SHADER, vertShaderText);
198 fragShader = CompileShaderText(GL_FRAGMENT_SHADER, fragShaderText);
199 program = LinkShaders(vertShader, fragShader);
200
201 glUseProgram(program);
202
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);
207
208 /*assert(glGetError() == 0);*/
209
210 glClearColor(0.3f, 0.3f, 0.3f, 0.0f);
211 glEnable(GL_DEPTH_TEST);
212
213 printf("GL_RENDERER = %s\n",(const char *) glGetString(GL_RENDERER));
214
215 assert(glIsProgram(program));
216 assert(glIsShader(fragShader));
217 assert(glIsShader(vertShader));
218
219 glColor3f(1, 0, 0);
220 }
221
222
223 static void
224 ParseOptions(int argc, char *argv[])
225 {
226 int i;
227 for (i = 1; i < argc; i++) {
228 if (strcmp(argv[i], "-fs") == 0) {
229 FragProgFile = argv[i+1];
230 }
231 else if (strcmp(argv[i], "-vs") == 0) {
232 VertProgFile = argv[i+1];
233 }
234 }
235 }
236
237
238 int
239 main(int argc, char *argv[])
240 {
241 glutInit(&argc, argv);
242 glutInitWindowSize(WinWidth, WinHeight);
243 glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
244 win = glutCreateWindow(argv[0]);
245 glewInit();
246 glutReshapeFunc(Reshape);
247 glutKeyboardFunc(Key);
248 glutDisplayFunc(Redisplay);
249 if (anim)
250 glutIdleFunc(Idle);
251 ParseOptions(argc, argv);
252 Init();
253 glutMainLoop();
254 return 0;
255 }