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

« back to all changes in this revision

Viewing changes to src/xdemos/glxgears_fbconfig.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
 * \file glxgears_fbconfig.c
 
24
 * Yet-another-version of gears.  Originally ported to GLX by Brian Paul on
 
25
 * 23 March 2001.  Modified to use fbconfigs by Ian Romanick on 10 Feb 2004.
 
26
 *
 
27
 * Command line options:
 
28
 *    -info      print GL implementation information
 
29
 *
 
30
 * \author Brian Paul
 
31
 * \author Ian Romanick <idr@us.ibm.com>
 
32
 */
 
33
 
 
34
 
 
35
#define GLX_GLXEXT_PROTOTYPES
 
36
 
 
37
#include <math.h>
 
38
#include <stdlib.h>
 
39
#include <stdio.h>
 
40
#include <string.h>
 
41
#include <X11/Xlib.h>
 
42
#include <X11/keysym.h>
 
43
#include <GL/gl.h>
 
44
#include <GL/glx.h>
 
45
#include <GL/glxext.h>
 
46
#include <assert.h>
 
47
#include "pbutil.h"
 
48
 
 
49
static PFNGLXCHOOSEFBCONFIGPROC choose_fbconfig = NULL;
 
50
static PFNGLXGETVISUALFROMFBCONFIGPROC get_visual_from_fbconfig = NULL;
 
51
static PFNGLXCREATENEWCONTEXTPROC create_new_context = NULL;
 
52
static PFNGLXCREATEWINDOWPROC create_window = NULL;
 
53
static PFNGLXDESTROYWINDOWPROC destroy_window = NULL;
 
54
 
 
55
#define BENCHMARK
 
56
 
 
57
#ifdef BENCHMARK
 
58
 
 
59
/* XXX this probably isn't very portable */
 
60
 
 
61
#include <sys/time.h>
 
62
#include <unistd.h>
 
63
 
 
64
/* return current time (in seconds) */
 
65
static int
 
66
current_time(void)
 
67
{
 
68
   struct timeval tv;
 
69
#ifdef __VMS
 
70
   (void) gettimeofday(&tv, NULL );
 
71
#else
 
72
   struct timezone tz;
 
73
   (void) gettimeofday(&tv, &tz);
 
74
#endif
 
75
   return (int) tv.tv_sec;
 
76
}
 
77
 
 
78
#else /*BENCHMARK*/
 
79
 
 
80
/* dummy */
 
81
static int
 
82
current_time(void)
 
83
{
 
84
   return 0;
 
85
}
 
86
 
 
87
#endif /*BENCHMARK*/
 
88
 
 
89
 
 
90
 
 
91
#ifndef M_PI
 
92
#define M_PI 3.14159265
 
93
#endif
 
94
 
 
95
 
 
96
static GLfloat view_rotx = 20.0, view_roty = 30.0, view_rotz = 0.0;
 
97
static GLint gear1, gear2, gear3;
 
98
static GLfloat angle = 0.0;
 
99
 
 
100
 
 
101
/*
 
102
 *
 
103
 *  Draw a gear wheel.  You'll probably want to call this function when
 
104
 *  building a display list since we do a lot of trig here.
 
105
 * 
 
106
 *  Input:  inner_radius - radius of hole at center
 
107
 *          outer_radius - radius at center of teeth
 
108
 *          width - width of gear
 
109
 *          teeth - number of teeth
 
110
 *          tooth_depth - depth of tooth
 
111
 */
 
112
static void
 
113
gear(GLfloat inner_radius, GLfloat outer_radius, GLfloat width,
 
114
     GLint teeth, GLfloat tooth_depth)
 
115
{
 
116
   GLint i;
 
117
   GLfloat r0, r1, r2;
 
118
   GLfloat angle, da;
 
119
   GLfloat u, v, len;
 
120
 
 
121
   r0 = inner_radius;
 
122
   r1 = outer_radius - tooth_depth / 2.0;
 
123
   r2 = outer_radius + tooth_depth / 2.0;
 
124
 
 
125
   da = 2.0 * M_PI / teeth / 4.0;
 
126
 
 
127
   glShadeModel(GL_FLAT);
 
128
 
 
129
   glNormal3f(0.0, 0.0, 1.0);
 
130
 
 
131
   /* draw front face */
 
132
   glBegin(GL_QUAD_STRIP);
 
133
   for (i = 0; i <= teeth; i++) {
 
134
      angle = i * 2.0 * M_PI / teeth;
 
135
      glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
 
136
      glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
 
137
      if (i < teeth) {
 
138
         glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
 
139
         glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
 
140
                    width * 0.5);
 
141
      }
 
142
   }
 
