~ubuntu-branches/ubuntu/oneiric/mesa-demos/oneiric

« back to all changes in this revision

Viewing changes to src/glsl/shtest.c

  • Committer: Bazaar Package Importer
  • Author(s): Christopher James Halse Rogers
  • Date: 2010-09-27 16:18:27 UTC
  • Revision ID: james.westby@ubuntu.com-20100927161827-1yfgolc1oy9sjhi8
Tags: upstream-8.0.1
ImportĀ upstreamĀ versionĀ 8.0.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Simple shader test harness.
 
3
 * Brian Paul
 
4
 * 13 Aug 2009
 
5
 *
 
6
 * Usage:
 
7
 *   shtest --vs vertShaderFile --fs fragShaderFile
 
8
 *
 
9
 *   In this case the given vertex/frag shaders are read and compiled.
 
10
 *   Random values are assigned to the uniforms.
 
11
 *
 
12
 * or:
 
13
 *   shtest configFile
 
14
 *
 
15
 *   In this case a config file is read that specifies the file names
 
16
 *   of the shaders plus initial values for uniforms.
 
17
 *
 
18
 * Example config file:
 
19
 *
 
20
 * vs shader.vert
 
21
 * fs shader.frag
 
22
 * uniform pi 3.14159
 
23
 * uniform v1 1.0 0.5 0.2 0.3
 
24
 * texture 0 2D texture0.rgb
 
25
 * texture 1 CUBE texture1.rgb
 
26
 * texture 2 RECT texture2.rgb
 
27
 *
 
28
 */
 
29
 
 
30
 
 
31
#include <assert.h>
 
32
#include <stdio.h>
 
33
#include <stdlib.h>
 
34
#include <string.h>
 
35
#include <math.h>
 
36
#include <GL/glew.h>
 
37
#include <GL/glu.h>
 
38
#include <GL/glut.h>
 
39
#include "shaderutil.h"
 
40
#include "readtex.h"
 
41
 
 
42
 
 
43
typedef enum
 
44
{
 
45
   SPHERE,
 
46
   CUBE,
 
47
   NUM_SHAPES
 
48
} shape;
 
49
 
 
50
 
 
51
static char *FragShaderFile = NULL;
 
52
static char *VertShaderFile = NULL;
 
53
static char *ConfigFile = NULL;
 
54
 
 
55
/* program/shader objects */
 
56
static GLuint fragShader;
 
57
static GLuint vertShader;
 
58
static GLuint Program;
 
59
 
 
60
 
 
61
#define MAX_UNIFORMS 100
 
62
static struct uniform_info Uniforms[MAX_UNIFORMS];
 
63
static GLuint NumUniforms = 0;
 
64
 
 
65
 
 
66
#define MAX_ATTRIBS 100
 
67
static struct attrib_info Attribs[MAX_ATTRIBS];
 
68
static GLuint NumAttribs = 0;
 
69
 
 
70
 
 
71
/**
 
72
 * Config file info.
 
73
 */
 
74
struct config_file
 
75
{
 
76
   struct name_value
 
77
   {
 
78
      char name[100];
 
79
      float value[4];
 
80
      int type;
 
81
   } uniforms[100];
 
82
 
 
83
   int num_uniforms;
 
84
};
 
85
 
 
86
 
 
87
static GLint win = 0;
 
88
static GLboolean Anim = GL_FALSE;
 
89
static GLfloat TexRot = 0.0;
 
90
static GLfloat xRot = 0.0f, yRot = 0.0f, zRot = 0.0f;
 
91
static shape Object = SPHERE;
 
92
 
 
93
 
 
94
static float
 
95
RandomFloat(float min, float max)
 
96
{
 
97
   int k = rand() % 10000;
 
98
   float x = min + (max - min) * k / 10000.0;
 
99
   return x;
 
100
}
 
101
 
 
102
 
 
103
/** Set new random values for uniforms */
 
104
static void
 
105
RandomUniformValues(void)
 
