132001f49Smrg/*
232001f49Smrg * Test AUX buffer rendering
332001f49Smrg * Use GLX since GLUT doesn't support AUX buffers
432001f49Smrg */
532001f49Smrg
632001f49Smrg
732001f49Smrg/*
832001f49Smrg * Copyright (C) 1999-2001  Brian Paul   All Rights Reserved.
932001f49Smrg *
1032001f49Smrg * Permission is hereby granted, free of charge, to any person obtaining a
1132001f49Smrg * copy of this software and associated documentation files (the "Software"),
1232001f49Smrg * to deal in the Software without restriction, including without limitation
1332001f49Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
1432001f49Smrg * and/or sell copies of the Software, and to permit persons to whom the
1532001f49Smrg * Software is furnished to do so, subject to the following conditions:
1632001f49Smrg *
1732001f49Smrg * The above copyright notice and this permission notice shall be included
1832001f49Smrg * in all copies or substantial portions of the Software.
1932001f49Smrg *
2032001f49Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
2132001f49Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
2232001f49Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
2332001f49Smrg * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
2432001f49Smrg * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
2532001f49Smrg * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2632001f49Smrg */
2732001f49Smrg
2832001f49Smrg/*
2932001f49Smrg * This is a port of the infamous "gears" demo to straight GLX (i.e. no GLUT)
3032001f49Smrg * Port by Brian Paul  23 March 2001
3132001f49Smrg *
3232001f49Smrg * Command line options:
3332001f49Smrg *    -info      print GL implementation information
3432001f49Smrg *
3532001f49Smrg */
3632001f49Smrg
3732001f49Smrg
3832001f49Smrg#include <math.h>
3932001f49Smrg#include <stdlib.h>
4032001f49Smrg#include <stdio.h>
4132001f49Smrg#include <string.h>
4232001f49Smrg#include <X11/Xlib.h>
4332001f49Smrg#include <X11/keysym.h>
4432001f49Smrg#include <GL/glew.h>
4532001f49Smrg#include <GL/glx.h>
4632001f49Smrg
4732001f49Smrg
4832001f49Smrgstatic int
4932001f49Smrgcurrent_time(void)
5032001f49Smrg{
5132001f49Smrg   return 0;
5232001f49Smrg}
5332001f49Smrg
5432001f49Smrg
5532001f49Smrg
5632001f49Smrg
5732001f49Smrg#ifndef M_PI
5832001f49Smrg#define M_PI 3.14159265
5932001f49Smrg#endif
6032001f49Smrg
6132001f49Smrgstatic int WinWidth = 300, WinHeight = 300;
6232001f49Smrgstatic GLfloat view_rotx = 20.0, view_roty = 30.0, view_rotz = 0.0;
6332001f49Smrgstatic GLint gear1, gear2, gear3;
6432001f49Smrgstatic GLfloat angle = 0.0;
6532001f49Smrg
6632001f49Smrg
6732001f49Smrg/*
6832001f49Smrg *
6932001f49Smrg *  Draw a gear wheel.  You'll probably want to call this function when
7032001f49Smrg *  building a display list since we do a lot of trig here.
7132001f49Smrg *
7232001f49Smrg *  Input:  inner_radius - radius of hole at center
7332001f49Smrg *          outer_radius - radius at center of teeth
7432001f49Smrg *          width - width of gear
7532001f49Smrg *          teeth - number of teeth
7632001f49Smrg *          tooth_depth - depth of tooth
7732001f49Smrg */
7832001f49Smrgstatic void
7932001f49Smrggear(GLfloat inner_radius, GLfloat outer_radius, GLfloat width,
8032001f49Smrg     GLint teeth, GLfloat tooth_depth)
8132001f49Smrg{
8232001f49Smrg   GLint i;
8332001f49Smrg   GLfloat r0, r1, r2;
8432001f49Smrg   GLfloat angle, da;
8532001f49Smrg   GLfloat u, v, len;
8632001f49Smrg
8732001f49Smrg   r0 = inner_radius;
8832001f49Smrg   r1 = outer_radius - tooth_depth / 2.0;
8932001f49Smrg   r2 = outer_radius + tooth_depth / 2.0;
9032001f49Smrg
9132001f49Smrg   da = 2.0 * M_PI / teeth / 4.0;
9232001f49Smrg
9332001f49Smrg   glShadeModel(GL_FLAT);
9432001f49Smrg
9532001f49Smrg   glNormal3f(0.0, 0.0, 1.0);
9632001f49Smrg
9732001f49Smrg   /* draw front face */
9832001f49Smrg   glBegin(GL_QUAD_STRIP);
9932001f49Smrg   for (i = 0; i <= teeth; i++) {
10032001f49Smrg      angle = i * 2.0 * M_PI / teeth;
10132001f49Smrg      glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
10232001f49Smrg      glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
10332001f49Smrg      if (i < teeth) {
10432001f49Smrg	 glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
10532001f49Smrg	 glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
10632001f49Smrg		    width * 0.5);
10732001f49Smrg      }
10832001f49Smrg   }
10932001f49Smrg   glEnd();
11032001f49Smrg
11132001f49Smrg   /* draw front sides of teeth */
11232001f49Smrg   glBegin(GL_QUADS);
11332001f49Smrg   da = 2.0 * M_PI / teeth / 4.0;
11432001f49Smrg   for (i = 0; i < teeth; i++) {
11532001f49Smrg      angle = i * 2.0 * M_PI / teeth;
11632001f49Smrg
11732001f49Smrg      glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
11832001f49Smrg      glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), width * 0.5);
11932001f49Smrg      glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da),
12032001f49Smrg		 width * 0.5);
12132001f49Smrg      glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
12232001f49Smrg		 width * 0.5);
12332001f49Smrg   }
12432001f49Smrg   glEnd();
12532001f49Smrg
12632001f49Smrg   glNormal3f(0.0, 0.0, -1.0);
12732001f49Smrg
12832001f49Smrg   /* draw back face */
12932001f49Smrg   glBegin(GL_QUAD_STRIP);
13032001f49Smrg   for (i = 0; i <= teeth; i++) {
13132001f49Smrg      angle = i * 2.0 * M_PI / teeth;
13232001f49Smrg      glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
13332001f49Smrg      glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
13432001f49Smrg      if (i < teeth) {
13532001f49Smrg	 glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
13632001f49Smrg		    -width * 0.5);
13732001f49Smrg	 glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
13832001f49Smrg      }
13932001f49Smrg   }
14032001f49Smrg   glEnd();
14132001f49Smrg
14232001f49Smrg   /* draw back sides of teeth */
14332001f49Smrg   glBegin(GL_QUADS);
14432001f49Smrg   da = 2.0 * M_PI / teeth / 4.0;
14532001f49Smrg   for (i = 0; i < teeth; i++) {
14632001f49Smrg      angle = i * 2.0 * M_PI / teeth;
14732001f49Smrg
14832001f49Smrg      glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
14932001f49Smrg		 -width * 0.5);
15032001f49Smrg      glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da),
15132001f49Smrg		 -width * 0.5);
15232001f49Smrg      glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -width * 0.5);
15332001f49Smrg      glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
15432001f49Smrg   }
15532001f49Smrg   glEnd();
15632001f49Smrg
15732001f49Smrg   /* draw outward faces of teeth */
15832001f49Smrg   glBegin(GL_QUAD_STRIP);
15932001f49Smrg   for (i = 0; i < teeth; i++) {
16032001f49Smrg      angle = i * 2.0 * M_PI / teeth;
16132001f49Smrg
16232001f49Smrg      glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
16332001f49Smrg      glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
16432001f49Smrg      u = r2 * cos(angle + da) - r1 * cos(angle);
16532001f49Smrg      v = r2 * sin(angle + da) - r1 * sin(angle);
16632001f49Smrg      len = sqrt(u * u + v * v);
16732001f49Smrg      u /= len;
16832001f49Smrg      v /= len;
16932001f49Smrg      glNormal3f(v, -u, 0.0);
17032001f49Smrg      glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), width * 0.5);
17132001f49Smrg      glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -width * 0.5);
17232001f49Smrg      glNormal3f(cos(angle), sin(angle), 0.0);
17332001f49Smrg      glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da),
17432001f49Smrg		 width * 0.5);
17532001f49Smrg      glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da),
17632001f49Smrg		 -width * 0.5);
17732001f49Smrg      u = r1 * cos(angle + 3 * da) - r2 * cos(angle + 2 * da);
17832001f49Smrg      v = r1 * sin(angle + 3 * da) - r2 * sin(angle + 2 * da);
17932001f49Smrg      glNormal3f(v, -u, 0.0);
18032001f49Smrg      glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
18132001f49Smrg		 width * 0.5);
18232001f49Smrg      glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
18332001f49Smrg		 -width * 0.5);
18432001f49Smrg      glNormal3f(cos(angle), sin(angle), 0.0);
18532001f49Smrg   }
18632001f49Smrg
18732001f49Smrg   glVertex3f(r1 * cos(0), r1 * sin(0), width * 0.5);
18832001f49Smrg   glVertex3f(r1 * cos(0), r1 * sin(0), -width * 0.5);
18932001f49Smrg
19032001f49Smrg   glEnd();
19132001f49Smrg
19232001f49Smrg   glShadeModel(GL_SMOOTH);
19332001f49Smrg
19432001f49Smrg   /* draw inside radius cylinder */
19532001f49Smrg   glBegin(GL_QUAD_STRIP);
19632001f49Smrg   for (i = 0; i <= teeth; i++) {
19732001f49Smrg      angle = i * 2.0 * M_PI / teeth;
19832001f49Smrg      glNormal3f(-cos(angle), -sin(angle), 0.0);
19932001f49Smrg      glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
20032001f49Smrg      glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
20132001f49Smrg   }
20232001f49Smrg   glEnd();
20332001f49Smrg}
20432001f49Smrg
20532001f49Smrg
20632001f49Smrgstatic void
20732001f49Smrgdraw(void)
20832001f49Smrg{
20932001f49Smrg   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
21032001f49Smrg
21132001f49Smrg   glPushMatrix();
21232001f49Smrg   glRotatef(view_rotx, 1.0, 0.0, 0.0);
21332001f49Smrg   glRotatef(view_roty, 0.0, 1.0, 0.0);
21432001f49Smrg   glRotatef(view_rotz, 0.0, 0.0, 1.0);
21532001f49Smrg
21632001f49Smrg   glPushMatrix();
21732001f49Smrg   glTranslatef(-3.0, -2.0, 0.0);
21832001f49Smrg   glRotatef(angle, 0.0, 0.0, 1.0);
21932001f49Smrg   glCallList(gear1);
22032001f49Smrg   glPopMatrix();
22132001f49Smrg
22232001f49Smrg   glPushMatrix();
22332001f49Smrg   glTranslatef(3.1, -2.0, 0.0);
22432001f49Smrg   glRotatef(-2.0 * angle - 9.0, 0.0, 0.0, 1.0);
22532001f49Smrg   glCallList(gear2);
22632001f49Smrg   glPopMatrix();
22732001f49Smrg
22832001f49Smrg   glPushMatrix();
22932001f49Smrg   glTranslatef(-3.1, 4.2, 0.0);
23032001f49Smrg   glRotatef(-2.0 * angle - 25.0, 0.0, 0.0, 1.0);
23132001f49Smrg   glCallList(gear3);
23232001f49Smrg   glPopMatrix();
23332001f49Smrg
23432001f49Smrg   glPopMatrix();
23532001f49Smrg}
23632001f49Smrg
23732001f49Smrg
23832001f49Smrg/* new window size or exposure */
23932001f49Smrgstatic void
24032001f49Smrgreshape(int width, int height)
24132001f49Smrg{
24232001f49Smrg   GLfloat h = (GLfloat) height / (GLfloat) width;
24332001f49Smrg
24432001f49Smrg   WinWidth = width;
24532001f49Smrg   WinHeight = height;
24632001f49Smrg   glViewport(0, 0, (GLint) width, (GLint) height);
24732001f49Smrg   glMatrixMode(GL_PROJECTION);
24832001f49Smrg   glLoadIdentity();
24932001f49Smrg   glFrustum(-1.0, 1.0, -h, h, 5.0, 60.0);
25032001f49Smrg   glMatrixMode(GL_MODELVIEW);
25132001f49Smrg   glLoadIdentity();
25232001f49Smrg   glTranslatef(0.0, 0.0, -40.0);
25332001f49Smrg}
25432001f49Smrg
25532001f49Smrg
25632001f49Smrgstatic void
25732001f49Smrginit(void)
25832001f49Smrg{
25932001f49Smrg   static GLfloat pos[4] = { 5.0, 5.0, 10.0, 0.0 };
26032001f49Smrg   static GLfloat red[4] = { 0.8, 0.1, 0.0, 1.0 };
26132001f49Smrg   static GLfloat green[4] = { 0.0, 0.8, 0.2, 1.0 };
26232001f49Smrg   static GLfloat blue[4] = { 0.2, 0.2, 1.0, 1.0 };
26332001f49Smrg   int i;
26432001f49Smrg
26532001f49Smrg   glGetIntegerv(GL_AUX_BUFFERS, &i);
26632001f49Smrg   printf("AUX BUFFERS: %d\n", i);
26732001f49Smrg
26832001f49Smrg   glLightfv(GL_LIGHT0, GL_POSITION, pos);
26932001f49Smrg   glEnable(GL_CULL_FACE);
27032001f49Smrg   glEnable(GL_LIGHTING);
27132001f49Smrg   glEnable(GL_LIGHT0);
27232001f49Smrg   glEnable(GL_DEPTH_TEST);
27332001f49Smrg
27432001f49Smrg   /* make the gears */
27532001f49Smrg   gear1 = glGenLists(1);
27632001f49Smrg   glNewList(gear1, GL_COMPILE);
27732001f49Smrg   glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red);
27832001f49Smrg   gear(1.0, 4.0, 1.0, 20, 0.7);
27932001f49Smrg   glEndList();
28032001f49Smrg
28132001f49Smrg   gear2 = glGenLists(1);
28232001f49Smrg   glNewList(gear2, GL_COMPILE);
28332001f49Smrg   glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, green);
28432001f49Smrg   gear(0.5, 2.0, 2.0, 10, 0.7);
28532001f49Smrg   glEndList();
28632001f49Smrg
28732001f49Smrg   gear3 = glGenLists(1);
28832001f49Smrg   glNewList(gear3, GL_COMPILE);
28932001f49Smrg   glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, blue);
29032001f49Smrg   gear(1.3, 2.0, 0.5, 10, 0.7);
29132001f49Smrg   glEndList();
29232001f49Smrg
29332001f49Smrg   glEnable(GL_NORMALIZE);
29432001f49Smrg}
29532001f49Smrg
29632001f49Smrg
29732001f49Smrg/*
29832001f49Smrg * Create an RGB, double-buffered window.
29932001f49Smrg * Return the window and context handles.
30032001f49Smrg */
30132001f49Smrgstatic void
30232001f49Smrgmake_window( Display *dpy, const char *name,
30332001f49Smrg             int x, int y, int width, int height,
30432001f49Smrg             Window *winRet, GLXContext *ctxRet)
30532001f49Smrg{
30632001f49Smrg   int attrib[] = { GLX_RGBA,
30732001f49Smrg		    GLX_RED_SIZE, 1,
30832001f49Smrg		    GLX_GREEN_SIZE, 1,
30932001f49Smrg		    GLX_BLUE_SIZE, 1,
31032001f49Smrg		    GLX_DOUBLEBUFFER,
31132001f49Smrg		    GLX_DEPTH_SIZE, 1,
31232001f49Smrg                    GLX_AUX_BUFFERS, 1,
31332001f49Smrg		    None };
31432001f49Smrg   int scrnum;
31532001f49Smrg   XSetWindowAttributes attr;
31632001f49Smrg   unsigned long mask;
31732001f49Smrg   Window root;
31832001f49Smrg   Window win;
31932001f49Smrg   GLXContext ctx;
32032001f49Smrg   XVisualInfo *visinfo;
32132001f49Smrg
32232001f49Smrg   scrnum = DefaultScreen( dpy );
32332001f49Smrg   root = RootWindow( dpy, scrnum );
32432001f49Smrg
32532001f49Smrg   visinfo = glXChooseVisual( dpy, scrnum, attrib );
32632001f49Smrg   if (!visinfo) {
32732001f49Smrg      printf("Error: couldn't get an RGB, Double-buffered visual\n");
32832001f49Smrg      exit(1);
32932001f49Smrg   }
33032001f49Smrg
33132001f49Smrg   /* window attributes */
33232001f49Smrg   attr.background_pixel = 0;
33332001f49Smrg   attr.border_pixel = 0;
33432001f49Smrg   attr.colormap = XCreateColormap( dpy, root, visinfo->visual, AllocNone);
33532001f49Smrg   attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
33632001f49Smrg   mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
33732001f49Smrg
33832001f49Smrg   win = XCreateWindow( dpy, root, 0, 0, width, height,
33932001f49Smrg		        0, visinfo->depth, InputOutput,
34032001f49Smrg		        visinfo->visual, mask, &attr );
34132001f49Smrg
34232001f49Smrg   /* set hints and properties */
34332001f49Smrg   {
34432001f49Smrg      XSizeHints sizehints;
34532001f49Smrg      sizehints.x = x;
34632001f49Smrg      sizehints.y = y;
34732001f49Smrg      sizehints.width  = width;
34832001f49Smrg      sizehints.height = height;
34932001f49Smrg      sizehints.flags = USSize | USPosition;
35032001f49Smrg      XSetNormalHints(dpy, win, &sizehints);
35132001f49Smrg      XSetStandardProperties(dpy, win, name, name,
35232001f49Smrg                              None, (char **)NULL, 0, &sizehints);
35332001f49Smrg   }
35432001f49Smrg
35532001f49Smrg   ctx = glXCreateContext( dpy, visinfo, NULL, True );
35632001f49Smrg   if (!ctx) {
35732001f49Smrg      printf("Error: glXCreateContext failed\n");
35832001f49Smrg      exit(1);
35932001f49Smrg   }
36032001f49Smrg
36132001f49Smrg   XFree(visinfo);
36232001f49Smrg
36332001f49Smrg   *winRet = win;
36432001f49Smrg   *ctxRet = ctx;
36532001f49Smrg}
36632001f49Smrg
36732001f49Smrg
36832001f49Smrgstatic void
36932001f49Smrgevent_loop(Display *dpy, Window win)
37032001f49Smrg{
37132001f49Smrg   while (1) {
37232001f49Smrg      while (XPending(dpy) > 0) {
37332001f49Smrg         XEvent event;
37432001f49Smrg         XNextEvent(dpy, &event);
37532001f49Smrg         switch (event.type) {
37632001f49Smrg	 case Expose:
37732001f49Smrg            /* we'll redraw below */
37832001f49Smrg	    break;
37932001f49Smrg	 case ConfigureNotify:
38032001f49Smrg	    reshape(event.xconfigure.width, event.xconfigure.height);
38132001f49Smrg	    break;
38232001f49Smrg         case KeyPress:
38332001f49Smrg            {
38432001f49Smrg               char buffer[10];
38532001f49Smrg               int r, code;
38632001f49Smrg               code = XLookupKeysym(&event.xkey, 0);
38732001f49Smrg               if (code == XK_Left) {
38832001f49Smrg                  view_roty += 5.0;
38932001f49Smrg               }
39032001f49Smrg               else if (code == XK_Right) {
39132001f49Smrg                  view_roty -= 5.0;
39232001f49Smrg               }
39332001f49Smrg               else if (code == XK_Up) {
39432001f49Smrg                  view_rotx += 5.0;
39532001f49Smrg               }
39632001f49Smrg               else if (code == XK_Down) {
39732001f49Smrg                  view_rotx -= 5.0;
39832001f49Smrg               }
39932001f49Smrg               else {
40032001f49Smrg                  r = XLookupString(&event.xkey, buffer, sizeof(buffer),
40132001f49Smrg                                    NULL, NULL);
40232001f49Smrg                  if (buffer[0] == 27) {
40332001f49Smrg                     /* escape */
40432001f49Smrg                     return;
40532001f49Smrg                  }
40632001f49Smrg               }
40732001f49Smrg            }
40832001f49Smrg         }
40932001f49Smrg      }
41032001f49Smrg
41132001f49Smrg      /* next frame */
41232001f49Smrg      angle += 2.0;
41332001f49Smrg
41432001f49Smrg      /* draw to aux buffer */
41532001f49Smrg      glDrawBuffer(GL_AUX0);
41632001f49Smrg
41732001f49Smrg      draw();
41832001f49Smrg
41932001f49Smrg      /* Copy aux buffer image to back color buffer */
42032001f49Smrg      glReadBuffer(GL_AUX0);
42132001f49Smrg      glDrawBuffer(GL_BACK);
42232001f49Smrg      glWindowPos2iARB(0, 0);
42332001f49Smrg      glDisable(GL_DEPTH_TEST);
42432001f49Smrg      glCopyPixels(0, 0, WinWidth, WinHeight, GL_COLOR);
42532001f49Smrg      glEnable(GL_DEPTH_TEST);
42632001f49Smrg
42732001f49Smrg      glXSwapBuffers(dpy, win);
42832001f49Smrg
42932001f49Smrg      /* calc framerate */
43032001f49Smrg      {
43132001f49Smrg         static int t0 = -1;
43232001f49Smrg         static int frames = 0;
43332001f49Smrg         int t = current_time();
43432001f49Smrg
43532001f49Smrg         if (t0 < 0)
43632001f49Smrg            t0 = t;
43732001f49Smrg
43832001f49Smrg         frames++;
43932001f49Smrg
44032001f49Smrg         if (t - t0 >= 5.0) {
44132001f49Smrg            GLfloat seconds = t - t0;
44232001f49Smrg            GLfloat fps = frames / seconds;
44332001f49Smrg            printf("%d frames in %3.1f seconds = %6.3f FPS\n", frames, seconds,
44432001f49Smrg                   fps);
44532001f49Smrg            t0 = t;
44632001f49Smrg            frames = 0;
44732001f49Smrg         }
44832001f49Smrg      }
44932001f49Smrg   }
45032001f49Smrg}
45132001f49Smrg
45232001f49Smrg
45332001f49Smrgint
45432001f49Smrgmain(int argc, char *argv[])
45532001f49Smrg{
45632001f49Smrg   Display *dpy;
45732001f49Smrg   Window win;
45832001f49Smrg   GLXContext ctx;
45932001f49Smrg   char *dpyName = ":0";
46032001f49Smrg   GLboolean printInfo = GL_FALSE;
46132001f49Smrg   int i;
46232001f49Smrg
46332001f49Smrg   for (i = 1; i < argc; i++) {
46432001f49Smrg      if (strcmp(argv[i], "-display") == 0) {
46532001f49Smrg         dpyName = argv[i+1];
46632001f49Smrg         i++;
46732001f49Smrg      }
46832001f49Smrg      else if (strcmp(argv[i], "-info") == 0) {
46932001f49Smrg         printInfo = GL_TRUE;
47032001f49Smrg      }
47132001f49Smrg   }
47232001f49Smrg
47332001f49Smrg   dpy = XOpenDisplay(dpyName);
47432001f49Smrg   if (!dpy) {
47532001f49Smrg      printf("Error: couldn't open display %s\n", dpyName);
47632001f49Smrg      return -1;
47732001f49Smrg   }
47832001f49Smrg
47932001f49Smrg   make_window(dpy, "glxgears", 0, 0, WinWidth, WinHeight, &win, &ctx);
48032001f49Smrg   XMapWindow(dpy, win);
48132001f49Smrg   glXMakeCurrent(dpy, win, ctx);
48232001f49Smrg
48332001f49Smrg   glewInit();
48432001f49Smrg
48532001f49Smrg   if (printInfo) {
48632001f49Smrg      printf("GL_RENDERER   = %s\n", (char *) glGetString(GL_RENDERER));
48732001f49Smrg      printf("GL_VERSION    = %s\n", (char *) glGetString(GL_VERSION));
48832001f49Smrg      printf("GL_VENDOR     = %s\n", (char *) glGetString(GL_VENDOR));
48932001f49Smrg      printf("GL_EXTENSIONS = %s\n", (char *) glGetString(GL_EXTENSIONS));
49032001f49Smrg   }
49132001f49Smrg
49232001f49Smrg   init();
49332001f49Smrg
49432001f49Smrg   event_loop(dpy, win);
49532001f49Smrg
49632001f49Smrg   glXDestroyContext(dpy, ctx);
49732001f49Smrg   XDestroyWindow(dpy, win);
49832001f49Smrg   XCloseDisplay(dpy);
49932001f49Smrg
50032001f49Smrg   return 0;
50132001f49Smrg}
502