143
   glEnd();
 
144
 
 
145
   /* draw front sides of teeth */
 
146
   glBegin(GL_QUADS);
 
147
   da = 2.0 * M_PI / teeth / 4.0;
 
148
   for (i = 0; i < teeth; i++) {
 
149
      angle = i * 2.0 * M_PI / teeth;
 
150
 
 
151
      glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
 
152
      glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), width * 0.5);
 
153
      glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da),
 
154
                 width * 0.5);
 
155
      glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
 
156
                 width * 0.5);
 
157
   }
 
158
   glEnd();
 
159
 
 
160
   glNormal3f(0.0, 0.0, -1.0);
 
161
 
 
162
   /* draw back face */
 
163
   glBegin(GL_QUAD_STRIP);
 
164
   for (i = 0; i <= teeth; i++) {
 
165
      angle = i * 2.0 * M_PI / teeth;
 
166
      glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
 
167
      glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
 
168
      if (i < teeth) {
 
169
         glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
 
170
                    -width * 0.5);
 
171
         glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
 
172
      }
 
173
   }
 
174
   glEnd();
 
175
 
 
176
   /* draw back sides of teeth */
 
177
   glBegin(GL_QUADS);
 
178
   da = 2.0 * M_PI / teeth / 4.0;
 
179
   for (i = 0; i < teeth; i++) {
 
180
      angle = i * 2.0 * M_PI / teeth;
 
181
 
 
182
      glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
 
183
                 -width * 0.5);
 
184
      glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da),
 
185
                 -width * 0.5);
 
186
      glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -width * 0.5);
 
187
      glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
 
188
   }
 
189
   glEnd();
 
190
 
 
191
   /* draw outward faces of teeth */
 
192
   glBegin(GL_QUAD_STRIP);
 
193
   for (i = 0; i < teeth; i++) {
 
194
      angle = i * 2.0 * M_PI / teeth;
 
195
 
 
196
      glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
 
197
      glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
 
198
      u = r2 * cos(angle + da) - r1 * cos(angle);
 
199
      v = r2 * sin(angle + da) - r1 * sin(angle);
 
200
      len = sqrt(u * u + v * v);
 
201
      u /= len;
 
202
      v /= len;
 
203
      glNormal3f(v, -u, 0.0);
 
204
      glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), width * 0.5);
 
205
      glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -width * 0.5);
 
206
      glNormal3f(cos(angle), sin(angle), 0.0);
 
207
      glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da),
 
208
                 width * 0.5);
 
209
      glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da),
 
210
                 -width * 0.5);
 
211
      u = r1 * cos(angle + 3 * da) - r2 * cos(angle + 2 * da);
 
212
      v = r1 * sin(angle + 3 * da) - r2 * sin(angle + 2 * da);
 
213
      glNormal3f(v, -u, 0.0);
 
214
      glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
 
215
                 width * 0.5);
 
216
      glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
 
217
                 -width * 0.5);
 
218
      glNormal3f(cos(angle), sin(angle), 0.0);
 
219
   }
 
220
 
 
221
   glVertex3f(r1 * cos(0), r1 * sin(0), width * 0.5);
 
222
   glVertex3f(r1 * cos(0), r1 * sin(0), -width * 0.5);
 
223
 
 
224
   glEnd();
 
225
 
 
226
   glShadeModel(GL_SMOOTH);
 
227
 
 
228
   /* draw inside radius cylinder */
 
229
   glBegin(GL_QUAD_STRIP);
 
230
   for (i = 0; i <= teeth; i++) {
 
231
      angle = i * 2.0 * M_PI / teeth;
 
232
      glNormal3f(-cos(angle), -sin(angle), 0.0);
 
233
      glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
 
234
      glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
 
235
   }
 
