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

« back to all changes in this revision

Viewing changes to src/xdemos/glxcontexts.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
 * Copyright (C) 1999-2001  Brian Paul   All Rights Reserved.
 
3
 * 
 
4
 * Permission is hereby granted, free of charge, to any person obtaining a
 
5
 * copy of this software and associated documentation files (the "Software"),
 
6
 * to deal in the Software without restriction, including without limitation
 
7
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 
8
 * and/or sell copies of the Software, and to permit persons to whom the
 
9
 * Software is furnished to do so, subject to the following conditions:
 
10
 * 
 
11
 * The above copyright notice and this permission notice shall be included
 
12
 * in all copies or substantial portions of the Software.
 
13
 * 
 
14
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 
15
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
16
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 
17
 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
 
18
 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 
19
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
20
 */
 
21
 
 
22
/*
 
23
 * Version of glxgears that creates/destroys the rendering context for each
 
24
 * frame.  Also periodically destroy/recreate the window.
 
25
 * Good for finding memory leaks, etc.
 
26
 *
 
27
 * Command line options:
 
28
 *    -info      print GL implementation information
 
29
 *
 
30
 */
 
31
 
 
32
 
 
33
#include <assert.h>
 
34
#include <math.h>
 
35
#include <stdlib.h>
 
36
#include <stdio.h>
 
37
#include <string.h>
 
38
#include <X11/Xlib.h>
 
39
#include <X11/keysym.h>
 
40
#include <GL/gl.h>
 
41
#include <GL/glx.h>
 
42
 
 
43
 
 
44
#define BENCHMARK
 
45
 
 
46
#ifdef BENCHMARK
 
47
 
 
48
/* XXX this probably isn't very portable */
 
49
 
 
50
#include <sys/time.h>
 
51
#include <unistd.h>
 
52
 
 
53
/* return current time (in seconds) */
 
54
static double
 
55
current_time(void)
 
56
{
 
57
   struct timeval tv;
 
58
#ifdef __VMS
 
59
   (void) gettimeofday(&tv, NULL );
 
60
#else
 
61
   struct timezone tz;
 
62
   (void) gettimeofday(&tv, &tz);
 
63
#endif
 
64
   return (double) tv.tv_sec + tv.tv_usec / 1000000.0;
 
65
}
 
66
 
 
67
#else /*BENCHMARK*/
 
68
 
 
69
/* dummy */
 
70
static double
 
71
current_time(void)
 
72
{
 
73
   /* update this function for other platforms! */
 
74
   static double t = 0.0;
 
75
   static int warn = 1;
 
76
   if (warn) {
 
77
      fprintf(stderr, "Warning: current_time() not implemented!!\n");
 
78
      warn = 0;
 
79
   }
 
80
   return t += 1.0;
 
81
}
 
82
 
 
83
#endif /*BENCHMARK*/
 
84
 
 
85
 
 
86
 
 
87
#ifndef M_PI
 
88
#define M_PI 3.14159265
 
89
#endif
 
90
 
 
91
 
 
92
static GLfloat view_rotx = 20.0, view_roty = 30.0, view_rotz = 0.0;
 
93
static GLint gear1, gear2, gear3;
 
94
static GLfloat angle = 0.0;
 
95
 
 
96
static XVisualInfo *visinfo = NULL;
 
97
static int WinWidth = 300, WinHeight = 300;
 
98
 
 
99
 
 
100
/*
 
101
 *
 
102
 *  Draw a gear wheel.  You'll probably want to call this function when
 
103
 *  building a display list since we do a lot of trig here.
 
104
 * 
 
105
 *  Input:  inner_radius - radius of hole at center
 
106
 *          outer_radius - radius at center of teeth
 
107
 *          width - width of gear
 
108
 *          teeth - number of teeth
 
109
 *          tooth_depth - depth of tooth
 
110
 */
 
111
static void
 
112
gear(GLfloat inner_radius, GLfloat outer_radius, GLfloat width,
 
113
     GLint teeth, GLfloat tooth_depth)
 
