Use GNU AS label aliasing, if available. This must be enabled by adding
[mesa.git] / progs / windml / uglgears.c
1
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 /*
14 DESCRIPTION
15 Spinning 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
35 UGL_LOCAL UGL_EVENT_SERVICE_ID eventServiceId;
36 UGL_LOCAL UGL_EVENT_Q_ID qId;
37 UGL_LOCAL volatile UGL_BOOL stopWex;
38 UGL_LOCAL UGL_MESA_CONTEXT umc;
39
40 UGL_LOCAL GLfloat view_rotx, view_roty, view_rotz;
41 UGL_LOCAL GLint gear1, gear2, gear3;
42 UGL_LOCAL GLfloat angle;
43
44 UGL_LOCAL GLuint limit;
45 UGL_LOCAL GLuint count;
46 UGL_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
60 UGL_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
187 UGL_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 glFlush();
223
224 uglMesaSwapBuffers ();
225
226 #ifdef COUNT_FRAMES
227 if (count > limit)
228 {
229 tickStop = tickGet ();
230 time = (tickStop-tickStart)/tickBySec;
231 printf (" %i fps\n", count/time);
232 tickStart = tickStop;
233 count = 0;
234 }
235 else
236 count++;
237 #endif
238 }
239
240
241 UGL_LOCAL void initGL (GLsizei width, GLsizei height)
242 {
243 UGL_LOCAL GLfloat pos[4] = {5.0, 5.0, 10.0, 1.0 };
244 UGL_LOCAL GLfloat red[4] = {0.8, 0.1, 0.0, 1.0 };
245 UGL_LOCAL GLfloat green[4] = {0.0, 0.8, 0.2, 1.0 };
246 UGL_LOCAL GLfloat blue[4] = {0.2, 0.2, 1.0, 1.0 };
247
248 glLightfv (GL_LIGHT0, GL_POSITION, pos);
249 glEnable (GL_CULL_FACE);
250 glEnable (GL_LIGHTING);
251 glEnable (GL_LIGHT0);
252 glEnable (GL_DEPTH_TEST);
253
254 /* make the gears */
255 gear1 = glGenLists (1);
256 glNewList (gear1, GL_COMPILE);
257 glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red);
258 gear (1.0, 4.0, 1.0, 20, 0.7);
259 glEndList ();
260
261 gear2 = glGenLists (1);
262 glNewList (gear2, GL_COMPILE);
263 glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, green);
264 gear (0.5, 2.0, 2.0, 10, 0.7);
265 glEndList ();
266
267 gear3 = glGenLists (1);
268 glNewList (gear3, GL_COMPILE);
269 glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, blue);
270 gear (1.3, 2.0, 0.5, 10, 0.7);
271 glEndList ();
272
273 glEnable (GL_NORMALIZE);
274
275 glViewport (0, 0, width, height);
276
277 glMatrixMode (GL_PROJECTION);
278 glLoadIdentity ();
279 if (width>height)
280 {
281 GLfloat w = (GLfloat) width / (GLfloat) height;
282 glFrustum (-w, w, -1.0, 1.0, 5.0, 60.0);
283 }
284 else
285 {
286 GLfloat h = (GLfloat) height / (GLfloat) width;
287 glFrustum (-1.0, 1.0, -h, h, 5.0, 60.0);
288 }
289
290 glMatrixMode (GL_MODELVIEW);
291 glLoadIdentity ();
292 glTranslatef (0.0, 0.0, -40.0);
293
294 #ifdef COUNT_FRAMES
295 tickStart = tickGet ();
296 tickBySec = sysClkRateGet ();
297 #endif
298 }
299
300 UGL_LOCAL void echoUse(void)
301 {
302 printf("tGears keys:\n");
303 printf(" z Counter clockwise rotation (z-axis)\n");
304 printf(" Z Clockwise rotation (z-axis)\n");
305 printf(" Up Counter clockwise rotation (x-axis)\n");
306 printf(" Down Clockwise rotation (x-axis)\n");
307 printf(" Left Counter clockwise rotation (y-axis)\n");
308 printf(" Right Clockwise rotation (y-axis)\n");
309 printf(" ESC Exit\n");
310 }
311
312
313 UGL_LOCAL void readKey (UGL_WCHAR key)
314 {
315
316 switch(key)
317 {
318 case 'z':
319 view_rotz += 5.0;
320 break;
321 case 'Z':
322 view_rotz -= 5.0;
323 break;
324 case UGL_UNI_UP_ARROW:
325 view_rotx += 5.0;
326 break;
327 case UGL_UNI_DOWN_ARROW:
328 view_rotx -= 5.0;
329 break;
330 case UGL_UNI_LEFT_ARROW:
331 view_roty += 5.0;
332 break;
333 case UGL_UNI_RIGHT_ARROW:
334 view_roty -= 5.0;
335 break;
336 case UGL_UNI_ESCAPE:
337 stopWex = UGL_TRUE;
338 break;
339 }
340 }
341
342 UGL_LOCAL void loopEvent(void)
343 {
344 UGL_EVENT event;
345 UGL_INPUT_EVENT * pInputEvent;
346
347 UGL_FOREVER
348 {
349 if (uglEventGet (qId, &event, sizeof (event), UGL_NO_WAIT)
350 != UGL_STATUS_Q_EMPTY)
351 {
352 pInputEvent = (UGL_INPUT_EVENT *)&event;
353
354 if (pInputEvent->header.type == UGL_EVENT_TYPE_KEYBOARD &&
355 pInputEvent->modifiers & UGL_KEYBOARD_KEYDOWN)
356 readKey(pInputEvent->type.keyboard.key);
357 }
358
359 drawGL();
360 if (stopWex)
361 break;
362 }
363 }
364
365 void windMLGears (UGL_BOOL windMLMode);
366
367 void uglgears (void)
368 {
369 taskSpawn ("tGears", 210, VX_FP_TASK, 100000, (FUNCPTR)windMLGears,
370 UGL_FALSE,1,2,3,4,5,6,7,8,9);
371 }
372
373 void windMLGears (UGL_BOOL windMLMode)
374 {
375 GLsizei width, height;
376 UGL_INPUT_DEVICE_ID keyboardDevId;
377
378 view_rotx=20.0;
379 view_roty=30.0;
380 view_rotz=0.0;
381 angle = 0.0;
382 limit = 100;
383 count = 1;
384
385 uglInitialize ();
386
387 uglDriverFind (UGL_KEYBOARD_TYPE, 0,
388 (UGL_UINT32 *)&keyboardDevId);
389
390 uglDriverFind (UGL_EVENT_SERVICE_TYPE, 0, (UGL_UINT32 *)&eventServiceId);
391
392 qId = uglEventQCreate (eventServiceId, 100);
393
394 /* Double buffering */
395 if (windMLMode)
396 umc = uglMesaCreateNewContext(UGL_MESA_DOUBLE
397 | UGL_MESA_WINDML_EXCLUSIVE, NULL);
398 else
399 umc = uglMesaCreateNewContext(UGL_MESA_DOUBLE, NULL);
400
401 if (umc == NULL)
402 {
403 uglDeinitialize ();
404 return;
405 }
406
407 /* Fullscreen */
408
409 uglMesaMakeCurrentContext (umc, 0, 0, UGL_MESA_FULLSCREEN_WIDTH,
410 UGL_MESA_FULLSCREEN_HEIGHT);
411
412 uglMesaGetIntegerv(UGL_MESA_WIDTH, &width);
413 uglMesaGetIntegerv(UGL_MESA_HEIGHT, &height);
414
415 initGL (width, height);
416
417 echoUse();
418
419 stopWex = UGL_FALSE;
420 loopEvent();
421
422 uglEventQDestroy (eventServiceId, qId);
423
424 uglMesaDestroyContext();
425 uglDeinitialize ();
426
427 return;
428 }