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;
38 #define M_PI 3.1415926535
41 extern void shadowmatrix(GLfloat
[4][4], GLfloat
[4], GLfloat
[4]);
42 extern void findplane(GLfloat
[4], GLfloat
[3], GLfloat
[3], GLfloat
[3]);
47 static float obs
[3]={5.0,0.0,1.0};
50 static float alpha
=-90.0;
51 static float beta
=90.0;
53 static GLfloat baseshadow
[4][4];
54 static GLfloat lightpos
[4]={2.3,0.0,3.0,1.0};
55 static GLfloat lightdir
[3]={-2.3,0.0,-3.0};
56 static GLfloat lightalpha
=0.0;
62 static int joyavailable
=0;
63 static int joyactive
=0;
65 static GLuint t1id
,t2id
;
66 static GLuint teapotdlist
,basedlist
,lightdlist
;
68 static float gettime(void)
70 static clock_t told
=0;
79 return(ris
/(float)CLOCKS_PER_SEC
);
82 static void calcposobs(void)
84 dir
[0]=sin(alpha
*M_PI
/180.0);
85 dir
[1]=cos(alpha
*M_PI
/180.0)*sin(beta
*M_PI
/180.0);
86 dir
[2]=cos(beta
*M_PI
/180.0);
93 static void special(int k
, int x
, int y
)
111 static void key(unsigned char k
, int x
, int y
)
126 joyactive
=(!joyactive
);
139 glDisable(GL_CULL_FACE
);
142 glEnable(GL_CULL_FACE
);
148 XMesaSetFXmode(fullscreen
? XMESA_FX_FULLSCREEN
: XMESA_FX_WINDOW
);
149 fullscreen
=(!fullscreen
);
155 static void reshape(int w
, int h
)
159 glMatrixMode(GL_PROJECTION
);
161 gluPerspective(45.0,w
/(float)h
,0.2,40.0);
162 glMatrixMode(GL_MODELVIEW
);
167 static void printstring(void *font
, char *string
)
171 len
=(int)strlen(string
);
173 glutBitmapCharacter(font
,string
[i
]);
176 static void printhelp(void)
179 glColor4f(0.5,0.5,0.5,0.5);
180 glRecti(40,40,600,440);
183 glColor3f(1.0,0.0,0.0);
184 glRasterPos2i(300,420);
185 printstring(GLUT_BITMAP_TIMES_ROMAN_24
,"Help");
187 glRasterPos2i(60,390);
188 printstring(GLUT_BITMAP_TIMES_ROMAN_24
,"h - Togle Help");
189 glRasterPos2i(60,360);
190 printstring(GLUT_BITMAP_TIMES_ROMAN_24
,"t - Togle Textures");
191 glRasterPos2i(60,330);
192 printstring(GLUT_BITMAP_TIMES_ROMAN_24
,"f - Togle Fog");
193 glRasterPos2i(60,300);
194 printstring(GLUT_BITMAP_TIMES_ROMAN_24
,"b - Togle Back face culling");
195 glRasterPos2i(60,270);
196 printstring(GLUT_BITMAP_TIMES_ROMAN_24
,"Arrow Keys - Rotate");
197 glRasterPos2i(60,240);
198 printstring(GLUT_BITMAP_TIMES_ROMAN_24
,"a - Increase velocity");
199 glRasterPos2i(60,210);
200 printstring(GLUT_BITMAP_TIMES_ROMAN_24
,"z - Decrease velocity");
202 glRasterPos2i(60,180);
204 printstring(GLUT_BITMAP_TIMES_ROMAN_24
,"j - Togle jostick control (Joystick control available)");
206 printstring(GLUT_BITMAP_TIMES_ROMAN_24
,"(No Joystick control available)");
209 static void drawbase(void)
214 glBindTexture(GL_TEXTURE_2D
,t1id
);
217 dy
=-BASESIZE
/BASERES
;
218 for(y
=BASESIZE
/2.0,j
=0;j
<BASERES
;y
+=dy
,j
++) {
219 glBegin(GL_QUAD_STRIP
);
220 glColor3f(1.0,1.0,1.0);
221 glNormal3f(0.0,0.0,1.0);
222 for(x
=-BASESIZE
/2.0,i
=0;i
<BASERES
;x
+=dx
,i
++) {
226 glTexCoord2f(x
,y
+dy
);
227 glVertex3f(x
,y
+dy
,0.0);
233 static void drawteapot(void)
235 static float xrot
=0.0;
236 static float zrot
=0.0;
239 glRotatef(lightalpha
,0.0,0.0,1.0);
240 glMultMatrixf((GLfloat
*)baseshadow
);
241 glRotatef(-lightalpha
,0.0,0.0,1.0);
243 glTranslatef(0.0,0.0,1.0);
244 glRotatef(xrot
,1.0,0.0,0.0);
245 glRotatef(zrot
,0.0,0.0,1.0);
247 glDisable(GL_TEXTURE_2D
);
248 glDisable(GL_DEPTH_TEST
);
249 glDisable(GL_LIGHTING
);
251 glColor3f(0.0,0.0,0.0);
252 glCallList(teapotdlist
);
254 glEnable(GL_DEPTH_TEST
);
255 glEnable(GL_LIGHTING
);
257 glEnable(GL_TEXTURE_2D
);
262 glTranslatef(0.0,0.0,1.0);
263 glRotatef(xrot
,1.0,0.0,0.0);
264 glRotatef(zrot
,0.0,0.0,1.0);
266 glCallList(teapotdlist
);
273 static void drawlight1(void)
276 glRotatef(lightalpha
,0.0,0.0,1.0);
277 glLightfv(GL_LIGHT0
,GL_POSITION
,lightpos
);
278 glLightfv(GL_LIGHT0
,GL_SPOT_DIRECTION
,lightdir
);
283 static void drawlight2(void)
286 glRotatef(lightalpha
,0.0,0.0,1.0);
287 glTranslatef(lightpos
[0],lightpos
[1],lightpos
[2]);
289 glDisable(GL_TEXTURE_2D
);
290 glCallList(lightdlist
);
292 glEnable(GL_TEXTURE_2D
);
299 static void dojoy(void)
302 static UINT max
[2]={0,0};
303 static UINT min
[2]={0xffffffff,0xffffffff},center
[2];
307 res
=joyGetPos(JOYSTICKID1
,&joy
);
309 if(res
==JOYERR_NOERROR
) {
316 center
[0]=(max
[0]+min
[0])/2;
322 center
[1]=(max
[1]+min
[1])/2;
325 if(fabs(center
[0]-(float)joy
.wXpos
)>0.1*(max
[0]-min
[0]))
326 alpha
-=2.5*(center
[0]-(float)joy
.wXpos
)/(max
[0]-min
[0]);
327 if(fabs(center
[1]-(float)joy
.wYpos
)>0.1*(max
[1]-min
[1]))
328 beta
+=2.5*(center
[1]-(float)joy
.wYpos
)/(max
[1]-min
[1]);
330 if(joy
.wButtons
& JOY_BUTTON1
)
332 if(joy
.wButtons
& JOY_BUTTON2
)
340 static void draw(void)
343 static char frbuf
[80];
348 glEnable(GL_DEPTH_TEST
);
349 glClear(GL_COLOR_BUFFER_BIT
|GL_DEPTH_BUFFER_BIT
);
352 glEnable(GL_TEXTURE_2D
);
354 glDisable(GL_TEXTURE_2D
);
361 glEnable(GL_LIGHTING
);
363 glShadeModel(GL_SMOOTH
);
368 gluLookAt(obs
[0],obs
[1],obs
[2],
369 obs
[0]+dir
[0],obs
[1]+dir
[1],obs
[2]+dir
[2],
373 glCallList(basedlist
);
378 if((count
% FRAME
)==0) {
380 sprintf(frbuf
,"Frame rate: %f",FRAME
/fr
);
383 glDisable(GL_LIGHTING
);
384 glDisable(GL_TEXTURE_2D
);
385 glDisable(GL_DEPTH_TEST
);
387 glShadeModel(GL_FLAT
);
389 glMatrixMode(GL_PROJECTION
);
391 glOrtho(-0.5,639.5,-0.5,479.5,-1.0,1.0);
392 glMatrixMode(GL_MODELVIEW
);
395 glColor3f(1.0,0.0,0.0);
396 glRasterPos2i(10,10);
397 printstring(GLUT_BITMAP_HELVETICA_18
,frbuf
);
398 glRasterPos2i(350,470);
399 printstring(GLUT_BITMAP_HELVETICA_10
,"Teapot V1.2 Written by David Bucciarelli (tech.hmw@plus.it)");
404 reshape(WIDTH
,HEIGHT
);
411 static void inittextures(void)
413 glGenTextures(1,&t1id
);
414 glBindTexture(GL_TEXTURE_2D
,t1id
);
416 glPixelStorei(GL_UNPACK_ALIGNMENT
,4);
417 if (!LoadRGBMipmaps("../images/tile.rgb", GL_RGB
)) {
418 fprintf(stderr
,"Error reading a texture.\n");
422 glTexParameterf(GL_TEXTURE_2D
,GL_TEXTURE_WRAP_S
,GL_REPEAT
);
423 glTexParameterf(GL_TEXTURE_2D
,GL_TEXTURE_WRAP_T
,GL_REPEAT
);
425 glTexParameterf(GL_TEXTURE_2D
,GL_TEXTURE_MIN_FILTER
,GL_LINEAR_MIPMAP_LINEAR
);
426 glTexParameterf(GL_TEXTURE_2D
,GL_TEXTURE_MAG_FILTER
,GL_LINEAR
);
428 glTexEnvf(GL_TEXTURE_ENV
,GL_TEXTURE_ENV_MODE
,GL_MODULATE
);
430 glGenTextures(1,&t2id
);
431 glBindTexture(GL_TEXTURE_2D
,t2id
);
433 if (!LoadRGBMipmaps("../images/bw.rgb", GL_RGB
)) {
434 fprintf(stderr
,"Error reading a texture.\n");
438 glTexParameterf(GL_TEXTURE_2D
,GL_TEXTURE_WRAP_S
,GL_REPEAT
);
439 glTexParameterf(GL_TEXTURE_2D
,GL_TEXTURE_WRAP_T
,GL_REPEAT
);
441 glTexParameterf(GL_TEXTURE_2D
,GL_TEXTURE_MIN_FILTER
,GL_LINEAR_MIPMAP_LINEAR
);
442 glTexParameterf(GL_TEXTURE_2D
,GL_TEXTURE_MAG_FILTER
,GL_LINEAR
);
444 glTexEnvf(GL_TEXTURE_ENV
,GL_TEXTURE_ENV_MODE
,GL_MODULATE
);
447 static void initlight(void)
449 float lamb
[4]={0.2,0.2,0.2,1.0};
450 float lspec
[4]={1.0,1.0,1.0,1.0};
452 glLightf(GL_LIGHT0
,GL_SPOT_CUTOFF
,70.0);
453 glLightf(GL_LIGHT0
,GL_SPOT_EXPONENT
,20.0);
454 glLightfv(GL_LIGHT0
,GL_AMBIENT
,lamb
);
455 glLightfv(GL_LIGHT0
,GL_SPECULAR
,lspec
);
457 glMaterialf(GL_FRONT_AND_BACK
,GL_SHININESS
,20.0);
458 glMaterialfv(GL_FRONT_AND_BACK
,GL_SPECULAR
,lspec
);
463 static void initdlists(void)
465 GLUquadricObj
*lcone
,*lbase
;
467 GLfloat v0
[3]={0.0,0.0,0.0};
468 GLfloat v1
[3]={1.0,0.0,0.0};
469 GLfloat v2
[3]={0.0,1.0,0.0};
471 findplane(plane
,v0
,v1
,v2
);
472 shadowmatrix(baseshadow
,plane
,lightpos
);
474 teapotdlist
=glGenLists(1);
475 glNewList(teapotdlist
,GL_COMPILE
);
476 glRotatef(90.0,1.0,0.0,0.0);
477 glCullFace(GL_FRONT
);
478 glBindTexture(GL_TEXTURE_2D
,t2id
);
479 glutSolidTeapot(0.75);
483 basedlist
=glGenLists(1);
484 glNewList(basedlist
,GL_COMPILE
);
488 lightdlist
=glGenLists(1);
489 glNewList(lightdlist
,GL_COMPILE
);
490 glDisable(GL_LIGHTING
);
492 lcone
=gluNewQuadric();
493 lbase
=gluNewQuadric();
494 glRotatef(45.0,0.0,1.0,0.0);
496 glColor3f(1.0,1.0,1.0);
497 glCullFace(GL_FRONT
);
498 gluDisk(lbase
,0.0,0.2,12.0,1.0);
501 glColor3f(0.5,0.0,0.0);
502 gluCylinder(lcone
,0.2,0.0,0.5,12,1);
504 gluDeleteQuadric(lcone
);
505 gluDeleteQuadric(lbase
);
507 glEnable(GL_LIGHTING
);
511 int main(int ac
, char **av
)
513 float fogcolor
[4]={0.025,0.025,0.025,1.0};
515 fprintf(stderr
,"Teapot V1.2\nWritten by David Bucciarelli (tech.hmw@plus.it)\n");
518 if(!SetPriorityClass(GetCurrentProcess(),REALTIME_PRIORITY_CLASS)) {
519 fprintf(stderr,"Error setting the process class.\n");
523 if(!SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_TIME_CRITICAL)) {
524 fprintf(stderr,"Error setting the process priority.\n");
529 glutInitWindowPosition(0,0);
530 glutInitWindowSize(WIDTH
,HEIGHT
);
533 glutInitDisplayMode(GLUT_RGB
|GLUT_DEPTH
|GLUT_DOUBLE
);
535 if(!(win
=glutCreateWindow("Teapot"))) {
536 fprintf(stderr
,"Error, couldn't open window\n");
540 reshape(WIDTH
,HEIGHT
);
542 glShadeModel(GL_SMOOTH
);
543 glEnable(GL_DEPTH_TEST
);
544 glEnable(GL_CULL_FACE
);
545 glEnable(GL_TEXTURE_2D
);
548 glFogi(GL_FOG_MODE
,GL_EXP2
);
549 glFogfv(GL_FOG_COLOR
,fogcolor
);
551 glFogf(GL_FOG_DENSITY
,0.04);
552 glHint(GL_FOG_HINT
,GL_NICEST
);
553 glBlendFunc(GL_SRC_ALPHA
,GL_ONE_MINUS_SRC_ALPHA
);
562 glClearColor(fogcolor
[0],fogcolor
[1],fogcolor
[2],fogcolor
[3]);
564 glutReshapeFunc(reshape
);
565 glutDisplayFunc(draw
);
566 glutKeyboardFunc(key
);
567 glutSpecialFunc(special
);