114
{
 
115
   GLint i;
 
116
   GLfloat r0, r1, r2;
 
117
   GLfloat angle, da;
 
118
   GLfloat u, v, len;
 
119
 
 
120
   r0 = inner_radius;
 
121
   r1 = outer_radius - tooth_depth / 2.0;
 
122
   r2 = outer_radius + tooth_depth / 2.0;
 
123
 
 
124
   da = 2.0 * M_PI / teeth / 4.0;
 
125
 
 
126
   glShadeModel(GL_FLAT);
 
127
 
 
128
   glNormal3f(0.0, 0.0, 1.0);
 
129
 
 
130
   /* draw front face */
 
131
   glBegin(GL_QUAD_STRIP);
 
132
   for (i = 0; i <= teeth; i++) {
 
133
      angle = i * 2.0 * M_PI / teeth;
 
134
      glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
 
135
      glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
 
136
      if (i < teeth) {
 
137
         glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
 
138
         glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
 
139
                    width * 0.5);
 
140
      }
 
141
   }
 
142
   glEnd();
 
143
 
 
144
   /* draw front sides of teeth */
 
145
   glBegin(GL_QUADS);
 
146
   da = 2.0 * M_PI / teeth / 4.0;
 
147
   for (i = 0; i < teeth; i++) {
 
148
      angle = i * 2.0 * M_PI / teeth;
 
149
 
 
150
      glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
 
151
      glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), width * 0.5);
 
152
      glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da),
 
153
                 width * 0.5);
 
154
      glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
 
155
                 width * 0.5);
 
156
   }
 
157
   glEnd();
 
158
 
 
159
   glNormal3f(0.0, 0.0, -1.0);
 
160
 
 
161
   /* draw back face */
 
162
   glBegin(GL_QUAD_STRIP);
 
163
   for (i = 0; i <= teeth; i++) {
 
164
      angle = i * 2.0 * M_PI / teeth;
 
165
      glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
 
166
      glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
 
167
      if (i < teeth) {
 
168
         glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
 
169
                    -width * 0.5);
 
170
         glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
 
171
      }
 
172
   }
 
173
   glEnd();
 
174
 
 
175
   /* draw back sides of teeth */
 
176
   glBegin(GL_QUADS);
 
177
   da = 2.0 * M_PI / teeth / 4.0;
 
178
   for (i = 0; i < teeth; i++) {
 
179
      angle = i * 2.0 * M_PI / teeth;
 
180
 
 
181
      glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
 
182
                 -width * 0.5);
 
183
      glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da),
 
184
                 -width * 0.5);
 
185
      glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -width * 0.5);
 
186
      glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
 
187
   }
 
188
   glEnd();
 
189
 
 
190
   /* draw outward faces of teeth */
 
191
   glBegin(GL_QUAD_STRIP);
 
192
   for (i = 0; i < teeth; i++) {
 
193
      angle = i * 2.0 * M_PI / teeth;
 
194
 
 
195
      glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
 
196
      glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
 
197
      u = r2 * cos(angle + da) - r1 * cos(angle);
 
198
      v = r2 * sin(angle + da) - r1 * sin(angle);
 
199
      len = sqrt(u * u + v * v);
 
200
      u /= len;
 
201
      v /= len;
 
202
      glNormal3f(v, -u, 0.0);
 
203
      glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), width * 0.5);
 
204
      glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -width * 0.5);
 
205
      glNormal3f(cos(angle), sin(angle), 0.0);
 
206
      glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da),
 
207
                 width * 0.5);
 
208
      glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da),
 
209
                 -width * 0.5);
 
210
      u = r1 * cos(angle + 3 * da) - r2 * cos(angle + 2 * da);
 
211
      v = r1 * sin(angle + 3 * da) - r2 * sin(angle + 2 * da);
 
212
      glNormal3f(v, -u, 0.0);
 
213
      glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
 
214
                 width * 0.5);
 
215
      glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
 
216
                 -width * 0.5);
 
217
      glNormal3f(cos(angle), sin(angle), 0.0);
 
218
   }
 
219
 
 
220
   glVertex3f(r1 * cos(0), r1 * sin(0), width * 0.5);
 
221
   glVertex3f(r1 * cos(0), r1 * sin(0), -width * 0.5);
 
222
 
 
223
   glEnd();
 
224
 
 
225
   glShadeModel(GL_SMOOTH);
 