106
{
 
107
   GLuint i;
 
108
   for (i = 0; i < NumUniforms; i++) {
 
109
      switch (Uniforms[i].type) {
 
110
      case GL_FLOAT:
 
111
         Uniforms[i].value[0] = RandomFloat(0.0, 1.0);
 
112
         break;
 
113
      case GL_SAMPLER_1D:
 
114
      case GL_SAMPLER_2D:
 
115
      case GL_SAMPLER_3D:
 
116
      case GL_SAMPLER_CUBE:
 
117
      case GL_SAMPLER_2D_RECT_ARB:
 
118
         /* don't change sampler values - random values are bad */
 
119
         break;
 
120
      default:
 
121
         Uniforms[i].value[0] = RandomFloat(-1.0, 2.0);
 
122
         Uniforms[i].value[1] = RandomFloat(-1.0, 2.0);
 
123
         Uniforms[i].value[2] = RandomFloat(-1.0, 2.0);
 
124
         Uniforms[i].value[3] = RandomFloat(-1.0, 2.0);
 
125
      }
 
126
   }
 
127
}
 
128
 
 
129
 
 
130
static void
 
131
Idle(void)
 
132
{
 
133
   yRot += 2.0;
 
134
   if (yRot > 360.0)
 
135
      yRot -= 360.0;
 
136
   glutPostRedisplay();
 
137
}
 
138
 
 
139
 
 
140
 
 
141
static void
 
142
SquareVertex(GLfloat s, GLfloat t, GLfloat size)
 
143
{
 
144
   GLfloat x = -size + s * 2.0 * size;
 
145
   GLfloat y = -size + t * 2.0 * size;
 
146
   GLuint i;
 
147
 
 
148
   glMultiTexCoord2f(GL_TEXTURE0, s, t);
 
149
   glMultiTexCoord2f(GL_TEXTURE1, s, t);
 
150
   glMultiTexCoord2f(GL_TEXTURE2, s, t);
 
151
   glMultiTexCoord2f(GL_TEXTURE3, s, t);
 
152
 
 
153
   /* assign (s,t) to the generic attributes */
 
154
   for (i = 0; i < NumAttribs; i++) {
 
155
      if (Attribs[i].location >= 0) {
 
156
         glVertexAttrib2f(Attribs[i].location, s, t);
 
157
      }
 
158
   }
 
159
 
 
160
   glVertex2f(x, y);
 
161
}
 
162
 
 
163
 
 
164
/*
 
165
 * Draw a square, specifying normal and tangent vectors.
 
166
 */
 
167
static void
 
168
Square(GLfloat size)
 
169
{
 
170
   GLint tangentAttrib = 1;
 
171
   glNormal3f(0, 0, 1);
 
172
   glVertexAttrib3f(tangentAttrib, 1, 0, 0);
 
173
   glBegin(GL_POLYGON);
 
174
#if 1
 
175
   SquareVertex(0, 0, size);
 
176
   SquareVertex(1, 0, size);
 
177
   SquareVertex(1, 1, size);
 
178
   SquareVertex(0, 1, size);
 
179
#else
 
180
   glTexCoord2f(0, 0);  glVertex2f(-size, -size);
 
181
   glTexCoord2f(1, 0);  glVertex2f( size, -size);
 
182
   glTexCoord2f(1, 1);  glVertex2f( size,  size);
 
183
   glTexCoord2f(0, 1);  glVertex2f(-size,  size);
 
184
#endif
 
185
   glEnd();
 
186
}
 
187
 
 
188
 
 
189
static void
 
190
Cube(GLfloat size)
 
