blob: fe750a57d8dcaca649d5b833a49975d7b9d7b553 [file] [log] [blame]
Brian Paul976c26c2001-08-20 16:07:10 +00001
2/* uglgears.c - WindML/Mesa example program */
3
4/*
5 * 3-D gear wheels. This program is in the public domain.
6 *
7 * Brian Paul
8 *
9 * Conversion to GLUT by Mark J. Kilgard
10 * Conversion to UGL/Mesa from GLUT by Stephane Raimbault
11 */
12
13/*
14DESCRIPTION
15Spinning gears demo
16*/
17
18#include <stdio.h>
19#include <math.h>
20#include <tickLib.h>
21
22#include <ugl/ugl.h>
23#include <ugl/uglucode.h>
24#include <ugl/uglevent.h>
25#include <ugl/uglinput.h>
26#include <GL/uglmesa.h>
27#include <GL/glu.h>
28
29#ifndef M_PI
30#define M_PI 3.14159265358979323846
31#endif
32
33#define COUNT_FRAMES
34
35UGL_LOCAL UGL_EVENT_SERVICE_ID eventServiceId;
36UGL_LOCAL UGL_EVENT_Q_ID qId;
37UGL_LOCAL volatile UGL_BOOL stopWex;
38UGL_LOCAL UGL_MESA_CONTEXT umc;
39
40UGL_LOCAL GLfloat view_rotx, view_roty, view_rotz;
41UGL_LOCAL GLint gear1, gear2, gear3;
42UGL_LOCAL GLfloat angle;
43
44UGL_LOCAL GLuint limit;
45UGL_LOCAL GLuint count;
46UGL_LOCAL GLuint tickStart, tickStop, tickBySec;
47
48
49/*
50* Draw a gear wheel. You'll probably want to call this function when
51* building a display list since we do a lot of trig here.
52*
53* Input: inner_radius - radius of hole at center
54* outer_radius - radius at center of teeth
55* width - width of gear
56* teeth - number of teeth
57* tooth_depth - depth of tooth
58*/
59
60UGL_LOCAL void gear
61 (
62 GLfloat inner_radius,
63 GLfloat outer_radius,
64 GLfloat width,
65 GLint teeth,
66 GLfloat tooth_depth
67 )
68 {
69 GLint i;
70 GLfloat r0, r1, r2;
71 GLfloat angle, da;
72 GLfloat u, v, len;
73
74 r0 = inner_radius;
75 r1 = outer_radius - tooth_depth/2.0;
76 r2 = outer_radius + tooth_depth/2.0;
77
78 da = 2.0*M_PI / teeth / 4.0;
79
80 glShadeModel (GL_FLAT);
81
82 glNormal3f (0.0, 0.0, 1.0);
83
84 /* draw front face */
85 glBegin (GL_QUAD_STRIP);
86 for (i=0;i<=teeth;i++)
87 {
88 angle = i * 2.0*M_PI / teeth;
89 glVertex3f (r0*cos (angle), r0*sin (angle), width*0.5);
90 glVertex3f (r1*cos (angle), r1*sin (angle), width*0.5);
91 glVertex3f (r0*cos (angle), r0*sin (angle), width*0.5);
92 glVertex3f (r1*cos (angle+3*da), r1*sin (angle+3*da), width*0.5);
93 }
94 glEnd ();
95
96 /* draw front sides of teeth */
97 glBegin (GL_QUADS);
98 da = 2.0*M_PI / teeth / 4.0;
99 for (i=0; i<teeth; i++)
100 {
101 angle = i * 2.0*M_PI / teeth;
102
103 glVertex3f (r1*cos (angle), r1*sin (angle), width*0.5);
104 glVertex3f (r2*cos (angle+da), r2*sin (angle+da), width*0.5);
105 glVertex3f (r2*cos (angle+2*da), r2*sin (angle+2*da), width*0.5);
106 glVertex3f (r1*cos (angle+3*da), r1*sin (angle+3*da), width*0.5);
107 }
108 glEnd ();
109
110
111 glNormal3f (0.0, 0.0, -1.0);
112
113 /* draw back face */
114 glBegin (GL_QUAD_STRIP);
115 for (i=0; i<=teeth ;i++)
116 {
117 angle = i * 2.0*M_PI / teeth;
118 glVertex3f (r1*cos (angle), r1*sin (angle), -width*0.5);
119 glVertex3f (r0*cos (angle), r0*sin (angle), -width*0.5);
120 glVertex3f (r1*cos (angle+3*da), r1*sin (angle+3*da), -width*0.5);
121 glVertex3f (r0*cos (angle), r0*sin (angle), -width*0.5);
122 }
123 glEnd ();
124
125 /* draw back sides of teeth */
126 glBegin (GL_QUADS);
127 da = 2.0*M_PI / teeth / 4.0;
128 for (i=0;i<teeth;i++)
129 {
130 angle = i * 2.0*M_PI / teeth;
131
132 glVertex3f (r1*cos (angle+3*da), r1*sin (angle+3*da), -width*0.5);
133 glVertex3f (r2*cos (angle+2*da), r2*sin (angle+2*da), -width*0.5);
134 glVertex3f (r2*cos (angle+da), r2*sin (angle+da), -width*0.5);
135 glVertex3f (r1*cos (angle), r1*sin (angle), -width*0.5);
136 }
137 glEnd ();
138
139
140 /* draw outward faces of teeth */
141 glBegin (GL_QUAD_STRIP);
142 for (i=0;i<teeth;i++)
143 {
144 angle = i * 2.0*M_PI / teeth;
145
146 glVertex3f (r1*cos (angle), r1*sin (angle), width*0.5);
147 glVertex3f (r1*cos (angle), r1*sin (angle), -width*0.5);
148 u = r2*cos (angle+da) - r1*cos (angle);
149 v = r2*sin (angle+da) - r1*sin (angle);
150 len = sqrt (u*u + v*v);
151 u /= len;
152 v /= len;
153 glNormal3f (v, -u, 0.0);
154 glVertex3f (r2*cos (angle+da), r2*sin (angle+da), width*0.5);
155 glVertex3f (r2*cos (angle+da), r2*sin (angle+da), -width*0.5);
156 glNormal3f (cos (angle), sin (angle), 0.0);
157 glVertex3f (r2*cos (angle+2*da), r2*sin (angle+2*da), width*0.5);
158 glVertex3f (r2*cos (angle+2*da), r2*sin (angle+2*da), -width*0.5);
159 u = r1*cos (angle+3*da) - r2*cos (angle+2*da);
160 v = r1*sin (angle+3*da) - r2*sin (angle+2*da);
161 glNormal3f (v, -u, 0.0);
162 glVertex3f (r1*cos (angle+3*da), r1*sin (angle+3*da), width*0.5);
163 glVertex3f (r1*cos (angle+3*da), r1*sin (angle+3*da), -width*0.5);
164 glNormal3f (cos (angle), sin (angle), 0.0);
165 }
166
167 glVertex3f (r1*cos (0), r1*sin (0), width*0.5);
168 glVertex3f (r1*cos (0), r1*sin (0), -width*0.5);
169
170 glEnd ();
171
172 glShadeModel (GL_SMOOTH);
173
174 /* draw inside radius cylinder */
175 glBegin (GL_QUAD_STRIP);
176 for (i=0;i<=teeth;i++)
177 {
178 angle = i * 2.0*M_PI / teeth;
179 glNormal3f (-cos (angle), -sin (angle), 0.0);
180 glVertex3f (r0*cos (angle), r0*sin (angle), -width*0.5);
181 glVertex3f (r0*cos (angle), r0*sin (angle), width*0.5);
182 }
183 glEnd ();
184
185}
186
187UGL_LOCAL void drawGL (void)
188 {
189#ifdef COUNT_FRAMES
190 int time;
191#endif
192
193 angle += 2.0;
194
195 glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
196
197 glPushMatrix ();
198 glRotatef (view_rotx, 1.0, 0.0, 0.0);
199 glRotatef (view_roty, 0.0, 1.0, 0.0);
200 glRotatef (view_rotz, 0.0, 0.0, 1.0);
201
202 glPushMatrix ();
203 glTranslatef (-3.0, -2.0, 0.0);
204 glRotatef (angle, 0.0, 0.0, 1.0);
205 glCallList (gear1);
206 glPopMatrix ();
207
208 glPushMatrix ();
209 glTranslatef (3.1, -2.0, 0.0);
210 glRotatef (-2.0*angle-9.0, 0.0, 0.0, 1.0);
211 glCallList (gear2);
212 glPopMatrix ();
213
214 glPushMatrix ();
215 glTranslatef (-3.1, 4.2, 0.0);
216 glRotatef (-2.0*angle-25.0, 0.0, 0.0, 1.0);
217 glCallList (gear3);
218 glPopMatrix ();
219
220 glPopMatrix ();
221
222 uglMesaSwapBuffers ();
223
224#ifdef COUNT_FRAMES
225 if (count > limit)
226 {
227 tickStop = tickGet ();
228 time = (tickStop-tickStart)/tickBySec;
229 printf (" %i fps\n", count/time);
230 tickStart = tickStop;
231 count = 0;
232 }
233 else
234 count++;
235#endif
236}
237
238
239UGL_LOCAL void initGL (GLsizei width, GLsizei height)
240 {
241 UGL_LOCAL GLfloat pos[4] = {5.0, 5.0, 10.0, 1.0 };
242 UGL_LOCAL GLfloat red[4] = {0.8, 0.1, 0.0, 1.0 };
243 UGL_LOCAL GLfloat green[4] = {0.0, 0.8, 0.2, 1.0 };
244 UGL_LOCAL GLfloat blue[4] = {0.2, 0.2, 1.0, 1.0 };
245
246 glLightfv (GL_LIGHT0, GL_POSITION, pos);
247 glEnable (GL_CULL_FACE);
248 glEnable (GL_LIGHTING);
249 glEnable (GL_LIGHT0);
250 glEnable (GL_DEPTH_TEST);
251
252 /* make the gears */
253 gear1 = glGenLists (1);
254 glNewList (gear1, GL_COMPILE);
255 glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red);
256 gear (1.0, 4.0, 1.0, 20, 0.7);
257 glEndList ();
258
259 gear2 = glGenLists (1);
260 glNewList (gear2, GL_COMPILE);
261 glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, green);
262 gear (0.5, 2.0, 2.0, 10, 0.7);
263 glEndList ();
264
265 gear3 = glGenLists (1);
266 glNewList (gear3, GL_COMPILE);
267 glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, blue);
268 gear (1.3, 2.0, 0.5, 10, 0.7);
269 glEndList ();
270
271 glEnable (GL_NORMALIZE);
272
273 glViewport (0, 0, width, height);
274
275 glMatrixMode (GL_PROJECTION);
276 glLoadIdentity ();
277 if (width>height)
278 {
279 GLfloat w = (GLfloat) width / (GLfloat) height;
280 glFrustum (-w, w, -1.0, 1.0, 5.0, 60.0);
281 }
282 else
283 {
284 GLfloat h = (GLfloat) height / (GLfloat) width;
285 glFrustum (-1.0, 1.0, -h, h, 5.0, 60.0);
286 }
287
288 glMatrixMode (GL_MODELVIEW);
289 glLoadIdentity ();
290 glTranslatef (0.0, 0.0, -40.0);
291
292#ifdef COUNT_FRAMES
293 tickStart = tickGet ();
294 tickBySec = sysClkRateGet ();
295#endif
296}
297
298UGL_LOCAL void echoUse(void)
299 {
300 printf("tGears keys:\n");
301 printf(" z Counter clockwise rotation (z-axis)\n");
302 printf(" Z Clockwise rotation (z-axis)\n");
303 printf(" Up Counter clockwise rotation (x-axis)\n");
304 printf(" Down Clockwise rotation (x-axis)\n");
305 printf(" Left Counter clockwise rotation (y-axis)\n");
306 printf(" Right Clockwise rotation (y-axis)\n");
307 printf(" ESC Exit\n");
308 }
309
310
311UGL_LOCAL void readKey (UGL_WCHAR key)
312 {
313
314 switch(key)
315 {
316 case 'z':
317 view_rotz += 5.0;
318 break;
319 case 'Z':
320 view_rotz -= 5.0;
321 break;
322 case UGL_UNI_UP_ARROW:
323 view_rotx += 5.0;
324 break;
325 case UGL_UNI_DOWN_ARROW:
326 view_rotx -= 5.0;
327 break;
328 case UGL_UNI_LEFT_ARROW:
329 view_roty += 5.0;
330 break;
331 case UGL_UNI_RIGHT_ARROW:
332 view_roty -= 5.0;
333 break;
334 case UGL_UNI_ESCAPE:
335 stopWex = UGL_TRUE;
336 break;
337 }
338 }
339
340UGL_LOCAL void loopEvent(void)
341 {
342 UGL_EVENT event;
343 UGL_INPUT_EVENT * pInputEvent;
344
345 UGL_FOREVER
346 {
347 if (uglEventGet (qId, &event, sizeof (event), UGL_NO_WAIT)
348 != UGL_STATUS_Q_EMPTY)
349 {
350 pInputEvent = (UGL_INPUT_EVENT *)&event;
351
352 if (pInputEvent->header.type == UGL_EVENT_TYPE_KEYBOARD &&
353 pInputEvent->modifiers & UGL_KEYBOARD_KEYDOWN)
354 readKey(pInputEvent->type.keyboard.key);
355 }
356
357 drawGL();
358 if (stopWex)
359 break;
360 }
361 }
362
363void windMLGears (void);
364
365void uglgears (void)
366 {
367 taskSpawn ("tGears", 210, VX_FP_TASK, 100000, (FUNCPTR)windMLGears,
368 0,1,2,3,4,5,6,7,8,9);
369 }
370
371void windMLGears (void)
372 {
373 GLsizei width, height;
374 UGL_INPUT_DEVICE_ID keyboardDevId;
375
376 view_rotx=20.0;
377 view_roty=30.0;
378 view_rotz=0.0;
379 angle = 0.0;
380 limit = 100;
381 count = 1;
382
383 uglInitialize ();
384
385 uglDriverFind (UGL_KEYBOARD_TYPE, 0,
386 (UGL_UINT32 *)&keyboardDevId);
387
388 uglDriverFind (UGL_EVENT_SERVICE_TYPE, 0, (UGL_UINT32 *)&eventServiceId);
389
390 qId = uglEventQCreate (eventServiceId, 100);
391
392 /* Double buffering */
393
394 umc = uglMesaCreateNewContext (UGL_MESA_DOUBLE, NULL);
395 if (umc == NULL)
396 {
397 uglDeinitialize ();
398 return;
399 }
400
401 /* Fullscreen */
402
403 uglMesaMakeCurrentContext (umc, 0, 0, UGL_MESA_FULLSCREEN_WIDTH,
404 UGL_MESA_FULLSCREEN_HEIGHT);
405
406 uglMesaGetIntegerv(UGL_MESA_WIDTH, &width);
407 uglMesaGetIntegerv(UGL_MESA_HEIGHT, &height);
408
409 initGL (width, height);
410
411 echoUse();
412
413 stopWex = UGL_FALSE;
414 loopEvent();
415
416 uglEventQDestroy (eventServiceId, qId);
417
418 uglMesaDestroyContext();
419 uglDeinitialize ();
420
421 return;
422 }