Fix for bug 618459. Mods to allow compilation on VC++ 5.0 (Michael Krause)
[mesa.git] / progs / ggi / gears2.c
1 /* 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
20 ggi_visual_t vis;
21 char text[100];
22 int db_flag,vis_x, vis_y, vir_x, vir_y, gt;
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 static void draw( void )
160 {
161 static int n = 0;
162 glClearColor(0,0,0,0);
163 glClearIndex(0);
164 glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
165
166 glPushMatrix();
167 glRotatef( view_rotx, 1.0, 0.0, 0.0 );
168 glRotatef( view_roty, 0.0, 1.0, 0.0 );
169 glRotatef( view_rotz, 0.0, 0.0, 1.0 );
170
171 glPushMatrix();
172 glTranslatef( -3.0, -2.0, 0.0 );
173 glRotatef( angle, 0.0, 0.0, 1.0 );
174 glCallList(gear1);
175 glPopMatrix();
176
177 glPushMatrix();
178 glTranslatef( 3.1, -2.0, 0.0 );
179 glRotatef( -2.0*angle-9.0, 0.0, 0.0, 1.0 );
180 glCallList(gear2);
181 glPopMatrix();
182
183 glPushMatrix();
184 glTranslatef( -3.1, 4.2, 0.0 );
185 glRotatef( -2.0*angle-25.0, 0.0, 0.0, 1.0 );
186 glCallList(gear3);
187 glPopMatrix();
188
189 glPopMatrix();
190 glFlush();
191 glFinish();
192
193 #if 0
194 ggiSetGCForeground(vis,255);
195 ggiPuts(vis,0,0,"Mesa -> GGI");
196 ggiPuts(vis,0,ggiGetInfo(vis)->mode->visible.y," Mesa -> GGI");
197
198 ggiPuts(vis,0,16,text);
199 ggiPuts(vis,0,ggiGetInfo(vis)->mode->visible.y+16,text);
200 #endif
201
202 if(db_flag)
203 ggiMesaSwapBuffers();
204
205 count++;
206 if (count==limit) {
207 exit(1);
208 }
209 ++n;
210 /*
211 if (!(n%10)){
212 ggi_color rgb = { 10000, 10000, 10000 };
213 ggiSetSimpleMode(vis,vis_x+(n/10),vis_y+(n/10),db_flag?2:1, gt);
214 glViewport(0, 0,vis_x+(n/10),vis_y+(n/10));
215 ggiSetGCForeground(vis, ggiMapColor(vis, &rgb));
216 ggiDrawBox(vis, 20, 20, 100, 100);
217 if(db_flag)
218 ggiSetWriteFrame(vis, 1);
219 }
220 */
221 }
222
223 static void idle( void )
224 {
225 angle += 2.0;
226 draw();
227 }
228
229 /* new window size or exposure */
230 static void reshape( int width, int height )
231 {
232 GLfloat h = (GLfloat) height / (GLfloat) width;
233
234 if(db_flag)
235 glDrawBuffer(GL_BACK);
236 else
237 glDrawBuffer(GL_FRONT);
238 glViewport(0, 0, (GLint)width, (GLint)height);
239 glMatrixMode(GL_PROJECTION);
240 glLoadIdentity();
241 glFrustum( -1.0, 1.0, -h, h, 5.0, 60.0 );
242 glMatrixMode(GL_MODELVIEW);
243 glLoadIdentity();
244 glTranslatef( 0.0, 0.0, -40.0 );
245 glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
246
247 }
248
249
250 static void init( void )
251 {
252 static GLfloat pos[4] = {5.0, 5.0, 10.0, 0.0 };
253 static GLfloat red[4] = {0.9, 0.9, 0.9, 1.0 };
254 static GLfloat green[4] = {0.0, 0.8, 0.9, 1.0 };
255 static GLfloat blue[4] = {0.2, 0.2, 1.0, 1.0 };
256
257 glLightfv( GL_LIGHT0, GL_POSITION, pos );
258 glEnable( GL_CULL_FACE );
259 glEnable( GL_LIGHTING );
260 glEnable( GL_LIGHT0 );
261 glEnable( GL_DEPTH_TEST );
262
263 /* make the gears */
264 gear1 = glGenLists(1);
265 glNewList(gear1, GL_COMPILE);
266 glMaterialfv( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red );
267 glIndexi(1);
268 gear( 1.0, 4.0, 1.0, 20, 0.7 );
269 glEndList();
270
271 gear2 = glGenLists(1);
272 glNewList(gear2, GL_COMPILE);
273 glMaterialfv( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, green );
274 glIndexi(2);
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 glIndexi(3);
282 gear( 1.3, 2.0, 0.5, 10, 0.7 );
283 glEndList();
284
285 glEnable( GL_NORMALIZE );
286 }
287
288 static void usage(char *s)
289 {
290 printf("%s visible_x visible_y virtual_x virtual_y bpp db_flag\n",s);
291 printf("example:\n");
292 printf("%s 320 200 320 400 8 1\n",s);
293 exit(1);
294 }
295
296 int main( int argc, char *argv[] )
297 {
298 ggi_mesa_context_t ctx;
299 ggi_mode mode;
300 int bpp;
301
302 limit=0;
303
304 if (argc<7) usage(argv[0]);
305
306 vis_x=atoi(argv[1]);
307 vis_y=atoi(argv[2]);
308 vir_x=atoi(argv[3]);
309 vir_y=atoi(argv[4]);
310 bpp=atoi(argv[5]);
311 db_flag=atoi(argv[6]);
312
313 switch(bpp)
314 {
315 case 4: gt=GT_4BIT;break;
316 case 8: gt=GT_8BIT;break;
317 case 15:gt=GT_15BIT;break;
318 case 16:gt=GT_16BIT;break;
319 case 24:gt=GT_24BIT;break;
320 case 32:gt=GT_32BIT;break;
321 default:
322 printf("%i Bits per Pixel ???\n",bpp);
323 exit(1);
324 }
325 sprintf(text,"%sx%s %i colors, RGB mode, %s",
326 argv[1],argv[2],1<<bpp,
327 (db_flag) ? "doublebuffer" : "no doublebuffer");
328
329 if (ggiInit()<0)
330 {
331 printf("ggiInit() failed\n");
332 exit(1);
333 }
334
335 if (ggiMesaInit() < 0)
336 {
337 printf("ggiMesaInit failed\n");
338 exit(1);
339 }
340
341 vis=ggiOpen(NULL);
342 if (vis==NULL)
343 {
344 printf("ggiOpen() failed\n");
345 exit(1);
346 }
347
348 if (ggiSetSimpleMode(vis,vis_x,vis_y,db_flag ? 2 : 1,gt)<0)
349 {
350 printf("%s: can't set graphmode (%i %i %i %i) %i BPP\n",
351 argv[0],vis_x,vis_y,vir_x,vir_y,bpp);
352 exit(1);
353 }
354
355 if (ggiMesaAttach(vis) < 0)
356 {
357 printf("ggiMesaAttach failed\n");
358 exit(1);
359 }
360 if (ggiMesaExtendVisual(vis, GL_FALSE, GL_FALSE, 16,
361 0, 0, 0, 0, 0, 1) < 0)
362 {
363 printf ("GGIMesaSetVisual() failed\n");
364 exit(1);
365 }
366
367 ctx = ggiMesaCreateContext(vis);
368 if (ctx==NULL)
369 {
370 printf("GGIMesaCreateContext() failed\n");
371 exit(1);
372 }
373
374 ggiMesaMakeCurrent(ctx, vis);
375 ggiGetMode(vis,&mode);
376
377 reshape(mode.visible.x,mode.visible.y);
378
379 init();
380
381 while (!ggiKbhit(vis)) { /*sleep(1);*/ idle(); }
382
383 ggiMesaDestroyContext(ctx);
384 ggiClose(vis);
385
386 printf("%s\n",text);
387
388 ggiExit();
389 return 0;
390 }