191
{
 
192
   /* +X */
 
193
   glPushMatrix();
 
194
   glRotatef(90, 0, 1, 0);
 
195
   glTranslatef(0, 0, size);
 
196
   Square(size);
 
197
   glPopMatrix();
 
198
 
 
199
   /* -X */
 
200
   glPushMatrix();
 
201
   glRotatef(-90, 0, 1, 0);
 
202
   glTranslatef(0, 0, size);
 
203
   Square(size);
 
204
   glPopMatrix();
 
205
 
 
206
   /* +Y */
 
207
   glPushMatrix();
 
208
   glRotatef(90, 1, 0, 0);
 
209
   glTranslatef(0, 0, size);
 
210
   Square(size);
 
211
   glPopMatrix();
 
212
 
 
213
   /* -Y */
 
214
   glPushMatrix();
 
215
   glRotatef(-90, 1, 0, 0);
 
216
   glTranslatef(0, 0, size);
 
217
   Square(size);
 
218
   glPopMatrix();
 
219
 
 
220
 
 
221
   /* +Z */
 
222
   glPushMatrix();
 
223
   glTranslatef(0, 0, size);
 
224
   Square(size);
 
225
   glPopMatrix();
 
226
 
 
227
   /* -Z */
 
228
   glPushMatrix();
 
229
   glRotatef(180, 0, 1, 0);
 
230
   glTranslatef(0, 0, size);
 
231
   Square(size);
 
232
   glPopMatrix();
 
233
}
 
234
 
 
235
 
 
236
static void
 
237
Sphere(GLfloat radius, GLint slices, GLint stacks)
 
238
{
 
239
   static GLUquadricObj *q = NULL;
 
240
 
 
241
   if (!q) {
 
242
      q = gluNewQuadric();
 
243
      gluQuadricDrawStyle(q, GLU_FILL);
 
244
      gluQuadricNormals(q, GLU_SMOOTH);
 
245
      gluQuadricTexture(q, GL_TRUE);
 
246
   }
 
247
 
 
248
   gluSphere(q, radius, slices, stacks);
 
249
}
 
250
 
 
251
 
 
252
static void
 
253
Redisplay(void)
 
254
{
 
255
   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
256
   
 
257
   glPushMatrix();
 
258
   glRotatef(xRot, 1.0f, 0.0f, 0.0f);
 
259
   glRotatef(yRot, 0.0f, 1.0f, 0.0f);
 
260
   glRotatef(zRot, 0.0f, 0.0f, 1.0f);
 
261
 
 
262
   glMatrixMode(GL_TEXTURE);
 
263
   glLoadIdentity();
 
264
   glRotatef(TexRot, 0.0f, 1.0f, 0.0f);
 
265
   glMatrixMode(GL_MODELVIEW);
 
266
 
 
267
   if (Object == SPHERE) {
 
268
      Sphere(2.5, 20, 10);
 
269
   }
 
270
   else if (Object == CUBE) {
 
271
      Cube(2.0);
 
272
   }
 
273
 
 
274
   glPopMatrix();
 
275
 
 
276
   glutSwapBuffers();
 
277
}
 
278
 
 
279
 
 
280
static void
 
281
Reshape(int width, int height)
 
282
{
 
283
   glViewport(0, 0, width, height);
 
284
   glMatrixMode(GL_PROJECTION);
 
285
   glLoadIdentity();
 
286
   glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 25.0);
 
287
   glMatrixMode(GL_MODELVIEW);
 
288
   glLoadIdentity();
 
289
   glTranslatef(0.0f, 0.0f, -15.0f);
 
290
}
 
291
 
 
292
 
 
293
static void
 
294
CleanUp(void)
 
295
{
 
296
   glDeleteShader(fragShader);
 
297
   glDeleteShader(vertShader);
 
298
   glDeleteProgram(Program);
 
299
   glutDestroyWindow(win);
 
300
}
 
301
 
 
302
 
 
303
static void
 
304
Key(unsigned char key, int x, int y)
 
305
{
 
306
   const GLfloat step = 2.0;
 
307
  (void) x;
 
308
  (void) y;
 
309
 
 
310
   switch(key) {
 
311
   case 'a':
 
312
      Anim = !Anim;
 
313
      if (Anim)
 
314
         glutIdleFunc(Idle);
 
315
      else
 
316
         glutIdleFunc(NULL);
 
317
      break;
 
318
   case 'z':
 
319
      zRot += step;
 
320
      break;
 
321
   case 'Z':
 
322
      zRot -= step;
 
323
      break;
 
324
   case 'o':
 
325
      Object = (Object + 1) % NUM_SHAPES;
 
326
      break;
 
327
   case 'r':
 
328
      RandomUniformValues();
 
329
      SetUniformValues(Program, Uniforms);
 
330
      PrintUniforms(Uniforms);
 
331
      break;
 
332
   case 27:
 
333
      CleanUp();
 
334
      exit(0);
 
335
      break;
 
336
   }
 
337
   glutPostRedisplay();
 
338
}
 
