| /* |
| * This program is under the GNU GPL. |
| * Use at your own risk. |
| * |
| * written by David Bucciarelli (tech.hmw@plus.it) |
| * Humanware s.r.l. |
| */ |
| |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <math.h> |
| #include <time.h> |
| #include <string.h> |
| |
| #ifdef WIN32 |
| #include <windows.h> |
| #endif |
| |
| #include <GL/glut.h> |
| #include "readtex.h" |
| |
| #ifdef XMESA |
| #include "GL/xmesa.h" |
| static int fullscreen=1; |
| #endif |
| |
| static int WIDTH=640; |
| static int HEIGHT=480; |
| |
| static GLint T0 = 0; |
| static GLint Frames = 0; |
| |
| #define BASESIZE 10.0 |
| |
| #define BASERES 12 |
| #define TEAPOTRES 3 |
| |
| #ifndef M_PI |
| #define M_PI 3.1415926535 |
| #endif |
| |
| extern void shadowmatrix(GLfloat [4][4], GLfloat [4], GLfloat [4]); |
| extern void findplane(GLfloat [4], GLfloat [3], GLfloat [3], GLfloat [3]); |
| |
| |
| static int win=0; |
| |
| static float obs[3]={5.0,0.0,1.0}; |
| static float dir[3]; |
| static float v=0.0; |
| static float alpha=-90.0; |
| static float beta=90.0; |
| |
| static GLfloat baseshadow[4][4]; |
| static GLfloat lightpos[4]={2.3,0.0,3.0,1.0}; |
| static GLfloat lightdir[3]={-2.3,0.0,-3.0}; |
| static GLfloat lightalpha=0.0; |
| |
| static int fog=1; |
| static int bfcull=1; |
| static int usetex=1; |
| static int help=1; |
| static int joyavailable=0; |
| static int joyactive=0; |
| |
| static GLuint t1id,t2id; |
| static GLuint teapotdlist,basedlist,lightdlist; |
| |
| |
| |
| /******************** begin shadow code ********************/ |
| |
| /* Taken from the projshadow.c - by Tom McReynolds, SGI */ |
| |
| /* Modified by David Bucciarelli */ |
| |
| enum { |
| X, Y, Z, W |
| }; |
| enum { |
| A, B, C, D |
| }; |
| |
| /* create a matrix that will project the desired shadow */ |
| void |
| shadowmatrix(GLfloat shadowMat[4][4], |
| GLfloat groundplane[4], |
| GLfloat lightpos[4]) |
| { |
| GLfloat dot; |
| |
| /* find dot product between light position vector and ground plane normal */ |
| dot = groundplane[X] * lightpos[X] + |
| groundplane[Y] * lightpos[Y] + |
| groundplane[Z] * lightpos[Z] + |
| groundplane[W] * lightpos[W]; |
| |
| shadowMat[0][0] = dot - lightpos[X] * groundplane[X]; |
| shadowMat[1][0] = 0.f - lightpos[X] * groundplane[Y]; |
| shadowMat[2][0] = 0.f - lightpos[X] * groundplane[Z]; |
| shadowMat[3][0] = 0.f - lightpos[X] * groundplane[W]; |
| |
| shadowMat[X][1] = 0.f - lightpos[Y] * groundplane[X]; |
| shadowMat[1][1] = dot - lightpos[Y] * groundplane[Y]; |
| shadowMat[2][1] = 0.f - lightpos[Y] * groundplane[Z]; |
| shadowMat[3][1] = 0.f - lightpos[Y] * groundplane[W]; |
| |
| shadowMat[X][2] = 0.f - lightpos[Z] * groundplane[X]; |
| shadowMat[1][2] = 0.f - lightpos[Z] * groundplane[Y]; |
| shadowMat[2][2] = dot - lightpos[Z] * groundplane[Z]; |
| shadowMat[3][2] = 0.f - lightpos[Z] * groundplane[W]; |
| |
| shadowMat[X][3] = 0.f - lightpos[W] * groundplane[X]; |
| shadowMat[1][3] = 0.f - lightpos[W] * groundplane[Y]; |
| shadowMat[2][3] = 0.f - lightpos[W] * groundplane[Z]; |
| shadowMat[3][3] = dot - lightpos[W] * groundplane[W]; |
| |
| } |
| |
| /* find the plane equation given 3 points */ |
| void |
| findplane(GLfloat plane[4], |
| GLfloat v0[3], GLfloat v1[3], GLfloat v2[3]) |
| { |
| GLfloat vec0[3], vec1[3]; |
| |
| /* need 2 vectors to find cross product */ |
| vec0[X] = v1[X] - v0[X]; |
| vec0[Y] = v1[Y] - v0[Y]; |
| vec0[Z] = v1[Z] - v0[Z]; |
| |
| vec1[X] = v2[X] - v0[X]; |
| vec1[Y] = v2[Y] - v0[Y]; |
| vec1[Z] = v2[Z] - v0[Z]; |
| |
| /* find cross product to get A, B, and C of plane equation */ |
| plane[A] = vec0[Y] * vec1[Z] - vec0[Z] * vec1[Y]; |
| plane[B] = -(vec0[X] * vec1[Z] - vec0[Z] * vec1[X]); |
| plane[C] = vec0[X] * vec1[Y] - vec0[Y] * vec1[X]; |
| |
| plane[D] = -(plane[A] * v0[X] + plane[B] * v0[Y] + plane[C] * v0[Z]); |
| } |
| |
| /******************** end shadow code ********************/ |
| |
| |
| static void calcposobs(void) |
| { |
| dir[0]=sin(alpha*M_PI/180.0); |
| dir[1]=cos(alpha*M_PI/180.0)*sin(beta*M_PI/180.0); |
| dir[2]=cos(beta*M_PI/180.0); |
| |
| obs[0]+=v*dir[0]; |
| obs[1]+=v*dir[1]; |
| obs[2]+=v*dir[2]; |
| } |
| |
| static void special(int k, int x, int y) |
| { |
| switch(k) { |
| case GLUT_KEY_LEFT: |
| alpha-=2.0; |
| break; |
| case GLUT_KEY_RIGHT: |
| alpha+=2.0; |
| break; |
| case GLUT_KEY_DOWN: |
| beta-=2.0; |
| break; |
| case GLUT_KEY_UP: |
| beta+=2.0; |
| break; |
| } |
| } |
| |
| static void key(unsigned char k, int x, int y) |
| { |
| switch(k) { |
| case 27: |
| exit(0); |
| break; |
| |
| case 'a': |
| v+=0.005; |
| break; |
| case 'z': |
| v-=0.005; |
| break; |
| |
| case 'j': |
| joyactive=(!joyactive); |
| break; |
| case 'h': |
| help=(!help); |
| break; |
| case 'f': |
| fog=(!fog); |
| break; |
| case 't': |
| usetex=(!usetex); |
| break; |
| case 'b': |
| if(bfcull) { |
| glDisable(GL_CULL_FACE); |
| bfcull=0; |
| } else { |
| glEnable(GL_CULL_FACE); |
| bfcull=1; |
| } |
| break; |
| #ifdef XMESA |
| case ' ': |
| XMesaSetFXmode(fullscreen ? XMESA_FX_FULLSCREEN : XMESA_FX_WINDOW); |
| fullscreen=(!fullscreen); |
| break; |
| #endif |
| } |
| } |
| |
| static void reshape(int w, int h) |
| { |
| WIDTH=w; |
| HEIGHT=h; |
| glMatrixMode(GL_PROJECTION); |
| glLoadIdentity(); |
| gluPerspective(45.0,w/(float)h,0.2,40.0); |
| glMatrixMode(GL_MODELVIEW); |
| glLoadIdentity(); |
| glViewport(0,0,w,h); |
| } |
| |
| static void printstring(void *font, char *string) |
| { |
| int len,i; |
| |
| len=(int)strlen(string); |
| for(i=0;i<len;i++) |
| glutBitmapCharacter(font,string[i]); |
| } |
| |
| static void printhelp(void) |
| { |
| glEnable(GL_BLEND); |
| glColor4f(0.5,0.5,0.5,0.5); |
| glRecti(40,40,600,440); |
| glDisable(GL_BLEND); |
| |
| glColor3f(1.0,0.0,0.0); |
| glRasterPos2i(300,420); |
| printstring(GLUT_BITMAP_TIMES_ROMAN_24,"Help"); |
| |
| glRasterPos2i(60,390); |
| printstring(GLUT_BITMAP_TIMES_ROMAN_24,"h - Toggle Help"); |
| glRasterPos2i(60,360); |
| printstring(GLUT_BITMAP_TIMES_ROMAN_24,"t - Toggle Textures"); |
| glRasterPos2i(60,330); |
| printstring(GLUT_BITMAP_TIMES_ROMAN_24,"f - Toggle Fog"); |
| glRasterPos2i(60,300); |
| printstring(GLUT_BITMAP_TIMES_ROMAN_24,"b - Toggle Back face culling"); |
| glRasterPos2i(60,270); |
| printstring(GLUT_BITMAP_TIMES_ROMAN_24,"Arrow Keys - Rotate"); |
| glRasterPos2i(60,240); |
| printstring(GLUT_BITMAP_TIMES_ROMAN_24,"a - Increase velocity"); |
| glRasterPos2i(60,210); |
| printstring(GLUT_BITMAP_TIMES_ROMAN_24,"z - Decrease velocity"); |
| |
| glRasterPos2i(60,180); |
| if(joyavailable) |
| printstring(GLUT_BITMAP_TIMES_ROMAN_24,"j - Toggle jostick control (Joystick control available)"); |
| else |
| printstring(GLUT_BITMAP_TIMES_ROMAN_24,"(No Joystick control available)"); |
| } |
| |
| static void drawbase(void) |
| { |
| static const GLfloat amb[4] = { 1, .5, 0.2, 1 }; |
| static const GLfloat diff[4] = { 1, .4, 0.2, 1 }; |
| int i,j; |
| float x,y,dx,dy; |
| |
| glBindTexture(GL_TEXTURE_2D,t1id); |
| |
| glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, amb); |
| glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diff); |
| dx=BASESIZE/BASERES; |
| dy=-BASESIZE/BASERES; |
| for(y=BASESIZE/2.0,j=0;j<BASERES;y+=dy,j++) { |
| glBegin(GL_QUAD_STRIP); |
| glColor3f(1.0,1.0,1.0); |
| glNormal3f(0.0,0.0,1.0); |
| for(x=-BASESIZE/2.0,i=0;i<BASERES;x+=dx,i++) { |
| glTexCoord2f(x,y); |
| glVertex3f(x,y,0.0); |
| |
| glTexCoord2f(x,y+dy); |
| glVertex3f(x,y+dy,0.0); |
| } |
| glEnd(); |
| } |
| } |
| |
| static void drawteapot(void) |
| { |
| static const GLfloat amb[4] = { 0.2, 0.2, 0.2, 1 }; |
| static const GLfloat diff[4] = { 0.8, 0.3, 0.5, 1 }; |
| static float xrot=0.0; |
| static float zrot=0.0; |
| |
| glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, amb); |
| glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diff); |
| |
| glPushMatrix(); |
| glRotatef(lightalpha,0.0,0.0,1.0); |
| glMultMatrixf((GLfloat *)baseshadow); |
| glRotatef(-lightalpha,0.0,0.0,1.0); |
| |
| glTranslatef(0.0,0.0,1.0); |
| glRotatef(xrot,1.0,0.0,0.0); |
| glRotatef(zrot,0.0,0.0,1.0); |
| |
| glDisable(GL_TEXTURE_2D); |
| glDisable(GL_DEPTH_TEST); |
| glDisable(GL_LIGHTING); |
| |
| glColor3f(0.0,0.0,0.0); |
| glCallList(teapotdlist); |
| |
| glEnable(GL_DEPTH_TEST); |
| glEnable(GL_LIGHTING); |
| if(usetex) |
| glEnable(GL_TEXTURE_2D); |
| |
| glPopMatrix(); |
| |
| glPushMatrix(); |
| glTranslatef(0.0,0.0,1.0); |
| glRotatef(xrot,1.0,0.0,0.0); |
| glRotatef(zrot,0.0,0.0,1.0); |
| |
| glCallList(teapotdlist); |
| glPopMatrix(); |
| |
| xrot+=2.0; |
| zrot+=1.0; |
| } |
| |
| static void drawlight1(void) |
| { |
| glPushMatrix(); |
| glRotatef(lightalpha,0.0,0.0,1.0); |
| glLightfv(GL_LIGHT0,GL_POSITION,lightpos); |
| glLightfv(GL_LIGHT0,GL_SPOT_DIRECTION,lightdir); |
| |
| glPopMatrix(); |
| } |
| |
| static void drawlight2(void) |
| { |
| glPushMatrix(); |
| glRotatef(lightalpha,0.0,0.0,1.0); |
| glTranslatef(lightpos[0],lightpos[1],lightpos[2]); |
| |
| glDisable(GL_TEXTURE_2D); |
| glCallList(lightdlist); |
| if(usetex) |
| glEnable(GL_TEXTURE_2D); |
| |
| glPopMatrix(); |
| |
| lightalpha+=1.0; |
| } |
| |
| static void dojoy(void) |
| { |
| #ifdef WIN32 |
| static UINT max[2]={0,0}; |
| static UINT min[2]={0xffffffff,0xffffffff},center[2]; |
| MMRESULT res; |
| JOYINFO joy; |
| |
| res=joyGetPos(JOYSTICKID1,&joy); |
| |
| if(res==JOYERR_NOERROR) { |
| joyavailable=1; |
| |
| if(max[0]<joy.wXpos) |
| max[0]=joy.wXpos; |
| if(min[0]>joy.wXpos) |
| min[0]=joy.wXpos; |
| center[0]=(max[0]+min[0])/2; |
| |
| if(max[1]<joy.wYpos) |
| max[1]=joy.wYpos; |
| if(min[1]>joy.wYpos) |
| min[1]=joy.wYpos; |
| center[1]=(max[1]+min[1])/2; |
| |
| if(joyactive) { |
| if(fabs(center[0]-(float)joy.wXpos)>0.1*(max[0]-min[0])) |
| alpha-=2.5*(center[0]-(float)joy.wXpos)/(max[0]-min[0]); |
| if(fabs(center[1]-(float)joy.wYpos)>0.1*(max[1]-min[1])) |
| beta+=2.5*(center[1]-(float)joy.wYpos)/(max[1]-min[1]); |
| |
| if(joy.wButtons & JOY_BUTTON1) |
| v+=0.005; |
| if(joy.wButtons & JOY_BUTTON2) |
| v-=0.005; |
| } |
| } else |
| joyavailable=0; |
| #endif |
| } |
| |
| static void draw(void) |
| { |
| static char frbuf[80] = ""; |
| |
| dojoy(); |
| |
| glEnable(GL_DEPTH_TEST); |
| glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); |
| |
| if(usetex) |
| glEnable(GL_TEXTURE_2D); |
| else |
| glDisable(GL_TEXTURE_2D); |
| |
| if(fog) |
| glEnable(GL_FOG); |
| else |
| glDisable(GL_FOG); |
| |
| glEnable(GL_LIGHTING); |
| |
| glShadeModel(GL_SMOOTH); |
| |
| glPushMatrix(); |
| calcposobs(); |
| |
| gluLookAt(obs[0],obs[1],obs[2], |
| obs[0]+dir[0],obs[1]+dir[1],obs[2]+dir[2], |
| 0.0,0.0,1.0); |
| |
| drawlight1(); |
| glCallList(basedlist); |
| drawteapot(); |
| drawlight2(); |
| glPopMatrix(); |
| |
| glDisable(GL_LIGHTING); |
| glDisable(GL_TEXTURE_2D); |
| glDisable(GL_DEPTH_TEST); |
| glDisable(GL_FOG); |
| glShadeModel(GL_FLAT); |
| |
| glMatrixMode(GL_PROJECTION); |
| glLoadIdentity(); |
| glOrtho(-0.5,639.5,-0.5,479.5,-1.0,1.0); |
| glMatrixMode(GL_MODELVIEW); |
| glLoadIdentity(); |
| |
| glColor3f(1.0,0.0,0.0); |
| glRasterPos2i(10,10); |
| printstring(GLUT_BITMAP_HELVETICA_18,frbuf); |
| glRasterPos2i(350,470); |
| printstring(GLUT_BITMAP_HELVETICA_10,"Teapot V1.2 Written by David Bucciarelli (tech.hmw@plus.it)"); |
| |
| if(help) |
| printhelp(); |
| |
| reshape(WIDTH,HEIGHT); |
| |
| glutSwapBuffers(); |
| |
| Frames++; |
| |
| { |
| GLint t = glutGet(GLUT_ELAPSED_TIME); |
| if (t - T0 >= 2000) { |
| GLfloat seconds = (t - T0) / 1000.0; |
| GLfloat fps = Frames / seconds; |
| sprintf(frbuf, "Frame rate: %f", fps); |
| T0 = t; |
| Frames = 0; |
| } |
| } |
| } |
| |
| static void inittextures(void) |
| { |
| glGenTextures(1,&t1id); |
| glBindTexture(GL_TEXTURE_2D,t1id); |
| |
| glPixelStorei(GL_UNPACK_ALIGNMENT,4); |
| if (!LoadRGBMipmaps("../images/tile.rgb", GL_RGB)) { |
| fprintf(stderr,"Error reading a texture.\n"); |
| exit(-1); |
| } |
| |
| glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT); |
| glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT); |
| |
| glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_LINEAR); |
| glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); |
| |
| glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE); |
| |
| glGenTextures(1,&t2id); |
| glBindTexture(GL_TEXTURE_2D,t2id); |
| |
| glPixelTransferf(GL_RED_SCALE, 0.75); |
| glPixelTransferf(GL_RED_BIAS, 0.25); |
| glPixelTransferf(GL_GREEN_SCALE, 0.75); |
| glPixelTransferf(GL_GREEN_BIAS, 0.25); |
| glPixelTransferf(GL_BLUE_SCALE, 0.75); |
| glPixelTransferf(GL_BLUE_BIAS, 0.25); |
| |
| if (!LoadRGBMipmaps("../images/bw.rgb", GL_RGB)) { |
| fprintf(stderr,"Error reading a texture.\n"); |
| exit(-1); |
| } |
| |
| glPixelTransferf(GL_RED_SCALE, 1.0); |
| glPixelTransferf(GL_RED_BIAS, 0.0); |
| glPixelTransferf(GL_GREEN_SCALE, 1.0); |
| glPixelTransferf(GL_GREEN_BIAS, 0.0); |
| glPixelTransferf(GL_BLUE_SCALE, 1.0); |
| glPixelTransferf(GL_BLUE_BIAS, 0.0); |
| |
| |
| glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT); |
| glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT); |
| |
| glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_LINEAR); |
| glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); |
| |
| glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE); |
| } |
| |
| static void initlight(void) |
| { |
| float matamb[4] ={0.5, 0.5, 0.5, 1.0}; |
| float matdiff[4]={0.9, 0.2, 0.2, 1.0}; |
| float matspec[4]={1.0,1.0,1.0,1.0}; |
| |
| float lamb[4] ={1.5, 1.5, 1.5, 1.0}; |
| float ldiff[4]={1.0, 1.0, 1.0, 1.0}; |
| float lspec[4]={1.0, 1.0, 1.0, 1.0}; |
| |
| glLightf(GL_LIGHT0,GL_SPOT_CUTOFF,70.0); |
| glLightf(GL_LIGHT0,GL_SPOT_EXPONENT,20.0); |
| glLightfv(GL_LIGHT0,GL_AMBIENT,lamb); |
| glLightfv(GL_LIGHT0,GL_DIFFUSE,ldiff); |
| glLightfv(GL_LIGHT0,GL_SPECULAR,lspec); |
| |
| glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 15.0); |
| glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, matdiff); |
| glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, matspec); |
| glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, matamb); |
| |
| glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lamb); |
| glEnable(GL_LIGHT0); |
| } |
| |
| static void initdlists(void) |
| { |
| GLUquadricObj *lcone,*lbase; |
| GLfloat plane[4]; |
| GLfloat v0[3]={0.0,0.0,0.0}; |
| GLfloat v1[3]={1.0,0.0,0.0}; |
| GLfloat v2[3]={0.0,1.0,0.0}; |
| |
| findplane(plane,v0,v1,v2); |
| shadowmatrix(baseshadow,plane,lightpos); |
| |
| teapotdlist=glGenLists(1); |
| glNewList(teapotdlist,GL_COMPILE); |
| glRotatef(90.0,1.0,0.0,0.0); |
| glCullFace(GL_FRONT); |
| glBindTexture(GL_TEXTURE_2D,t2id); |
| glutSolidTeapot(0.75); |
| glCullFace(GL_BACK); |
| glEndList(); |
| |
| basedlist=glGenLists(1); |
| glNewList(basedlist,GL_COMPILE); |
| drawbase(); |
| glEndList(); |
| |
| lightdlist=glGenLists(1); |
| glNewList(lightdlist,GL_COMPILE); |
| glDisable(GL_LIGHTING); |
| |
| lcone=gluNewQuadric(); |
| lbase=gluNewQuadric(); |
| glRotatef(45.0,0.0,1.0,0.0); |
| |
| glColor3f(1.0,1.0,1.0); |
| glCullFace(GL_FRONT); |
| gluDisk(lbase,0.0,0.2,12.0,1.0); |
| glCullFace(GL_BACK); |
| |
| glColor3f(0.5,0.0,0.0); |
| gluCylinder(lcone,0.2,0.0,0.5,12,1); |
| |
| gluDeleteQuadric(lcone); |
| gluDeleteQuadric(lbase); |
| |
| glEnable(GL_LIGHTING); |
| glEndList(); |
| } |
| |
| int main(int ac, char **av) |
| { |
| float fogcolor[4]={0.025,0.025,0.025,1.0}; |
| |
| fprintf(stderr,"Teapot V1.2\nWritten by David Bucciarelli (tech.hmw@plus.it)\n"); |
| |
| /* |
| if(!SetPriorityClass(GetCurrentProcess(),REALTIME_PRIORITY_CLASS)) { |
| fprintf(stderr,"Error setting the process class.\n"); |
| return 0; |
| } |
| |
| if(!SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_TIME_CRITICAL)) { |
| fprintf(stderr,"Error setting the process priority.\n"); |
| return 0; |
| } |
| */ |
| |
| glutInitWindowPosition(0,0); |
| glutInitWindowSize(WIDTH,HEIGHT); |
| glutInit(&ac,av); |
| |
| glutInitDisplayMode(GLUT_RGB|GLUT_DEPTH|GLUT_DOUBLE); |
| |
| if(!(win=glutCreateWindow("Teapot"))) { |
| fprintf(stderr,"Error, couldn't open window\n"); |
| return -1; |
| } |
| |
| reshape(WIDTH,HEIGHT); |
| |
| glShadeModel(GL_SMOOTH); |
| glEnable(GL_DEPTH_TEST); |
| glEnable(GL_CULL_FACE); |
| glEnable(GL_TEXTURE_2D); |
| |
| glEnable(GL_FOG); |
| glFogi(GL_FOG_MODE,GL_EXP2); |
| glFogfv(GL_FOG_COLOR,fogcolor); |
| |
| glFogf(GL_FOG_DENSITY,0.04); |
| glHint(GL_FOG_HINT,GL_NICEST); |
| glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); |
| |
| calcposobs(); |
| |
| inittextures(); |
| initlight(); |
| |
| initdlists(); |
| |
| glClearColor(fogcolor[0],fogcolor[1],fogcolor[2],fogcolor[3]); |
| |
| glutReshapeFunc(reshape); |
| glutDisplayFunc(draw); |
| glutKeyboardFunc(key); |
| glutSpecialFunc(special); |
| glutIdleFunc(draw); |
| |
| glutMainLoop(); |
| |
| return 0; |
| } |