2 /* uglgears.c - WindML/Mesa example program */
5 * 3-D gear wheels. This program is in the public domain.
9 * Conversion to GLUT by Mark J. Kilgard
10 * Conversion to UGL/Mesa from GLUT by Stephane Raimbault
23 #include <ugl/uglucode.h>
24 #include <ugl/uglevent.h>
25 #include <ugl/uglinput.h>
26 #include <GL/uglmesa.h>
30 #define M_PI 3.14159265358979323846
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
;
40 UGL_LOCAL GLfloat view_rotx
, view_roty
, view_rotz
;
41 UGL_LOCAL GLint gear1
, gear2
, gear3
;
42 UGL_LOCAL GLfloat angle
;
44 UGL_LOCAL GLuint limit
;
45 UGL_LOCAL GLuint count
;
46 UGL_LOCAL GLuint tickStart
, tickStop
, tickBySec
;
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.
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
75 r1
= outer_radius
- tooth_depth
/2.0;
76 r2
= outer_radius
+ tooth_depth
/2.0;
78 da
= 2.0*M_PI
/ teeth
/ 4.0;
80 glShadeModel (GL_FLAT
);
82 glNormal3f (0.0, 0.0, 1.0);
85 glBegin (GL_QUAD_STRIP
);
86 for (i
=0;i
<=teeth
;i
++)
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);
96 /* draw front sides of teeth */
98 da
= 2.0*M_PI
/ teeth
/ 4.0;
99 for (i
=0; i
<teeth
; i
++)
101 angle
= i
* 2.0*M_PI
/ teeth
;
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);
111 glNormal3f (0.0, 0.0, -1.0);
114 glBegin (GL_QUAD_STRIP
);
115 for (i
=0; i
<=teeth
;i
++)
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);
125 /* draw back sides of teeth */
127 da
= 2.0*M_PI
/ teeth
/ 4.0;
128 for (i
=0;i
<teeth
;i
++)
130 angle
= i
* 2.0*M_PI
/ teeth
;
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);
140 /* draw outward faces of teeth */
141 glBegin (GL_QUAD_STRIP
);
142 for (i
=0;i
<teeth
;i
++)
144 angle
= i
* 2.0*M_PI
/ teeth
;
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
);
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);
167 glVertex3f (r1
*cos (0), r1
*sin (0), width
*0.5);
168 glVertex3f (r1
*cos (0), r1
*sin (0), -width
*0.5);
172 glShadeModel (GL_SMOOTH
);
174 /* draw inside radius cylinder */
175 glBegin (GL_QUAD_STRIP
);
176 for (i
=0;i
<=teeth
;i
++)
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);
187 UGL_LOCAL
void drawGL (void)
195 glClear (GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
);
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);
203 glTranslatef (-3.0, -2.0, 0.0);
204 glRotatef (angle
, 0.0, 0.0, 1.0);
209 glTranslatef (3.1, -2.0, 0.0);
210 glRotatef (-2.0*angle
-9.0, 0.0, 0.0, 1.0);
215 glTranslatef (-3.1, 4.2, 0.0);
216 glRotatef (-2.0*angle
-25.0, 0.0, 0.0, 1.0);
224 uglMesaSwapBuffers ();
229 tickStop
= tickGet ();
230 time
= (tickStop
-tickStart
)/tickBySec
;
231 printf (" %i fps\n", count
/time
);
232 tickStart
= tickStop
;
241 UGL_LOCAL
void initGL (GLsizei width
, GLsizei height
)
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 };
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
);
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);
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);
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);
273 glEnable (GL_NORMALIZE
);
275 glViewport (0, 0, width
, height
);
277 glMatrixMode (GL_PROJECTION
);
281 GLfloat w
= (GLfloat
) width
/ (GLfloat
) height
;
282 glFrustum (-w
, w
, -1.0, 1.0, 5.0, 60.0);
286 GLfloat h
= (GLfloat
) height
/ (GLfloat
) width
;
287 glFrustum (-1.0, 1.0, -h
, h
, 5.0, 60.0);
290 glMatrixMode (GL_MODELVIEW
);
292 glTranslatef (0.0, 0.0, -40.0);
295 tickStart
= tickGet ();
296 tickBySec
= sysClkRateGet ();
300 UGL_LOCAL
void echoUse(void)
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");
313 UGL_LOCAL
void readKey (UGL_WCHAR key
)
324 case UGL_UNI_UP_ARROW
:
327 case UGL_UNI_DOWN_ARROW
:
330 case UGL_UNI_LEFT_ARROW
:
333 case UGL_UNI_RIGHT_ARROW
:
342 UGL_LOCAL
void loopEvent(void)
345 UGL_INPUT_EVENT
* pInputEvent
;
349 if (uglEventGet (qId
, &event
, sizeof (event
), UGL_NO_WAIT
)
350 != UGL_STATUS_Q_EMPTY
)
352 pInputEvent
= (UGL_INPUT_EVENT
*)&event
;
354 if (pInputEvent
->header
.type
== UGL_EVENT_TYPE_KEYBOARD
&&
355 pInputEvent
->modifiers
& UGL_KEYBOARD_KEYDOWN
)
356 readKey(pInputEvent
->type
.keyboard
.key
);
365 void windMLGears (UGL_BOOL windMLMode
);
369 taskSpawn ("tGears", 210, VX_FP_TASK
, 100000, (FUNCPTR
)windMLGears
,
370 UGL_FALSE
,1,2,3,4,5,6,7,8,9);
373 void windMLGears (UGL_BOOL windMLMode
)
375 GLsizei width
, height
;
376 UGL_INPUT_DEVICE_ID keyboardDevId
;
387 uglDriverFind (UGL_KEYBOARD_TYPE
, 0,
388 (UGL_UINT32
*)&keyboardDevId
);
390 uglDriverFind (UGL_EVENT_SERVICE_TYPE
, 0, (UGL_UINT32
*)&eventServiceId
);
392 qId
= uglEventQCreate (eventServiceId
, 100);
394 /* Double buffering */
396 umc
= uglMesaCreateNewContext(UGL_MESA_DOUBLE
397 | UGL_MESA_WINDML_EXCLUSIVE
, NULL
);
399 umc
= uglMesaCreateNewContext(UGL_MESA_DOUBLE
, NULL
);
409 uglMesaMakeCurrentContext (umc
, 0, 0, UGL_MESA_FULLSCREEN_WIDTH
,
410 UGL_MESA_FULLSCREEN_HEIGHT
);
412 uglMesaGetIntegerv(UGL_MESA_WIDTH
, &width
);
413 uglMesaGetIntegerv(UGL_MESA_HEIGHT
, &height
);
415 initGL (width
, height
);
422 uglEventQDestroy (eventServiceId
, qId
);
424 uglMesaDestroyContext();