339
 
 
340
 
 
341
static void
 
342
SpecialKey(int key, int x, int y)
 
343
{
 
344
   const GLfloat step = 2.0;
 
345
 
 
346
  (void) x;
 
347
  (void) y;
 
348
 
 
349
   switch(key) {
 
350
   case GLUT_KEY_UP:
 
351
      xRot += step;
 
352
      break;
 
353
   case GLUT_KEY_DOWN:
 
354
      xRot -= step;
 
355
      break;
 
356
   case GLUT_KEY_LEFT:
 
357
      yRot -= step;
 
358
      break;
 
359
   case GLUT_KEY_RIGHT:
 
360
      yRot += step;
 
361
      break;
 
362
   }
 
363
   glutPostRedisplay();
 
364
}
 
365
 
 
366
 
 
367
static void
 
368
InitUniforms(const struct config_file *conf,
 
369
             struct uniform_info uniforms[])
 
370
{
 
371
   int i;
 
372
 
 
373
   for (i = 0; i < conf->num_uniforms; i++) {
 
374
      int j;
 
375
      for (j = 0; uniforms[j].name; j++) {
 
376
         if (strcmp(uniforms[j].name, conf->uniforms[i].name) == 0) {
 
377
            uniforms[j].type = conf->uniforms[i].type;
 
378
            uniforms[j].value[0] = conf->uniforms[i].value[0];
 
379
            uniforms[j].value[1] = conf->uniforms[i].value[1];
 
380
            uniforms[j].value[2] = conf->uniforms[i].value[2];
 
381
            uniforms[j].value[3] = conf->uniforms[i].value[3];
 
382
         }
 
383
      }
 
384
   }
 
385
}
 
386
 
 
387
 
 
388
static void
 
389
LoadTexture(GLint unit, GLenum target, const char *texFileName)
 
390
{
 
391
   GLint imgWidth, imgHeight;
 
392
   GLenum imgFormat;
 
393
   GLubyte *image = NULL;
 
394
   GLuint tex;
 
395
   GLenum filter = GL_LINEAR;
 
396
   GLenum objTarget;
 
397
 
 
398
   image = LoadRGBImage(texFileName, &imgWidth, &imgHeight, &imgFormat);
 
399
   if (!image) {
 
400
      printf("Couldn't read %s\n", texFileName);
 
401
      exit(1);
 
402
   }
 
403
 
 
404
   printf("Load Texture: unit %d, target 0x%x: %s %d x %d\n",
 
405
          unit, target, texFileName, imgWidth, imgHeight);
 
406
 
 
407
   if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X &&
 
408
       target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z) {
 
409
      objTarget = GL_TEXTURE_CUBE_MAP;
 
410
   }
 
411
   else {
 
412
      objTarget = target;
 
413
   }
 
414
 
 
415
   glActiveTexture(GL_TEXTURE0 + unit);
 
416
   glGenTextures(1, &tex);
 
417
   glBindTexture(objTarget, tex);
 
418
 
 
419
   if (target == GL_TEXTURE_3D) {
 
420
      /* depth=1 */
 
421
      gluBuild3DMipmaps(target, 4, imgWidth, imgHeight, 1,
 
422
                        imgFormat, GL_UNSIGNED_BYTE, image);
 
423
   }
 
424
   else if (target == GL_TEXTURE_1D) {
 
425
      gluBuild1DMipmaps(target, 4, imgWidth,
 
426
                        imgFormat, GL_UNSIGNED_BYTE, image);
 
427
   }
 
428
   else {
 
429
      gluBuild2DMipmaps(target, 4, imgWidth, imgHeight,
 
430
                        imgFormat, GL_UNSIGNED_BYTE, image);
 
431
   }
 
