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