226
 
 
227
   /* draw inside radius cylinder */
 
228
   glBegin(GL_QUAD_STRIP);
 
229
   for (i = 0; i <= teeth; i++) {
 
230
      angle = i * 2.0 * M_PI / teeth;
 
231
      glNormal3f(-cos(angle), -sin(angle), 0.0);
 
232
      glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
 
233
      glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
 
234
   }
 
235
   glEnd();
 
236
}
 
237
 
 
238
 
 
239
static void
 
240
do_draw(void)
 
241
{
 
242
   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
243
 
 
244
   glPushMatrix();
 
245
   glRotatef(view_rotx, 1.0, 0.0, 0.0);
 
246
   glRotatef(view_roty, 0.0, 1.0, 0.0);
 
247
   glRotatef(view_rotz, 0.0, 0.0, 1.0);
 
248
 
 
249
   glPushMatrix();
 
250
   glTranslatef(-3.0, -2.0, 0.0);
 
251
   glRotatef(angle, 0.0, 0.0, 1.0);
 
252
   glCallList(gear1);
 
253
   glPopMatrix();
 
254
 
 
255
   glPushMatrix();
 
256
   glTranslatef(3.1, -2.0, 0.0);
 
257
   glRotatef(-2.0 * angle - 9.0, 0.0, 0.0, 1.0);
 
258
   glCallList(gear2);
 
259
   glPopMatrix();
 
260
 
 
261
   glPushMatrix();
 
262
   glTranslatef(-3.1, 4.2, 0.0);
 
263
   glRotatef(-2.0 * angle - 25.0, 0.0, 0.0, 1.0);
 
264
   glCallList(gear3);
 
265
   glPopMatrix();
 
266
 
 
267
   glPopMatrix();
 
268
}
 
269
 
 
270
 
 
271
/* new window size or exposure */
 
272
static void
 
273
reshape(int width, int height)
 
274
{
 
275
   glViewport(0, 0, (GLint) width, (GLint) height);
 
276
 
 
277
   {
 
278
      GLfloat h = (GLfloat) height / (GLfloat) width;
 
279
 
 
280
      glMatrixMode(GL_PROJECTION);
 
281
      glLoadIdentity();
 
282
      glFrustum(-1.0, 1.0, -h, h, 5.0, 60.0);
 
283
   }
 
284
   
 
285
   glMatrixMode(GL_MODELVIEW);
 
286
   glLoadIdentity();
 
287
   glTranslatef(0.0, 0.0, -40.0);
 
288
}
 
289
 
 
290
 
 
291
static void
 
292
init(void)
 
293
{
 
294
   static GLfloat pos[4] = { 5.0, 5.0, 10.0, 0.0 };
 
295
   static GLfloat red[4] = { 0.8, 0.1, 0.0, 1.0 };
 
296
   static GLfloat green[4] = { 0.0, 0.8, 0.2, 1.0 };
 
297
   static GLfloat blue[4] = { 0.2, 0.2, 1.0, 1.0 };
 
298
 
 
299
   glLightfv(GL_LIGHT0, GL_POSITION, pos);
 
300
   glEnable(GL_CULL_FACE);
 
301
   glEnable(GL_LIGHTING);
 
302
   glEnable(GL_LIGHT0);
 
303
   glEnable(GL_DEPTH_TEST);
 
304
 
 
305
   /* make the gears */
 
306
   gear1 = glGenLists(1);
 
307
   glNewList(gear1, GL_COMPILE);
 
308
   glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red);
 
309
   gear(1.0, 4.0, 1.0, 20, 0.7);
 
310
   glEndList();
 
311
 
 
312
   gear2 = glGenLists(1);
 
313
   glNewList(gear2, GL_COMPILE);
 
314
   glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, green);
 
315
   gear(0.5, 2.0, 2.0, 10, 0.7);
 
316
   glEndList();
 
317
 
 
318
   gear3 = glGenLists(1);
 
319
   glNewList(gear3, GL_COMPILE);
 
320
   glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, blue);
 
321
   gear(1.3, 2.0, 0.5, 10, 0.7);
 
322
   glEndList();
 
323
 
 
324
   glEnable(GL_NORMALIZE);
 