432
 
 
433
   free(image);
 
434
      
 
435
   glTexParameteri(objTarget, GL_TEXTURE_WRAP_S, GL_REPEAT);
 
436
   glTexParameteri(objTarget, GL_TEXTURE_WRAP_T, GL_REPEAT);
 
437
   glTexParameteri(objTarget, GL_TEXTURE_MIN_FILTER, filter);
 
438
   glTexParameteri(objTarget, GL_TEXTURE_MAG_FILTER, filter);
 
439
}
 
440
 
 
441
 
 
442
static GLenum
 
443
TypeFromName(const char *n)
 
444
{
 
445
   static const struct {
 
446
      const char *name;
 
447
      GLenum type;
 
448
   } types[] = {
 
449
      { "GL_FLOAT", GL_FLOAT },
 
450
      { "GL_FLOAT_VEC2", GL_FLOAT_VEC2 },
 
451
      { "GL_FLOAT_VEC3", GL_FLOAT_VEC3 },
 
452
      { "GL_FLOAT_VEC4", GL_FLOAT_VEC4 },
 
453
      { "GL_INT", GL_INT },
 
454
      { "GL_INT_VEC2", GL_INT_VEC2 },
 
455
      { "GL_INT_VEC3", GL_INT_VEC3 },
 
456
      { "GL_INT_VEC4", GL_INT_VEC4 },
 
457
      { "GL_SAMPLER_1D", GL_SAMPLER_1D },
 
458
      { "GL_SAMPLER_2D", GL_SAMPLER_2D },
 
459
      { "GL_SAMPLER_3D", GL_SAMPLER_3D },
 
460
      { "GL_SAMPLER_CUBE", GL_SAMPLER_CUBE },
 
461
      { "GL_SAMPLER_2D_RECT", GL_SAMPLER_2D_RECT_ARB },
 
462
      { NULL, 0 }
 
463
   };
 
464
   GLuint i;
 
465
 
 
466
   for (i = 0; types[i].name; i++) {
 
467
      if (strcmp(types[i].name, n) == 0)
 
468
         return types[i].type;
 
469
   }
 
470
   abort();
 
471
   return GL_NONE;
 
472
}
 
473
 
 
474
 
 
475
 
 
476
/**
 
477
 * Read a config file.
 
478
 */
 
479
static void
 
480
ReadConfigFile(const char *filename, struct config_file *conf)
 
