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

« back to all changes in this revision

Viewing changes to src/tests/random.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
 * Random rendering, to check for crashes, hangs, etc.
 
3
 *
 
4
 * Brian Paul
 
5
 * 21 June 2007
 
6
 */
 
7
 
 
8
 
 
9
#include <assert.h>
 
10
#include <stdio.h>
 
11
#include <stdlib.h>
 
12
#include <string.h>
 
13
#include <math.h>
 
14
#include <GL/glew.h>
 
15
#include <GL/glut.h>
 
16
 
 
17
static int Win;
 
18
static GLboolean Anim = GL_TRUE;
 
19
static int Width = 200, Height = 200;
 
20
static int DB = 0;
 
21
static int MinVertexCount = 0, MaxVertexCount = 1000;
 
22
static int Count = 0;
 
23
 
 
24
struct vertex
 
25
{
 
26
   int type;
 
27
   float v[4];
 
28
};
 
29
 
 
30
static int BufferSize = 10000;
 
31
static struct vertex *Vbuffer = NULL;
 
32
static int Vcount, Vprim;
 
33
 
 
34
enum {
 
35
   BEGIN,
 
36
   END,
 
37
   VERTEX2,
 
38
   VERTEX3,
 
39
   VERTEX4,
 
40
   COLOR3,
 
41
   COLOR4,
 
42
   TEX2,
 
43
   TEX3,
 
44
   TEX4,
 
45
   SECCOLOR3,
 
46
   NORMAL3
 
47
};
 
48
 
 
49
 
 
50
 
 
51
/**
 
52
 * This can be called from within gdb after a crash:
 
53
 * (gdb) call ReportState()
 
54
 */
 
55
static void
 
56
ReportState(void)
 
57
{
 
58
   static const struct {
 
59
      GLenum token;
 
60
      char *str;
 
61
      GLenum type;
 
62
   } state [] = {
 
63
      { GL_ALPHA_TEST, "GL_ALPHA_TEST", GL_INT },
 
64
      { GL_BLEND, "GL_BLEND", GL_INT },
 
65
      { GL_CLIP_PLANE0, "GL_CLIP_PLANE0", GL_INT },
 
66
      { GL_DEPTH_TEST, "GL_DEPTH_TEST", GL_INT },
 
67
      { GL_LIGHTING, "GL_LIGHTING", GL_INT },
 
68
      { GL_LINE_WIDTH, "GL_LINE_WIDTH", GL_FLOAT },
 
69
      { GL_POINT_SIZE, "GL_POINT_SIZE", GL_FLOAT },
 
70
      { GL_SHADE_MODEL, "GL_SHADE_MODEL", GL_INT },
 
71
      { GL_SCISSOR_TEST, "GL_SCISSOR_TEST", GL_INT },
 
72
      { 0, NULL, 0 }
 
73
   };
 
74
 
 
75
   GLint i;
 
76
 
 
77
   for (i = 0; state[i].token; i++) {
 
78
      if (state[i].type == GL_INT) {
 
79
         GLint v;
 
80
         glGetIntegerv(state[i].token, &v);
 
81
         printf("%s = %d\n", state[i].str, v);
 
82
      }
 
83
      else {
 
84
         GLfloat v;
 
85
         glGetFloatv(state[i].token, &v);
 
86
         printf("%s = %f\n", state[i].str, v);
 
87
      }
 
88
   }
 
89
}
 
90
 
 
91
static void
 
92
PrintVertex(const char *f, const struct vertex *v, int sz)
 
93
{
 
94
   int i;
 
95
   printf("%s(", f);
 
96
   for (i = 0; i < sz; i++) {
 
97
      printf("%g%s", v->v[i], (i == sz-1) ? "" : ", ");
 
98
   }
 
99
   printf(");\n");
 
100
}
 
101
 
 
102
/**
 
103
 * This can be called from within gdb after a crash:
 
104
 * (gdb) call ReportState()
 
105
 */
 
106
static void
 
107
LastPrim(void)
 
