Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /* gears.c */
  2.  
  3. /*
  4.  * 3-D gear wheels.  This program is in the public domain.
  5.  *
  6.  * Brian Paul
  7.  */
  8.  
  9.  
  10. #include <math.h>
  11. #include <stdlib.h>
  12. #include <stdio.h>
  13. #include <string.h>
  14.  
  15. #include <GL/glx.h>
  16. #include <GL/gl.h>
  17. #include "ui.h"
  18.  
  19. #ifndef M_PI
  20. #  define M_PI 3.14159265
  21. #endif
  22.  
  23.  
  24. /*
  25.  * Draw a gear wheel.  You'll probably want to call this function when
  26.  * building a display list since we do a lot of trig here.
  27.  *
  28.  * Input:  inner_radius - radius of hole at center
  29.  *         outer_radius - radius at center of teeth
  30.  *         width - width of gear
  31.  *         teeth - number of teeth
  32.  *         tooth_depth - depth of tooth
  33.  */
  34. static void gear( GLfloat inner_radius, GLfloat outer_radius, GLfloat width,
  35.                   GLint teeth, GLfloat tooth_depth )
  36. {
  37.    GLint i;
  38.    GLfloat r0, r1, r2;
  39.    GLfloat angle, da;
  40.    GLfloat u, v, len;
  41.  
  42.    r0 = inner_radius;
  43.    r1 = outer_radius - tooth_depth/2.0;
  44.    r2 = outer_radius + tooth_depth/2.0;
  45.  
  46.    da = 2.0*M_PI / teeth / 4.0;
  47.  
  48.    glShadeModel( GL_FLAT );
  49.  
  50.    glNormal3f( 0.0, 0.0, 1.0 );
  51.  
  52.    /* draw front face */
  53.    glBegin( GL_QUAD_STRIP );
  54.    for (i=0;i<=teeth;i++) {
  55.       angle = i * 2.0*M_PI / teeth;
  56.       glVertex3f( r0*cos(angle), r0*sin(angle), width*0.5 );
  57.       glVertex3f( r1*cos(angle), r1*sin(angle), width*0.5 );
  58.       glVertex3f( r0*cos(angle), r0*sin(angle), width*0.5 );
  59.       glVertex3f( r1*cos(angle+3*da), r1*sin(angle+3*da), width*0.5 );
  60.    }
  61.    glEnd();
  62.  
  63.    /* draw front sides of teeth */
  64.    glBegin( GL_QUADS );
  65.    da = 2.0*M_PI / teeth / 4.0;
  66.    for (i=0;i<teeth;i++) {
  67.       angle = i * 2.0*M_PI / teeth;
  68.  
  69.       glVertex3f( r1*cos(angle),      r1*sin(angle),      width*0.5 );
  70.       glVertex3f( r2*cos(angle+da),   r2*sin(angle+da),   width*0.5 );
  71.       glVertex3f( r2*cos(angle+2*da), r2*sin(angle+2*da), width*0.5 );
  72.       glVertex3f( r1*cos(angle+3*da), r1*sin(angle+3*da), width*0.5 );
  73.    }
  74.    glEnd();
  75.  
  76.  
  77.    glNormal3f( 0.0, 0.0, -1.0 );
  78.  
  79.    /* draw back face */
  80.    glBegin( GL_QUAD_STRIP );
  81.    for (i=0;i<=teeth;i++) {
  82.       angle = i * 2.0*M_PI / teeth;
  83.       glVertex3f( r1*cos(angle), r1*sin(angle), -width*0.5 );
  84.       glVertex3f( r0*cos(angle), r0*sin(angle), -width*0.5 );
  85.       glVertex3f( r1*cos(angle+3*da), r1*sin(angle+3*da), -width*0.5 );
  86.       glVertex3f( r0*cos(angle), r0*sin(angle), -width*0.5 );
  87.    }
  88.    glEnd();
  89.  
  90.    /* draw back sides of teeth */
  91.    glBegin( GL_QUADS );
  92.    da = 2.0*M_PI / teeth / 4.0;
  93.    for (i=0;i<teeth;i++) {
  94.       angle = i * 2.0*M_PI / teeth;
  95.  
  96.       glVertex3f( r1*cos(angle+3*da), r1*sin(angle+3*da), -width*0.5 );
  97.       glVertex3f( r2*cos(angle+2*da), r2*sin(angle+2*da), -width*0.5 );
  98.       glVertex3f( r2*cos(angle+da),   r2*sin(angle+da),   -width*0.5 );
  99.       glVertex3f( r1*cos(angle),      r1*sin(angle),      -width*0.5 );
  100.    }
  101.    glEnd();
  102.  
  103.  
  104.    /* draw outward faces of teeth */
  105.    glBegin( GL_QUAD_STRIP );
  106.    for (i=0;i<teeth;i++) {
  107.       angle = i * 2.0*M_PI / teeth;
  108.  
  109.       glVertex3f( r1*cos(angle),      r1*sin(angle),       width*0.5 );
  110.       glVertex3f( r1*cos(angle),      r1*sin(angle),      -width*0.5 );
  111.       u = r2*cos(angle+da) - r1*cos(angle);
  112.       v = r2*sin(angle+da) - r1*sin(angle);
  113.       len = sqrt( u*u + v*v );
  114.       u /= len;
  115.       v /= len;
  116.       glNormal3f( v, -u, 0.0 );
  117.       glVertex3f( r2*cos(angle+da),   r2*sin(angle+da),    width*0.5 );
  118.       glVertex3f( r2*cos(angle+da),   r2*sin(angle+da),   -width*0.5 );
  119.       glNormal3f( cos(angle), sin(angle), 0.0 );
  120.       glVertex3f( r2*cos(angle+2*da), r2*sin(angle+2*da),  width*0.5 );
  121.       glVertex3f( r2*cos(angle+2*da), r2*sin(angle+2*da), -width*0.5 );
  122.       u = r1*cos(angle+3*da) - r2*cos(angle+2*da);
  123.       v = r1*sin(angle+3*da) - r2*sin(angle+2*da);
  124.       glNormal3f( v, -u, 0.0 );
  125.       glVertex3f( r1*cos(angle+3*da), r1*sin(angle+3*da),  width*0.5 );
  126.       glVertex3f( r1*cos(angle+3*da), r1*sin(angle+3*da), -width*0.5 );
  127.       glNormal3f( cos(angle), sin(angle), 0.0 );
  128.    }
  129.  
  130.    glVertex3f( r1*cos(0), r1*sin(0), width*0.5 );
  131.    glVertex3f( r1*cos(0), r1*sin(0), -width*0.5 );
  132.  
  133.    glEnd();
  134.  
  135.  
  136.    glShadeModel( GL_SMOOTH );
  137.  
  138.    /* draw inside radius cylinder */
  139.    glBegin( GL_QUAD_STRIP );
  140.    for (i=0;i<=teeth;i++) {
  141.       angle = i * 2.0*M_PI / teeth;
  142.       glNormal3f( -cos(angle), -sin(angle), 0.0 );
  143.       glVertex3f( r0*cos(angle), r0*sin(angle), -width*0.5 );
  144.       glVertex3f( r0*cos(angle), r0*sin(angle), width*0.5 );
  145.    }
  146.    glEnd();
  147.      
  148. }
  149.  
  150.  
  151. static GLfloat view_rotx=20.0, view_roty=30.0, view_rotz=0.0;
  152. static GLint gear1, gear2, gear3;
  153. static GLfloat angle = 0.0;
  154.  
  155. static GLuint limit;
  156. static GLuint count = 1;
  157.  
  158.  
  159. void draw( void )
  160. {
  161.    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
  162.  
  163.    glPushMatrix();
  164.    glRotatef( view_rotx, 1.0, 0.0, 0.0 );
  165.    glRotatef( view_roty, 0.0, 1.0, 0.0 );
  166.    glRotatef( view_rotz, 0.0, 0.0, 1.0 );
  167.  
  168.    glPushMatrix();
  169.    glTranslatef( -3.0, -2.0, 0.0 );
  170.    glRotatef( angle, 0.0, 0.0, 1.0 );
  171.    glCallList(gear1);
  172.    glPopMatrix();
  173.  
  174.    glPushMatrix();
  175.    glTranslatef( 3.1, -2.0, 0.0 );
  176.    glRotatef( -2.0*angle-9.0, 0.0, 0.0, 1.0 );
  177.    glCallList(gear2);
  178.    glPopMatrix();
  179.  
  180.    glPushMatrix();
  181.    glTranslatef( -3.1, 4.2, 0.0 );
  182.    glRotatef( -2.0*angle-25.0, 0.0, 0.0, 1.0 );
  183.    glCallList(gear3);
  184.    glPopMatrix();
  185.  
  186.    glPopMatrix();
  187.  
  188.    tkSwapBuffers();
  189.  
  190.    count++;
  191.    if (count==limit) {
  192.        exit(0);
  193.    }
  194. }
  195.  
  196.  
  197.  
  198. void idle( void )
  199. {
  200.    angle += 2.0;
  201.    draw();
  202. }
  203.  
  204.  
  205.  
  206. /* change view angle, exit upon ESC */
  207. GLenum key(int k, GLenum mask)
  208. {
  209.    switch (k) {
  210.       case KEY_UP:
  211.          view_rotx += 5.0;
  212.          return GL_TRUE;
  213.       case KEY_DOWN:
  214.          view_rotx -= 5.0;
  215.          return GL_TRUE;
  216.       case KEY_LEFT:
  217.          view_roty += 5.0;
  218.          return GL_TRUE;
  219.       case KEY_RIGHT:
  220.          view_roty -= 5.0;
  221.          return GL_TRUE;
  222.       case 'z':
  223.          view_rotz += 5.0;
  224.          return GL_TRUE;
  225.       case 'Z':
  226.          view_rotz -= 5.0;
  227.          return GL_TRUE;
  228.       case KEY_ESCAPE:
  229.           exit(0);
  230.    }
  231.    return GL_FALSE;
  232. }
  233.  
  234.  
  235.  
  236. /* new window size or exposure */
  237. void reshape( int width, int height )
  238. {
  239.    GLfloat  h = (GLfloat) height / (GLfloat) width;
  240.  
  241.    glViewport(0, 0, (GLint)width, (GLint)height);
  242.    glMatrixMode(GL_PROJECTION);
  243.    glLoadIdentity();
  244.    glFrustum( -1.0, 1.0, -h, h, 5.0, 60.0 );
  245.    glMatrixMode(GL_MODELVIEW);
  246.    glLoadIdentity();
  247.    glTranslatef( 0.0, 0.0, -40.0 );
  248.    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
  249. }
  250.  
  251.  
  252. void init( void )
  253. {
  254.    static GLfloat pos[4] = {5.0, 5.0, 10.0, 0.0 };
  255.    static GLfloat red[4] = {0.8, 0.1, 0.0, 1.0 };
  256.    static GLfloat green[4] = {0.0, 0.8, 0.2, 1.0 };
  257.    static GLfloat blue[4] = {0.2, 0.2, 1.0, 1.0 };
  258.  
  259.    glLightfv( GL_LIGHT0, GL_POSITION, pos );
  260.    glEnable( GL_CULL_FACE );
  261.    glEnable( GL_LIGHTING );
  262.    glEnable( GL_LIGHT0 );
  263.    glEnable( GL_DEPTH_TEST );
  264.  
  265.    /* make the gears */
  266.    gear1 = glGenLists(1);
  267.    glNewList(gear1, GL_COMPILE);
  268.    glMaterialfv( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red );
  269.    gear( 1.0, 4.0, 1.0, 20, 0.7 );
  270.    glEndList();
  271.  
  272.    gear2 = glGenLists(1);
  273.    glNewList(gear2, GL_COMPILE);
  274.    glMaterialfv( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, green );
  275.    gear( 0.5, 2.0, 2.0, 10, 0.7 );
  276.    glEndList();
  277.  
  278.    gear3 = glGenLists(1);
  279.    glNewList(gear3, GL_COMPILE);
  280.    glMaterialfv( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, blue );
  281.    gear( 1.3, 2.0, 0.5, 10, 0.7 );
  282.    glEndList();
  283.  
  284.    glEnable( GL_NORMALIZE );
  285. }
  286.  
  287. int main(int argc, char **argv)
  288. {
  289.    if (argc>1) {
  290.       /* do 'n' frames then exit */
  291.       limit = atoi( argv[1] ) + 1;
  292.    }
  293.    else {
  294.       limit = 0;
  295.    }
  296.  
  297.    return ui_loop(argc, argv, "gears");
  298. }
  299.  
  300.  
  301.