325
}
 
326
   
 
327
 
 
328
static void
 
329
draw( Display *dpy, Window win )
 
330
{
 
331
   GLXContext ctx;
 
332
 
 
333
   ctx = glXCreateContext( dpy, visinfo, NULL, True );
 
334
   if (!ctx) {
 
335
      printf("Error: glXCreateContext failed\n");
 
336
      exit(1);
 
337
   }
 
338
 
 
339
   glXMakeCurrent(dpy, win, ctx);
 
340
 
 
341
   init();
 
342
 
 
343
   reshape(WinWidth, WinHeight);
 
344
 
 
345
   do_draw();
 
346
 
 
347
   glDeleteLists(gear1, 1);
 
348
   glDeleteLists(gear2, 1);
 
349
   glDeleteLists(gear3, 1);
 
350
 
 
351
   glXSwapBuffers(dpy, win);
 
352
   glXDestroyContext(dpy, ctx);
 
353
}
 
354
 
 
355
 
 
356
/*
 
357
 * Create an RGB, double-buffered window.
 
358
 * Return the window and context handles.
 
359
 */
 
360
static void
 
361
make_window( Display *dpy, const char *name,
 
362
             int x, int y, int width, int height,
 
363
             Window *winRet)
 
364
{
 
365
   int attribs[] = { GLX_RGBA,
 
366
                     GLX_RED_SIZE, 1,
 
367
                     GLX_GREEN_SIZE, 1,
 
368
                     GLX_BLUE_SIZE, 1,
 
369
                     GLX_DOUBLEBUFFER,
 
370
                     GLX_DEPTH_SIZE, 1,
 
371
                     None };
 
372
   int scrnum;
 
373
   XSetWindowAttributes attr;
 
374
   unsigned long mask;
 
375
   Window root;
 
376
   Window win;
 
377
 
 
378
   scrnum = DefaultScreen( dpy );
 
379
   root = RootWindow( dpy, scrnum );
 
380
 
 
381
   if (visinfo)
 
382
           XFree(visinfo);
 
383
 
 
384
   visinfo = glXChooseVisual( dpy, scrnum, attribs );
 
385
   if (!visinfo) {
 
386
      printf("Error: couldn't get an RGB, Double-buffered visual\n");
 
387
      exit(1);
 
388
   }
 
389
 
 
390
   /* window attributes */
 
391
   attr.background_pixel = 0;
 
392
   attr.border_pixel = 0;
 
393
   attr.colormap = XCreateColormap( dpy, root, visinfo->visual, AllocNone);
 
394
   attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
 
395
   attr.override_redirect = 0;
 
396
   mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask | CWOverrideRedirect;
 
397
 
 
398
   win = XCreateWindow( dpy, root, x, y, width, height,
 
399
                        0, visinfo->depth, InputOutput,
 
400
                        visinfo->visual, mask, &attr );
 
401
 
 
402
   /* set hints and properties */
 
403
   {
 
404
      XSizeHints sizehints;
 
405
      sizehints.x = x;
 
406
      sizehints.y = y;
 
407
      sizehints.width  = width;
 
408
      sizehints.height = height;
 
409
      sizehints.flags = USSize | USPosition;
 
410
      XSetNormalHints(dpy, win, &sizehints);
 
411
      XSetStandardProperties(dpy, win, name, name,
 
412
                              None, (char **)NULL, 0, &sizehints);
 
413
   }
 
414
 
 
415
   *winRet = win;
 
416
}
 
417
 
 
418
 
 
419
static void
 
420
event_loop(Display *dpy)
 