108
{
 
109
   int i;
 
110
   for (i = 0; i < Vcount; i++) {
 
111
      switch (Vbuffer[i].type) {
 
112
      case BEGIN:
 
113
         printf("glBegin(%d);\n", (int) Vbuffer[i].v[0]);
 
114
         break;
 
115
      case END:
 
116
         printf("glEnd();\n");
 
117
         break;
 
118
      case VERTEX2:
 
119
         PrintVertex("glVertex2f", Vbuffer + i, 2);
 
120
         break;
 
121
      case VERTEX3:
 
122
         PrintVertex("glVertex3f", Vbuffer + i, 3);
 
123
         break;
 
124
      case VERTEX4:
 
125
         PrintVertex("glVertex4f", Vbuffer + i, 4);
 
126
         break;
 
127
      case COLOR3:
 
128
         PrintVertex("glColor3f", Vbuffer + i, 3);
 
129
         break;
 
130
      case COLOR4:
 
131
         PrintVertex("glColor4f", Vbuffer + i, 4);
 
132
         break;
 
133
      case TEX2:
 
134
         PrintVertex("glTexCoord2f", Vbuffer + i, 2);
 
135
         break;
 
136
      case TEX3:
 
137
         PrintVertex("glTexCoord3f", Vbuffer + i, 3);
 
138
         break;
 
139
      case TEX4:
 
140
         PrintVertex("glTexCoord4f", Vbuffer + i, 4);
 
141
         break;
 
142
      case SECCOLOR3:
 
143
         PrintVertex("glSecondaryColor3f", Vbuffer + i, 3);
 
144
         break;
 
145
      case NORMAL3:
 
146
         PrintVertex("glNormal3f", Vbuffer + i, 3);
 
147
         break;
 
148
      default:
 
149
         abort();
 
150
      }
 
151
   }
 
152
}
 
153
 
 
154
 
 
155
static int
 
156
RandomInt(int max)
 
157
{
 
158
   if (max == 0)
 
159
      return 0;
 
160
   return rand() % max;
 
161
}
 
162
 
 
163
static float
 
164
RandomFloat(float min, float max)
 
165
{
 
166
   int k = rand() % 10000;
 
167
   float x = min + (max - min) * k / 10000.0;
 
168
   return x;
 
169
}
 
170
 
 
171
/*
 
172
 * Return true if random number in [0,1] is <= percentile.
 
173
 */
 
174
static GLboolean
 
175
RandomChoice(float percentile)
 
176
{
 
177
   return RandomFloat(0.0, 1.0) <= percentile;
 
178
}
 
179
 
 
180
static void
 
181
RandomStateChange(void)
 
182
{
 
183
   int k = RandomInt(19);
 
184
   switch (k) {
 
185
   case 0:
 
186
      glEnable(GL_BLEND);
 
187
      break;
 
188
   case 1:
 
189
      glDisable(GL_BLEND);
 
190
      break;
 
191
   case 2:
 
192
      glEnable(GL_ALPHA_TEST);
 
193
      break;
 
194
   case 3:
 
195
      glEnable(GL_ALPHA_TEST);
 
196
      break;
 
197
   case 4:
 
198
      glEnable(GL_DEPTH_TEST);
 
199
      break;
 
200
   case 5:
 
201
      glEnable(GL_DEPTH_TEST);
 
202
      break;
 
203
   case 6:
 
204
      glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
205
      break;
 
206
   case 7:
 
207
      glPointSize(10.0);
 
208
      break;
 
209
   case 8:
 
210
      glPointSize(1.0);
 
211
      break;
 
212
   case 9:
 
213
      glLineWidth(10.0);
 
214
      break;
 
215
   case 10:
 
216
      glLineWidth(1.0);
 
217
      break;
 
218
   case 11:
 
219
      glEnable(GL_LIGHTING);
 
220
      break;
 
221
   case 12:
 
222
      glDisable(GL_LIGHTING);
 
223
      break;
 
224
   case 13:
 
225
      glEnable(GL_SCISSOR_TEST);
 
226
      break;
 
227
   case 14:
 
228
      glDisable(GL_SCISSOR_TEST);
 
229
      break;
 
230
   case 15:
 
231
      glEnable(GL_CLIP_PLANE0);
 
232
      break;
 
233
   case 16:
 
234
      glDisable(GL_CLIP_PLANE0);
 
235
      break;
 
236
   case 17:
 
237
      glShadeModel(GL_FLAT);
 
238
      break;
 
239
   case 18:
 
240
      glShadeModel(GL_SMOOTH);
 
241
      break;
 
242
   }
 
243
}
 