236
   glEnd();
 
237
}
 
238
 
 
239
 
 
240
static void
 
241
draw(void)
 
242
{
 
243
   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
244
 
 
245
   glPushMatrix();
 
246
   glRotatef(view_rotx, 1.0, 0.0, 0.0);
 
247
   glRotatef(view_roty, 0.0, 1.0, 0.0);
 
248
   glRotatef(view_rotz, 0.0, 0.0, 1.0);
 
249
 
 
250
   glPushMatrix();
 
251
   glTranslatef(-3.0, -2.0, 0.0);
 
252
   glRotatef(angle, 0.0, 0.0, 1.0);
 
253
   glCallList(gear1);
 
254
   glPopMatrix();
 
255
 
 
256
   glPushMatrix();
 
257
   glTranslatef(3.1, -2.0, 0.0);
 
258
   glRotatef(-2.0 * angle - 9.0, 0.0, 0.0, 1.0);
 
259
   glCallList(gear2);
 
260
   glPopMatrix();
 
261
 
 
262
   glPushMatrix();
 
263
   glTranslatef(-3.1, 4.2, 0.0);
 
264
   glRotatef(-2.0 * angle - 25.0, 0.0, 0.0, 1.0);
 
265
   glCallList(gear3);
 
266
   glPopMatrix();
 
267
 
 
268
   glPopMatrix();
 
269
}
 
270
 
 
271
 
 
272
/* new window size or exposure */
 
273
static void
 
274
reshape(int width, int height)
 
275
{
 
276
   GLfloat h = (GLfloat) height / (GLfloat) width;
 
277
 
 
278
   glViewport(0, 0, (GLint) width, (GLint) height);
 
279
   glMatrixMode(GL_PROJECTION);
 
280
   glLoadIdentity();
 
281
   glFrustum(-1.0, 1.0, -h, h, 5.0, 60.0);
 
282
   glMatrixMode(GL_MODELVIEW);
 
283
   glLoadIdentity();
 
284
   glTranslatef(0.0, 0.0, -40.0);
 
285
}
 
286
 
 
287
 
 
288
static void
 
289
init(void)
 
290
{
 
291
   static GLfloat pos[4] = { 5.0, 5.0, 10.0, 0.0 };
 
292
   static GLfloat red[4] = { 0.8, 0.1, 0.0, 1.0 };
 
293
   static GLfloat green[4] = { 0.0, 0.8, 0.2, 1.0 };
 
294
   static GLfloat blue[4] = { 0.2, 0.2, 1.0, 1.0 };
 
295
 
 
296
   glLightfv(GL_LIGHT0, GL_POSITION, pos);
 
297
   glEnable(GL_CULL_FACE);
 
298
   glEnable(GL_LIGHTING);
 
299
   glEnable(GL_LIGHT0);
 
300
   glEnable(GL_DEPTH_TEST);
 
301
 
 
302
   /* make the gears */
 
303
   gear1 = glGenLists(1);
 
304
   glNewList(gear1, GL_COMPILE);
 
305
   glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red);
 
306
   gear(1.0, 4.0, 1.0, 20, 0.7);
 
307
   glEndList();
 
308
 
 
309
   gear2 = glGenLists(1);
 
310
   glNewList(gear2, GL_COMPILE);
 
311
   glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, green);
 
312
   gear(0.5, 2.0, 2.0, 10, 0.7);
 
313
   glEndList();
 
314
 
 
315
   gear3 = glGenLists(1);
 
316
   glNewList(gear3, GL_COMPILE);
 
317
   glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, blue);
 
318
   gear(1.3, 2.0, 0.5, 10, 0.7);
 
319
   glEndList();
 
320
 
 
321
   glEnable(GL_NORMALIZE);
 
322
}
 
323
 
 
324
 
 
325
static GLXWindow
 
326
dummy_create_window(Display *dpy, GLXFBConfig config, Window win,
 
327
                   const int *attrib_list)
 
328
{
 
329
   (void) dpy;
 
330
   (void) config;
 
331
   (void) attrib_list;
 
332
 
 
333
   return (GLXWindow) win;
 
334
}
 
335
 
 
336
 
 
337
static void
 
