diff options
Diffstat (limited to 'progs/windml/uglgears.c')
-rw-r--r-- | progs/windml/uglgears.c | 428 |
1 files changed, 428 insertions, 0 deletions
diff --git a/progs/windml/uglgears.c b/progs/windml/uglgears.c new file mode 100644 index 000000000..468fe8998 --- /dev/null +++ b/progs/windml/uglgears.c @@ -0,0 +1,428 @@ + +/* uglgears.c - WindML/Mesa example program */ + +/* + * 3-D gear wheels. This program is in the public domain. + * + * Brian Paul + * + * Conversion to GLUT by Mark J. Kilgard + * Conversion to UGL/Mesa from GLUT by Stephane Raimbault + */ + +/* +DESCRIPTION +Spinning gears demo +*/ + +#include <stdio.h> +#include <math.h> +#include <tickLib.h> + +#include <ugl/ugl.h> +#include <ugl/uglucode.h> +#include <ugl/uglevent.h> +#include <ugl/uglinput.h> +#include <GL/uglmesa.h> +#include <GL/glu.h> + +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +#define COUNT_FRAMES + +UGL_LOCAL UGL_EVENT_SERVICE_ID eventServiceId; +UGL_LOCAL UGL_EVENT_Q_ID qId; +UGL_LOCAL volatile UGL_BOOL stopWex; +UGL_LOCAL UGL_MESA_CONTEXT umc; + +UGL_LOCAL GLfloat view_rotx, view_roty, view_rotz; +UGL_LOCAL GLint gear1, gear2, gear3; +UGL_LOCAL GLfloat angle; + +UGL_LOCAL GLuint limit; +UGL_LOCAL GLuint count; +UGL_LOCAL GLuint tickStart, tickStop, tickBySec; + + +/* +* Draw a gear wheel. You'll probably want to call this function when +* building a display list since we do a lot of trig here. +* +* Input: inner_radius - radius of hole at center +* outer_radius - radius at center of teeth +* width - width of gear +* teeth - number of teeth +* tooth_depth - depth of tooth +*/ + +UGL_LOCAL void gear + ( + GLfloat inner_radius, + GLfloat outer_radius, + GLfloat width, + GLint teeth, + GLfloat tooth_depth + ) + { + GLint i; + GLfloat r0, r1, r2; + GLfloat angle, da; + GLfloat u, v, len; + + r0 = inner_radius; + r1 = outer_radius - tooth_depth/2.0; + r2 = outer_radius + tooth_depth/2.0; + + da = 2.0*M_PI / teeth / 4.0; + + glShadeModel (GL_FLAT); + + glNormal3f (0.0, 0.0, 1.0); + + /* draw front face */ + glBegin (GL_QUAD_STRIP); + for (i=0;i<=teeth;i++) + { + angle = i * 2.0*M_PI / teeth; + glVertex3f (r0*cos (angle), r0*sin (angle), width*0.5); + glVertex3f (r1*cos (angle), r1*sin (angle), width*0.5); + glVertex3f (r0*cos (angle), r0*sin (angle), width*0.5); + glVertex3f (r1*cos (angle+3*da), r1*sin (angle+3*da), width*0.5); + } + glEnd (); + + /* draw front sides of teeth */ + glBegin (GL_QUADS); + da = 2.0*M_PI / teeth / 4.0; + for (i=0; i<teeth; i++) + { + angle = i * 2.0*M_PI / teeth; + + glVertex3f (r1*cos (angle), r1*sin (angle), width*0.5); + glVertex3f (r2*cos (angle+da), r2*sin (angle+da), width*0.5); + glVertex3f (r2*cos (angle+2*da), r2*sin (angle+2*da), width*0.5); + glVertex3f (r1*cos (angle+3*da), r1*sin (angle+3*da), width*0.5); + } + glEnd (); + + + glNormal3f (0.0, 0.0, -1.0); + + /* draw back face */ + glBegin (GL_QUAD_STRIP); + for (i=0; i<=teeth ;i++) + { + angle = i * 2.0*M_PI / teeth; + glVertex3f (r1*cos (angle), r1*sin (angle), -width*0.5); + glVertex3f (r0*cos (angle), r0*sin (angle), -width*0.5); + glVertex3f (r1*cos (angle+3*da), r1*sin (angle+3*da), -width*0.5); + glVertex3f (r0*cos (angle), r0*sin (angle), -width*0.5); + } + glEnd (); + + /* draw back sides of teeth */ + glBegin (GL_QUADS); + da = 2.0*M_PI / teeth / 4.0; + for (i=0;i<teeth;i++) + { + angle = i * 2.0*M_PI / teeth; + + glVertex3f (r1*cos (angle+3*da), r1*sin (angle+3*da), -width*0.5); + glVertex3f (r2*cos (angle+2*da), r2*sin (angle+2*da), -width*0.5); + glVertex3f (r2*cos (angle+da), r2*sin (angle+da), -width*0.5); + glVertex3f (r1*cos (angle), r1*sin (angle), -width*0.5); + } + glEnd (); + + + /* draw outward faces of teeth */ + glBegin (GL_QUAD_STRIP); + for (i=0;i<teeth;i++) + { + angle = i * 2.0*M_PI / teeth; + + glVertex3f (r1*cos (angle), r1*sin (angle), width*0.5); + glVertex3f (r1*cos (angle), r1*sin (angle), -width*0.5); + u = r2*cos (angle+da) - r1*cos (angle); + v = r2*sin (angle+da) - r1*sin (angle); + len = sqrt (u*u + v*v); + u /= len; + v /= len; + glNormal3f (v, -u, 0.0); + glVertex3f (r2*cos (angle+da), r2*sin (angle+da), width*0.5); + glVertex3f (r2*cos (angle+da), r2*sin (angle+da), -width*0.5); + glNormal3f (cos (angle), sin (angle), 0.0); + glVertex3f (r2*cos (angle+2*da), r2*sin (angle+2*da), width*0.5); + glVertex3f (r2*cos (angle+2*da), r2*sin (angle+2*da), -width*0.5); + u = r1*cos (angle+3*da) - r2*cos (angle+2*da); + v = r1*sin (angle+3*da) - r2*sin (angle+2*da); + glNormal3f (v, -u, 0.0); + glVertex3f (r1*cos (angle+3*da), r1*sin (angle+3*da), width*0.5); + glVertex3f (r1*cos (angle+3*da), r1*sin (angle+3*da), -width*0.5); + glNormal3f (cos (angle), sin (angle), 0.0); + } + + glVertex3f (r1*cos (0), r1*sin (0), width*0.5); + glVertex3f (r1*cos (0), r1*sin (0), -width*0.5); + + glEnd (); + + glShadeModel (GL_SMOOTH); + + /* draw inside radius cylinder */ + glBegin (GL_QUAD_STRIP); + for (i=0;i<=teeth;i++) + { + angle = i * 2.0*M_PI / teeth; + glNormal3f (-cos (angle), -sin (angle), 0.0); + glVertex3f (r0*cos (angle), r0*sin (angle), -width*0.5); + glVertex3f (r0*cos (angle), r0*sin (angle), width*0.5); + } + glEnd (); + +} + +UGL_LOCAL void drawGL (void) + { +#ifdef COUNT_FRAMES + int time; +#endif + + angle += 2.0; + + glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glPushMatrix (); + glRotatef (view_rotx, 1.0, 0.0, 0.0); + glRotatef (view_roty, 0.0, 1.0, 0.0); + glRotatef (view_rotz, 0.0, 0.0, 1.0); + + glPushMatrix (); + glTranslatef (-3.0, -2.0, 0.0); + glRotatef (angle, 0.0, 0.0, 1.0); + glCallList (gear1); + glPopMatrix (); + + glPushMatrix (); + glTranslatef (3.1, -2.0, 0.0); + glRotatef (-2.0*angle-9.0, 0.0, 0.0, 1.0); + glCallList (gear2); + glPopMatrix (); + + glPushMatrix (); + glTranslatef (-3.1, 4.2, 0.0); + glRotatef (-2.0*angle-25.0, 0.0, 0.0, 1.0); + glCallList (gear3); + glPopMatrix (); + + glPopMatrix (); + + glFlush(); + + uglMesaSwapBuffers (); + +#ifdef COUNT_FRAMES + if (count > limit) + { + tickStop = tickGet (); + time = (tickStop-tickStart)/tickBySec; + printf (" %i fps\n", count/time); + tickStart = tickStop; + count = 0; + } + else + count++; +#endif +} + + +UGL_LOCAL void initGL (GLsizei width, GLsizei height) + { + UGL_LOCAL GLfloat pos[4] = {5.0, 5.0, 10.0, 1.0 }; + UGL_LOCAL GLfloat red[4] = {0.8, 0.1, 0.0, 1.0 }; + UGL_LOCAL GLfloat green[4] = {0.0, 0.8, 0.2, 1.0 }; + UGL_LOCAL GLfloat blue[4] = {0.2, 0.2, 1.0, 1.0 }; + + glLightfv (GL_LIGHT0, GL_POSITION, pos); + glEnable (GL_CULL_FACE); + glEnable (GL_LIGHTING); + glEnable (GL_LIGHT0); + glEnable (GL_DEPTH_TEST); + + /* make the gears */ + gear1 = glGenLists (1); + glNewList (gear1, GL_COMPILE); + glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red); + gear (1.0, 4.0, 1.0, 20, 0.7); + glEndList (); + + gear2 = glGenLists (1); + glNewList (gear2, GL_COMPILE); + glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, green); + gear (0.5, 2.0, 2.0, 10, 0.7); + glEndList (); + + gear3 = glGenLists (1); + glNewList (gear3, GL_COMPILE); + glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, blue); + gear (1.3, 2.0, 0.5, 10, 0.7); + glEndList (); + + glEnable (GL_NORMALIZE); + + glViewport (0, 0, width, height); + + glMatrixMode (GL_PROJECTION); + glLoadIdentity (); + if (width>height) + { + GLfloat w = (GLfloat) width / (GLfloat) height; + glFrustum (-w, w, -1.0, 1.0, 5.0, 60.0); + } + else + { + GLfloat h = (GLfloat) height / (GLfloat) width; + glFrustum (-1.0, 1.0, -h, h, 5.0, 60.0); + } + + glMatrixMode (GL_MODELVIEW); + glLoadIdentity (); + glTranslatef (0.0, 0.0, -40.0); + +#ifdef COUNT_FRAMES + tickStart = tickGet (); + tickBySec = sysClkRateGet (); +#endif +} + +UGL_LOCAL void echoUse(void) + { + printf("tGears keys:\n"); + printf(" z Counter clockwise rotation (z-axis)\n"); + printf(" Z Clockwise rotation (z-axis)\n"); + printf(" Up Counter clockwise rotation (x-axis)\n"); + printf(" Down Clockwise rotation (x-axis)\n"); + printf(" Left Counter clockwise rotation (y-axis)\n"); + printf(" Right Clockwise rotation (y-axis)\n"); + printf(" ESC Exit\n"); + } + + +UGL_LOCAL void readKey (UGL_WCHAR key) + { + + switch(key) + { + case 'z': + view_rotz += 5.0; + break; + case 'Z': + view_rotz -= 5.0; + break; + case UGL_UNI_UP_ARROW: + view_rotx += 5.0; + break; + case UGL_UNI_DOWN_ARROW: + view_rotx -= 5.0; + break; + case UGL_UNI_LEFT_ARROW: + view_roty += 5.0; + break; + case UGL_UNI_RIGHT_ARROW: + view_roty -= 5.0; + break; + case UGL_UNI_ESCAPE: + stopWex = UGL_TRUE; + break; + } + } + +UGL_LOCAL void loopEvent(void) + { + UGL_EVENT event; + UGL_INPUT_EVENT * pInputEvent; + + UGL_FOREVER + { + if (uglEventGet (qId, &event, sizeof (event), UGL_NO_WAIT) + != UGL_STATUS_Q_EMPTY) + { + pInputEvent = (UGL_INPUT_EVENT *)&event; + + if (pInputEvent->header.type == UGL_EVENT_TYPE_KEYBOARD && + pInputEvent->modifiers & UGL_KEYBOARD_KEYDOWN) + readKey(pInputEvent->type.keyboard.key); + } + + drawGL(); + if (stopWex) + break; + } + } + +void windMLGears (UGL_BOOL windMLMode); + +void uglgears (void) + { + taskSpawn ("tGears", 210, VX_FP_TASK, 100000, (FUNCPTR)windMLGears, + UGL_FALSE,1,2,3,4,5,6,7,8,9); + } + +void windMLGears (UGL_BOOL windMLMode) + { + GLsizei width, height; + UGL_INPUT_DEVICE_ID keyboardDevId; + + view_rotx=20.0; + view_roty=30.0; + view_rotz=0.0; + angle = 0.0; + limit = 100; + count = 1; + + uglInitialize (); + + uglDriverFind (UGL_KEYBOARD_TYPE, 0, + (UGL_UINT32 *)&keyboardDevId); + + uglDriverFind (UGL_EVENT_SERVICE_TYPE, 0, (UGL_UINT32 *)&eventServiceId); + + qId = uglEventQCreate (eventServiceId, 100); + + /* Double buffering */ + if (windMLMode) + umc = uglMesaCreateNewContext(UGL_MESA_DOUBLE + | UGL_MESA_WINDML_EXCLUSIVE, NULL); + else + umc = uglMesaCreateNewContext(UGL_MESA_DOUBLE, NULL); + + if (umc == NULL) + { + uglDeinitialize (); + return; + } + + /* Fullscreen */ + + uglMesaMakeCurrentContext (umc, 0, 0, UGL_MESA_FULLSCREEN_WIDTH, + UGL_MESA_FULLSCREEN_HEIGHT); + + uglMesaGetIntegerv(UGL_MESA_WIDTH, &width); + uglMesaGetIntegerv(UGL_MESA_HEIGHT, &height); + + initGL (width, height); + + echoUse(); + + stopWex = UGL_FALSE; + loopEvent(); + + uglEventQDestroy (eventServiceId, qId); + + uglMesaDestroyContext(); + uglDeinitialize (); + + return; + } |