244
 
 
245
 
 
246
static void
 
247
RandomPrimitive(void)
 
248
{
 
249
   int i;
 
250
   int len = MinVertexCount + RandomInt(MaxVertexCount - MinVertexCount);
 
251
 
 
252
   Vprim = RandomInt(10);
 
253
 
 
254
   glBegin(Vprim);
 
255
   Vbuffer[Vcount].type = BEGIN;
 
256
   Vbuffer[Vcount].v[0] = Vprim;
 
257
   Vcount++;
 
258
 
 
259
   for (i = 0; i < len; i++) {
 
260
      int k = RandomInt(9);
 
261
      Vbuffer[Vcount].v[0] = RandomFloat(-3, 3);
 
262
      Vbuffer[Vcount].v[1] = RandomFloat(-3, 3);
 
263
      Vbuffer[Vcount].v[2] = RandomFloat(-3, 3);
 
264
      Vbuffer[Vcount].v[3] = RandomFloat(-3, 3);
 
265
      switch (k) {
 
266
      case 0:
 
267
         glVertex2fv(Vbuffer[Vcount].v);
 
268
         Vbuffer[Vcount].type = VERTEX2;
 
269
         break;
 
270
      case 1:
 
271
         glVertex3fv(Vbuffer[Vcount].v);
 
272
         Vbuffer[Vcount].type = VERTEX3;
 
273
         break;
 
274
      case 2:
 
275
         glVertex4fv(Vbuffer[Vcount].v);
 
276
         Vbuffer[Vcount].type = VERTEX4;
 
277
         break;
 
278
      case 3:
 
279
         glColor3fv(Vbuffer[Vcount].v);
 
280
         Vbuffer[Vcount].type = COLOR3;
 
281
         break;
 
282
      case 4:
 
283
         glColor4fv(Vbuffer[Vcount].v);
 
284
         Vbuffer[Vcount].type = COLOR4;
 
285
         break;
 
286
      case 5:
 
287
         glTexCoord2fv(Vbuffer[Vcount].v);
 
288
         Vbuffer[Vcount].type = TEX2;
 
289
         break;
 
290
      case 6:
 
291
         glTexCoord3fv(Vbuffer[Vcount].v);
 
292
         Vbuffer[Vcount].type = TEX3;
 
293
         break;
 
294
      case 7:
 
295
         glTexCoord4fv(Vbuffer[Vcount].v);
 
296
         Vbuffer[Vcount].type = TEX4;
 
297
         break;
 
298
      case 8:
 
299
         glSecondaryColor3fv(Vbuffer[Vcount].v);
 
300
         Vbuffer[Vcount].type = SECCOLOR3;
 
301
         break;
 
302
      case 9:
 
303
         glNormal3fv(Vbuffer[Vcount].v);
 
304
         Vbuffer[Vcount].type = NORMAL3;
 
305
         break;
 
306
      default:
 
307
         abort();
 
308
      }
 
309
      Vcount++;
 
310
 
 
311
      if (Vcount >= BufferSize - 2) {
 
312
         /* reset */
 
313
         Vcount = 0;
 
314
      }
 
315
   }
 
316
 
 
317
   Vbuffer[Vcount++].type = END;
 
318
 
 
319
   glEnd();
 
320
}
 
321
 
 
322
 
 
323
static void
 
324
RandomDraw(void)
 