481
{
 
482
   char line[1000];
 
483
   FILE *f;
 
484
 
 
485
   f = fopen(filename, "r");
 
486
   if (!f) {
 
487
      fprintf(stderr, "Unable to open config file %s\n", filename);
 
488
      exit(1);
 
489
   }
 
490
 
 
491
   conf->num_uniforms = 0;
 
492
 
 
493
   /* ugly but functional parser */
 
494
   while (fgets(line, sizeof(line), f) != NULL) {
 
495
      if (line[0]) {
 
496
         if (strncmp(line, "vs ", 3) == 0) {
 
497
            VertShaderFile = strdup(line + 3);
 
498
            VertShaderFile[strlen(VertShaderFile) - 1] = 0;
 
499
         }
 
500
         else if (strncmp(line, "fs ", 3) == 0) {
 
501
            FragShaderFile = strdup(line + 3);
 
502
            FragShaderFile[strlen(FragShaderFile) - 1] = 0;
 
503
         }
 
504
         else if (strncmp(line, "texture ", 8) == 0) {
 
505
            char target[100], texFileName[100];
 
506
            int unit, k;
 
507
            k = sscanf(line + 8, "%d %s %s", &unit, target, texFileName);
 
508
            assert(k == 3 || k == 8);
 
509
            if (strcmp(target, "CUBE") == 0) {
 
510
               char texFileNames[6][100];
 
511
               k = sscanf(line + 8, "%d %s  %s %s %s %s %s %s",
 
512
                          &unit, target,
 
513
                          texFileNames[0],
 
514
                          texFileNames[1],
 
515
                          texFileNames[2],
 
516
                          texFileNames[3],
 
517
                          texFileNames[4],
 
518
                          texFileNames[5]);
 
519
               LoadTexture(unit, GL_TEXTURE_CUBE_MAP_POSITIVE_X, texFileNames[0]);
 
520
               LoadTexture(unit, GL_TEXTURE_CUBE_MAP_NEGATIVE_X, texFileNames[1]);
 
521
               LoadTexture(unit, GL_TEXTURE_CUBE_MAP_POSITIVE_Y, texFileNames[2]);
 
522
               LoadTexture(unit, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, texFileNames[3]);
 
523
               LoadTexture(unit, GL_TEXTURE_CUBE_MAP_POSITIVE_Z, texFileNames[4]);
 
524
               LoadTexture(unit, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, texFileNames[5]);
 
525
            }
 
526
            else if (!strcmp(target, "2D")) {
 
527
               LoadTexture(unit, GL_TEXTURE_2D, texFileName);
 
528
            }
 
529
            else if (!strcmp(target, "3D")) {
 
530
               LoadTexture(unit, GL_TEXTURE_3D, texFileName);
 
531
            }
 
532
            else if (!strcmp(target, "RECT")) {
 
533
               LoadTexture(unit, GL_TEXTURE_RECTANGLE_ARB, texFileName);
 
534
            }
 
535
            else {
 
536
               printf("Bad texture target: %s\n", target);
 
537
               exit(1);
 
538
            }
 
539
         }
 
540
         else if (strncmp(line, "uniform ", 8) == 0) {
 
541
            char name[1000], typeName[100];
 
542
            int k;
 
543
            float v1 = 0.0F, v2 = 0.0F, v3 = 0.0F, v4 = 0.0F;
 
544
            GLenum type;
 
545
 
 
546
            k = sscanf(line + 8, "%s %s %f %f %f %f", name, typeName,
 
547
                       &v1, &v2, &v3, &v4);
 
548
 
 
549
            type = TypeFromName(typeName);
 
550
 
 
551
            if (strlen(name) + 1 > sizeof(conf->uniforms[conf->num_uniforms].name)) {
 
552
               fprintf(stderr, "string overflow\n");
 
553
               exit(1);
 
554
            }
 
555
            strcpy(conf->uniforms[conf->num_uniforms].name, name);
 
556
            conf->uniforms[conf->num_uniforms].value[0] = v1;
 
557
            conf->uniforms[conf->num_uniforms].value[1] = v2;
 
558
            conf->uniforms[conf->num_uniforms].value[2] = v3;
 
559
            conf->uniforms[conf->num_uniforms].value[3] = v4;
 
560
            conf->uniforms[conf->num_uniforms].type = type;
 
561
            conf->num_uniforms++;
 
562
         }
 
563
         else {
 
564
            if (strlen(line) > 1) {
 
565
               fprintf(stderr, "syntax error in: %s\n", line);
 
566
               break;
 
567
            }
 
568
         }
 
569
      }
 
570
   }
 
571
 
 
572
   fclose(f);
 
573
}
 
574
 
 
575
 
 
576
static void
 
577
Init(void)
 
