version 2.8
gears.c
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