132001f49Smrg/* 232001f49Smrg * This program is under the GNU GPL. 332001f49Smrg * Use at your own risk. 432001f49Smrg * 532001f49Smrg * written by David Bucciarelli (tech.hmw@plus.it) 632001f49Smrg * Humanware s.r.l. 732001f49Smrg */ 832001f49Smrg 932001f49Smrg#include <stdio.h> 1032001f49Smrg#include <stdlib.h> 1132001f49Smrg#include <math.h> 1232001f49Smrg#include <time.h> 1332001f49Smrg#include <string.h> 1432001f49Smrg 1532001f49Smrg#ifdef WIN32 1632001f49Smrg#include <windows.h> 1732001f49Smrg#endif 1832001f49Smrg 1932001f49Smrg#include "glut_wrap.h" 2032001f49Smrg#include "readtex.h" 2132001f49Smrg 2232001f49Smrg#ifdef XMESA 2332001f49Smrg#include "GL/xmesa.h" 2432001f49Smrgstatic int fullscreen=1; 2532001f49Smrg#endif 2632001f49Smrg 2732001f49Smrgstatic int WIDTH=640; 2832001f49Smrgstatic int HEIGHT=480; 2932001f49Smrg 3032001f49Smrgstatic GLint T0 = 0; 3132001f49Smrgstatic GLint Frames = 0; 3232001f49Smrg 3332001f49Smrg#define BASESIZE 10.0 3432001f49Smrg 3532001f49Smrg#define BASERES 12 3632001f49Smrg#define TEAPOTRES 3 3732001f49Smrg 3832001f49Smrg#ifndef M_PI 3932001f49Smrg#define M_PI 3.1415926535 4032001f49Smrg#endif 4132001f49Smrg 4232001f49Smrgextern void shadowmatrix(GLfloat [4][4], GLfloat [4], GLfloat [4]); 4332001f49Smrgextern void findplane(GLfloat [4], GLfloat [3], GLfloat [3], GLfloat [3]); 4432001f49Smrg 4532001f49Smrg 4632001f49Smrgstatic int win=0; 4732001f49Smrg 4832001f49Smrgstatic float obs[3]={5.0,0.0,1.0}; 4932001f49Smrgstatic float dir[3]; 5032001f49Smrgstatic float v=0.0; 5132001f49Smrgstatic float alpha=-90.0; 5232001f49Smrgstatic float beta=90.0; 5332001f49Smrg 5432001f49Smrgstatic GLfloat baseshadow[4][4]; 5532001f49Smrgstatic GLfloat lightpos[4]={2.3,0.0,3.0,1.0}; 5632001f49Smrgstatic GLfloat lightdir[3]={-2.3,0.0,-3.0}; 5732001f49Smrgstatic GLfloat lightalpha=0.0; 5832001f49Smrg 5932001f49Smrgstatic int fog=1; 6032001f49Smrgstatic int bfcull=1; 6132001f49Smrgstatic int usetex=1; 6232001f49Smrgstatic int help=1; 6332001f49Smrgstatic int joyavailable=0; 6432001f49Smrgstatic int joyactive=0; 6532001f49Smrg 6632001f49Smrgstatic GLuint t1id,t2id; 6732001f49Smrgstatic GLuint teapotdlist,basedlist,lightdlist; 6832001f49Smrg 6932001f49Smrg 7032001f49Smrg 7132001f49Smrg/******************** begin shadow code ********************/ 7232001f49Smrg 7332001f49Smrg/* Taken from the projshadow.c - by Tom McReynolds, SGI */ 7432001f49Smrg 7532001f49Smrg/* Modified by David Bucciarelli */ 7632001f49Smrg 7732001f49Smrgenum { 7832001f49Smrg X, Y, Z, W 7932001f49Smrg}; 8032001f49Smrgenum { 8132001f49Smrg A, B, C, D 8232001f49Smrg}; 8332001f49Smrg 8432001f49Smrg/* create a matrix that will project the desired shadow */ 8532001f49Smrgvoid 8632001f49Smrgshadowmatrix(GLfloat shadowMat[4][4], 8732001f49Smrg GLfloat groundplane[4], 8832001f49Smrg GLfloat lightpos[4]) 8932001f49Smrg{ 9032001f49Smrg GLfloat dot; 9132001f49Smrg 9232001f49Smrg /* find dot product between light position vector and ground plane normal */ 9332001f49Smrg dot = groundplane[X] * lightpos[X] + 9432001f49Smrg groundplane[Y] * lightpos[Y] + 9532001f49Smrg groundplane[Z] * lightpos[Z] + 9632001f49Smrg groundplane[W] * lightpos[W]; 9732001f49Smrg 9832001f49Smrg shadowMat[0][0] = dot - lightpos[X] * groundplane[X]; 9932001f49Smrg shadowMat[1][0] = 0.f - lightpos[X] * groundplane[Y]; 10032001f49Smrg shadowMat[2][0] = 0.f - lightpos[X] * groundplane[Z]; 10132001f49Smrg shadowMat[3][0] = 0.f - lightpos[X] * groundplane[W]; 10232001f49Smrg 10332001f49Smrg shadowMat[X][1] = 0.f - lightpos[Y] * groundplane[X]; 10432001f49Smrg shadowMat[1][1] = dot - lightpos[Y] * groundplane[Y]; 10532001f49Smrg shadowMat[2][1] = 0.f - lightpos[Y] * groundplane[Z]; 10632001f49Smrg shadowMat[3][1] = 0.f - lightpos[Y] * groundplane[W]; 10732001f49Smrg 10832001f49Smrg shadowMat[X][2] = 0.f - lightpos[Z] * groundplane[X]; 10932001f49Smrg shadowMat[1][2] = 0.f - lightpos[Z] * groundplane[Y]; 11032001f49Smrg shadowMat[2][2] = dot - lightpos[Z] * groundplane[Z]; 11132001f49Smrg shadowMat[3][2] = 0.f - lightpos[Z] * groundplane[W]; 11232001f49Smrg 11332001f49Smrg shadowMat[X][3] = 0.f - lightpos[W] * groundplane[X]; 11432001f49Smrg shadowMat[1][3] = 0.f - lightpos[W] * groundplane[Y]; 11532001f49Smrg shadowMat[2][3] = 0.f - lightpos[W] * groundplane[Z]; 11632001f49Smrg shadowMat[3][3] = dot - lightpos[W] * groundplane[W]; 11732001f49Smrg 11832001f49Smrg} 11932001f49Smrg 12032001f49Smrg/* find the plane equation given 3 points */ 12132001f49Smrgvoid 12232001f49Smrgfindplane(GLfloat plane[4], 12332001f49Smrg GLfloat v0[3], GLfloat v1[3], GLfloat v2[3]) 12432001f49Smrg{ 12532001f49Smrg GLfloat vec0[3], vec1[3]; 12632001f49Smrg 12732001f49Smrg /* need 2 vectors to find cross product */ 12832001f49Smrg vec0[X] = v1[X] - v0[X]; 12932001f49Smrg vec0[Y] = v1[Y] - v0[Y]; 13032001f49Smrg vec0[Z] = v1[Z] - v0[Z]; 13132001f49Smrg 13232001f49Smrg vec1[X] = v2[X] - v0[X]; 13332001f49Smrg vec1[Y] = v2[Y] - v0[Y]; 13432001f49Smrg vec1[Z] = v2[Z] - v0[Z]; 13532001f49Smrg 13632001f49Smrg /* find cross product to get A, B, and C of plane equation */ 13732001f49Smrg plane[A] = vec0[Y] * vec1[Z] - vec0[Z] * vec1[Y]; 13832001f49Smrg plane[B] = -(vec0[X] * vec1[Z] - vec0[Z] * vec1[X]); 13932001f49Smrg plane[C] = vec0[X] * vec1[Y] - vec0[Y] * vec1[X]; 14032001f49Smrg 14132001f49Smrg plane[D] = -(plane[A] * v0[X] + plane[B] * v0[Y] + plane[C] * v0[Z]); 14232001f49Smrg} 14332001f49Smrg 14432001f49Smrg/******************** end shadow code ********************/ 14532001f49Smrg 14632001f49Smrg 14732001f49Smrgstatic void calcposobs(void) 14832001f49Smrg{ 14932001f49Smrg dir[0]=sin(alpha*M_PI/180.0); 15032001f49Smrg dir[1]=cos(alpha*M_PI/180.0)*sin(beta*M_PI/180.0); 15132001f49Smrg dir[2]=cos(beta*M_PI/180.0); 15232001f49Smrg 15332001f49Smrg obs[0]+=v*dir[0]; 15432001f49Smrg obs[1]+=v*dir[1]; 15532001f49Smrg obs[2]+=v*dir[2]; 15632001f49Smrg} 15732001f49Smrg 15832001f49Smrgstatic void special(int k, int x, int y) 15932001f49Smrg{ 16032001f49Smrg switch(k) { 16132001f49Smrg case GLUT_KEY_LEFT: 16232001f49Smrg alpha-=2.0; 16332001f49Smrg break; 16432001f49Smrg case GLUT_KEY_RIGHT: 16532001f49Smrg alpha+=2.0; 16632001f49Smrg break; 16732001f49Smrg case GLUT_KEY_DOWN: 16832001f49Smrg beta-=2.0; 16932001f49Smrg break; 17032001f49Smrg case GLUT_KEY_UP: 17132001f49Smrg beta+=2.0; 17232001f49Smrg break; 17332001f49Smrg } 17432001f49Smrg} 17532001f49Smrg 17632001f49Smrgstatic void cleanup(void) 17732001f49Smrg{ 17832001f49Smrg glDeleteTextures(1, &t1id); 17932001f49Smrg glDeleteTextures(1, &t2id); 18032001f49Smrg glDeleteLists(teapotdlist, 1); 18132001f49Smrg glDeleteLists(basedlist, 1); 18232001f49Smrg glDeleteLists(lightdlist, 1); 18332001f49Smrg} 18432001f49Smrg 18532001f49Smrgstatic void key(unsigned char k, int x, int y) 18632001f49Smrg{ 18732001f49Smrg switch(k) { 18832001f49Smrg case 27: 18932001f49Smrg cleanup(); 19032001f49Smrg exit(0); 19132001f49Smrg break; 19232001f49Smrg 19332001f49Smrg case 'a': 19432001f49Smrg v+=0.005; 19532001f49Smrg break; 19632001f49Smrg case 'z': 19732001f49Smrg v-=0.005; 19832001f49Smrg break; 19932001f49Smrg 20032001f49Smrg case 'j': 20132001f49Smrg joyactive=(!joyactive); 20232001f49Smrg break; 20332001f49Smrg case 'h': 20432001f49Smrg help=(!help); 20532001f49Smrg break; 20632001f49Smrg case 'f': 20732001f49Smrg fog=(!fog); 20832001f49Smrg break; 20932001f49Smrg case 't': 21032001f49Smrg usetex=(!usetex); 21132001f49Smrg break; 21232001f49Smrg case 'b': 21332001f49Smrg if(bfcull) { 21432001f49Smrg glDisable(GL_CULL_FACE); 21532001f49Smrg bfcull=0; 21632001f49Smrg } else { 21732001f49Smrg glEnable(GL_CULL_FACE); 21832001f49Smrg bfcull=1; 21932001f49Smrg } 22032001f49Smrg break; 22132001f49Smrg#ifdef XMESA 22232001f49Smrg case ' ': 22332001f49Smrg XMesaSetFXmode(fullscreen ? XMESA_FX_FULLSCREEN : XMESA_FX_WINDOW); 22432001f49Smrg fullscreen=(!fullscreen); 22532001f49Smrg break; 22632001f49Smrg#endif 22732001f49Smrg } 22832001f49Smrg} 22932001f49Smrg 23032001f49Smrgstatic void reshape(int w, int h) 23132001f49Smrg{ 23232001f49Smrg WIDTH=w; 23332001f49Smrg HEIGHT=h; 23432001f49Smrg glMatrixMode(GL_PROJECTION); 23532001f49Smrg glLoadIdentity(); 23632001f49Smrg gluPerspective(45.0,w/(float)h,0.2,40.0); 23732001f49Smrg glMatrixMode(GL_MODELVIEW); 23832001f49Smrg glLoadIdentity(); 23932001f49Smrg glViewport(0,0,w,h); 24032001f49Smrg} 24132001f49Smrg 24232001f49Smrgstatic void printstring(void *font, char *string) 24332001f49Smrg{ 24432001f49Smrg int len,i; 24532001f49Smrg 24632001f49Smrg len=(int)strlen(string); 24732001f49Smrg for(i=0;i<len;i++) 24832001f49Smrg glutBitmapCharacter(font,string[i]); 24932001f49Smrg} 25032001f49Smrg 25132001f49Smrgstatic void printhelp(void) 25232001f49Smrg{ 25332001f49Smrg glEnable(GL_BLEND); 25432001f49Smrg glColor4f(0.5,0.5,0.5,0.5); 25532001f49Smrg glRecti(40,40,600,440); 25632001f49Smrg glDisable(GL_BLEND); 25732001f49Smrg 25832001f49Smrg glColor3f(1.0,0.0,0.0); 25932001f49Smrg glRasterPos2i(300,420); 26032001f49Smrg printstring(GLUT_BITMAP_TIMES_ROMAN_24,"Help"); 26132001f49Smrg 26232001f49Smrg glRasterPos2i(60,390); 26332001f49Smrg printstring(GLUT_BITMAP_TIMES_ROMAN_24,"h - Toggle Help"); 26432001f49Smrg glRasterPos2i(60,360); 26532001f49Smrg printstring(GLUT_BITMAP_TIMES_ROMAN_24,"t - Toggle Textures"); 26632001f49Smrg glRasterPos2i(60,330); 26732001f49Smrg printstring(GLUT_BITMAP_TIMES_ROMAN_24,"f - Toggle Fog"); 26832001f49Smrg glRasterPos2i(60,300); 26932001f49Smrg printstring(GLUT_BITMAP_TIMES_ROMAN_24,"b - Toggle Back face culling"); 27032001f49Smrg glRasterPos2i(60,270); 27132001f49Smrg printstring(GLUT_BITMAP_TIMES_ROMAN_24,"Arrow Keys - Rotate"); 27232001f49Smrg glRasterPos2i(60,240); 27332001f49Smrg printstring(GLUT_BITMAP_TIMES_ROMAN_24,"a - Increase velocity"); 27432001f49Smrg glRasterPos2i(60,210); 27532001f49Smrg printstring(GLUT_BITMAP_TIMES_ROMAN_24,"z - Decrease velocity"); 27632001f49Smrg 27732001f49Smrg glRasterPos2i(60,180); 27832001f49Smrg if(joyavailable) 27932001f49Smrg printstring(GLUT_BITMAP_TIMES_ROMAN_24,"j - Toggle jostick control (Joystick control available)"); 28032001f49Smrg else 28132001f49Smrg printstring(GLUT_BITMAP_TIMES_ROMAN_24,"(No Joystick control available)"); 28232001f49Smrg} 28332001f49Smrg 28432001f49Smrgstatic void drawbase(void) 28532001f49Smrg{ 28632001f49Smrg static const GLfloat amb[4] = { 1, .5, 0.2, 1 }; 28732001f49Smrg static const GLfloat diff[4] = { 1, .4, 0.2, 1 }; 28832001f49Smrg int i,j; 28932001f49Smrg float x,y,dx,dy; 29032001f49Smrg 29132001f49Smrg glBindTexture(GL_TEXTURE_2D,t1id); 29232001f49Smrg 29332001f49Smrg glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, amb); 29432001f49Smrg glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diff); 29532001f49Smrg dx=BASESIZE/BASERES; 29632001f49Smrg dy=-BASESIZE/BASERES; 29732001f49Smrg for(y=BASESIZE/2.0,j=0;j<BASERES;y+=dy,j++) { 29832001f49Smrg glBegin(GL_QUAD_STRIP); 29932001f49Smrg glColor3f(1.0,1.0,1.0); 30032001f49Smrg glNormal3f(0.0,0.0,1.0); 30132001f49Smrg for(x=-BASESIZE/2.0,i=0;i<BASERES;x+=dx,i++) { 30232001f49Smrg glTexCoord2f(x,y); 30332001f49Smrg glVertex3f(x,y,0.0); 30432001f49Smrg 30532001f49Smrg glTexCoord2f(x,y+dy); 30632001f49Smrg glVertex3f(x,y+dy,0.0); 30732001f49Smrg } 30832001f49Smrg glEnd(); 30932001f49Smrg } 31032001f49Smrg} 31132001f49Smrg 31232001f49Smrgstatic void drawteapot(void) 31332001f49Smrg{ 31432001f49Smrg static const GLfloat amb[4] = { 0.2, 0.2, 0.2, 1 }; 31532001f49Smrg static const GLfloat diff[4] = { 0.8, 0.3, 0.5, 1 }; 31632001f49Smrg static float xrot=0.0; 31732001f49Smrg static float zrot=0.0; 31832001f49Smrg 31932001f49Smrg glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, amb); 32032001f49Smrg glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diff); 32132001f49Smrg 32232001f49Smrg glPushMatrix(); 32332001f49Smrg glRotatef(lightalpha,0.0,0.0,1.0); 32432001f49Smrg glMultMatrixf((GLfloat *)baseshadow); 32532001f49Smrg glRotatef(-lightalpha,0.0,0.0,1.0); 32632001f49Smrg 32732001f49Smrg glTranslatef(0.0,0.0,1.0); 32832001f49Smrg glRotatef(xrot,1.0,0.0,0.0); 32932001f49Smrg glRotatef(zrot,0.0,0.0,1.0); 33032001f49Smrg 33132001f49Smrg glDisable(GL_TEXTURE_2D); 33232001f49Smrg glDisable(GL_DEPTH_TEST); 33332001f49Smrg glDisable(GL_LIGHTING); 33432001f49Smrg 33532001f49Smrg glColor3f(0.0,0.0,0.0); 33632001f49Smrg glCallList(teapotdlist); 33732001f49Smrg 33832001f49Smrg glEnable(GL_DEPTH_TEST); 33932001f49Smrg glEnable(GL_LIGHTING); 34032001f49Smrg if(usetex) 34132001f49Smrg glEnable(GL_TEXTURE_2D); 34232001f49Smrg 34332001f49Smrg glPopMatrix(); 34432001f49Smrg 34532001f49Smrg glPushMatrix(); 34632001f49Smrg glTranslatef(0.0,0.0,1.0); 34732001f49Smrg glRotatef(xrot,1.0,0.0,0.0); 34832001f49Smrg glRotatef(zrot,0.0,0.0,1.0); 34932001f49Smrg 35032001f49Smrg glCallList(teapotdlist); 35132001f49Smrg glPopMatrix(); 35232001f49Smrg 35332001f49Smrg xrot+=2.0; 35432001f49Smrg zrot+=1.0; 35532001f49Smrg} 35632001f49Smrg 35732001f49Smrgstatic void drawlight1(void) 35832001f49Smrg{ 35932001f49Smrg glPushMatrix(); 36032001f49Smrg glRotatef(lightalpha,0.0,0.0,1.0); 36132001f49Smrg glLightfv(GL_LIGHT0,GL_POSITION,lightpos); 36232001f49Smrg glLightfv(GL_LIGHT0,GL_SPOT_DIRECTION,lightdir); 36332001f49Smrg 36432001f49Smrg glPopMatrix(); 36532001f49Smrg} 36632001f49Smrg 36732001f49Smrgstatic void drawlight2(void) 36832001f49Smrg{ 36932001f49Smrg glPushMatrix(); 37032001f49Smrg glRotatef(lightalpha,0.0,0.0,1.0); 37132001f49Smrg glTranslatef(lightpos[0],lightpos[1],lightpos[2]); 37232001f49Smrg 37332001f49Smrg glDisable(GL_TEXTURE_2D); 37432001f49Smrg glCallList(lightdlist); 37532001f49Smrg if(usetex) 37632001f49Smrg glEnable(GL_TEXTURE_2D); 37732001f49Smrg 37832001f49Smrg glPopMatrix(); 37932001f49Smrg 38032001f49Smrg lightalpha+=1.0; 38132001f49Smrg} 38232001f49Smrg 38332001f49Smrgstatic void dojoy(void) 38432001f49Smrg{ 38532001f49Smrg#ifdef WIN32 38632001f49Smrg static UINT max[2]={0,0}; 38732001f49Smrg static UINT min[2]={0xffffffff,0xffffffff},center[2]; 38832001f49Smrg MMRESULT res; 38932001f49Smrg JOYINFO joy; 39032001f49Smrg 39132001f49Smrg res=joyGetPos(JOYSTICKID1,&joy); 39232001f49Smrg 39332001f49Smrg if(res==JOYERR_NOERROR) { 39432001f49Smrg joyavailable=1; 39532001f49Smrg 39632001f49Smrg if(max[0]<joy.wXpos) 39732001f49Smrg max[0]=joy.wXpos; 39832001f49Smrg if(min[0]>joy.wXpos) 39932001f49Smrg min[0]=joy.wXpos; 40032001f49Smrg center[0]=(max[0]+min[0])/2; 40132001f49Smrg 40232001f49Smrg if(max[1]<joy.wYpos) 40332001f49Smrg max[1]=joy.wYpos; 40432001f49Smrg if(min[1]>joy.wYpos) 40532001f49Smrg min[1]=joy.wYpos; 40632001f49Smrg center[1]=(max[1]+min[1])/2; 40732001f49Smrg 40832001f49Smrg if(joyactive) { 40932001f49Smrg if(fabs(center[0]-(float)joy.wXpos)>0.1*(max[0]-min[0])) 41032001f49Smrg alpha-=2.5*(center[0]-(float)joy.wXpos)/(max[0]-min[0]); 41132001f49Smrg if(fabs(center[1]-(float)joy.wYpos)>0.1*(max[1]-min[1])) 41232001f49Smrg beta+=2.5*(center[1]-(float)joy.wYpos)/(max[1]-min[1]); 41332001f49Smrg 41432001f49Smrg if(joy.wButtons & JOY_BUTTON1) 41532001f49Smrg v+=0.005; 41632001f49Smrg if(joy.wButtons & JOY_BUTTON2) 41732001f49Smrg v-=0.005; 41832001f49Smrg } 41932001f49Smrg } else 42032001f49Smrg joyavailable=0; 42132001f49Smrg#endif 42232001f49Smrg} 42332001f49Smrg 42432001f49Smrgstatic void draw(void) 42532001f49Smrg{ 42632001f49Smrg static char frbuf[80] = ""; 42732001f49Smrg 42832001f49Smrg dojoy(); 42932001f49Smrg 43032001f49Smrg glEnable(GL_DEPTH_TEST); 43132001f49Smrg glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); 43232001f49Smrg 43332001f49Smrg if(usetex) 43432001f49Smrg glEnable(GL_TEXTURE_2D); 43532001f49Smrg else 43632001f49Smrg glDisable(GL_TEXTURE_2D); 43732001f49Smrg 43832001f49Smrg if(fog) 43932001f49Smrg glEnable(GL_FOG); 44032001f49Smrg else 44132001f49Smrg glDisable(GL_FOG); 44232001f49Smrg 44332001f49Smrg glEnable(GL_LIGHTING); 44432001f49Smrg 44532001f49Smrg glShadeModel(GL_SMOOTH); 44632001f49Smrg 44732001f49Smrg glPushMatrix(); 44832001f49Smrg calcposobs(); 44932001f49Smrg 45032001f49Smrg gluLookAt(obs[0],obs[1],obs[2], 45132001f49Smrg obs[0]+dir[0],obs[1]+dir[1],obs[2]+dir[2], 45232001f49Smrg 0.0,0.0,1.0); 45332001f49Smrg 45432001f49Smrg drawlight1(); 45532001f49Smrg glCallList(basedlist); 45632001f49Smrg drawteapot(); 45732001f49Smrg drawlight2(); 45832001f49Smrg glPopMatrix(); 45932001f49Smrg 46032001f49Smrg glDisable(GL_LIGHTING); 46132001f49Smrg glDisable(GL_TEXTURE_2D); 46232001f49Smrg glDisable(GL_DEPTH_TEST); 46332001f49Smrg glDisable(GL_FOG); 46432001f49Smrg glShadeModel(GL_FLAT); 46532001f49Smrg 46632001f49Smrg glMatrixMode(GL_PROJECTION); 46732001f49Smrg glLoadIdentity(); 46832001f49Smrg glOrtho(-0.5,639.5,-0.5,479.5,-1.0,1.0); 46932001f49Smrg glMatrixMode(GL_MODELVIEW); 47032001f49Smrg glLoadIdentity(); 47132001f49Smrg 47232001f49Smrg glColor3f(1.0,0.0,0.0); 47332001f49Smrg glRasterPos2i(10,10); 47432001f49Smrg printstring(GLUT_BITMAP_HELVETICA_18,frbuf); 47532001f49Smrg glRasterPos2i(350,470); 47632001f49Smrg printstring(GLUT_BITMAP_HELVETICA_10,"Teapot V1.2 Written by David Bucciarelli (tech.hmw@plus.it)"); 47732001f49Smrg 47832001f49Smrg if(help) 47932001f49Smrg printhelp(); 48032001f49Smrg 48132001f49Smrg reshape(WIDTH,HEIGHT); 48232001f49Smrg 48332001f49Smrg glutSwapBuffers(); 48432001f49Smrg 48532001f49Smrg Frames++; 48632001f49Smrg 48732001f49Smrg { 48832001f49Smrg GLint t = glutGet(GLUT_ELAPSED_TIME); 48932001f49Smrg if (t - T0 >= 2000) { 49032001f49Smrg GLfloat seconds = (t - T0) / 1000.0; 49132001f49Smrg GLfloat fps = Frames / seconds; 49232001f49Smrg sprintf(frbuf, "Frame rate: %f", fps); 49332001f49Smrg printf("%s\n", frbuf); 4947ec3b29aSmrg fflush(stdout); 49532001f49Smrg T0 = t; 49632001f49Smrg Frames = 0; 49732001f49Smrg } 49832001f49Smrg } 49932001f49Smrg} 50032001f49Smrg 50132001f49Smrgstatic void inittextures(void) 50232001f49Smrg{ 50332001f49Smrg glGenTextures(1,&t1id); 50432001f49Smrg glBindTexture(GL_TEXTURE_2D,t1id); 50532001f49Smrg 50632001f49Smrg glPixelStorei(GL_UNPACK_ALIGNMENT,4); 50732001f49Smrg if (!LoadRGBMipmaps(DEMOS_DATA_DIR "tile.rgb", GL_RGB)) { 50832001f49Smrg fprintf(stderr,"Error reading a texture.\n"); 50932001f49Smrg exit(-1); 51032001f49Smrg } 51132001f49Smrg 51232001f49Smrg glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT); 51332001f49Smrg glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT); 51432001f49Smrg 51532001f49Smrg glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_LINEAR); 51632001f49Smrg glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); 51732001f49Smrg 51832001f49Smrg glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE); 51932001f49Smrg 52032001f49Smrg glGenTextures(1,&t2id); 52132001f49Smrg glBindTexture(GL_TEXTURE_2D,t2id); 52232001f49Smrg 52332001f49Smrg glPixelTransferf(GL_RED_SCALE, 0.75); 52432001f49Smrg glPixelTransferf(GL_RED_BIAS, 0.25); 52532001f49Smrg glPixelTransferf(GL_GREEN_SCALE, 0.75); 52632001f49Smrg glPixelTransferf(GL_GREEN_BIAS, 0.25); 52732001f49Smrg glPixelTransferf(GL_BLUE_SCALE, 0.75); 52832001f49Smrg glPixelTransferf(GL_BLUE_BIAS, 0.25); 52932001f49Smrg 53032001f49Smrg if (!LoadRGBMipmaps(DEMOS_DATA_DIR "bw.rgb", GL_RGB)) { 53132001f49Smrg fprintf(stderr,"Error reading a texture.\n"); 53232001f49Smrg exit(-1); 53332001f49Smrg } 53432001f49Smrg 53532001f49Smrg glPixelTransferf(GL_RED_SCALE, 1.0); 53632001f49Smrg glPixelTransferf(GL_RED_BIAS, 0.0); 53732001f49Smrg glPixelTransferf(GL_GREEN_SCALE, 1.0); 53832001f49Smrg glPixelTransferf(GL_GREEN_BIAS, 0.0); 53932001f49Smrg glPixelTransferf(GL_BLUE_SCALE, 1.0); 54032001f49Smrg glPixelTransferf(GL_BLUE_BIAS, 0.0); 54132001f49Smrg 54232001f49Smrg 54332001f49Smrg glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT); 54432001f49Smrg glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT); 54532001f49Smrg 54632001f49Smrg glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_LINEAR); 54732001f49Smrg glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); 54832001f49Smrg 54932001f49Smrg glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE); 55032001f49Smrg} 55132001f49Smrg 55232001f49Smrgstatic void initlight(void) 55332001f49Smrg{ 55432001f49Smrg float matamb[4] ={0.5, 0.5, 0.5, 1.0}; 55532001f49Smrg float matdiff[4]={0.9, 0.2, 0.2, 1.0}; 55632001f49Smrg float matspec[4]={1.0,1.0,1.0,1.0}; 55732001f49Smrg 55832001f49Smrg float lamb[4] ={1.5, 1.5, 1.5, 1.0}; 55932001f49Smrg float ldiff[4]={1.0, 1.0, 1.0, 1.0}; 56032001f49Smrg float lspec[4]={1.0, 1.0, 1.0, 1.0}; 56132001f49Smrg 56232001f49Smrg glLightf(GL_LIGHT0,GL_SPOT_CUTOFF,70.0); 56332001f49Smrg glLightf(GL_LIGHT0,GL_SPOT_EXPONENT,20.0); 56432001f49Smrg glLightfv(GL_LIGHT0,GL_AMBIENT,lamb); 56532001f49Smrg glLightfv(GL_LIGHT0,GL_DIFFUSE,ldiff); 56632001f49Smrg glLightfv(GL_LIGHT0,GL_SPECULAR,lspec); 56732001f49Smrg 56832001f49Smrg glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 15.0); 56932001f49Smrg glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, matdiff); 57032001f49Smrg glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, matspec); 57132001f49Smrg glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, matamb); 57232001f49Smrg 57332001f49Smrg glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lamb); 57432001f49Smrg glEnable(GL_LIGHT0); 57532001f49Smrg} 57632001f49Smrg 57732001f49Smrgstatic void initdlists(void) 57832001f49Smrg{ 57932001f49Smrg GLUquadricObj *lcone,*lbase; 58032001f49Smrg GLfloat plane[4]; 58132001f49Smrg GLfloat v0[3]={0.0,0.0,0.0}; 58232001f49Smrg GLfloat v1[3]={1.0,0.0,0.0}; 58332001f49Smrg GLfloat v2[3]={0.0,1.0,0.0}; 58432001f49Smrg 58532001f49Smrg findplane(plane,v0,v1,v2); 58632001f49Smrg shadowmatrix(baseshadow,plane,lightpos); 58732001f49Smrg 58832001f49Smrg teapotdlist=glGenLists(1); 58932001f49Smrg glNewList(teapotdlist,GL_COMPILE); 59032001f49Smrg glRotatef(90.0,1.0,0.0,0.0); 59132001f49Smrg glCullFace(GL_FRONT); 59232001f49Smrg glBindTexture(GL_TEXTURE_2D,t2id); 59332001f49Smrg glutSolidTeapot(0.75); 59432001f49Smrg glCullFace(GL_BACK); 59532001f49Smrg glEndList(); 59632001f49Smrg 59732001f49Smrg basedlist=glGenLists(1); 59832001f49Smrg glNewList(basedlist,GL_COMPILE); 59932001f49Smrg drawbase(); 60032001f49Smrg glEndList(); 60132001f49Smrg 60232001f49Smrg lightdlist=glGenLists(1); 60332001f49Smrg glNewList(lightdlist,GL_COMPILE); 60432001f49Smrg glDisable(GL_LIGHTING); 60532001f49Smrg 60632001f49Smrg lcone=gluNewQuadric(); 60732001f49Smrg lbase=gluNewQuadric(); 60832001f49Smrg glRotatef(45.0,0.0,1.0,0.0); 60932001f49Smrg 61032001f49Smrg glColor3f(1.0,1.0,1.0); 61132001f49Smrg glCullFace(GL_FRONT); 61232001f49Smrg gluDisk(lbase,0.0,0.2,12.0,1.0); 61332001f49Smrg glCullFace(GL_BACK); 61432001f49Smrg 61532001f49Smrg glColor3f(0.5,0.0,0.0); 61632001f49Smrg gluCylinder(lcone,0.2,0.0,0.5,12,1); 61732001f49Smrg 61832001f49Smrg gluDeleteQuadric(lcone); 61932001f49Smrg gluDeleteQuadric(lbase); 62032001f49Smrg 62132001f49Smrg glEnable(GL_LIGHTING); 62232001f49Smrg glEndList(); 62332001f49Smrg} 62432001f49Smrg 62532001f49Smrgint main(int ac, char **av) 62632001f49Smrg{ 62732001f49Smrg float fogcolor[4]={0.025,0.025,0.025,1.0}; 62832001f49Smrg 62932001f49Smrg fprintf(stderr,"Teapot V1.2\nWritten by David Bucciarelli (tech.hmw@plus.it)\n"); 63032001f49Smrg 63132001f49Smrg /* 63232001f49Smrg if(!SetPriorityClass(GetCurrentProcess(),REALTIME_PRIORITY_CLASS)) { 63332001f49Smrg fprintf(stderr,"Error setting the process class.\n"); 63432001f49Smrg return 0; 63532001f49Smrg } 63632001f49Smrg 63732001f49Smrg if(!SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_TIME_CRITICAL)) { 63832001f49Smrg fprintf(stderr,"Error setting the process priority.\n"); 63932001f49Smrg return 0; 64032001f49Smrg } 64132001f49Smrg */ 64232001f49Smrg 64332001f49Smrg glutInitWindowSize(WIDTH,HEIGHT); 64432001f49Smrg glutInit(&ac,av); 64532001f49Smrg 64632001f49Smrg glutInitDisplayMode(GLUT_RGB|GLUT_DEPTH|GLUT_DOUBLE); 64732001f49Smrg 64832001f49Smrg if(!(win=glutCreateWindow("Teapot"))) { 64932001f49Smrg fprintf(stderr,"Error, couldn't open window\n"); 65032001f49Smrg return -1; 65132001f49Smrg } 65232001f49Smrg 65332001f49Smrg reshape(WIDTH,HEIGHT); 65432001f49Smrg 65532001f49Smrg glShadeModel(GL_SMOOTH); 65632001f49Smrg glEnable(GL_DEPTH_TEST); 65732001f49Smrg glEnable(GL_CULL_FACE); 65832001f49Smrg glEnable(GL_TEXTURE_2D); 65932001f49Smrg 66032001f49Smrg glEnable(GL_FOG); 66132001f49Smrg glFogi(GL_FOG_MODE,GL_EXP2); 66232001f49Smrg glFogfv(GL_FOG_COLOR,fogcolor); 66332001f49Smrg 66432001f49Smrg glFogf(GL_FOG_DENSITY,0.04); 66532001f49Smrg glHint(GL_FOG_HINT,GL_NICEST); 66632001f49Smrg glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); 66732001f49Smrg 66832001f49Smrg calcposobs(); 66932001f49Smrg 67032001f49Smrg inittextures(); 67132001f49Smrg initlight(); 67232001f49Smrg 67332001f49Smrg initdlists(); 67432001f49Smrg 67532001f49Smrg glClearColor(fogcolor[0],fogcolor[1],fogcolor[2],fogcolor[3]); 67632001f49Smrg 67732001f49Smrg glutReshapeFunc(reshape); 67832001f49Smrg glutDisplayFunc(draw); 67932001f49Smrg glutKeyboardFunc(key); 68032001f49Smrg glutSpecialFunc(special); 68132001f49Smrg glutIdleFunc(draw); 68232001f49Smrg 68332001f49Smrg glutMainLoop(); 68432001f49Smrg cleanup(); 68532001f49Smrg 68632001f49Smrg return 0; 68732001f49Smrg} 688