421
{
 
422
   Window win;
 
423
   make_window(dpy, "glxgears", 0, 0, WinWidth, WinHeight, &win);
 
424
   XMapWindow(dpy, win);
 
425
 
 
426
   while (1) {
 
427
      while (XPending(dpy) > 0) {
 
428
         XEvent event;
 
429
         XNextEvent(dpy, &event);
 
430
         switch (event.type) {
 
431
         case Expose:
 
432
            /* we'll redraw below */
 
433
            break;
 
434
         case ConfigureNotify:
 
435
            WinWidth = event.xconfigure.width;
 
436
            WinHeight = event.xconfigure.height;
 
437
            break;
 
438
         case KeyPress:
 
439
            {
 
440
               char buffer[10];
 
441
               int r, code;
 
442
               code = XLookupKeysym(&event.xkey, 0);
 
443
               if (code == XK_Left) {
 
444
                  view_roty += 5.0;
 
445
               }
 
446
               else if (code == XK_Right) {
 
447
                  view_roty -= 5.0;
 
448
               }
 
449
               else if (code == XK_Up) {
 
450
                  view_rotx += 5.0;
 
451
               }
 
452
               else if (code == XK_Down) {
 
453
                  view_rotx -= 5.0;
 
454
               }
 
455
               else {
 
456
                  r = XLookupString(&event.xkey, buffer, sizeof(buffer),
 
457
                                    NULL, NULL);
 
458
                  if (buffer[0] == 27) {
 
459
                     /* escape */
 
460
                     return;
 
461
                  }
 
462
               }
 
463
            }
 
464
         }
 
465
      }
 
466
 
 
467
      {
 
468
         static int frames = 0;
 
469
         static double tRot0 = -1.0, tRate0 = -1.0;
 
470
         double dt, t = current_time();
 
471
         if (tRot0 < 0.0)
 
472
            tRot0 = t;
 
473
         dt = t - tRot0;
 
474
         tRot0 = t;
 
475
 
 
476
         /* advance rotation for next frame */
 
477
         angle += 70.0 * dt;  /* 70 degrees per second */
 
478
         if (angle > 3600.0)
 
479
            angle -= 3600.0;
 
480
 
 
481
         draw( dpy, win );
 
482
 
 
483
         frames++;
 
484
 
 
485
         if (tRate0 < 0.0)
 
486
            tRate0 = t;
 
487
 
 
488
         if (t - tRate0 >= 1.0) {
 
489
            GLfloat seconds = t - tRate0;
 
490
            GLfloat fps = frames / seconds;
 
491
            printf("%d frames in %3.1f seconds = %6.3f FPS\n", frames, seconds,
 
492
                   fps);
 
493
            tRate0 = t;
 
494
 
 
495
            /* Destroy window and create new one */         
 
496
            XDestroyWindow(dpy, win);
 
497
            make_window(dpy, "glxgears",
 
498
                        (int)(fps * 100) % 100, (int)(fps * 100) % 100, /* x,y */
 
499
                        WinWidth, WinHeight, &win);
 
500
            XMapWindow(dpy, win);
 
501
 
 
502
            frames = 0;
 
503
         }
 
504
      }
 
505
   }
 
506
}
 
507
 
 
508
 
 
509
int
 
510
main(int argc, char *argv[])
 
511
{
 
512
   Display *dpy;
 
513
   char *dpyName = NULL;
 
514
   GLboolean printInfo = GL_FALSE;
 
515
   int i;
 
516
 
 
517
   for (i = 1; i < argc; i++) {
 
518
      if (strcmp(argv[i], "-display") == 0) {
 
519
         dpyName = argv[i+1];
 
520
         i++;
 
521
      }
 
522
      else if (strcmp(argv[i], "-info") == 0) {
 
523
         printInfo = GL_TRUE;
 
524
      }
 
525
      else
 
526
         printf("Warrning: unknown parameter: %s\n", argv[i]);
 
527
   }
 
528
 
 
529
   dpy = XOpenDisplay(dpyName);
 
530
   if (!dpy) {
 
531
      fprintf(stderr, "Error: couldn't open display %s\n",
 
532
              XDisplayName(dpyName));
 
533
      return -1;
 
534
   }
 
535
 
 
536
   if (printInfo) {
 
537
      printf("GL_RENDERER   = %s\n", (char *) glGetString(GL_RENDERER));
 
538
      printf("GL_VERSION    = %s\n", (char *) glGetString(GL_VERSION));
 
539
      printf("GL_VENDOR     = %s\n", (char *) glGetString(GL_VENDOR));
 
540
      printf("GL_EXTENSIONS = %s\n", (char *) glGetString(GL_EXTENSIONS));
 
541
   }
 
542
 
 
543
   event_loop(dpy);
 
544
 
 
545
   XCloseDisplay(dpy);
 
546
 
 
547
   return 0;
 
548
}