325
{
 
326
   int i;
 
327
   GLboolean dlist = RandomChoice(0.1);
 
328
   if (dlist)
 
329
      glNewList(1, GL_COMPILE);
 
330
   for (i = 0; i < 3; i++) {
 
331
      RandomStateChange();
 
332
   }
 
333
   RandomPrimitive();
 
334
 
 
335
   if (dlist) {
 
336
      glEndList();
 
337
      glCallList(1);
 
338
   }
 
339
}
 
340
 
 
341
 
 
342
static void
 
343
Idle(void)
 
344
{
 
345
   glutPostRedisplay();
 
346
}
 
347
 
 
348
 
 
349
static void
 
350
Draw(void)
 
351
{
 
352
#if 1
 
353
   RandomDraw();
 
354
   Count++;
 
355
#else
 
356
   /* cut & paste temp code here */
 
357
#endif
 
358
 
 
359
   assert(glGetError() == 0);
 
360
 
 
361
   if (DB)
 
362
      glutSwapBuffers();
 
363
   else
 
364
      glFinish();
 
365
}
 
366
 
 
367
 
 
368
static void
 
369
Reshape(int width, int height)
 
370
{
 
371
   Width = width;
 
372
   Height = height;
 
373
   glViewport(0, 0, width, height);
 
374
   glScissor(20, 20, Width-40, Height-40);
 
375
   glMatrixMode(GL_PROJECTION);
 
376
   glLoadIdentity();
 
377
   glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 25.0);
 
378
   glMatrixMode(GL_MODELVIEW);
 
379
   glLoadIdentity();
 
380
   glTranslatef(0.0, 0.0, -15.0);
 
381
}
 
382
 
 
383
 
 
384
static void
 
385
Key(unsigned char key, int x, int y)
 
386
{
 
387
   (void) x;
 
388
   (void) y;
 
389
   switch (key) {
 
390
      case 27:
 
391
         glutDestroyWindow(Win);
 
392
         exit(0);
 
393
         break;
 
394
   }
 
395
   glutPostRedisplay();
 
396
}
 
397
 
 
398
 
 
399
static void
 
400
Init(void)
 
401
{
 
402
   static const GLdouble plane[4] = {1, 1, 0, 0};
 
403
   glDrawBuffer(GL_FRONT);
 
404
   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
405
   glEnable(GL_LIGHT0);
 
406
   glClipPlane(GL_CLIP_PLANE0, plane);
 
407
 
 
408
   Vbuffer = (struct vertex *)
 
409
      malloc(BufferSize * sizeof(struct vertex));
 
410
 
 
411
   /* silence warnings */
 
412
   (void) ReportState;
 
413
   (void) LastPrim;
 
414
}
 
415
 
 
416
 
 
417
static void
 
418
ParseArgs(int argc, char *argv[])
 
419
{
 
420
   int i;
 
421
   for (i = 1; i < argc; i++) {
 
422
      if (strcmp(argv[i], "-s") == 0) {
 
423
         int j = atoi(argv[i + 1]);
 
424
         printf("Random seed value: %d\n", j);
 
425
         srand(j);
 
426
         i++;
 
427
      }
 
428
      else if (strcmp(argv[i], "-a") == 0) {
 
429
         i++;
 
430
         MinVertexCount = atoi(argv[i]);
 
431
      }
 
432
      else if (strcmp(argv[i], "-b") == 0) {
 
433
         i++;
 
434
         MaxVertexCount = atoi(argv[i]);
 
435
      }
 
436
   }
 
437
}
 
438
 
 
439
 
 
440
int
 
441
main(int argc, char *argv[])
 
442
{
 
443
   glutInit(&argc, argv);
 
444
   glutInitWindowPosition(0, 0);
 
445
   glutInitWindowSize(Width, Height);
 
446
   glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
 
447
   Win = glutCreateWindow(argv[0]);
 
448
   glewInit();
 
449
   ParseArgs(argc, argv);
 
450
   glutReshapeFunc(Reshape);
 
451
   glutKeyboardFunc(Key);
 
452
   glutDisplayFunc(Draw);
 
453
   if (Anim)
 
454
      glutIdleFunc(Idle);
 
455
   Init();
 
456
   glutMainLoop();
 
457
   return 0;
 
458
}