2 * This program is under the GNU GPL.
3 * Use at your own risk.
5 * written by David Bucciarelli (tech.hmw@plus.it)
19 #include "../util/readtex.c"
24 static int fullscreen
=1;
28 static int HEIGHT
=480;
31 static GLint Frames
= 0;
39 #define M_PI 3.1415926535
42 extern void shadowmatrix(GLfloat
[4][4], GLfloat
[4], GLfloat
[4]);
43 extern void findplane(GLfloat
[4], GLfloat
[3], GLfloat
[3], GLfloat
[3]);
48 static float obs
[3]={5.0,0.0,1.0};
51 static float alpha
=-90.0;
52 static float beta
=90.0;
54 static GLfloat baseshadow
[4][4];
55 static GLfloat lightpos
[4]={2.3,0.0,3.0,1.0};
56 static GLfloat lightdir
[3]={-2.3,0.0,-3.0};
57 static GLfloat lightalpha
=0.0;
63 static int joyavailable
=0;
64 static int joyactive
=0;
66 static GLuint t1id
,t2id
;
67 static GLuint teapotdlist
,basedlist
,lightdlist
;
69 static void calcposobs(void)
71 dir
[0]=sin(alpha
*M_PI
/180.0);
72 dir
[1]=cos(alpha
*M_PI
/180.0)*sin(beta
*M_PI
/180.0);
73 dir
[2]=cos(beta
*M_PI
/180.0);
80 static void special(int k
, int x
, int y
)
98 static void key(unsigned char k
, int x
, int y
)
113 joyactive
=(!joyactive
);
126 glDisable(GL_CULL_FACE
);
129 glEnable(GL_CULL_FACE
);
135 XMesaSetFXmode(fullscreen
? XMESA_FX_FULLSCREEN
: XMESA_FX_WINDOW
);
136 fullscreen
=(!fullscreen
);
142 static void reshape(int w
, int h
)
146 glMatrixMode(GL_PROJECTION
);
148 gluPerspective(45.0,w
/(float)h
,0.2,40.0);
149 glMatrixMode(GL_MODELVIEW
);
154 static void printstring(void *font
, char *string
)
158 len
=(int)strlen(string
);
160 glutBitmapCharacter(font
,string
[i
]);
163 static void printhelp(void)
166 glColor4f(0.5,0.5,0.5,0.5);
167 glRecti(40,40,600,440);
170 glColor3f(1.0,0.0,0.0);
171 glRasterPos2i(300,420);
172 printstring(GLUT_BITMAP_TIMES_ROMAN_24
,"Help");
174 glRasterPos2i(60,390);
175 printstring(GLUT_BITMAP_TIMES_ROMAN_24
,"h - Togle Help");
176 glRasterPos2i(60,360);
177 printstring(GLUT_BITMAP_TIMES_ROMAN_24
,"t - Togle Textures");
178 glRasterPos2i(60,330);
179 printstring(GLUT_BITMAP_TIMES_ROMAN_24
,"f - Togle Fog");
180 glRasterPos2i(60,300);
181 printstring(GLUT_BITMAP_TIMES_ROMAN_24
,"b - Togle Back face culling");
182 glRasterPos2i(60,270);
183 printstring(GLUT_BITMAP_TIMES_ROMAN_24
,"Arrow Keys - Rotate");
184 glRasterPos2i(60,240);
185 printstring(GLUT_BITMAP_TIMES_ROMAN_24
,"a - Increase velocity");
186 glRasterPos2i(60,210);
187 printstring(GLUT_BITMAP_TIMES_ROMAN_24
,"z - Decrease velocity");
189 glRasterPos2i(60,180);
191 printstring(GLUT_BITMAP_TIMES_ROMAN_24
,"j - Togle jostick control (Joystick control available)");
193 printstring(GLUT_BITMAP_TIMES_ROMAN_24
,"(No Joystick control available)");
196 static void drawbase(void)
201 glBindTexture(GL_TEXTURE_2D
,t1id
);
204 dy
=-BASESIZE
/BASERES
;
205 for(y
=BASESIZE
/2.0,j
=0;j
<BASERES
;y
+=dy
,j
++) {
206 glBegin(GL_QUAD_STRIP
);
207 glColor3f(1.0,1.0,1.0);
208 glNormal3f(0.0,0.0,1.0);
209 for(x
=-BASESIZE
/2.0,i
=0;i
<BASERES
;x
+=dx
,i
++) {
213 glTexCoord2f(x
,y
+dy
);
214 glVertex3f(x
,y
+dy
,0.0);
220 static void drawteapot(void)
222 static float xrot
=0.0;
223 static float zrot
=0.0;
226 glRotatef(lightalpha
,0.0,0.0,1.0);
227 glMultMatrixf((GLfloat
*)baseshadow
);
228 glRotatef(-lightalpha
,0.0,0.0,1.0);
230 glTranslatef(0.0,0.0,1.0);
231 glRotatef(xrot
,1.0,0.0,0.0);
232 glRotatef(zrot
,0.0,0.0,1.0);
234 glDisable(GL_TEXTURE_2D
);
235 glDisable(GL_DEPTH_TEST
);
236 glDisable(GL_LIGHTING
);
238 glColor3f(0.0,0.0,0.0);
239 glCallList(teapotdlist
);
241 glEnable(GL_DEPTH_TEST
);
242 glEnable(GL_LIGHTING
);
244 glEnable(GL_TEXTURE_2D
);
249 glTranslatef(0.0,0.0,1.0);
250 glRotatef(xrot
,1.0,0.0,0.0);
251 glRotatef(zrot
,0.0,0.0,1.0);
253 glCallList(teapotdlist
);
260 static void drawlight1(void)
263 glRotatef(lightalpha
,0.0,0.0,1.0);
264 glLightfv(GL_LIGHT0
,GL_POSITION
,lightpos
);
265 glLightfv(GL_LIGHT0
,GL_SPOT_DIRECTION
,lightdir
);
270 static void drawlight2(void)
273 glRotatef(lightalpha
,0.0,0.0,1.0);
274 glTranslatef(lightpos
[0],lightpos
[1],lightpos
[2]);
276 glDisable(GL_TEXTURE_2D
);
277 glCallList(lightdlist
);
279 glEnable(GL_TEXTURE_2D
);
286 static void dojoy(void)
289 static UINT max
[2]={0,0};
290 static UINT min
[2]={0xffffffff,0xffffffff},center
[2];
294 res
=joyGetPos(JOYSTICKID1
,&joy
);
296 if(res
==JOYERR_NOERROR
) {
303 center
[0]=(max
[0]+min
[0])/2;
309 center
[1]=(max
[1]+min
[1])/2;
312 if(fabs(center
[0]-(float)joy
.wXpos
)>0.1*(max
[0]-min
[0]))
313 alpha
-=2.5*(center
[0]-(float)joy
.wXpos
)/(max
[0]-min
[0]);
314 if(fabs(center
[1]-(float)joy
.wYpos
)>0.1*(max
[1]-min
[1]))
315 beta
+=2.5*(center
[1]-(float)joy
.wYpos
)/(max
[1]-min
[1]);
317 if(joy
.wButtons
& JOY_BUTTON1
)
319 if(joy
.wButtons
& JOY_BUTTON2
)
327 static void draw(void)
329 static char frbuf
[80] = "";
333 glEnable(GL_DEPTH_TEST
);
334 glClear(GL_COLOR_BUFFER_BIT
|GL_DEPTH_BUFFER_BIT
);
337 glEnable(GL_TEXTURE_2D
);
339 glDisable(GL_TEXTURE_2D
);
346 glEnable(GL_LIGHTING
);
348 glShadeModel(GL_SMOOTH
);
353 gluLookAt(obs
[0],obs
[1],obs
[2],
354 obs
[0]+dir
[0],obs
[1]+dir
[1],obs
[2]+dir
[2],
358 glCallList(basedlist
);
363 glDisable(GL_LIGHTING
);
364 glDisable(GL_TEXTURE_2D
);
365 glDisable(GL_DEPTH_TEST
);
367 glShadeModel(GL_FLAT
);
369 glMatrixMode(GL_PROJECTION
);
371 glOrtho(-0.5,639.5,-0.5,479.5,-1.0,1.0);
372 glMatrixMode(GL_MODELVIEW
);
375 glColor3f(1.0,0.0,0.0);
376 glRasterPos2i(10,10);
377 printstring(GLUT_BITMAP_HELVETICA_18
,frbuf
);
378 glRasterPos2i(350,470);
379 printstring(GLUT_BITMAP_HELVETICA_10
,"Teapot V1.2 Written by David Bucciarelli (tech.hmw@plus.it)");
384 reshape(WIDTH
,HEIGHT
);
391 GLint t
= glutGet(GLUT_ELAPSED_TIME
);
392 if (t
- T0
>= 2000) {
393 GLfloat seconds
= (t
- T0
) / 1000.0;
394 GLfloat fps
= Frames
/ seconds
;
395 sprintf(frbuf
, "Frame rate: %f", fps
);
402 static void inittextures(void)
404 glGenTextures(1,&t1id
);
405 glBindTexture(GL_TEXTURE_2D
,t1id
);
407 glPixelStorei(GL_UNPACK_ALIGNMENT
,4);
408 if (!LoadRGBMipmaps("../images/tile.rgb", GL_RGB
)) {
409 fprintf(stderr
,"Error reading a texture.\n");
413 glTexParameterf(GL_TEXTURE_2D
,GL_TEXTURE_WRAP_S
,GL_REPEAT
);
414 glTexParameterf(GL_TEXTURE_2D
,GL_TEXTURE_WRAP_T
,GL_REPEAT
);
416 glTexParameterf(GL_TEXTURE_2D
,GL_TEXTURE_MIN_FILTER
,GL_LINEAR_MIPMAP_LINEAR
);
417 glTexParameterf(GL_TEXTURE_2D
,GL_TEXTURE_MAG_FILTER
,GL_LINEAR
);
419 glTexEnvf(GL_TEXTURE_ENV
,GL_TEXTURE_ENV_MODE
,GL_MODULATE
);
421 glGenTextures(1,&t2id
);
422 glBindTexture(GL_TEXTURE_2D
,t2id
);
424 if (!LoadRGBMipmaps("../images/bw.rgb", GL_RGB
)) {
425 fprintf(stderr
,"Error reading a texture.\n");
429 glTexParameterf(GL_TEXTURE_2D
,GL_TEXTURE_WRAP_S
,GL_REPEAT
);
430 glTexParameterf(GL_TEXTURE_2D
,GL_TEXTURE_WRAP_T
,GL_REPEAT
);
432 glTexParameterf(GL_TEXTURE_2D
,GL_TEXTURE_MIN_FILTER
,GL_LINEAR_MIPMAP_LINEAR
);
433 glTexParameterf(GL_TEXTURE_2D
,GL_TEXTURE_MAG_FILTER
,GL_LINEAR
);
435 glTexEnvf(GL_TEXTURE_ENV
,GL_TEXTURE_ENV_MODE
,GL_MODULATE
);
438 static void initlight(void)
440 float lamb
[4]={0.2,0.2,0.2,1.0};
441 float lspec
[4]={1.0,1.0,1.0,1.0};
443 glLightf(GL_LIGHT0
,GL_SPOT_CUTOFF
,70.0);
444 glLightf(GL_LIGHT0
,GL_SPOT_EXPONENT
,20.0);
445 glLightfv(GL_LIGHT0
,GL_AMBIENT
,lamb
);
446 glLightfv(GL_LIGHT0
,GL_SPECULAR
,lspec
);
448 glMaterialf(GL_FRONT_AND_BACK
,GL_SHININESS
,20.0);
449 glMaterialfv(GL_FRONT_AND_BACK
,GL_SPECULAR
,lspec
);
454 static void initdlists(void)
456 GLUquadricObj
*lcone
,*lbase
;
458 GLfloat v0
[3]={0.0,0.0,0.0};
459 GLfloat v1
[3]={1.0,0.0,0.0};
460 GLfloat v2
[3]={0.0,1.0,0.0};
462 findplane(plane
,v0
,v1
,v2
);
463 shadowmatrix(baseshadow
,plane
,lightpos
);
465 teapotdlist
=glGenLists(1);
466 glNewList(teapotdlist
,GL_COMPILE
);
467 glRotatef(90.0,1.0,0.0,0.0);
468 glCullFace(GL_FRONT
);
469 glBindTexture(GL_TEXTURE_2D
,t2id
);
470 glutSolidTeapot(0.75);
474 basedlist
=glGenLists(1);
475 glNewList(basedlist
,GL_COMPILE
);
479 lightdlist
=glGenLists(1);
480 glNewList(lightdlist
,GL_COMPILE
);
481 glDisable(GL_LIGHTING
);
483 lcone
=gluNewQuadric();
484 lbase
=gluNewQuadric();
485 glRotatef(45.0,0.0,1.0,0.0);
487 glColor3f(1.0,1.0,1.0);
488 glCullFace(GL_FRONT
);
489 gluDisk(lbase
,0.0,0.2,12.0,1.0);
492 glColor3f(0.5,0.0,0.0);
493 gluCylinder(lcone
,0.2,0.0,0.5,12,1);
495 gluDeleteQuadric(lcone
);
496 gluDeleteQuadric(lbase
);
498 glEnable(GL_LIGHTING
);
502 int main(int ac
, char **av
)
504 float fogcolor
[4]={0.025,0.025,0.025,1.0};
506 fprintf(stderr
,"Teapot V1.2\nWritten by David Bucciarelli (tech.hmw@plus.it)\n");
509 if(!SetPriorityClass(GetCurrentProcess(),REALTIME_PRIORITY_CLASS)) {
510 fprintf(stderr,"Error setting the process class.\n");
514 if(!SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_TIME_CRITICAL)) {
515 fprintf(stderr,"Error setting the process priority.\n");
520 glutInitWindowPosition(0,0);
521 glutInitWindowSize(WIDTH
,HEIGHT
);
524 glutInitDisplayMode(GLUT_RGB
|GLUT_DEPTH
|GLUT_DOUBLE
);
526 if(!(win
=glutCreateWindow("Teapot"))) {
527 fprintf(stderr
,"Error, couldn't open window\n");
531 reshape(WIDTH
,HEIGHT
);
533 glShadeModel(GL_SMOOTH
);
534 glEnable(GL_DEPTH_TEST
);
535 glEnable(GL_CULL_FACE
);
536 glEnable(GL_TEXTURE_2D
);
539 glFogi(GL_FOG_MODE
,GL_EXP2
);
540 glFogfv(GL_FOG_COLOR
,fogcolor
);
542 glFogf(GL_FOG_DENSITY
,0.04);
543 glHint(GL_FOG_HINT
,GL_NICEST
);
544 glBlendFunc(GL_SRC_ALPHA
,GL_ONE_MINUS_SRC_ALPHA
);
553 glClearColor(fogcolor
[0],fogcolor
[1],fogcolor
[2],fogcolor
[3]);
555 glutReshapeFunc(reshape
);
556 glutDisplayFunc(draw
);
557 glutKeyboardFunc(key
);
558 glutSpecialFunc(special
);