338
dummy_destroy_window(Display *dpy, GLXWindow win)
 
339
{
 
340
   (void) dpy;
 
341
   (void) win;
 
342
}
 
343
 
 
344
 
 
345
/**
 
346
 * Initialize fbconfig related function pointers.
 
347
 */
 
348
static void
 
349
init_fbconfig_functions(Display *dpy, int scrnum)
 
350
{
 
351
   const char * glx_extensions;
 
352
   const char * match;
 
353
   static const char ext_name[] = "GLX_SGIX_fbconfig";
 
354
   const size_t len = strlen( ext_name );
 
355
   int major;
 
356
   int minor;
 
357
   GLboolean ext_version_supported;
 
358
   GLboolean glx_1_3_supported;
 
359
 
 
360
 
 
361
   /* Determine if GLX 1.3 or greater is supported.
 
362
    */
 
363
   glXQueryVersion(dpy, & major, & minor);
 
364
   glx_1_3_supported = (major == 1) && (minor >= 3);
 
365
 
 
366
   /* Determine if GLX_SGIX_fbconfig is supported.
 
367
    */
 
368
   glx_extensions = glXQueryExtensionsString(dpy, scrnum);
 
369
   match = strstr( glx_extensions, ext_name );
 
370
 
 
371
   ext_version_supported = (match != NULL)
 
372
       && ((match[len] == '\0') || (match[len] == ' '));
 
373
 
 
374
   printf( "GLX 1.3 is %ssupported.\n",
 
375
           (glx_1_3_supported) ? "" : "not " );
 
376
   printf( "%s is %ssupported.\n",
 
377
           ext_name, (ext_version_supported) ? "" : "not " );
 
378
 
 
379
   if ( glx_1_3_supported ) {
 
380
      choose_fbconfig = (PFNGLXCHOOSEFBCONFIGPROC)
 
381
         glXGetProcAddressARB((GLubyte *) "glXChooseFBConfig");
 
382
      get_visual_from_fbconfig = (PFNGLXGETVISUALFROMFBCONFIGPROC)
 
383
         glXGetProcAddressARB((GLubyte *) "glXGetVisualFromFBConfig");
 
384
      create_new_context = (PFNGLXCREATENEWCONTEXTPROC)
 
385
         glXGetProcAddressARB((GLubyte *) "glXCreateNewContext");
 
386
      create_window = (PFNGLXCREATEWINDOWPROC)
 
387
         glXGetProcAddressARB((GLubyte *) "glXCreateWindow");
 
388
      destroy_window = (PFNGLXDESTROYWINDOWPROC)
 
389
         glXGetProcAddressARB((GLubyte *) "glXDestroyWindow");
 
390
   }
 
391
   else if ( ext_version_supported ) {
 
392
      choose_fbconfig = (PFNGLXCHOOSEFBCONFIGPROC)
 
393
         glXGetProcAddressARB((GLubyte *) "glXChooseFBConfigSGIX");
 
394
      get_visual_from_fbconfig = (PFNGLXGETVISUALFROMFBCONFIGPROC)
 
395
         glXGetProcAddressARB((GLubyte *) "glXGetVisualFromFBConfigSGIX");
 
396
      create_new_context = (PFNGLXCREATENEWCONTEXTPROC)
 
397
         glXGetProcAddressARB((GLubyte *) "glXCreateContextWithConfigSGIX");
 
398
      create_window = dummy_create_window;
 
399
      destroy_window = dummy_destroy_window;
 
400
   }
 
401
   else {
 
402
      printf( "This demo requires either GLX 1.3 or %s be supported.\n",
 
403
              ext_name );
 
404
      exit(1);
 
405
   }
 
406
 
 
407
   if ( choose_fbconfig == NULL ) {
 
408
      printf( "glXChooseFBConfig not found!\n" );
 
409
      exit(1);
 
410
   }
 
411
 
 
412
   if ( get_visual_from_fbconfig == NULL ) {
 
413
      printf( "glXGetVisualFromFBConfig not found!\n" );
 
414
      exit(1);
 
415
   }
 
416
 
 
417
   if ( create_new_context == NULL ) {
 
418
      printf( "glXCreateNewContext not found!\n" );
 
419
      exit(1);
 
420
   }
 
421
}
 