578
{
 
579
   GLdouble vertTime, fragTime, linkTime;
 
580
   struct config_file config;
 
581
 
 
582
   memset(&config, 0, sizeof(config));
 
583
 
 
584
   if (ConfigFile)
 
585
      ReadConfigFile(ConfigFile, &config);
 
586
 
 
587
   if (!VertShaderFile) {
 
588
      fprintf(stderr, "Error: no vertex shader\n");
 
589
      exit(1);
 
590
   }
 
591
 
 
592
   if (!FragShaderFile) {
 
593
      fprintf(stderr, "Error: no fragment shader\n");
 
594
      exit(1);
 
595
   }
 
596
 
 
597
   if (!ShadersSupported())
 
598
      exit(1);
 
599
 
 
600
   vertShader = CompileShaderFile(GL_VERTEX_SHADER, VertShaderFile);
 
601
   vertTime = GetShaderCompileTime();
 
602
   fragShader = CompileShaderFile(GL_FRAGMENT_SHADER, FragShaderFile);
 
603
   fragTime = GetShaderCompileTime();
 
604
 
 
605
   Program = LinkShaders(vertShader, fragShader);
 
606
   linkTime = GetShaderLinkTime();
 
607
 
 
608
   printf("Read vert shader %s\n", VertShaderFile);
 
609
   printf("Read frag shader %s\n", FragShaderFile);
 
610
 
 
611
   printf("Time to compile vertex shader: %fs\n", vertTime);
 
612
   printf("Time to compile fragment shader: %fs\n", fragTime);
 
613
   printf("Time to link shaders: %fs\n", linkTime);
 
614
 
 
615
   assert(ValidateShaderProgram(Program));
 
616
 
 
617
   glUseProgram(Program);
 
618
 
 
619
   NumUniforms = GetUniforms(Program, Uniforms);
 
620
   if (config.num_uniforms) {
 
621
      InitUniforms(&config, Uniforms);
 
622
   }
 
623
   else {
 
624
      RandomUniformValues();
 
625
   }
 
626
   SetUniformValues(Program, Uniforms);
 
627
   PrintUniforms(Uniforms);
 
628
 
 
629
   NumAttribs = GetAttribs(Program, Attribs);
 
630
   PrintAttribs(Attribs);
 
631
 
 
632
   /* assert(glGetError() == 0); */
 
633
 
 
634
   glClearColor(0.4f, 0.4f, 0.8f, 0.0f);
 
635
 
 
636
   glEnable(GL_DEPTH_TEST);
 
637
 
 
638
   glColor3f(1, 0, 0);
 
639
}
 
640
 
 
641
 
 
642
static void
 
643
Keys(void)
 
644
{
 
645
   printf("Keyboard:\n");
 
646
   printf("       a  Animation toggle\n");
 
647
   printf("       r  Randomize uniform values\n");
 
648
   printf("       o  Change object\n");
 
649
   printf("  arrows  Rotate object\n");
 
650
   printf("     ESC  Exit\n");
 
651
}
 
652
 
 
653
 
 
654
static void
 
655
Usage(void)
 
656
{
 
657
   printf("Usage:\n");
 
658
   printf("   shtest config.shtest\n");
 
659
   printf("       Run w/ given config file.\n");
 
660
   printf("   shtest --vs vertShader --fs fragShader\n");
 
661
   printf("       Load/compile given shaders.\n");
 
662
}
 
663
 
 
664
 
 
665
static void
 
666
ParseOptions(int argc, char *argv[])
 
667
{
 
668
   int i;
 
669
 
 
670
   if (argc == 1) {
 
671
      Usage();
 
672
      exit(1);
 
673
   }
 
674
 
 
675
   for (i = 1; i < argc; i++) {
 
676
      if (strcmp(argv[i], "--fs") == 0) {
 
677
         FragShaderFile = argv[i+1];
 
678
         i++;
 
679
      }
 
680
      else if (strcmp(argv[i], "--vs") == 0) {
 
681
         VertShaderFile = argv[i+1];
 
682
         i++;
 
683
      }
 
684
      else {
 
685
         /* assume the arg is a config file */
 
686
         ConfigFile = argv[i];
 
687
         break;
 
688
      }
 
689
   }
 
690
}
 
691
 
 
692
 
 
693
int
 
694
main(int argc, char *argv[])
 
695
{
 
696
   glutInitWindowSize(400, 400);
 
697
   glutInit(&argc, argv);
 
698
   glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
 
699
   win = glutCreateWindow(argv[0]);
 
700
   glewInit();
 
701
   glutReshapeFunc(Reshape);
 
702
   glutKeyboardFunc(Key);
 
703
   glutSpecialFunc(SpecialKey);
 
704
   glutDisplayFunc(Redisplay);
 
705
   ParseOptions(argc, argv);
 
706
   Init();
 
707
   Keys();
 
708
   glutMainLoop();
 
709
   return 0;
 
710
}
 
711