blob: 1d1e10db545d4d6ec5704484d494aa45359501e8 [file] [log] [blame]
Jon Taylor035e96e1999-08-21 06:27:37 +00001/* gears.c */
2
3/*
4 * 3-D gear wheels. This program is in the public domain.
5 *
6 * Brian Paul
7 * modified by Uwe Maurer (uwe_maurer@t-online.de)
8 */
9
10#include <string.h>
11#include <math.h>
12#include <stdlib.h>
13#include <ggi/ggi.h>
14#include <GL/ggimesa.h>
15#ifndef M_PI
16# define M_PI 3.14159265
17#endif
18
19
20ggi_visual_t vis;
21char text[100];
22
23/*
24 * Draw a gear wheel. You'll probably want to call this function when
25 * building a display list since we do a lot of trig here.
26 *
27 * Input: inner_radius - radius of hole at center
28 * outer_radius - radius at center of teeth
29 * width - width of gear
30 * teeth - number of teeth
31 * tooth_depth - depth of tooth
32 */
33static void gear( GLfloat inner_radius, GLfloat outer_radius, GLfloat width,
34 GLint teeth, GLfloat tooth_depth )
35{
36 GLint i;
37 GLfloat r0, r1, r2;
38 GLfloat angle, da;
39 GLfloat u, v, len;
40
41 r0 = inner_radius;
42 r1 = outer_radius - tooth_depth/2.0;
43 r2 = outer_radius + tooth_depth/2.0;
44
45 da = 2.0*M_PI / teeth / 4.0;
46
47 glShadeModel( GL_FLAT );
48
49 glNormal3f( 0.0, 0.0, 1.0 );
50
51 /* draw front face */
52 glBegin( GL_QUAD_STRIP );
53 for (i=0;i<=teeth;i++) {
54 angle = i * 2.0*M_PI / teeth;
55 glVertex3f( r0*cos(angle), r0*sin(angle), width*0.5 );
56 glVertex3f( r1*cos(angle), r1*sin(angle), width*0.5 );
57 glVertex3f( r0*cos(angle), r0*sin(angle), width*0.5 );
58 glVertex3f( r1*cos(angle+3*da), r1*sin(angle+3*da), width*0.5 );
59 }
60 glEnd();
61
62 /* draw front sides of teeth */
63 glBegin( GL_QUADS );
64 da = 2.0*M_PI / teeth / 4.0;
65 for (i=0;i<teeth;i++) {
66 angle = i * 2.0*M_PI / teeth;
67
68 glVertex3f( r1*cos(angle), r1*sin(angle), width*0.5 );
69 glVertex3f( r2*cos(angle+da), r2*sin(angle+da), width*0.5 );
70 glVertex3f( r2*cos(angle+2*da), r2*sin(angle+2*da), width*0.5 );
71 glVertex3f( r1*cos(angle+3*da), r1*sin(angle+3*da), width*0.5 );
72 }
73 glEnd();
74
75
76 glNormal3f( 0.0, 0.0, -1.0 );
77
78 /* draw back face */
79 glBegin( GL_QUAD_STRIP );
80 for (i=0;i<=teeth;i++) {
81 angle = i * 2.0*M_PI / teeth;
82 glVertex3f( r1*cos(angle), r1*sin(angle), -width*0.5 );
83 glVertex3f( r0*cos(angle), r0*sin(angle), -width*0.5 );
84 glVertex3f( r1*cos(angle+3*da), r1*sin(angle+3*da), -width*0.5 );
85 glVertex3f( r0*cos(angle), r0*sin(angle), -width*0.5 );
86 }
87 glEnd();
88
89 /* draw back sides of teeth */
90 glBegin( GL_QUADS );
91 da = 2.0*M_PI / teeth / 4.0;
92 for (i=0;i<teeth;i++) {
93 angle = i * 2.0*M_PI / teeth;
94
95 glVertex3f( r1*cos(angle+3*da), r1*sin(angle+3*da), -width*0.5 );
96 glVertex3f( r2*cos(angle+2*da), r2*sin(angle+2*da), -width*0.5 );
97 glVertex3f( r2*cos(angle+da), r2*sin(angle+da), -width*0.5 );
98 glVertex3f( r1*cos(angle), r1*sin(angle), -width*0.5 );
99 }
100 glEnd();
101
102
103 /* draw outward faces of teeth */
104 glBegin( GL_QUAD_STRIP );
105 for (i=0;i<teeth;i++) {
106 angle = i * 2.0*M_PI / teeth;
107
108 glVertex3f( r1*cos(angle), r1*sin(angle), width*0.5 );
109 glVertex3f( r1*cos(angle), r1*sin(angle), -width*0.5 );
110 u = r2*cos(angle+da) - r1*cos(angle);
111 v = r2*sin(angle+da) - r1*sin(angle);
112 len = sqrt( u*u + v*v );
113 u /= len;
114 v /= len;
115 glNormal3f( v, -u, 0.0 );
116 glVertex3f( r2*cos(angle+da), r2*sin(angle+da), width*0.5 );
117 glVertex3f( r2*cos(angle+da), r2*sin(angle+da), -width*0.5 );
118 glNormal3f( cos(angle), sin(angle), 0.0 );
119 glVertex3f( r2*cos(angle+2*da), r2*sin(angle+2*da), width*0.5 );
120 glVertex3f( r2*cos(angle+2*da), r2*sin(angle+2*da), -width*0.5 );
121 u = r1*cos(angle+3*da) - r2*cos(angle+2*da);
122 v = r1*sin(angle+3*da) - r2*sin(angle+2*da);
123 glNormal3f( v, -u, 0.0 );
124 glVertex3f( r1*cos(angle+3*da), r1*sin(angle+3*da), width*0.5 );
125 glVertex3f( r1*cos(angle+3*da), r1*sin(angle+3*da), -width*0.5 );
126 glNormal3f( cos(angle), sin(angle), 0.0 );
127 }
128
129 glVertex3f( r1*cos(0), r1*sin(0), width*0.5 );
130 glVertex3f( r1*cos(0), r1*sin(0), -width*0.5 );
131
132 glEnd();
133
134
135 glShadeModel( GL_SMOOTH );
136
137 /* draw inside radius cylinder */
138 glBegin( GL_QUAD_STRIP );
139 for (i=0;i<=teeth;i++) {
140 angle = i * 2.0*M_PI / teeth;
141 glNormal3f( -cos(angle), -sin(angle), 0.0 );
142 glVertex3f( r0*cos(angle), r0*sin(angle), -width*0.5 );
143 glVertex3f( r0*cos(angle), r0*sin(angle), width*0.5 );
144 }
145 glEnd();
146
147}
148
149
150static GLfloat view_rotx=20.0, view_roty=30.0, view_rotz=0.0;
151static GLint gear1, gear2, gear3;
152static GLfloat angle = 0.0;
153
154static GLuint limit;
155static GLuint count = 1;
156
157
158static void draw( void )
159{
160 glClearColor(0,0,0,0);
161 glClearIndex(0);
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 glFlush();
189 glFinish();
190
191#if 0
192 ggiSetGCForeground(vis,255);
193 ggiPuts(vis,0,0,"Mesa -> GGI");
194 ggiPuts(vis,0,ggiGetInfo(vis)->mode->visible.y," Mesa -> GGI");
195
196 ggiPuts(vis,0,16,text);
197 ggiPuts(vis,0,ggiGetInfo(vis)->mode->visible.y+16,text);
198#endif
199
200 GGIMesaSwapBuffers();
201
202 count++;
203 if (count==limit) {
204 exit(1);
205 }
206}
207
208static void idle( void )
209{
210 angle += 2.0;
211 draw();
212}
213
214/* new window size or exposure */
215static void reshape( int width, int height )
216{
217 GLfloat h = (GLfloat) height / (GLfloat) width;
218
219 glViewport(0, 0, (GLint)width, (GLint)height);
220 glMatrixMode(GL_PROJECTION);
221 glLoadIdentity();
222 glFrustum( -1.0, 1.0, -h, h, 5.0, 60.0 );
223 glMatrixMode(GL_MODELVIEW);
224 glLoadIdentity();
225 glTranslatef( 0.0, 0.0, -40.0 );
226 glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
227
228}
229
230
231static void init( void )
232{
233 static GLfloat pos[4] = {5.0, 5.0, 10.0, 0.0 };
234 static GLfloat red[4] = {0.8, 0.1, 0.0, 1.0 };
235 static GLfloat green[4] = {0.0, 0.8, 0.2, 1.0 };
236 static GLfloat blue[4] = {0.2, 0.2, 1.0, 1.0 };
237
238 glLightfv( GL_LIGHT0, GL_POSITION, pos );
239 glEnable( GL_CULL_FACE );
240 glEnable( GL_LIGHTING );
241 glEnable( GL_LIGHT0 );
242 glEnable( GL_DEPTH_TEST );
243
244 /* make the gears */
245 gear1 = glGenLists(1);
246 glNewList(gear1, GL_COMPILE);
247 glMaterialfv( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red );
248 glIndexi(1);
249 gear( 1.0, 4.0, 1.0, 20, 0.7 );
250 glEndList();
251
252 gear2 = glGenLists(1);
253 glNewList(gear2, GL_COMPILE);
254 glMaterialfv( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, green );
255 glIndexi(2);
256 gear( 0.5, 2.0, 2.0, 10, 0.7 );
257 glEndList();
258
259 gear3 = glGenLists(1);
260 glNewList(gear3, GL_COMPILE);
261 glMaterialfv( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, blue );
262 glIndexi(3);
263 gear( 1.3, 2.0, 0.5, 10, 0.7 );
264 glEndList();
265
266 glEnable( GL_NORMALIZE );
267}
268
269static void usage(char *s)
270{
271 printf("%s visible_x visible_y virtual_x virtual_y bpp db_flag\n",s);
272 printf("example:\n");
273 printf("%s 320 200 320 400 8 1\n",s);
274 exit(1);
275}
276
277int main( int argc, char *argv[] )
278{
279 GGIMesaContext ctx;
280 int vis_x,vis_y,vir_x,vir_y,bpp,db_flag,gt;
281 ggi_mode mode;
282
283 limit=0;
284
285 if (argc<7) usage(argv[0]);
286
287 vis_x=atoi(argv[1]);
288 vis_y=atoi(argv[2]);
289 vir_x=atoi(argv[3]);
290 vir_y=atoi(argv[4]);
291 bpp=atoi(argv[5]);
292 db_flag=atoi(argv[6]);
293
294 switch(bpp)
295 {
296 case 4: gt=GT_4BIT;break;
297 case 8: gt=GT_8BIT;break;
298 case 15:gt=GT_15BIT;break;
299 case 16:gt=GT_16BIT;break;
300 case 24:gt=GT_24BIT;break;
301 case 32:gt=GT_32BIT;break;
302 default:
303 printf("%i Bits per Pixel ???\n",bpp);
304 exit(1);
305 }
306 sprintf(text,"%sx%s %i colors, RGB mode, %s",
307 argv[1],argv[2],1<<bpp,
308 (db_flag) ? "doublebuffer" : "no doublebuffer");
309
310 if (ggiInit()<0)
311 {
312 printf("ggiInit() failed\n");
313 exit(1);
314 }
315
316 ctx=GGIMesaCreateContext();
317 if (ctx==NULL)
318 {
319 printf("GGIMesaCreateContext() failed\n");
320 exit(1);
321 }
322
323 vis=ggiOpen(NULL);
324 if (vis==NULL)
325 {
326 printf("ggiOpen() failed\n");
327 exit(1);
328 }
329
330 if (ggiSetGraphMode(vis,vis_x,vis_y,vir_x,vir_y,gt)<0)
331 {
332 printf("%s: can't set graphmode (%i %i %i %i) %i BPP\n",
333 argv[0],vis_x,vis_y,vir_x,vir_y,bpp);
334 exit(1);
335 }
336
337 if (GGIMesaSetVisual(ctx,vis,GL_TRUE,db_flag)<0)
338 {
339 printf ("GGIMesaSetVisual() failed\n");
340 exit(1);
341 }
342
343 GGIMesaMakeCurrent(ctx);
344 ggiGetMode(vis,&mode);
345
346 reshape(mode.visible.x,mode.visible.y);
347
348 init();
349
350 while (!ggiKbhit(vis)) idle();
351
352 GGIMesaDestroyContext(ctx);
353 ggiClose(vis);
354
355 printf("%s\n",text);
356
357 ggiExit();
358 return 0;
359}