422
 
 
423
 
 
424
/*
 
425
 * Create an RGB, double-buffered window.
 
426
 * Return the window and context handles.
 
427
 */
 
428
static void
 
429
make_window( Display *dpy, const char *name,
 
430
             int x, int y, int width, int height,
 
431
             Window *winRet, GLXWindow *glxWinRet, GLXContext *ctxRet)
 
432
{
 
433
   int attrib[] = { GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
 
434
                    GLX_RENDER_TYPE,   GLX_RGBA_BIT,
 
435
                    GLX_RED_SIZE,      1,
 
436
                    GLX_GREEN_SIZE,    1,
 
437
                    GLX_BLUE_SIZE,     1,
 
438
                    GLX_DOUBLEBUFFER,  GL_TRUE,
 
439
                    GLX_DEPTH_SIZE,    1,
 
440
                    None };
 
441
   GLXFBConfig * fbconfig;
 
442
   int num_configs;
 
443
   int scrnum;
 
444
   int i;
 
445
   XSetWindowAttributes attr;
 
446
   unsigned long mask;
 
447
   Window root;
 
448
   Window win;
 
449
   GLXWindow glxWin;
 
450
   GLXContext ctx;
 
451
   XVisualInfo *visinfo;
 
452
 
 
453
   scrnum = DefaultScreen( dpy );
 
454
   root = RootWindow( dpy, scrnum );
 
455
 
 
456
   init_fbconfig_functions(dpy, scrnum);
 
457
   fbconfig = (*choose_fbconfig)(dpy, scrnum, attrib, & num_configs);
 
458
   if (fbconfig == NULL) {
 
459
      printf("Error: couldn't get an RGB, Double-buffered visual\n");
 
460
      exit(1);
 
461
   }
 
462
 
 
463
   printf("\nThe following fbconfigs meet the requirements.  The first one "
 
464
          "will be used.\n\n");
 
465
   for ( i = 0 ; i < num_configs ; i++ ) {
 
466
      PrintFBConfigInfo(dpy, scrnum, fbconfig[i], GL_TRUE);
 
467
   }
 
468
 
 
469
   /* window attributes */
 
470
   visinfo = (*get_visual_from_fbconfig)(dpy, fbconfig[0]);
 
471
   assert(visinfo != NULL);
 
472
   attr.background_pixel = 0;
 
473
   attr.border_pixel = 0;
 
474
   attr.colormap = XCreateColormap( dpy, root, visinfo->visual, AllocNone);
 
475
   attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
 
476
   mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
 
477
 
 
478
   win = XCreateWindow( dpy, root, 0, 0, width, height,
 
479
                        0, visinfo->depth, InputOutput,
 
480
                        visinfo->visual, mask, &attr );
 
481
 
 
482
   /* set hints and properties */
 
483
   {
 
484
      XSizeHints sizehints;
 
485
      sizehints.x = x;
 
486
      sizehints.y = y;
 
487
      sizehints.width  = width;
 
488
      sizehints.height = height;
 
489
      sizehints.flags = USSize | USPosition;
 
490
      XSetNormalHints(dpy, win, &sizehints);
 
491
      XSetStandardProperties(dpy, win, name, name,
 
492
                              None, (char **)NULL, 0, &sizehints);
 
493
   }
 
494
 
 
495
   glxWin = (*create_window)(dpy, fbconfig[0], win, NULL);
 
496
 
 
497
   ctx = (*create_new_context)(dpy, fbconfig[0], GLX_RGBA_TYPE, NULL, GL_TRUE);
 
498
   if (!ctx) {
 
499
      printf("Error: glXCreateNewContext failed\n");
 
500
      exit(1);
 
501
   }
 
502
 
 
503
   XFree(fbconfig);
 
504
 
 
505
   *glxWinRet = glxWin;
 
506
   *winRet = win;
 
507
   *ctxRet = ctx;
 
508
}
 
509
 
 
510
 
 
511
static void
 
512
event_loop(Display *dpy, GLXWindow win)
 
