gallium-intel: Improve Xorg Makefile a bit
[mesa.git] / progs / vpglsl / vp-tris.c
1
2 #include <assert.h>
3 #include <string.h>
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <math.h>
7
8 #include <GL/glew.h>
9 #include <GL/glut.h>
10
11 static const char *filename = NULL;
12 static GLuint nr_steps = 4;
13 static GLuint prim = GL_TRIANGLES;
14 static GLfloat psz = 1.0;
15 static GLboolean pointsmooth = 0;
16 static GLboolean program_point_size = 0;
17
18 static GLuint fragShader;
19 static GLuint vertShader;
20 static GLuint program;
21
22 static void usage( char *name )
23 {
24 fprintf( stderr, "usage: %s [ options ] shader_filename\n", name );
25 fprintf( stderr, "\n" );
26 fprintf( stderr, "options:\n" );
27 fprintf( stderr, " -f flat shaded\n" );
28 fprintf( stderr, " -nNr subdivision steps\n" );
29 }
30
31
32 static void load_and_compile_shader(GLuint shader, const char *text)
33 {
34 GLint stat;
35
36 glShaderSource(shader, 1, (const GLchar **) &text, NULL);
37
38 glCompileShader(shader);
39
40 glGetShaderiv(shader, GL_COMPILE_STATUS, &stat);
41 if (!stat) {
42 GLchar log[1000];
43 GLsizei len;
44 glGetShaderInfoLog(shader, 1000, &len, log);
45 fprintf(stderr, "vp-tris: problem compiling shader:\n%s\n", log);
46 exit(1);
47 }
48 }
49
50 static void read_shader(GLuint shader, const char *filename)
51 {
52 const int max = 100*1000;
53 int n;
54 char *buffer = (char*) malloc(max);
55 FILE *f = fopen(filename, "r");
56 if (!f) {
57 fprintf(stderr, "vp-tris: Unable to open shader file %s\n", filename);
58 exit(1);
59 }
60
61 n = fread(buffer, 1, max, f);
62 printf("vp-tris: read %d bytes from shader file %s\n", n, filename);
63 if (n > 0) {
64 buffer[n] = 0;
65 load_and_compile_shader(shader, buffer);
66 }
67
68 fclose(f);
69 free(buffer);
70 }
71
72 static void check_link(GLuint prog)
73 {
74 GLint stat;
75 glGetProgramiv(prog, GL_LINK_STATUS, &stat);
76 if (!stat) {
77 GLchar log[1000];
78 GLsizei len;
79 glGetProgramInfoLog(prog, 1000, &len, log);
80 fprintf(stderr, "Linker error:\n%s\n", log);
81 }
82 }
83
84 static void setup_uniforms()
85 {
86 {
87 GLuint loc1f = glGetUniformLocationARB(program, "Offset1f");
88 GLuint loc2f = glGetUniformLocationARB(program, "Offset2f");
89 GLuint loc4f = glGetUniformLocationARB(program, "Offset4f");
90 GLfloat vecKer[] =
91 { 1.0, 0.0, 0.0, 1.0,
92 0.0, 1.0, 0.0, 1.0,
93 1.0, 0.0, 0.0, 1.0,
94 0.0, 0.0, 0.0, 1.0
95 };
96 if (loc1f >= 0)
97 glUniform1fv(loc1f, 16, vecKer);
98
99 if (loc2f >= 0)
100 glUniform2fv(loc2f, 8, vecKer);
101
102 if (loc4f >= 0)
103 glUniform4fv(loc4f, 4, vecKer);
104
105 }
106
107 {
108 GLuint loc1f = glGetUniformLocationARB(program, "KernelValue1f");
109 GLuint loc2f = glGetUniformLocationARB(program, "KernelValue2f");
110 GLuint loc4f = glGetUniformLocationARB(program, "KernelValue4f");
111 GLfloat vecKer[] =
112 { 1.0, 0.0, 0.0, 0.25,
113 0.0, 1.0, 0.0, 0.25,
114 0.0, 0.0, 1.0, 0.25,
115 0.0, 0.0, 0.0, 0.25,
116 0.5, 0.0, 0.0, 0.35,
117 0.0, 0.5, 0.0, 0.35,
118 0.0, 0.0, 0.5, 0.35,
119 0.0, 0.0, 0.0, 0.35
120 };
121 if (loc1f >= 0)
122 glUniform1fv(loc1f, 16, vecKer);
123
124 if (loc2f >= 0)
125 glUniform2fv(loc2f, 8, vecKer);
126
127 if (loc4f >= 0)
128 glUniform4fv(loc4f, 4, vecKer);
129 }
130 }
131
132 static void prepare_shaders()
133 {
134 static const char *fragShaderText =
135 "void main() {\n"
136 " gl_FragColor = gl_Color;\n"
137 "}\n";
138 static const char *vertShaderText =
139 "void main() {\n"
140 " gl_FrontColor = gl_Color;\n"
141 " gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n"
142 "}\n";
143 fragShader = glCreateShader(GL_FRAGMENT_SHADER);
144 load_and_compile_shader(fragShader, fragShaderText);
145
146
147 vertShader = glCreateShader(GL_VERTEX_SHADER);
148 if (filename)
149 read_shader(vertShader, filename);
150 else
151 load_and_compile_shader(vertShader, vertShaderText);
152
153 program = glCreateProgram();
154 glAttachShader(program, fragShader);
155 glAttachShader(program, vertShader);
156 glLinkProgram(program);
157 check_link(program);
158 glUseProgram(program);
159
160 setup_uniforms();
161 }
162
163 static void args(int argc, char *argv[])
164 {
165 GLint i;
166
167 for (i = 1; i < argc; i++) {
168 if (strncmp(argv[i], "-n", 2) == 0) {
169 nr_steps = atoi((argv[i]) + 2);
170 }
171 else if (strcmp(argv[i], "-f") == 0) {
172 glShadeModel(GL_FLAT);
173 }
174 else if (i == argc - 1) {
175 filename = argv[i];
176 }
177 else {
178 usage(argv[0]);
179 exit(1);
180 }
181 }
182
183 if (!filename) {
184 usage(argv[0]);
185 exit(1);
186 }
187 }
188
189
190
191
192 union vert {
193 struct {
194 GLfloat color[3];
195 GLfloat pos[3];
196 } v;
197 GLfloat f[6];
198 };
199
200 static void make_midpoint( union vert *out,
201 const union vert *v0,
202 const union vert *v1)
203 {
204 int i;
205 for (i = 0; i < 6; i++)
206 out->f[i] = v0->f[i] + .5 * (v1->f[i] - v0->f[i]);
207 }
208
209 static void subdiv( union vert *v0,
210 union vert *v1,
211 union vert *v2,
212 GLuint depth )
213 {
214 if (depth == 0) {
215 glColor3fv(v0->v.color);
216 glVertex3fv(v0->v.pos);
217 glColor3fv(v1->v.color);
218 glVertex3fv(v1->v.pos);
219 glColor3fv(v2->v.color);
220 glVertex3fv(v2->v.pos);
221 }
222 else {
223 union vert m[3];
224
225 make_midpoint(&m[0], v0, v1);
226 make_midpoint(&m[1], v1, v2);
227 make_midpoint(&m[2], v2, v0);
228
229 subdiv(&m[0], &m[2], v0, depth-1);
230 subdiv(&m[1], &m[0], v1, depth-1);
231 subdiv(&m[2], &m[1], v2, depth-1);
232 subdiv(&m[0], &m[1], &m[2], depth-1);
233 }
234 }
235
236 static void enable( GLenum value, GLboolean flag )
237 {
238 if (flag)
239 glEnable(value);
240 else
241 glDisable(value);
242 }
243
244 /** Assignment */
245 #define ASSIGN_3V( V, V0, V1, V2 ) \
246 do { \
247 V[0] = V0; \
248 V[1] = V1; \
249 V[2] = V2; \
250 } while(0)
251
252 static void Display( void )
253 {
254 glClearColor(0.3, 0.3, 0.3, 1);
255 glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
256 glPointSize(psz);
257
258 glUseProgram(program);
259 enable( GL_POINT_SMOOTH, pointsmooth );
260 enable( GL_VERTEX_PROGRAM_POINT_SIZE_ARB, program_point_size );
261
262 glBegin(prim);
263
264
265 {
266 union vert v[3];
267
268 ASSIGN_3V(v[0].v.color, 0,0,1);
269 ASSIGN_3V(v[0].v.pos, 0.9, -0.9, 0.0);
270 ASSIGN_3V(v[1].v.color, 1,0,0);
271 ASSIGN_3V(v[1].v.pos, 0.9, 0.9, 0.0);
272 ASSIGN_3V(v[2].v.color, 0,1,0);
273 ASSIGN_3V(v[2].v.pos, -0.9, 0, 0.0);
274
275 subdiv(&v[0], &v[1], &v[2], nr_steps);
276 }
277
278 glEnd();
279
280
281 glFlush();
282 }
283
284
285 static void Reshape( int width, int height )
286 {
287 glViewport( 0, 0, width, height );
288 glMatrixMode( GL_PROJECTION );
289 glLoadIdentity();
290 glOrtho(-1.0, 1.0, -1.0, 1.0, -0.5, 1000.0);
291 glMatrixMode( GL_MODELVIEW );
292 glLoadIdentity();
293 /*glTranslatef( 0.0, 0.0, -15.0 );*/
294 }
295
296
297 static void CleanUp(void)
298 {
299 glDeleteShader(fragShader);
300 glDeleteShader(vertShader);
301 glDeleteProgram(program);
302 }
303
304 static void Key( unsigned char key, int x, int y )
305 {
306 (void) x;
307 (void) y;
308 switch (key) {
309 case 'p':
310 prim = GL_POINTS;
311 break;
312 case 't':
313 prim = GL_TRIANGLES;
314 break;
315 case 's':
316 psz += .5;
317 break;
318 case 'S':
319 if (psz > .5)
320 psz -= .5;
321 break;
322 case 'm':
323 pointsmooth = !pointsmooth;
324 break;
325 case 'z':
326 program_point_size = !program_point_size;
327 break;
328 case '+':
329 nr_steps++;
330 break;
331 case '-':
332 if (nr_steps)
333 nr_steps--;
334 break;
335 case ' ':
336 psz = 1.0;
337 prim = GL_TRIANGLES;
338 nr_steps = 4;
339 break;
340 case 27:
341 CleanUp();
342 exit(0);
343 break;
344 }
345 glutPostRedisplay();
346 }
347
348 int main( int argc, char *argv[] )
349 {
350 glutInit( &argc, argv );
351 glutInitWindowPosition( 0, 0 );
352 glutInitWindowSize( 250, 250 );
353 glutInitDisplayMode( GLUT_RGB | GLUT_SINGLE | GLUT_DEPTH );
354 glutCreateWindow(argv[argc-1]);
355 glewInit();
356 glutReshapeFunc( Reshape );
357 glutKeyboardFunc( Key );
358 glutDisplayFunc( Display );
359 args( argc, argv );
360 prepare_shaders();
361 glutMainLoop();
362 return 0;
363 }