prevent spaces in fp register names
[mesa.git] / progs / ggi / gears.c
1 /* $Id: gears.c,v 1.3 1999/08/22 08:56:50 jtaylor Exp $ */
2
3 /*
4 * 3-D gear wheels. This program is in the public domain.
5 *
6 * Brian Paul
7 */
8
9 /* Conversion to GLUT by Mark J. Kilgard */
10
11 #include <math.h>
12 #include <stdlib.h>
13 #include <stdio.h>
14 #include <GL/glut.h>
15
16 #ifndef M_PI
17 #define M_PI 3.14159265
18 #endif
19
20 static GLint T0 = 0;
21 static GLint Frames = 0;
22
23
24 /**
25
26 Draw a gear wheel. You'll probably want to call this function when
27 building a display list since we do a lot of trig here.
28
29 Input: inner_radius - radius of hole at center
30 outer_radius - radius at center of teeth
31 width - width of gear
32 teeth - number of teeth
33 tooth_depth - depth of tooth
34
35 **/
36
37 static void
38 gear(GLfloat inner_radius, GLfloat outer_radius, GLfloat width,
39 GLint teeth, GLfloat tooth_depth)
40 {
41 GLint i;
42 GLfloat r0, r1, r2;
43 GLfloat angle, da;
44 GLfloat u, v, len;
45
46 r0 = inner_radius;
47 r1 = outer_radius - tooth_depth / 2.0;
48 r2 = outer_radius + tooth_depth / 2.0;
49
50 da = 2.0 * M_PI / teeth / 4.0;
51
52 glShadeModel(GL_FLAT);
53
54 glNormal3f(0.0, 0.0, 1.0);
55
56 /* draw front face */
57 glBegin(GL_QUAD_STRIP);
58 for (i = 0; i <= teeth; i++) {
59 angle = i * 2.0 * M_PI / teeth;
60 glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
61 glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
62 if (i < teeth) {
63 glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
64 glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), width * 0.5);
65 }
66 }
67 glEnd();
68
69 /* draw front sides of teeth */
70 glBegin(GL_QUADS);
71 da = 2.0 * M_PI / teeth / 4.0;
72 for (i = 0; i < teeth; i++) {
73 angle = i * 2.0 * M_PI / teeth;
74
75 glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
76 glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), width * 0.5);
77 glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), width * 0.5);
78 glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), width * 0.5);
79 }
80 glEnd();
81
82 glNormal3f(0.0, 0.0, -1.0);
83
84 /* draw back face */
85 glBegin(GL_QUAD_STRIP);
86 for (i = 0; i <= teeth; i++) {
87 angle = i * 2.0 * M_PI / teeth;
88 glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
89 glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
90 if (i < teeth) {
91 glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), -width * 0.5);
92 glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
93 }
94 }
95 glEnd();
96
97 /* draw back sides of teeth */
98 glBegin(GL_QUADS);
99 da = 2.0 * M_PI / teeth / 4.0;
100 for (i = 0; i < teeth; i++) {
101 angle = i * 2.0 * M_PI / teeth;
102
103 glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), -width * 0.5);
104 glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), -width * 0.5);
105 glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -width * 0.5);
106 glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
107 }
108 glEnd();
109
110 /* draw outward faces of teeth */
111 glBegin(GL_QUAD_STRIP);
112 for (i = 0; i < teeth; i++) {
113 angle = i * 2.0 * M_PI / teeth;
114
115 glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
116 glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
117 u = r2 * cos(angle + da) - r1 * cos(angle);
118 v = r2 * sin(angle + da) - r1 * sin(angle);
119 len = sqrt(u * u + v * v);
120 u /= len;
121 v /= len;
122 glNormal3f(v, -u, 0.0);
123 glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), width * 0.5);
124 glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -width * 0.5);
125 glNormal3f(cos(angle), sin(angle), 0.0);
126 glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), width * 0.5);
127 glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), -width * 0.5);
128 u = r1 * cos(angle + 3 * da) - r2 * cos(angle + 2 * da);
129 v = r1 * sin(angle + 3 * da) - r2 * sin(angle + 2 * da);
130 glNormal3f(v, -u, 0.0);
131 glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), width * 0.5);
132 glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), -width * 0.5);
133 glNormal3f(cos(angle), sin(angle), 0.0);
134 }
135
136 glVertex3f(r1 * cos(0), r1 * sin(0), width * 0.5);
137 glVertex3f(r1 * cos(0), r1 * sin(0), -width * 0.5);
138
139 glEnd();
140
141 glShadeModel(GL_SMOOTH);
142
143 /* draw inside radius cylinder */
144 glBegin(GL_QUAD_STRIP);
145 for (i = 0; i <= teeth; i++) {
146 angle = i * 2.0 * M_PI / teeth;
147 glNormal3f(-cos(angle), -sin(angle), 0.0);
148 glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
149 glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
150 }
151 glEnd();
152
153 }
154
155 static GLfloat view_rotx = 20.0, view_roty = 30.0, view_rotz = 0.0;
156 static GLint gear1, gear2, gear3;
157 static GLfloat angle = 0.0;
158
159 static void
160 draw(void)
161 {
162 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
163
164 glPushMatrix();
165 glRotatef(view_rotx, 1.0, 0.0, 0.0);
166 glRotatef(view_roty, 0.0, 1.0, 0.0);
167 glRotatef(view_rotz, 0.0, 0.0, 1.0);
168
169 glPushMatrix();
170 glTranslatef(-3.0, -2.0, 0.0);
171 glRotatef(angle, 0.0, 0.0, 1.0);
172 glCallList(gear1);
173 glPopMatrix();
174
175 glPushMatrix();
176 glTranslatef(3.1, -2.0, 0.0);
177 glRotatef(-2.0 * angle - 9.0, 0.0, 0.0, 1.0);
178 glCallList(gear2);
179 glPopMatrix();
180
181 glPushMatrix();
182 glTranslatef(-3.1, 4.2, 0.0);
183 glRotatef(-2.0 * angle - 25.0, 0.0, 0.0, 1.0);
184 glCallList(gear3);
185 glPopMatrix();
186
187 glPopMatrix();
188
189 glutSwapBuffers();
190
191 Frames++;
192 {
193 GLint t = glutGet(GLUT_ELAPSED_TIME);
194 if (t - T0 >= 5000) {
195 GLfloat seconds = (t - T0) / 1000.0;
196 GLfloat fps = Frames / seconds;
197 printf("%d frames in %g seconds = %g FPS\n", Frames, seconds, fps);
198 T0 = t;
199 Frames = 0;
200 }
201 }
202 }
203
204
205 static void
206 idle(void)
207 {
208 angle += 2.0;
209 glutPostRedisplay();
210 }
211
212 /* change view angle, exit upon ESC */
213 /* ARGSUSED1 */
214 static void
215 key(unsigned char k, int x, int y)
216 {
217 switch (k) {
218 case 'z':
219 view_rotz += 5.0;
220 break;
221 case 'Z':
222 view_rotz -= 5.0;
223 break;
224 case 27: /* Escape */
225 exit(0); /* FIXME: Shutdown and free resources cleanly in ggiglut */
226 break;
227 default:
228 return;
229 }
230 glutPostRedisplay();
231 }
232
233 /* change view angle */
234 /* ARGSUSED1 */
235 static void
236 special(int k, int x, int y)
237 {
238 switch (k) {
239 case GLUT_KEY_UP:
240 view_rotx += 5.0;
241 break;
242 case GLUT_KEY_DOWN:
243 view_rotx -= 5.0;
244 break;
245 case GLUT_KEY_LEFT:
246 view_roty += 5.0;
247 break;
248 case GLUT_KEY_RIGHT:
249 view_roty -= 5.0;
250 break;
251 default:
252 return;
253 }
254 glutPostRedisplay();
255 }
256
257 /* new window size or exposure */
258 static void
259 reshape(int width, int height)
260 {
261 GLfloat h = (GLfloat) height / (GLfloat) width;
262
263 glViewport(0, 0, (GLint) width, (GLint) height);
264 glMatrixMode(GL_PROJECTION);
265 glLoadIdentity();
266 glFrustum(-1.0, 1.0, -h, h, 5.0, 60.0);
267 glMatrixMode(GL_MODELVIEW);
268 glLoadIdentity();
269 glTranslatef(0.0, 0.0, -40.0);
270 }
271
272 static void
273 init(void)
274 {
275 static GLfloat pos[4] =
276 {5.0, 5.0, 10.0, 0.0};
277 static GLfloat red[4] =
278 {0.8, 0.1, 0.0, 1.0};
279 static GLfloat green[4] =
280 {0.0, 0.8, 0.2, 1.0};
281 static GLfloat blue[4] =
282 {0.2, 0.2, 1.0, 1.0};
283
284 glLightfv(GL_LIGHT0, GL_POSITION, pos);
285 glEnable(GL_CULL_FACE);
286 glEnable(GL_LIGHTING);
287 glEnable(GL_LIGHT0);
288 glEnable(GL_DEPTH_TEST);
289
290 /* make the gears */
291 gear1 = glGenLists(1);
292 glNewList(gear1, GL_COMPILE);
293 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red);
294 gear(1.0, 4.0, 1.0, 20, 0.7);
295 glEndList();
296
297 gear2 = glGenLists(1);
298 glNewList(gear2, GL_COMPILE);
299 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, green);
300 gear(0.5, 2.0, 2.0, 10, 0.7);
301 glEndList();
302
303 gear3 = glGenLists(1);
304 glNewList(gear3, GL_COMPILE);
305 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, blue);
306 gear(1.3, 2.0, 0.5, 10, 0.7);
307 glEndList();
308
309 glEnable(GL_NORMALIZE);
310 }
311
312 void
313 visible(int vis)
314 {
315 if (vis == GLUT_VISIBLE)
316 glutIdleFunc(idle);
317 else
318 glutIdleFunc(NULL);
319 }
320
321 int main(int argc, char *argv[])
322 {
323 glutInit(&argc, argv);
324 glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
325
326 // glutInitWindowPosition(0, 0);
327 // glutInitWindowSize(300, 300);
328 glutCreateWindow("Gears");
329 init();
330
331 glutDisplayFunc(draw);
332 glutReshapeFunc(reshape);
333 glutKeyboardFunc(key);
334 glutSpecialFunc(special);
335 glutVisibilityFunc(visible);
336
337 glutMainLoop();
338
339 return 0;
340 }