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