513
{
 
514
   while (1) {
 
515
      while (XPending(dpy) > 0) {
 
516
         XEvent event;
 
517
         XNextEvent(dpy, &event);
 
518
         switch (event.type) {
 
519
         case Expose:
 
520
            /* we'll redraw below */
 
521
            break;
 
522
         case ConfigureNotify:
 
523
            reshape(event.xconfigure.width, event.xconfigure.height);
 
524
            break;
 
525
         case KeyPress:
 
526
            {
 
527
               char buffer[10];
 
528
               int r, code;
 
529
               code = XLookupKeysym(&event.xkey, 0);
 
530
               if (code == XK_Left) {
 
531
                  view_roty += 5.0;
 
532
               }
 
533
               else if (code == XK_Right) {
 
534
                  view_roty -= 5.0;
 
535
               }
 
536
               else if (code == XK_Up) {
 
537
                  view_rotx += 5.0;
 
538
               }
 
539
               else if (code == XK_Down) {
 
540
                  view_rotx -= 5.0;
 
541
               }
 
542
               else {
 
543
                  r = XLookupString(&event.xkey, buffer, sizeof(buffer),
 
544
                                    NULL, NULL);
 
545
                  if (buffer[0] == 27) {
 
546
                     /* escape */
 
547
                     return;
 
548
                  }
 
549
               }
 
550
            }
 
551
         }
 
552
      }
 
553
 
 
554
      /* next frame */
 
555
      angle += 2.0;
 
556
 
 
557
      draw();
 
558
      glXSwapBuffers(dpy, win);
 
559
 
 
560
      /* calc framerate */
 
561
      {
 
562
         static int t0 = -1;
 
563
         static int frames = 0;
 
564
         int t = current_time();
 
565
 
 
566
         if (t0 < 0)
 
567
            t0 = t;
 
568
 
 
569
         frames++;
 
570
 
 
571
         if (t - t0 >= 5.0) {
 
572
            GLfloat seconds = t - t0;
 
573
            GLfloat fps = frames / seconds;
 
574
            printf("%d frames in %3.1f seconds = %6.3f FPS\n", frames, seconds,
 
575
                   fps);
 
576
            t0 = t;
 
577
            frames = 0;
 
578
         }
 
579
      }
 
580
   }
 
581
}
 
582
 
 
583
 
 
584
int
 
585
main(int argc, char *argv[])
 
586
{
 
587
   Display *dpy;
 
588
   Window win;
 
589
   GLXWindow glxWin;
 
590
   GLXContext ctx;
 
591
   const char *dpyName = NULL;
 
592
   GLboolean printInfo = GL_FALSE;
 
593
   int i;
 
594
 
 
595
   for (i = 1; i < argc; i++) {
 
596
      if (strcmp(argv[i], "-display") == 0) {
 
597
         dpyName = argv[i+1];
 
598
         i++;
 
599
      }
 
600
      else if (strcmp(argv[i], "-info") == 0) {
 
601
         printInfo = GL_TRUE;
 
602
      }
 
603
   }
 
604
 
 
605
   dpy = XOpenDisplay(dpyName);
 
606
   if (!dpy) {
 
607
      printf("Error: couldn't open display %s\n", XDisplayName(dpyName));
 
608
      return -1;
 
609
   }
 
610
 
 
611
   make_window(dpy, "glxgears", 0, 0, 300, 300, &win, &glxWin, &ctx);
 
612
   XMapWindow(dpy, win);
 
613
   glXMakeCurrent(dpy, glxWin, ctx);
 
614
 
 
615
   if (printInfo) {
 
616
      printf("GL_RENDERER   = %s\n", (char *) glGetString(GL_RENDERER));
 
617
      printf("GL_VERSION    = %s\n", (char *) glGetString(GL_VERSION));
 
618
      printf("GL_VENDOR     = %s\n", (char *) glGetString(GL_VENDOR));
 
619
      printf("GL_EXTENSIONS = %s\n", (char *) glGetString(GL_EXTENSIONS));
 
620
   }
 
621
 
 
622
   init();
 
623
 
 
624
   event_loop(dpy, glxWin);
 
625
 
 
626
   glXDestroyContext(dpy, ctx);
 
627
   destroy_window(dpy, glxWin);
 
628
   XDestroyWindow(dpy, win);
 
629
   XCloseDisplay(dpy);
 
630
 
 
631
   return 0;
 
632
}