#include<gl/glut.h> #include<windows.h> #include<math.h> #include <stdio.h> #include <stdlib.h> GLfloat light_position1[]={0,28,-20,1.0}; GLfloat model_ambient[]={0.05f,0.05f,0.05f,1.0f}; GLfloat mat_specular[]={0.8,1.0,1.0,1.0}; GLfloat mat_shininess[]={5.0}; GLfloat mat_ambient[]={0.1,0.1,0.1,1}; GLfloat white_light[]={1.0,1.0,1.0,1.0}; GLfloat light[]={1.0,1.0,1.0,1}; GLfloat light_position0[]={0,28,20,1.0}; GLint WinWidth; GLint WinHeight; //define the eyepoint typedef struct EyePoint { GLfloat x; GLfloat y; GLfloat z; }EyePoint; EyePoint myEye; EyePoint vPoint; GLfloat vAngle=0; //the function about the texture #define BMP_Header_Length 54 void grab(void) { FILE* pDummyFile; FILE* pWritingFile; GLubyte* pPixelData; GLubyte BMP_Header[BMP_Header_Length]; GLint i, j; GLint PixelDataLength; i = WinWidth * 3; while( i%4 != 0 ) ++i; PixelDataLength = i * WinHeight; pPixelData = (GLubyte*)malloc(PixelDataLength); if( pPixelData == 0 ) exit(0); pDummyFile = fopen("dummy.bmp", "rb"); if( pDummyFile == 0 ) exit(0); pWritingFile = fopen("grab.bmp", "wb"); if( pWritingFile == 0 ) exit(0); glPixelStorei(GL_UNPACK_ALIGNMENT, 4); glReadPixels(0, 0, WinWidth, WinHeight,GL_BGR_EXT, GL_UNSIGNED_BYTE, pPixelData); fread(BMP_Header, sizeof(BMP_Header), 1, pDummyFile); fwrite(BMP_Header, sizeof(BMP_Header), 1, pWritingFile); fseek(pWritingFile, 0x0012, SEEK_SET); i = WinWidth; j = WinHeight; fwrite(&i, sizeof(i), 1, pWritingFile); fwrite(&j, sizeof(j), 1, pWritingFile); fseek(pWritingFile, 0, SEEK_END); fwrite(pPixelData, PixelDataLength, 1, pWritingFile); fclose(pDummyFile); fclose(pWritingFile); free(pPixelData); } //power of two int power_of_two(int n) { if( n <= 0 ) return 0; return (n & (n-1)) == 0; } //load texture function GLuint load_texture(const char* file_name) { GLint width, height, total_bytes; GLubyte* pixels = 0; GLint last_texture_ID=0; GLuint texture_ID = 0; FILE* pFile = fopen(file_name, "rb"); if( pFile == 0 ) return 0; fseek(pFile, 0x0012, SEEK_SET); fread(&width, 4, 1, pFile); fread(&height, 4, 1, pFile); fseek(pFile, BMP_Header_Length, SEEK_SET); { GLint line_bytes = width * 3; while( line_bytes % 4 != 0 ) ++line_bytes; total_bytes = line_bytes * height; } //{ pixels = (GLubyte*)malloc(total_bytes); if( pixels == 0 ){ fclose(pFile); return 0; } //if if( fread(pixels, total_bytes, 1, pFile) <= 0 ){ free(pixels); fclose(pFile); return 0; } //if { GLint max; glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max); if( !power_of_two(width)|| !power_of_two(height)|| width > max|| height > max ){ const GLint new_width = 256; const GLint new_height = 256; GLint new_line_bytes, new_total_bytes; GLubyte* new_pixels = 0; new_line_bytes = new_width * 3; while( new_line_bytes % 4 != 0 ) ++new_line_bytes; new_total_bytes = new_line_bytes * new_height; new_pixels = (GLubyte*)malloc(new_total_bytes); if( new_pixels == 0 ){ free(pixels); fclose(pFile); return 0; }//if gluScaleImage(GL_RGB,width, height, GL_UNSIGNED_BYTE, pixels,new_width, new_height, GL_UNSIGNED_BYTE, new_pixels); free(pixels); pixels = new_pixels; width = new_width; height = new_height; }//if }//{ glGenTextures(1, &texture_ID); if( texture_ID == 0 ) { free(pixels); fclose(pFile); return 0; } //if glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture_ID); glBindTexture(GL_TEXTURE_2D, texture_ID); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_BGR_EXT, GL_UNSIGNED_BYTE, pixels); glBindTexture(GL_TEXTURE_2D, last_texture_ID); free(pixels); return texture_ID; } //set the names of the texture objects GLuint texblackboard,texwindow,texceiling, texdoor,texbackwall,texgaodi,textdesk; //draw the scene of the classroom void drawscence() { //draw the ceiling glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, texceiling); glColor3f(0.3,0.3,0.3); glBegin(GL_QUADS); glNormal3f(0.0f, -1.0f, 0.0f); glTexCoord2f(0.0f, 0.0f); glVertex3f(-40.0f,30.0f, 30.0f); glTexCoord2f(0.0f, 3.0f); glVertex3f(-40.0f, 30.0f, -30.0f); glTexCoord2f(6.0f, 3.0f); glVertex3f(40.0f, 30.0f, -30.0f); glTexCoord2f(6.0f, 0.0f); glVertex3f(40.0f, 30.0f, 30.0f); glEnd(); glDisable(GL_TEXTURE_2D); //draw the floor glColor3f(1.0f, 1.0f, 1.0f); glBegin(GL_QUADS); glNormal3f(0.0f, 1.0f, 0.0f); glVertex3f(-40.0f,0.0f, 30.0f); glVertex3f(-40.0f, 0.0f, -30.0f); glVertex3f(40.0f, 0.0f, -30.0f); glVertex3f(40.0f, 0.0f, 30.0f); glEnd(); //the wall and the windows in left glColor3f(0.8f,0.8f, 0.8f); glBegin(GL_QUADS); glNormal3f(1.0f, 0.0f, 0.0f); glVertex3f(-40.0f,0.0f, 30.0f); glVertex3f(-40.0f, 30.0f, 30.0f); glVertex3f(-40.0f, 30.0f, -30.0f); glVertex3f(-40.0f, 0.0f, -30.0f); glEnd(); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, texwindow); for(int n=0;n<=1;n++) { glBegin(GL_QUADS); glNormal3f(1.0, 0.0f, 0.0f); glTexCoord2f(1.0f, 0.0f);glVertex3f(-39.9, 10, -8+n*18); glTexCoord2f(1.0f, 1.0f);glVertex3f(-39.9, 20, -8+n*18); glTexCoord2f(0.0f, 1.0f);glVertex3f(-39.9, 20, -18+n*18); glTexCoord2f(0.0f, 0.0f);glVertex3f(-39.9, 10, -18+n*18); glEnd(); } glDisable(GL_TEXTURE_2D); //the wall and the window in right glColor3f(0.8f,0.8f, 0.8f); glBegin(GL_QUADS); glNormal3f(-1.0f, 0.0f, 0.0f); glVertex3f(40.0f,0.0f, 30.0f); glVertex3f(40.0f, 30.0f, 30.0f); glVertex3f(40.0f, 30.0f, -30.0f); glVertex3f(40.0f, 0.0f, -30.0f); glEnd(); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, texwindow); glBegin(GL_QUADS); glNormal3f(-1.0, 0.0f, 0.0f); glTexCoord2f(1.0f, 0.0f);glVertex3f(39.5, 10, 10); glTexCoord2f(1.0f, 1.0f);glVertex3f(39.5, 20, 10); glTexCoord2f(0.0f, 1.0f);glVertex3f(39.5, 20, 0); glTexCoord2f(0.0f, 0.0f);glVertex3f(39.5, 10, 0); glEnd(); glDisable(GL_TEXTURE_2D); //backwall glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, texbackwall); glColor3f(0.8f,0.8f, 0.8f); glBegin(GL_QUADS); glNormal3f(0.0f, 0.0f, 1.0f); glTexCoord2f(0.0f, 0.0f); glVertex3f(-40.0f,0.0f, 30.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f(-40.0f, 30.0f, 30.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f(40.0f, 30.0f, 30.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f(40.0f, 0.0f, 30.0f); glEnd(); //frontwall glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, texbackwall); glColor3f(0.8f,0.8f, 0.8f); glBegin(GL_QUADS); glNormal3f(0.0f, 0.0f, 1.0f); glTexCoord2f(0.0f, 0.0f); glVertex3f(-40.0f,0.0f, -30.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f(-40.0f, 30.0f, -30.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f(40.0f, 30.0f, -30.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f(40.0f, 0.0f, -30.0f); glEnd(); //blackboard glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, texblackboard); glBegin(GL_QUADS); glNormal3f(0.0f, 0.0f, 1.0f); glTexCoord2f(0.0f, 0.0f);glVertex3f(-20.0,8.0f, -29.9f); glTexCoord2f(0.0f, 1.0f);glVertex3f(-20.0, 18.0f, -29.9f); glTexCoord2f(1.0f, 1.0f);glVertex3f(20.0, 18.0f, -29.9f); glTexCoord2f(1.0f, 0.0f);glVertex3f(20.0, 8.0f, -29.9f); glEnd(); glDisable(GL_TEXTURE_2D); //gaodi glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, texgaodi); //top glBegin(GL_QUADS); glNormal3f(0.0f, 1.0f, 0.0f); glTexCoord2f(0.0f, 0.0f);glVertex3f(-30.0f, 1.5f, -22.0f); glTexCoord2f(0.0f, 1.0f);glVertex3f(-30.0f, 1.5f, -30.0f); glTexCoord2f(1.0f, 1.0f);glVertex3f(30.0f, 1.5f, -30.0f); glTexCoord2f(1.0f, 0.0f);glVertex3f(30.0f, 1.5f, -22.0f); glEnd(); //down glBegin(GL_QUADS); glNormal3f(0.0f, 0.0f, 1.0f); glTexCoord2f(0.0f, 0.0f);glVertex3f(-30.0f, 0, -22.0f); glTexCoord2f(0.0f, 1.0f);glVertex3f(-30.0f, 1.5f, -22.0f); glTexCoord2f(1.0f, 1.0f);glVertex3f(-30.0f, 1.5f, -30.0f); glTexCoord2f(1.0f, 0.0f);glVertex3f(-30.0f, 0, -30.0f); glEnd(); //front glBegin(GL_QUADS); glNormal3f(0.0f, 1.0f, 0.0f); glTexCoord2f(0.0f, 0.0f);glVertex3f(-30.0f, 0, -22.0f); glTexCoord2f(0.0f, 1.0f);glVertex3f(-30.0f, 1.5f, -22.0f); glTexCoord2f(1.0f, 1.0f);glVertex3f(30.0f, 1.5f, -22.0f); glTexCoord2f(1.0f, 0.0f);glVertex3f(30.0f, 0, -22.0f); glEnd(); //back glBegin(GL_QUADS); glNormal3f(0.0f, 1.0f, 0.0f); glTexCoord2f(0.0f, 0.0f);glVertex3f(30.0f, 0, -22.0f); glTexCoord2f(0.0f, 1.0f);glVertex3f(30.0f, 1.5f, -22.0f); glTexCoord2f(1.0f, 1.0f);glVertex3f(30.0f, 1.5f, -30.0f); glTexCoord2f(1.0f, 0.0f);glVertex3f(30.0f, 0, -30.0f); glEnd(); glDisable(GL_TEXTURE_2D); //jiangtai glBindTexture(GL_TEXTURE_2D, textdesk); glEnable(GL_TEXTURE_2D); glBegin(GL_QUADS); glNormal3f(0.0f, 1.0f, 0.0f); glTexCoord2f(0.0f, 0.0f);glVertex3f(-7.5f, 1.5f, -24.0f); glTexCoord2f(0.0f, 1.0f);glVertex3f(-7.5f, 9.5f, -24.0f); glTexCoord2f(1.0f, 1.0f);glVertex3f(7.5f, 9.5f, -24.0f); glTexCoord2f(1.0f, 0.0f);glVertex3f(7.5f, 1.5f, -24.0f); glEnd(); glBegin(GL_QUADS); glNormal3f(0.0f, 1.0f, 0.0f); glTexCoord2f(0.0f, 0.0f);glVertex3f(7.5f, 1.5f, -24.0f); glTexCoord2f(0.0f, 1.0f);glVertex3f(7.5f, 9.5f, -24.0f); glTexCoord2f(1.0f, 1.0f);glVertex3f(7.5f, 9.5f, -28.0f); glTexCoord2f(1.0f, 0.0f);glVertex3f(7.5f, 1.5f, -28.0f); glEnd(); glBegin(GL_QUADS); glNormal3f(0.0f, 1.0f, 0.0f); glTexCoord2f(0.0f, 0.0f);glVertex3f(-7.5f, 1.5f, -24.0f); glTexCoord2f(0.0f, 1.0f);glVertex3f(-7.5f, 9.5f, -24.0f); glTexCoord2f(1.0f, 1.0f);glVertex3f(-7.5f, 9.5f, -28.0f); glTexCoord2f(1.0f, 0.0f);glVertex3f(-7.5f, 1.5f, -28.0f); glEnd(); glBegin(GL_QUADS); glNormal3f(0.0f, 1.0f, 0.0f); glTexCoord2f(0.0f, 0.0f);glVertex3f(-7.5f, 9.5f, -24.0f); glTexCoord2f(0.0f, 1.0f);glVertex3f(-7.5f, 9.5f, -26.0f); glTexCoord2f(1.0f, 1.0f);glVertex3f(7.5f, 9.5f, -26.0f); glTexCoord2f(1.0f, 0.0f);glVertex3f(7.5f, 9.5f, -24.0f); glEnd(); //door glColor3f(0.521f,0.121f,0.0547f); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, texdoor); glBegin(GL_QUADS); glNormal3f(-1.0f, 0.0f, 0.0f); glTexCoord2f(0.0f, 0.0f);glVertex3f(39.9f, 0.0f, -25.0f); glTexCoord2f(0.0f, 1.0f);glVertex3f(39.9f, 14.0f, -25.0f); glTexCoord2f(1.0f, 1.0f);glVertex3f(39.9f, 14.0f, -19.0f); glTexCoord2f(1.0f, 0.0f);glVertex3f(39.9f, 0.0f, -19.0f); glEnd(); glDisable(GL_TEXTURE_2D); } //draw the desks void drawdesks() { GLfloat desk[]={1,0.9647,0.56078}; for(int y=0;y<=2;y++) { for(int x=0;x<=1;x++) { //top glColor4f(1,0.9647,0.56078,1); glPushMatrix(); glTranslatef(-20.0+x*40,8.1,-17.5+y*8); glScalef(10,0.2,3); glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE,desk); glutSolidCube(1.0f); glPopMatrix(); //down glColor4f(1,0.9647,0.56078,1); glPushMatrix(); glTranslatef(-20.0+x*40,6.1,-17.5+y*8); glScalef(9,0.2,3); glutSolidCube(1.0f); glPopMatrix(); //front glColor4f(1,0.9647,0.56078,1); glPushMatrix(); glTranslatef(-20.0+x*40,7,-18.9+y*8); glScalef(10,2,0.2); glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE,desk); glutSolidCube(1.0f); glPopMatrix(); //leg glColor3f(0.0,0.0,0.0); glBegin(GL_LINES); glLineWidth(3.0f); glVertex3f(-25.0+x*40,6.0f, -19+y*8); glVertex3f(-25.0+x*40,0.0f, -19+y*8); glEnd(); glBegin(GL_LINES); glLineWidth(3.0f); glVertex3f(-15.0+x*40,6.0f, -19+y*8); glVertex3f(-15.0+x*40,0.0f, -19+y*8); glEnd(); glBegin(GL_LINES); glLineWidth(3.0f); glVertex3f(-25.0+x*40,0.0f, -18+y*8); glVertex3f(-25.0+x*40,0.0f, -20+y*8); glEnd(); glBegin(GL_LINES); glLineWidth(3.0f); glVertex3f(-15.0+x*40,0.0f, -18+y*8); glVertex3f(-15.0+x*40,0.0f, -20+y*8); glEnd(); } //for //the desks in the middle //top glColor3f(1,0.9647,0.56078); glPushMatrix(); glTranslatef(0,8.1,-17.5+y*8); glScalef(20,0.2,3); glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE,desk); glutSolidCube(1.0f); glPopMatrix(); //down glColor3f(1,0.9647,0.56078); glPushMatrix(); glTranslatef(0,6.1,-17.5+y*8); glScalef(19,0.2,3); glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE,desk); glutSolidCube(1.0f); glPopMatrix(); //front glColor3f(1,0.9647,0.56078); glPushMatrix(); glTranslatef(0,7,-18.9+y*8); glScalef(20,2,0.2); glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE,desk); glutSolidCube(1.0f); glPopMatrix(); //leg glColor3f(0.0,0.0,0.0); glBegin(GL_LINES); glLineWidth(3.0f); glVertex3f(-10.0,6.0f, -19+y*8); glVertex3f(-10.0,0.0f, -19+y*8); glEnd(); glBegin(GL_LINES); glLineWidth(3.0f); glVertex3f(10.0,6.0f, -19+y*8); glVertex3f(10.0,0.0f, -19+y*8); glEnd(); glBegin(GL_LINES); glLineWidth(3.0f); glVertex3f(-10.0,0.0f, -18+y*8); glVertex3f(-10,0.0f, -20+y*8); glEnd(); glBegin(GL_LINES); glLineWidth(3.0f); glVertex3f(10,0.0f, -18+y*8); glVertex3f(10,0.0f, -20+y*8); glEnd(); }//for } //drawchairs void drawchairs() { GLfloat chair[]={0.1,0.67,0.62}; for(int j=0;j<=2;j++){ for(int i=0;i<=1;i++){ //down glColor3f(0.1,0.67,0.62); glPushMatrix(); glTranslatef(-20+i*40,3.1,-14.5+j*8); glScalef(10,0.2,3); glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE,chair); glutSolidCube(1.0f); glPopMatrix(); //back glColor3f(0.1,0.67,0.62); glPushMatrix(); glTranslatef(-20+i*40,5,-13+j*8); glScalef(10,4,0.2); glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE,chair); glutSolidCube(1.0f); glPopMatrix(); //leg glColor3f(0.0,0.0,0.0); glBegin(GL_LINES); glLineWidth(3.0f); glVertex3f(-25+i*40,3.0f, -13+j*8); glVertex3f(-25+i*40,0.0f, -13+j*8); glEnd(); glColor3f(0.0,0.0,0.0); glBegin(GL_LINES); glLineWidth(3.0f); glVertex3f(-15.0+i*40,3.0f, -13+j*8); glVertex3f(-15.0+i*40,0.0f, -13+j*8); glEnd(); glColor3f(0.0,0.0,0.0); glBegin(GL_LINES); glLineWidth(3.0f); glVertex3f(-25.0+i*40,0.0f, -12.5+j*8); glVertex3f(-25+i*40,0.0f, -13.5+j*8); glEnd(); glColor3f(0.0,0.0,0.0); glBegin(GL_LINES); glLineWidth(3.0f); glVertex3f(-15+i*40,0.0f, -12.5+j*8); glVertex3f(-15+i*40,0.0f, -13.5+j*8); glEnd(); } //down glColor3f(0.1,0.67,0.62); glPushMatrix(); glTranslatef(0,3.1,-14.5+j*8); glScalef(20,0.2,3); glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE,chair); glutSolidCube(1.0f); glPopMatrix(); //back glColor3f(0.1,0.67,0.62); glPushMatrix(); glTranslatef(0,5,-13+j*8); glScalef(20,4,0.2); glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE,chair); glutSolidCube(1.0f); glPopMatrix(); //leg glColor3f(0.0,0.0,0.0); glBegin(GL_LINES); glLineWidth(3.0f); glVertex3f(-10,3.0f, -13+j*8); glVertex3f(-10,0.0f, -13+j*8); glEnd(); glColor3f(0.0,0.0,0.0); glBegin(GL_LINES); glLineWidth(3.0f); glVertex3f(10,3.0f, -13+j*8); glVertex3f(10,0.0f, -13+j*8); glEnd(); glColor3f(0.0,0.0,0.0); glBegin(GL_LINES); glLineWidth(3.0f); glVertex3f(-10,0.0f, -12.5+j*8); glVertex3f(-10,0.0f, -13.5+j*8); glEnd(); glColor3f(0.0,0.0,0.0); glBegin(GL_LINES); glLineWidth(3.0f); glVertex3f(10,0.0f, -12.5+j*8); glVertex3f(10,0.0f, -13.5+j*8); glEnd(); } } //reshape void reshape(int we,int he) { WinWidth=we; WinHeight=he; glViewport(0,0,(GLsizei) we, (GLsizei) he); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(90.0f, (GLfloat)we/(GLfloat)he, 0.01f,100.0f); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(myEye.x, myEye.y, myEye.z, vPoint.x+30*sin(vAngle), vPoint.y,-30*cos(vAngle), 0.0f, 1.0f, 0.0f); } void display() { glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); //the function of drawing drawscence(); //drawprojector(); drawdesks(); drawchairs(); glFlush(); } //the action of the keyboard GLvoid OnKeyboard(unsigned char key, int x, int y) { switch(key){ //left case 97: myEye.x-=0.5; vPoint.x-=0.5; if(myEye.x<=-40) myEye.x=-40; break; //right case 100: myEye.x+=0.5; vPoint.x+=0.5; if(myEye.x>=40) myEye.x=40; break; //down case 119: myEye.z-=0.5; if(myEye.z<=-30) myEye.z=-30; break; //up case 115: myEye.z+=0.5; if(myEye.z>=30) myEye.z=30; break; case 27: exit(0); } reshape(WinWidth,WinHeight); glutPostRedisplay(); } // the action of the special GLvoid OnSpecial(int key, int x, int y) { switch(key){ case GLUT_KEY_LEFT: vAngle-=0.5; break; case GLUT_KEY_RIGHT: vAngle+=0.5; break; case GLUT_KEY_UP: myEye.y+=0.5; if(myEye.y>=30) myEye.y=30; break; case GLUT_KEY_DOWN: myEye.y-=0.5; if(myEye.y<=0) myEye.y=30; break; case GLUT_KEY_PAGE_DOWN: myEye.z+=0.5; if(myEye.z>=30) myEye.z=30; break; case GLUT_KEY_PAGE_UP: myEye.z-=0.5; if(myEye.z<=-30) myEye.z=-30; break; } reshape(WinWidth,WinHeight); glutPostRedisplay(); } //idle function GLvoid OnIdle() { glutPostRedisplay(); } //initial function,initial many parameters including the light and so on void initial(){ glClearColor(0,0,0,0); glEnable(GL_TEXTURE_2D); glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_REPLACE);//set the mode of the current texture mapping glLightModelfv(GL_LIGHT_MODEL_AMBIENT,model_ambient); glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER,GL_TRUE); glMaterialfv(GL_FRONT,GL_SPECULAR,mat_specular); glMaterialfv(GL_FRONT,GL_SHININESS,mat_shininess); glLightfv(GL_LIGHT0,GL_POSITION,light_position0); glLightfv(GL_LIGHT0,GL_AMBIENT,mat_ambient); glLightfv(GL_LIGHT0,GL_DIFFUSE,light); glLightfv(GL_LIGHT0,GL_SPECULAR,light); glLightfv(GL_LIGHT1,GL_POSITION,light_position1); glLightfv(GL_LIGHT1,GL_AMBIENT,mat_ambient); glLightfv(GL_LIGHT1,GL_DIFFUSE,white_light); glLightfv(GL_LIGHT1,GL_SPECULAR,white_light); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_COLOR_MATERIAL); glShadeModel(GL_SMOOTH); //set the mode of the color(flat or smooth) glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE); glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular); glEnable(GL_DEPTH_TEST); } int main(int argc, char* argv[]) { myEye.x=0; myEye.y=15; myEye.z=25; vPoint.x=0; vPoint.y=15; vPoint.z=-30; vAngle=0; glEnable(GL_DEPTH_TEST); glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGBA | GLUT_SINGLE); glutInitWindowPosition(400, 0); glutInitWindowSize(800, 600); glutCreateWindow("Demo by zhpmatrix"); initial(); glutDisplayFunc(&display); glutReshapeFunc(reshape); glutKeyboardFunc(OnKeyboard); glutSpecialFunc(OnSpecial); glutIdleFunc(OnIdle); /* set the texture */ texblackboard=load_texture("blackboard.bmp"); texwindow=load_texture("window.bmp"); texgaodi=load_texture("gaodi.bmp"); texceiling=load_texture("Stone.jpg"); texdoor=load_texture("door.bmp"); texbackwall=load_texture("backwall.bmp"); textdesk=load_texture("tdesk.bmp"); glutMainLoop(); return 0; }
#include <windows.h> // Windows的头文件 #include <GL/glut.h> #include <stdio.h> #include <glaux.h> #include <math.h> // 数学库 #pragma comment(lib, "glaux.lib") #pragma comment(lib, "advapi32.lib") #pragma comment(lib, "legacy_stdio_definitions.lib") const float piover180 = 0.0174532925f; // π/180=0.0174532925用于乘以头部旋转角度heading float heading; // 头部旋转角度 float xpos; // x方向坐标 float zpos; // z方向坐标 GLfloat z=0.0f; // 头部上下旋转 typedef struct tagVERTEX// 创建Vertex顶点结构 { float x, y, z; // 3D 坐标 float u, v; // 纹理坐标 } VERTEX; typedef struct tagTRIANGLE//一个sector(区段)包含了一系列的多边形,所以我就定义了一个triangle(我的墙体、地板和天花板用三角形构成) { VERTEX vertex[3]; // VERTEX矢量数组,大小为3 } TRIANGLE; typedef struct tagSECTOR//每个3D世界基本上可以看作是sector(区段)的集合。一个sector可以是一个房间、一个立方体、或者任意一个闭合的区间 { int numtriangles; // Sector中的三角形个数 TRIANGLE* triangle;// 指向三角数组的指针 } SECTOR; SECTOR sector1; //创建一个世界 GLfloat xrot; // X 旋转量 GLfloat yrot; // Y 旋转量 BOOL light; // 光源的开/关 BOOL lp; // L键按下了么? bool blend; // 是否混合? bool bp; // B 键按下了么? GLfloat LightAmbient[]= { 0.5f, 0.5f, 0.5f, 1.0f }; // 环境光参数 GLfloat LightDiffuse[]= { 1.0f, 1.0f, 1.0f, 1.0f }; // 漫射光参数 GLfloat LightPosition[]= { 0.0f, 0.0f, 2.0f, 1.0f }; // 光源位置 GLuint texture[18]; // 18种纹理的储存空间 HDC hDC=NULL; // 窗口着色描述表句柄 HGLRC hRC=NULL; // OpenGL渲染描述表句柄 HWND hWnd=NULL; // 保存我们的窗口句柄 HINSTANCE hInstance; // 保存程序的实例 bool keys[256]; // 保存键盘按键的数组 bool active=TRUE; // 窗口的活动标志,缺省为TRUE bool fullscreen=TRUE; // 全屏标志缺省,缺省设定成全屏模式 LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); // WndProc的定义 //---------------读入字符串函数--------------------- void readstr(FILE *f,char *string) // 读入一个字符串 { do // 循环开始 { fgets(string, 255, f); // 读入一行 } while ((string[0] == ‘/‘) || (string[0] == ‘\n‘)); // 考察是否有必要进行处理 return; // 返回 } //-----------------------设置世界函数------------------------- void SetupWorld() // 设置我们的世界 { FILE *filein; // 工作文件 filein = fopen("data/world.txt", "rt"); // 打开文件 int numtriangles; // 区段中的三角形数量 char oneline[255]; // 存储数据的字符串 float x, y, z, u, v; // 3D 和 纹理坐标 readstr(filein,oneline); // 读入一行数据 sscanf(oneline, "NUMPOLLIES %d\n", &numtriangles); // 读入三角形数量 sector1.triangle = new TRIANGLE[numtriangles]; // 为numtriangles个三角形分配内存并设定指针 sector1.numtriangles = numtriangles; // 定义区段1中的三角形数量 // 遍历区段中的每个三角形 for (int triloop = 0; triloop < numtriangles; triloop++)// 遍历所有的三角形 { // 遍历三角形的每个顶点 for (int vertloop = 0; vertloop < 3; vertloop++) // 遍历所有的顶点 { readstr(filein,oneline); // 读入一行数据 // 读入各自的顶点数据 sscanf(oneline, "%f %f %f %f %f", &x, &y, &z, &u, &v); // 将顶点数据存入各自的顶点 sector1.triangle[triloop].vertex[vertloop].x = x; // 区段 1, 第 triloop 个三角形, 第 vertloop 个顶点, 值 x =x sector1.triangle[triloop].vertex[vertloop].y = y; // 区段 1, 第 triloop 个三角形, 第 vertloop 个顶点, 值 y =y sector1.triangle[triloop].vertex[vertloop].z = z; // 区段 1, 第 triloop 个三角形, 第 vertloop 个顶点, 值 z =z sector1.triangle[triloop].vertex[vertloop].u = u; // 区段 1, 第 triloop 个三角形, 第 vertloop 个顶点, 值 u =u sector1.triangle[triloop].vertex[vertloop].v = v; // 区段 1, 第 triloop 个三角形, 第 vertloop 个顶点, 值 e=v } } fclose(filein); return; // 返回 } AUX_RGBImageRec *LoadBMP(CHAR *Filename) // 载入位图图象 { FILE *File=NULL; // 文件句柄 if (!Filename) // 确保文件名已提供 { return NULL; // 如果没提供,返回 NULL } File=fopen(Filename,"r"); // 尝试打开文件 if (File) // 文件存在么? { fclose(File); // 关闭句柄 return auxDIBImageLoadA(Filename); // 载入位图并返回指针 } return NULL; // 如果载入失败,返回 NULL } int LoadGLTextures() // 载入位图(调用上面的代码)并转换成纹理 { int Status=FALSE; // 状态指示器 AUX_RGBImageRec *TextureImage[18]; // 创建纹理的存储空间 memset(TextureImage,0,sizeof(void *)*1); // 将指针设为 NULL //------------------------载入纹理图片------------------------// if (TextureImage[0]=LoadBMP("Data/ceiling.bmp")) { Status=TRUE; // 状态设为 TRUE glGenTextures(1, &texture[0]); // 创建纹理 // 创建线性滤波纹理 glBindTexture(GL_TEXTURE_2D, texture[0]); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data); } if (TextureImage[1]=LoadBMP("Data/door.bmp")) { Status=TRUE; // 状态设为 TRUE glGenTextures(1, &texture[1]); // 创建纹理 // 创建线性滤波纹理 glBindTexture(GL_TEXTURE_2D, texture[1]); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[1]->sizeX, TextureImage[1]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[1]->data); } if (TextureImage[2]=LoadBMP("Data/floor.bmp")) { Status=TRUE; // 状态设为 TRUE glGenTextures(1, &texture[2]); // 创建纹理 // 创建线性滤波纹理 glBindTexture(GL_TEXTURE_2D, texture[2]); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[2]->sizeX, TextureImage[2]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[2]->data); } if (TextureImage[3]=LoadBMP("Data/lblackboard.bmp")) { Status=TRUE; // 状态设为 TRUE glGenTextures(1, &texture[3]); // 创建纹理 // 创建线性滤波纹理 glBindTexture(GL_TEXTURE_2D, texture[3]); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[3]->sizeX, TextureImage[3]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[3]->data); } if (TextureImage[4]=LoadBMP("Data/rblackboard.bmp")) { Status=TRUE; // 状态设为 TRUE glGenTextures(1, &texture[4]); // 创建纹理 // 创建线性滤波纹理 glBindTexture(GL_TEXTURE_2D, texture[4]); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[4]->sizeX, TextureImage[4]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[4]->data); } if (TextureImage[5]=LoadBMP("Data/wall.bmp")) { Status=TRUE; // 状态设为 TRUE glGenTextures(1, &texture[5]); // 创建纹理 // 创建线性滤波纹理 glBindTexture(GL_TEXTURE_2D, texture[5]); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[5]->sizeX, TextureImage[5]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[5]->data); } if (TextureImage[6]=LoadBMP("Data/window.bmp")) { Status=TRUE; // 状态设为 TRUE glGenTextures(1, &texture[6]); // 创建纹理 // 创建线性滤波纹理 glBindTexture(GL_TEXTURE_2D, texture[6]); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[6]->sizeX, TextureImage[6]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[6]->data); } if (TextureImage[7]=LoadBMP("Data/desk.bmp")) { Status=TRUE; // 状态设为 TRUE glGenTextures(1, &texture[7]); // 创建纹理 // 创建线性滤波纹理 glBindTexture(GL_TEXTURE_2D, texture[7]); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[7]->sizeX, TextureImage[7]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[7]->data); } if (TextureImage[8]=LoadBMP("Data/air.bmp")) { Status=TRUE; // 状态设为 TRUE glGenTextures(1, &texture[8]); // 创建纹理 // 创建线性滤波纹理 glBindTexture(GL_TEXTURE_2D, texture[8]); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[8]->sizeX, TextureImage[8]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[8]->data); } if (TextureImage[9]=LoadBMP("Data/air-sides.bmp")) { Status=TRUE; // 状态设为 TRUE glGenTextures(1, &texture[9]); // 创建纹理 // 创建线性滤波纹理 glBindTexture(GL_TEXTURE_2D, texture[9]); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[9]->sizeX, TextureImage[9]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[9]->data); } if (TextureImage[10]=LoadBMP("Data/laptop.bmp")) { Status=TRUE; // 状态设为 TRUE glGenTextures(1, &texture[10]); // 创建纹理 // 创建线性滤波纹理 glBindTexture(GL_TEXTURE_2D, texture[10]); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[10]->sizeX, TextureImage[10]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[10]->data); } if (TextureImage[11]=LoadBMP("Data/laptop-sides.bmp")) { Status=TRUE; // 状态设为 TRUE glGenTextures(1, &texture[11]); // 创建纹理 // 创建线性滤波纹理 glBindTexture(GL_TEXTURE_2D, texture[11]); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[11]->sizeX, TextureImage[11]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[11]->data); } if (TextureImage[12]=LoadBMP("Data/voice box.bmp")) { Status=TRUE; // 状态设为 TRUE glGenTextures(1, &texture[12]); // 创建纹理 // 创建线性滤波纹理 glBindTexture(GL_TEXTURE_2D, texture[12]); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[12]->sizeX, TextureImage[12]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[12]->data); } if (TextureImage[13]=LoadBMP("Data/blackboard.bmp")) { Status=TRUE; // 状态设为 TRUE glGenTextures(1, &texture[13]); // 创建纹理 // 创建线性滤波纹理 glBindTexture(GL_TEXTURE_2D, texture[13]); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[13]->sizeX, TextureImage[13]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[13]->data); } if (TextureImage[14]=LoadBMP("Data/blackboard-sides.bmp")) { Status=TRUE; // 状态设为 TRUE glGenTextures(1, &texture[14]); // 创建纹理 // 创建线性滤波纹理 glBindTexture(GL_TEXTURE_2D, texture[14]); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[14]->sizeX, TextureImage[14]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[14]->data); } if (TextureImage[15]=LoadBMP("Data/projector.bmp")) { Status=TRUE; // 状态设为 TRUE glGenTextures(1, &texture[15]); // 创建纹理 // 创建线性滤波纹理 glBindTexture(GL_TEXTURE_2D, texture[15]); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[15]->sizeX, TextureImage[15]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[15]->data); } if (TextureImage[16]=LoadBMP("Data/zhuzi.bmp")) { Status=TRUE; // 状态设为 TRUE glGenTextures(1, &texture[16]); // 创建纹理 // 创建线性滤波纹理 glBindTexture(GL_TEXTURE_2D, texture[16]); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[16]->sizeX, TextureImage[16]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[16]->data); } if (TextureImage[17]=LoadBMP("Data/projector-sides.bmp")) { Status=TRUE; // 状态设为 TRUE glGenTextures(1, &texture[17]); // 创建纹理 // 创建线性滤波纹理 glBindTexture(GL_TEXTURE_2D, texture[17]); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[17]->sizeX, TextureImage[17]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[17]->data); } for(char h=17;h>0;h--){ if (TextureImage[h]) // 纹理是否存在 { if (TextureImage[h]->data) // 纹理图像是否存在 { free(TextureImage[h]->data); // 释放纹理图像占用的内存 } free(TextureImage[h]); // 释放图像结构 } } return Status; // 返回 Status } GLvoid ReSizeGLScene(GLsizei width, GLsizei height) // 重置OpenGL窗口大小 { if (height==0) // 防止被零除 { height=1; // 将Height设为1 } glViewport(0,0,width,height); // 重置当前的视口 glMatrixMode(GL_PROJECTION); // 选择投影矩阵 glLoadIdentity(); // 重置投影矩阵 // 设置视口的大小 gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f); glMatrixMode(GL_MODELVIEW); // 选择模型观察矩阵 glLoadIdentity(); // 重置模型观察矩阵 } int InitGL(GLvoid) // 此处开始对OpenGL进行所有设置 { if (!LoadGLTextures()) // 调用纹理载入子例程 { return FALSE; // 如果未能载入,返回FALSE } glLightfv(GL_LIGHT1, GL_AMBIENT, LightAmbient); // 设置环境光 glLightfv(GL_LIGHT1, GL_DIFFUSE, LightDiffuse); // 设置漫射光 glLightfv(GL_LIGHT1, GL_POSITION,LightPosition); // 设置光源位置 glEnable(GL_LIGHT1); // 启用一号光源 glEnable(GL_TEXTURE_2D); // 启用纹理映射 glShadeModel(GL_SMOOTH); // 启用阴影平滑 glClearColor(0.0f, 0.0f, 0.0f, 0.5f); // 黑色背景 glClearDepth(1.0f); // 设置深度缓存 glEnable(GL_DEPTH_TEST); // 启用深度测试 glDepthFunc(GL_LEQUAL); // 所作深度测试的类型 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // 告诉系统对透视进行修正 glColor4f(1.0f,1.0f,1.0f,0.5f); // 全亮度, 50% Alpha 混合 glBlendFunc(GL_SRC_ALPHA,GL_ONE); // 基于源象素alpha通道值的半透明混合函数 SetupWorld(); return TRUE; // 初始化 OK } int DrawGLScene(GLvoid) // 从这里开始进行所有的绘制 { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // 清除屏幕和深度缓存 glLoadIdentity(); // 重置当前的模型观察矩阵 GLfloat x_m, y_m, z_m, u_m, v_m; // 顶点的临时 X, Y, Z, U 和 V 的数值 GLfloat xtrans = -xpos; // 用于游戏者沿X轴平移时的大小 GLfloat ztrans = -zpos; // 用于游戏者沿Z轴平移时的大小 GLfloat ytrans = -0.7; // 用于设置游戏者头部高度 GLfloat sceneroty = 360.0f - yrot; // 位于游戏者方向的360度角 int numtriangles; // 保有三角形数量的整数 glRotatef(z,1.0f,0,0); // 上下旋转 glRotatef(sceneroty,0,1.0f,0); // 根据游戏者正面所对方向所作的旋转 glTranslatef(xtrans, ytrans, ztrans); // 以游戏者为中心的平移场景 numtriangles = sector1.numtriangles; // 取得Sector1的三角形数量 // 逐个处理三角形 for (int loop_m = 0; loop_m < numtriangles; loop_m++) // 遍历所有的三角形 { if(loop_m==0||loop_m==1) glBindTexture(GL_TEXTURE_2D, texture[2]); //根据墙壁的位置绑定纹理 if(loop_m==2||loop_m==3) glBindTexture(GL_TEXTURE_2D, texture[0]); if(loop_m==4||loop_m==5) glBindTexture(GL_TEXTURE_2D, texture[3]); if(loop_m==6||loop_m==7) glBindTexture(GL_TEXTURE_2D, texture[4]); if(loop_m==8||loop_m==9) glBindTexture(GL_TEXTURE_2D, texture[5]); if(loop_m==10||loop_m==11) glBindTexture(GL_TEXTURE_2D, texture[5]); if(loop_m==12||loop_m==13) glBindTexture(GL_TEXTURE_2D, texture[6]); if(loop_m==14||loop_m==15) glBindTexture(GL_TEXTURE_2D, texture[6]); if(loop_m==16||loop_m==17) glBindTexture(GL_TEXTURE_2D, texture[6]); if(loop_m==18||loop_m==19) glBindTexture(GL_TEXTURE_2D, texture[1]); glBegin(GL_TRIANGLES); // 开始绘制三角形 glNormal3f( 0.0f, 0.0f, 1.0f); // 指向前面的法线 x_m = sector1.triangle[loop_m].vertex[0].x; // 第一点的 X 分量 y_m = sector1.triangle[loop_m].vertex[0].y; // 第一点的 Y 分量 z_m = sector1.triangle[loop_m].vertex[0].z; // 第一点的 Z 分量 u_m = sector1.triangle[loop_m].vertex[0].u; // 第一点的 U 纹理坐标 v_m = sector1.triangle[loop_m].vertex[0].v; // 第一点的 V 纹理坐标 glTexCoord2f(u_m,v_m); glVertex3f(x_m,y_m,z_m); // 设置纹理坐标和顶点 x_m = sector1.triangle[loop_m].vertex[1].x; // 第二点的 X 分量 y_m = sector1.triangle[loop_m].vertex[1].y; // 第二点的 Y 分量 z_m = sector1.triangle[loop_m].vertex[1].z; // 第二点的 Z 分量 u_m = sector1.triangle[loop_m].vertex[1].u; // 第二点的 U 纹理坐标 v_m = sector1.triangle[loop_m].vertex[1].v; // 第二点的 V 纹理坐标 glTexCoord2f(u_m,v_m); glVertex3f(x_m,y_m,z_m); // 设置纹理坐标和顶点 x_m = sector1.triangle[loop_m].vertex[2].x; // 第三点的 X 分量 y_m = sector1.triangle[loop_m].vertex[2].y; // 第三点的 Y 分量 z_m = sector1.triangle[loop_m].vertex[2].z; // 第三点的 Z 分量 u_m = sector1.triangle[loop_m].vertex[2].u; // 第二点的 U 纹理坐标 v_m = sector1.triangle[loop_m].vertex[2].v; // 第二点的 V 纹理坐标 glTexCoord2f(u_m,v_m); glVertex3f(x_m,y_m,z_m); // 设置纹理坐标和顶点 glEnd();// 三角形绘制结束 } //绘制其他的物体: glBindTexture(GL_TEXTURE_2D, texture[7]); glBegin(GL_QUADS); glTexCoord2f(0,1);glVertex3f(-1.0f, 0.4f, -2.0f); // 课桌上面 glTexCoord2f(0,0);glVertex3f(-1.0f, 0.4f, -1.0f); // glTexCoord2f(1,0);glVertex3f( 1.0f, 0.4f, -1.0f); // glTexCoord2f(1,1);glVertex3f( 1.0f, 0.4f, -2.0f); // glTexCoord2f(0,1);glVertex3f(-1.0f, 0.0f, -2.0f); // 课桌下面 glTexCoord2f(0,0);glVertex3f(-1.0f, 0.0f, -1.0f); // glTexCoord2f(1,0);glVertex3f( 1.0f,-0.0f, -1.0f); // glTexCoord2f(1,1);glVertex3f( 1.0f,-0.0f, -2.0f); // glTexCoord2f(0,1);glVertex3f(-1.0f, 0.4f, -2.0f); // 课桌后面 glTexCoord2f(0,0);glVertex3f(-1.0f, 0.0f, -2.0f); // glTexCoord2f(1,0);glVertex3f( 1.0f, 0.0f, -2.0f); // glTexCoord2f(1,1);glVertex3f( 1.0f, 0.4f, -2.0f); // glTexCoord2f(0,1);glVertex3f(-1.0f, 0.4f, -1.0f); // 课桌前面 glTexCoord2f(0,0);glVertex3f(-1.0f, 0.0f, -1.0f); // glTexCoord2f(1,0);glVertex3f( 1.0f, 0.0f, -1.0f); // glTexCoord2f(1,1);glVertex3f( 1.0f, 0.4f, -1.0f); // glTexCoord2f(0,1);glVertex3f(-1.0f, 0.4f, -2.0f); // 课桌左面 glTexCoord2f(0,0);glVertex3f(-1.0f, 0.0f, -2.0f); // glTexCoord2f(1,0);glVertex3f(-1.0f, 0.0f, -1.0f); // glTexCoord2f(1,1);glVertex3f(-1.0f, 0.4f, -1.0f); // glTexCoord2f(0,1);glVertex3f( 1.0f, 0.4f, -1.0f); // 课桌右面 glTexCoord2f(0,0);glVertex3f( 1.0f, 0.0f, -1.0f); // glTexCoord2f(1,0);glVertex3f( 1.0f, 0.0f, -2.0f); // glTexCoord2f(1,1);glVertex3f( 1.0f, 0.4f, -2.0f); // glEnd(); glBindTexture(GL_TEXTURE_2D, texture[8]); glBegin(GL_QUADS); glTexCoord2f(0,1);glVertex3f( 3.0f, 2.0f, 2.6f); // 空调前面 glTexCoord2f(0,0);glVertex3f( 3.0f, 1.6f, 2.6f); // glTexCoord2f(1,0);glVertex3f( 1.0f, 1.6f, 2.6f); // glTexCoord2f(1,1);glVertex3f( 1.0f, 2.0f, 2.6f); // glEnd(); glBindTexture(GL_TEXTURE_2D, texture[9]); glBegin(GL_QUADS); glTexCoord2f(0,1);glVertex3f( 3.0f, 1.6f, 2.6f); // 空调下面 glTexCoord2f(0,0);glVertex3f( 3.0f, 1.6f, 3.0f); // glTexCoord2f(1,0);glVertex3f( 1.0f, 1.6f, 3.0f); // glTexCoord2f(1,1);glVertex3f( 1.0f, 1.6f, 2.6f); // glTexCoord2f(0,1);glVertex3f( 1.0f, 2.0f, 2.6f); // 空调右面 glTexCoord2f(0,0);glVertex3f( 1.0f, 1.6f, 2.6f); // glTexCoord2f(1,0);glVertex3f( 1.0f, 1.6f, 3.0f); // glTexCoord2f(1,1);glVertex3f( 1.0f, 2.0f, 3.0f); // glEnd(); glBindTexture(GL_TEXTURE_2D, texture[10]); glBegin(GL_QUADS); glTexCoord2f(0,1);glVertex3f( 0.8f, 0.41f, -1.7f); // 电脑正面 glTexCoord2f(0,0);glVertex3f( 0.8f, 0.41f, -1.9f); // glTexCoord2f(1,0);glVertex3f( 0.5f, 0.41f, -1.9f); // glTexCoord2f(1,1);glVertex3f( 0.5f, 0.41f, -1.7f); // glEnd(); glBindTexture(GL_TEXTURE_2D, texture[11]); glBegin(GL_QUADS); glTexCoord2f(0,1);glVertex3f( 0.8f, 0.41f, -1.7f); // 电脑侧面 glTexCoord2f(0,0);glVertex3f( 0.8f, 0.40f, -1.7f); // glTexCoord2f(1,0);glVertex3f( 0.8f, 0.40f, -1.9f); // glTexCoord2f(1,1);glVertex3f( 0.8f, 0.41f, -1.9f); // glTexCoord2f(0,1);glVertex3f( 0.5f, 0.41f, -1.7f); // 电脑侧面 glTexCoord2f(0,0);glVertex3f( 0.5f, 0.40f, -1.7f); // glTexCoord2f(1,0);glVertex3f( 0.8f, 0.40f, -1.7f); // glTexCoord2f(1,1);glVertex3f( 0.8f, 0.41f, -1.7f); // glTexCoord2f(0,1);glVertex3f( 0.5f, 0.41f, -1.9f); // 电脑侧面 glTexCoord2f(0,0);glVertex3f( 0.5f, 0.40f, -1.9f); // glTexCoord2f(1,0);glVertex3f( 0.5f, 0.40f, -1.7f); // glTexCoord2f(1,1);glVertex3f( 0.5f, 0.41f, -1.7f); // glTexCoord2f(0,1);glVertex3f( 0.8f, 0.41f, -1.9f); // 电脑侧面 glTexCoord2f(0,0);glVertex3f( 0.8f, 0.40f, -1.9f); // glTexCoord2f(1,0);glVertex3f( 0.5f, 0.40f, -1.9f); // glTexCoord2f(1,1);glVertex3f( 0.5f, 0.41f, -1.9f); // glEnd(); glBindTexture(GL_TEXTURE_2D, texture[12]); glBegin(GL_QUADS); glTexCoord2f(0,1);glVertex3f( 2.8f, 2.0f, -2.8f); // 右音箱正面 glTexCoord2f(0,0);glVertex3f( 2.8f, 1.7f, -2.8f); // glTexCoord2f(1,0);glVertex3f( 3.0f, 1.7f, -2.8f); // glTexCoord2f(1,1);glVertex3f( 3.0f, 2.0f, -2.8f); // glTexCoord2f(0,1);glVertex3f( -2.8f, 2.0f, -2.8f); // 左音箱正面 glTexCoord2f(0,0);glVertex3f( -2.8f, 1.7f, -2.8f); // glTexCoord2f(1,0);glVertex3f( -3.0f, 1.7f, -2.8f); // glTexCoord2f(1,1);glVertex3f( -3.0f, 2.0f, -2.8f); // glEnd(); glBindTexture(GL_TEXTURE_2D, texture[2]); glBegin(GL_QUADS); glTexCoord2f(0,1);glVertex3f( 2.8f, 2.0f, -3.0f); // 右音箱侧面 glTexCoord2f(0,0);glVertex3f( 2.8f, 1.7f, -3.0f); // glTexCoord2f(1,0);glVertex3f( 2.8f, 1.7f, -2.8f); // glTexCoord2f(1,1);glVertex3f( 2.8f, 2.0f, -2.8f); // glTexCoord2f(0,1);glVertex3f( -2.8f, 2.0f, -3.0f); // 左音箱侧面 glTexCoord2f(0,0);glVertex3f( -2.8f, 1.7f, -3.0f); // glTexCoord2f(1,0);glVertex3f( -2.8f, 1.7f, -2.8f); // glTexCoord2f(1,1);glVertex3f( -2.8f, 2.0f, -2.8f); // glTexCoord2f(0,1);glVertex3f( 2.8f, 1.7f, -3.0f); // 右音箱下面 glTexCoord2f(0,0);glVertex3f( 2.8f, 1.7f, -2.8f); // glTexCoord2f(1,0);glVertex3f( 3.0f, 1.7f, -2.8f); // glTexCoord2f(1,1);glVertex3f( 3.0f, 1.7f, -3.0f); // glTexCoord2f(0,1);glVertex3f( -2.8f, 1.7f, -3.0f); // 左音箱下面 glTexCoord2f(0,0);glVertex3f( -2.8f, 1.7f, -2.8f); // glTexCoord2f(1,0);glVertex3f( -3.0f, 1.7f, -2.8f); // glTexCoord2f(1,1);glVertex3f( -3.0f, 1.7f, -3.0f); // glEnd(); glBindTexture(GL_TEXTURE_2D, texture[13]); glBegin(GL_QUADS); glTexCoord2f(0,1);glVertex3f( -2.1f, 1.8f, -2.95f); // 黑板正面 glTexCoord2f(0,0);glVertex3f( -2.1f, 0.5f, -2.95f); // glTexCoord2f(1,0);glVertex3f( 2.1f, 0.5f, -2.95f); // glTexCoord2f(1,1);glVertex3f( 2.1f, 1.8f, -2.95f); // glEnd(); glBindTexture(GL_TEXTURE_2D, texture[14]); glBegin(GL_QUADS); glTexCoord2f(0,1);glVertex3f( 2.1f, 1.8f, -2.95f); // 黑板侧面 glTexCoord2f(0,0);glVertex3f( 2.1f, 0.5f, -2.95f); // glTexCoord2f(1,0);glVertex3f( 2.1f, 0.5f, -3.0f); // glTexCoord2f(1,1);glVertex3f( 2.1f, 1.8f, -3.0f); // glTexCoord2f(0,1);glVertex3f( -2.1f, 1.8f, -3.0f); // 黑板侧面 glTexCoord2f(0,0);glVertex3f( -2.1f, 1.8f, -2.95f); // glTexCoord2f(1,0);glVertex3f( 2.1f, 1.8f, -2.95f); // glTexCoord2f(1,1);glVertex3f( 2.1f, 1.8f, -3.0f); // glTexCoord2f(0,1);glVertex3f( -2.1f, 1.8f, -3.0f); // 黑板侧面 glTexCoord2f(0,0);glVertex3f( -2.1f, 0.5f, -3.0f); // glTexCoord2f(1,0);glVertex3f( -2.1f, 0.5f, -2.95f); // glTexCoord2f(1,1);glVertex3f( -2.1f, 1.8f, -2.95f); // glTexCoord2f(0,1);glVertex3f( -2.1f, 0.5f, -3.0f); // 黑板侧面 glTexCoord2f(0,0);glVertex3f( -2.1f, 0.5f, -2.95f); // glTexCoord2f(1,0);glVertex3f( 2.1f, 0.5f, -2.95f); // glTexCoord2f(1,1);glVertex3f( 2.1f, 0.5f, -3.0f); // glEnd(); glBindTexture(GL_TEXTURE_2D, texture[14]); glBegin(GL_QUADS); glTexCoord2f(0,1);glVertex3f( -0.6f, 2.0f, -2.90f); // 投影仪画布右 glTexCoord2f(0,0);glVertex3f( -0.6f, 1.9f, -2.90f); // glTexCoord2f(1,0);glVertex3f( -0.6f, 1.9f, -3.0f); // glTexCoord2f(1,1);glVertex3f( -0.6f, 2.0f, -3.0f); // glTexCoord2f(0,1);glVertex3f( -2.6f, 2.0f, -2.9f); // 投影仪画布前 glTexCoord2f(0,0);glVertex3f( -2.6f, 1.9f, -2.9f); // glTexCoord2f(1,0);glVertex3f( -0.6f, 1.9f, -2.9f); // glTexCoord2f(1,1);glVertex3f( -0.6f, 2.0f, -2.9f); // glTexCoord2f(0,1);glVertex3f( -2.6f, 1.9f, -2.9f); // 投影仪画布下 glTexCoord2f(0,0);glVertex3f( -2.6f, 1.9f, -3.0f); // glTexCoord2f(1,0);glVertex3f( -0.6f, 1.9f, -3.0f); // glTexCoord2f(1,1);glVertex3f( -0.6f, 1.9f, -2.9f); // glTexCoord2f(0,1);glVertex3f( -2.6f, 2.0f, -3.0f); // 投影仪画布左 glTexCoord2f(0,0);glVertex3f( -2.6f, 1.9f, -3.0f); // glTexCoord2f(1,0);glVertex3f( -2.6f, 1.9f, -2.9f); // glTexCoord2f(1,1);glVertex3f( -2.6f, 2.0f, -2.9f); // glEnd(); glBindTexture(GL_TEXTURE_2D, texture[16]); glBegin(GL_QUADS); glTexCoord2f(0,1);glVertex3f( -1.55f, 2.0f, -0.1f); // 投影仪柱子前 glTexCoord2f(0,0);glVertex3f( -1.55f, 1.6f, -0.1f); // glTexCoord2f(1,0);glVertex3f( -1.65f, 1.6f, -0.1f); // glTexCoord2f(1,1);glVertex3f( -1.65f, 2.0f, -0.1f); // glTexCoord2f(0,1);glVertex3f( -1.65f, 2.0f, -0.0f); // 投影仪柱子后 glTexCoord2f(0,0);glVertex3f( -1.65f, 1.6f, -0.0f); // glTexCoord2f(1,0);glVertex3f( -1.55f, 1.6f, -0.0f); // glTexCoord2f(1,1);glVertex3f( -1.55f, 2.0f, -0.0f); // glTexCoord2f(0,1);glVertex3f( -1.65f, 2.0f, -0.1f); // 投影仪柱子左 glTexCoord2f(0,0);glVertex3f( -1.65f, 1.6f, -0.1f); // glTexCoord2f(1,0);glVertex3f( -1.65f, 1.6f, -0.0f); // glTexCoord2f(1,1);glVertex3f( -1.65f, 2.0f, -0.0f); // glTexCoord2f(0,1);glVertex3f( -1.55f, 2.0f, -0.0f); // 投影仪柱子右 glTexCoord2f(0,0);glVertex3f( -1.55f, 1.6f, -0.0f); // glTexCoord2f(1,0);glVertex3f( -1.55f, 1.6f, -0.1f); // glTexCoord2f(1,1);glVertex3f( -1.55f, 2.0f, -0.1f); // glEnd(); glBindTexture(GL_TEXTURE_2D, texture[15]); glBegin(GL_QUADS); glTexCoord2f(0,1);glVertex3f( -1.25f, 1.6f, -0.4f); // 投影仪前 glTexCoord2f(0,0);glVertex3f( -1.25f, 1.5f, -0.4f); // glTexCoord2f(1,0);glVertex3f( -1.85f, 1.5f, -0.4f); // glTexCoord2f(1,1);glVertex3f( -1.85f, 1.6f, -0.4f); // glEnd(); glBindTexture(GL_TEXTURE_2D, texture[17]); glBegin(GL_QUADS); glTexCoord2f(0,1);glVertex3f( -1.85f, 1.6f, 0.2f); // 投影仪后 glTexCoord2f(0,0);glVertex3f( -1.85f, 1.5f, 0.2f); // glTexCoord2f(1,0);glVertex3f( -1.25f, 1.5f, 0.2f); // glTexCoord2f(1,1);glVertex3f( -1.25f, 1.6f, 0.2f); // glTexCoord2f(0,1);glVertex3f( -1.85f, 1.6f, -0.4f); // 投影仪左 glTexCoord2f(0,0);glVertex3f( -1.85f, 1.5f, -0.4f); // glTexCoord2f(1,0);glVertex3f( -1.85f, 1.5f, 0.2f); // glTexCoord2f(1,1);glVertex3f( -1.85f, 1.6f, 0.2f); // glTexCoord2f(0,1);glVertex3f( -1.25f, 1.6f, 0.2f); // 投影仪右 glTexCoord2f(0,0);glVertex3f( -1.25f, 1.5f, 0.2f); // glTexCoord2f(1,0);glVertex3f( -1.25f, 1.5f, -0.4f); // glTexCoord2f(1,1);glVertex3f( -1.25f, 1.6f, -0.4f); // glTexCoord2f(0,1);glVertex3f( -1.85f, 1.6f, -0.4f); // 投影仪上 glTexCoord2f(0,0);glVertex3f( -1.85f, 1.6f, 0.2f); // glTexCoord2f(1,0);glVertex3f( -1.25f, 1.6f, 0.2f); // glTexCoord2f(1,1);glVertex3f( -1.25f, 1.6f, -0.4f); // glTexCoord2f(0,1);glVertex3f( -1.85f, 1.5f, -0.4f); // 投影仪下 glTexCoord2f(0,0);glVertex3f( -1.85f, 1.5f, 0.2f); // glTexCoord2f(1,0);glVertex3f( -1.25f, 1.5f, 0.2f); // glTexCoord2f(1,1);glVertex3f( -1.25f, 1.5f, -0.4f); // glEnd(); return TRUE; // 一切 OK } GLvoid KillGLWindow(GLvoid) // 正常销毁窗口 { if (fullscreen) // 我们处于全屏模式吗? { ChangeDisplaySettings(NULL,0); // 是的话,切换回桌面 ShowCursor(TRUE); // 显示鼠标指针 } if (hRC) //我们拥有OpenGL描述表吗? { if (!wglMakeCurrent(NULL,NULL)) // 我们能否释放DC和RC描述表? { MessageBox(NULL,"释放DC或RC失败。","关闭错误",MB_OK | MB_ICONINFORMATION); } if (!wglDeleteContext(hRC)) // 我们能否删除RC? { MessageBox(NULL,"释放RC失败。","关闭错误",MB_OK | MB_ICONINFORMATION); } hRC=NULL; // 将RC设为 NULL } if (hDC && !ReleaseDC(hWnd,hDC)) // 我们能否释放 DC? { MessageBox(NULL,"释放DC失败。","关闭错误",MB_OK | MB_ICONINFORMATION); hDC=NULL; // 将 DC 设为 NULL } if (hWnd && !DestroyWindow(hWnd)) // 能否销毁窗口? { MessageBox(NULL,"释放窗口句柄失败。","关闭错误",MB_OK | MB_ICONINFORMATION); hWnd=NULL; // 将 hWnd 设为 NULL } if (!UnregisterClass("OpenG",hInstance)) // 能否注销类? { MessageBox(NULL,"不能注销窗口类。","关闭错误",MB_OK | MB_ICONINFORMATION); hInstance=NULL; // 将 hInstance 设为 NULL } } /* 这个函数创建我们OpenGL窗口,参数为: * * title - 窗口标题 * * width - 窗口宽度 * * height - 窗口高度 * * bits - 颜色的位深(8/16/32) * * fullscreenflag - 是否使用全屏模式,全屏模式(TRUE),窗口模式(FALSE) */ BOOL CreateGLWindow(char* title, int width, int height, int bits, bool fullscreenflag) { GLuint PixelFormat; // 保存查找匹配的结果 WNDCLASS wc; // 窗口类结构 DWORD dwExStyle; // 扩展窗口风格 DWORD dwStyle; // 窗口风格 RECT WindowRect; // 取得矩形的左上角和右下角的坐标值 WindowRect.left=(long)0; // 将Left 设为 0 WindowRect.right=(long)width; // 将Right 设为要求的宽度 WindowRect.top=(long)0; // 将Top 设为 0 WindowRect.bottom=(long)height; // 将Bottom 设为要求的高度 fullscreen=fullscreenflag; // 设置全局全屏标志 hInstance = GetModuleHandle(NULL); // 取得我们窗口的实例 wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; // 移动时重画,并为窗口取得DC wc.lpfnWndProc = (WNDPROC) WndProc; // WndProc处理消息 wc.cbClsExtra = 0; // 无额外窗口数据 wc.cbWndExtra = 0; // 无额外窗口数据 wc.hInstance = hInstance; // 设置实例 wc.hIcon = LoadIcon(NULL, IDI_WINLOGO); // 装入缺省图标 wc.hCursor = LoadCursor(NULL, IDC_ARROW); // 装入鼠标指针 wc.hbrBackground = NULL; // GL不需要背景 wc.lpszMenuName = NULL; // 不需要菜单 wc.lpszClassName = "OpenG"; // 设定类名字 if (!RegisterClass(&wc)) // 尝试注册窗口类 { MessageBox(NULL,"注册窗口失败","错误",MB_OK|MB_ICONEXCLAMATION); return FALSE; // 退出并返回FALSE } if (fullscreen) // 要尝试全屏模式吗? { DEVMODE dmScreenSettings; // 设备模式 memset(&dmScreenSettings,0,sizeof(dmScreenSettings)); // 确保内存清空为零 dmScreenSettings.dmSize=sizeof(dmScreenSettings); // Devmode 结构的大小 dmScreenSettings.dmPelsWidth = width; // 所选屏幕宽度 dmScreenSettings.dmPelsHeight = height; // 所选屏幕高度 dmScreenSettings.dmBitsPerPel = bits; // 每象素所选的色彩深度 dmScreenSettings.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT; // 尝试设置显示模式并返回结果。注: CDS_FULLSCREEN 移去了状态条 if (ChangeDisplaySettings(&dmScreenSettings,CDS_FULLSCREEN)!=DISP_CHANGE_SUCCESSFUL) { // 若模式失败,提供两个选项:退出或在窗口内运行。 if (MessageBox(NULL,"全屏模式在当前显卡上设置失败!\n使用窗口模式?","NeHe G",MB_YESNO|MB_ICONEXCLAMATION)==IDYES) { //如果用户选择窗口模式,变量fullscreen 的值变为FALSE,程序继续运行 fullscreen=FALSE; // 选择窗口模式(Fullscreen=FALSE) } else { //如果用户选择退出,弹出消息窗口告知用户程序将结束。并返回FALSE告诉程序窗口未能成功创建。程序退出。 MessageBox(NULL,"程序将被关闭","错误",MB_OK|MB_ICONSTOP); return FALSE; // 退出并返回 FALSE } } } if (fullscreen) // 仍处于全屏模式吗? { dwExStyle=WS_EX_APPWINDOW; // 扩展窗体风格 dwStyle=WS_POPUP; // 窗体风格 ShowCursor(FALSE); // 隐藏鼠标指针 } else { dwExStyle=WS_EX_APPWINDOW | WS_EX_WINDOWEDGE; // 扩展窗体风格 dwStyle=WS_OVERLAPPEDWINDOW; // 窗体风格 } AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle); // 调整窗口达到真正要求的大小 // 创建窗口 if (!(hWnd=CreateWindowEx( dwExStyle, // 扩展窗体风格 "OpenG", // 类名字 title, // 窗口标题 dwStyle | // 必须的窗体风格属性 WS_CLIPSIBLINGS | // 必须的窗体风格属性 WS_CLIPCHILDREN, // 必须的窗体风格属性 0, 0, // 窗口位置 WindowRect.right-WindowRect.left, // 计算调整好的窗口宽度 WindowRect.bottom-WindowRect.top, // 计算调整好的窗口高度 NULL, // 无父窗口 NULL, // 无菜单 hInstance, // 实例 NULL))) // 不向WM_CREATE传递任何东东 { KillGLWindow(); // 重置显示区 MessageBox(NULL,"窗口创建错误","错误",MB_OK|MB_ICONEXCLAMATION); return FALSE; // 返回 FALSE } static PIXELFORMATDESCRIPTOR pfd= //pfd 告诉窗口我们所希望的东东,即窗口使用的像素格式 { sizeof(PIXELFORMATDESCRIPTOR), // 上述格式描述符的大小 1, // 版本号 PFD_DRAW_TO_WINDOW | // 格式支持窗口 PFD_SUPPORT_OPENGL | // 格式必须支持OpenGL PFD_DOUBLEBUFFER, // 必须支持双缓冲 PFD_TYPE_RGBA, // 申请 RGBA 格式 bits, // 选定色彩深度 0, 0, 0, 0, 0, 0, // 忽略的色彩位 0, // 无Alpha缓存 0, // 忽略Shift Bit 0, // 无累加缓存 0, 0, 0, 0, // 忽略聚集位 16, // 16位 Z-缓存 (深度缓存) 0, // 无蒙板缓存 0, // 无辅助缓存 PFD_MAIN_PLANE, // 主绘图层 0, // 不使用重叠层 0, 0, 0 // 忽略层遮罩 }; if (!(hDC=GetDC(hWnd))) // 取得设备描述表了么? { KillGLWindow(); // 重置显示区 MessageBox(NULL,"不能创建一个窗口设备描述表","错误",MB_OK|MB_ICONEXCLAMATION); return FALSE; // 返回 FALSE } if (!(PixelFormat=ChoosePixelFormat(hDC,&pfd))) // Windows 找到相应的象素格式了吗? { KillGLWindow(); // 重置显示区 MessageBox(NULL,"不能创建一种相匹配的像素格式","错误",MB_OK|MB_ICONEXCLAMATION); return FALSE; // 返回 FALSE } if(!SetPixelFormat(hDC,PixelFormat,&pfd)) // 能够设置象素格式么? { KillGLWindow(); // 重置显示区 MessageBox(NULL,"不能设置像素格式","错误",MB_OK|MB_ICONEXCLAMATION); return FALSE; // 返回 FALSE } if (!(hRC=wglCreateContext(hDC))) // 能否取得OpenGL渲染描述表? { KillGLWindow(); // 重置显示区 MessageBox(NULL,"不能创建OpenGL渲染描述表","错误",MB_OK|MB_ICONEXCLAMATION); return FALSE; // 返回 FALSE } if(!wglMakeCurrent(hDC,hRC)) // 尝试激活着色描述表 { KillGLWindow(); // 重置显示区 MessageBox(NULL,"不能激活当前的OpenGL渲然描述表","错误",MB_OK|MB_ICONEXCLAMATION); return FALSE; // 返回 FALSE } ShowWindow(hWnd,SW_SHOW); // 显示窗口 SetForegroundWindow(hWnd); // 略略提高优先级 SetFocus(hWnd); // 设置键盘的焦点至此窗口 ReSizeGLScene(width, height); // 设置透视 GL 屏幕 if (!InitGL()) // 初始化新建的GL窗口 { KillGLWindow(); // 重置显示区 MessageBox(NULL,"初始化失败","错误",MB_OK|MB_ICONEXCLAMATION); return FALSE; // 返回 FALSE } return TRUE; // 成功 } LRESULT CALLBACK WndProc( HWND hWnd, // 窗口的句柄 UINT uMsg, // 窗口的消息 WPARAM wParam, // 附加的消息内容 LPARAM lParam) // 附加的消息内容 { switch (uMsg) // 检查Windows消息 { case WM_ACTIVATE: // 监视窗口激活消息 { if (!HIWORD(wParam)) // 检查最小化状态 { active=TRUE; // 程序处于激活状态 } else { active=FALSE; // 程序不再激活 } return 0; // 返回消息循环 } case WM_SYSCOMMAND: // 系统中断命令 { switch (wParam) // 检查系统调用 { case SC_SCREENSAVE: // 屏保要运行? case SC_MONITORPOWER: // 显示器要进入节电模式? return 0; // 阻止发生 } break; // 退出 } case WM_CLOSE: // 收到Close消息? { PostQuitMessage(0); // 发出退出消息 return 0; // 返回 } case WM_KEYDOWN: // 有键按下么? { keys[wParam] = TRUE; // 如果是,设为TRUE return 0; // 返回 } case WM_KEYUP: // 有键放开么? { keys[wParam] = FALSE; // 如果是,设为FALSE return 0; // 返回 } case WM_SIZE: // 调整OpenGL窗口大小 { ReSizeGLScene(LOWORD(lParam),HIWORD(lParam)); // LoWord=Width,HiWord=Height return 0; // 返回 } } // 向 DefWindowProc传递所有未处理的消息。 return DefWindowProc(hWnd,uMsg,wParam,lParam); } int WINAPI WinMain(HINSTANCE hInstance, // 当前窗口实例 HINSTANCE hPrevInstance, // 前一个窗口实例 LPSTR lpCmdLine, // 命令行参数 int nCmdShow) // 窗口显示状态 { MSG msg; // Windowsx消息结构 BOOL done=FALSE; // 用来退出循环的Bool 变量 // 提示用户选择运行模式 if (MessageBox(NULL,"你想在全屏模式下运行么?", "设置全屏模式",MB_YESNO|MB_ICONQUESTION)==IDNO) { fullscreen=FALSE; // FALSE为窗口模式 } // 创建OpenGL窗口 if (!CreateGLWindow("我的世界",640,480,16,fullscreen)) { return 0; // 失败退出 } while(!done) // 保持循环直到 done=TRUE { if (PeekMessage(&msg,NULL,0,0,PM_REMOVE)) // 有消息在等待吗? { if (msg.message==WM_QUIT) // 收到退出消息? { done=TRUE; // 是,则done=TRUE } else // 不是,处理窗口消息 { TranslateMessage(&msg); // 翻译消息 DispatchMessage(&msg); // 发送消息 } } else // 如果没有消息 { // 绘制场景。监视ESC键和来自DrawGLScene()的退出消息 if (active) // 程序激活的么? { if (keys[VK_ESCAPE]) // ESC 按下了么? { done=TRUE; // ESC 发出退出信号 } else // 不是退出的时候,刷新屏幕 { DrawGLScene(); // 绘制场景 SwapBuffers(hDC); // 交换缓存 (双缓存) if (keys[‘L‘] && !lp) // L 键已按下并且松开了? { lp=TRUE; // lp 设为 TRUE light=!light; // 切换光源的 TRUE/FALSE if (!light) // 如果没有光源 { glDisable(GL_LIGHTING); // 禁用光源 } else // 否则 { glEnable(GL_LIGHTING); // 启用光源 } } if (!keys[‘L‘]) // L键松开了么? { lp=FALSE; // 若是,则将lp设为FALSE } //上下视角变换 if (keys[VK_PRIOR]) // PageUp按下了? { if(z>-20) z-=0.02f; // 若按下,将木箱移向屏幕内部 } if (keys[VK_NEXT]) // PageDown按下了么 { if(z<20) z+=0.02f; // 若按下的话,将木箱移向观察者 } //左右视角变换 if (keys[VK_RIGHT]) // 右方向键按下了么? { yrot -= 0.1f; // 向左旋转场景 } if (keys[VK_LEFT]) // 左方向键按下了么? { yrot += 0.1f; // 向右侧旋转场景 } //前进后退 if (keys[VK_UP]) // 向上方向键按下了么? { heading=yrot; //判断是否碰到墙壁和桌子 if(xpos<=2.8&&xpos>=-2.8&& (zpos>-1||zpos<-2||(zpos>=-2&&zpos<=-1&&(xpos>=1||xpos<=-1)))){ xpos -= (float)sin(heading*piover180) * 0.002f; // 沿游戏者所在的X平面移动 } if(xpos<1&&xpos>0.9&&sin(heading*piover180)<0) xpos -= (float)sin(heading*piover180) * 0.002f;//到达C平面可以转身 if(xpos<=-0.9&&xpos>-1&&sin(heading*piover180)>0) xpos -= (float)sin(heading*piover180) * 0.002f;//到达D平面可以转身 if(xpos>2.8&&sin(heading*piover180)>0) xpos -= (float)sin(heading*piover180) * 0.002f;//到达墙4可以转身 if(xpos<-2.8&&sin(heading*piover180)<0) xpos -= (float)sin(heading*piover180) * 0.002f;//到达墙2可以转身 if(zpos>=-2.8&&zpos<=2.8&& (zpos>-1||zpos<-2||(zpos>=-2&&zpos<=-1&&(xpos>=1||xpos<=-1))) ){ //在整个框架内 zpos -= (float)cos(heading*piover180) * 0.002f; // 沿游戏者所在的Z平面移动 } if(zpos<-1&&zpos>-1.1&&cos(heading*piover180)<0) zpos -= (float)cos(heading*piover180) * 0.002f;//到达A平面可以转身 if(zpos<=-1.9&&zpos>-2&&cos(heading*piover180)>0) zpos -= (float)cos(heading*piover180) * 0.002f;//到达B平面可以转身 if(zpos<-2.8&&cos(heading*piover180)<0) zpos -= (float)cos(heading*piover180) * 0.002f;//到达墙1可以转身 if(zpos>2.8&&cos(heading*piover180)>0) zpos -= (float)cos(heading*piover180) * 0.002f;//到达墙3可以转身 } if (keys[VK_DOWN]) // 向下方向键按下了么? { heading=yrot; if(xpos<=2.8&&xpos>=-2.8&& (zpos>-1||zpos<-2||(zpos>=-2&&zpos<=-1&&(xpos>=1||xpos<=-1)))){ xpos += (float)sin(heading*piover180) * 0.002f; // 沿游戏者所在的X平面移动 } if(xpos<1&&xpos>0.9&&sin(heading*piover180)>0) xpos += (float)sin(heading*piover180) * 0.002f;//到达C平面可以转身 if(xpos<=-0.9&&xpos>-1&&sin(heading*piover180)<0) xpos += (float)sin(heading*piover180) * 0.002f;//到达D平面可以转身 if(xpos>2.8&&sin(heading*piover180)<0) xpos += (float)sin(heading*piover180) * 0.002f; if(xpos<-2.8&&sin(heading*piover180)>0) xpos += (float)sin(heading*piover180) * 0.002f; if(zpos>=-2.8&&zpos<=2.8&& (zpos>-1||zpos<-2||(zpos>=-2&&zpos<=-1&&(xpos>=1||xpos<=-1)))){ zpos += (float)cos(heading*piover180) * 0.002f; // 沿游戏者所在的Z平面移动 } if(zpos<-1&&zpos>-1.1&&cos(heading*piover180)>0) zpos += (float)cos(heading*piover180) * 0.002f;//到达A平面可以转身 if(zpos<=-1.9&&zpos>-2&&cos(heading*piover180)<0) zpos += (float)cos(heading*piover180) * 0.002f;//到达B平面可以转身 if(zpos<-2.8&&cos(heading*piover180)>0) zpos += (float)cos(heading*piover180) * 0.002f; if(zpos>2.8&&cos(heading*piover180)<0) zpos += (float)cos(heading*piover180) * 0.002f; } if (keys[‘B‘] && !bp) // B 健按下且bp为 FALSE么? { bp=TRUE; // 若是, bp 设为 TRUE blend = !blend; // 切换混合选项的 TRUE / FALSE if(blend) // 混合打开了么? { glEnable(GL_BLEND); // 打开混合 glDisable(GL_DEPTH_TEST); // 关闭深度测试 } else // 否则 { glDisable(GL_BLEND); // 关闭混合 glEnable(GL_DEPTH_TEST); // 打开深度测试 } } if (!keys[‘B‘]) // B 键松开了么? { bp=FALSE; // 若是, bp设为 FALSE } } } if (keys[VK_F1]) // F1键按下了么? { keys[VK_F1]=FALSE; // 若是,使对应的Key数组中的值为 FALSE KillGLWindow(); // 销毁当前的窗口 fullscreen=!fullscreen; // 切换 全屏 / 窗口 模式 // 重建 OpenGL 窗口 if (!CreateGLWindow("我的世界",640,480,16,fullscreen)) { return 0; // 如果窗口未能创建,程序退出 } } } } // 关闭程序 KillGLWindow(); // 销毁窗口 return (msg.wParam); // 退出程序 }
// BaseGraph.cpp: implementation of the BaseGraph class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "BaseGraph.h" #pragma comment(lib, "legacy_stdio_definitions.lib") //#include "bitmap.h" ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// extern GLfloat r; //飞机盘旋角度 float gao=1.8f; extern CString test; //场景信息 ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// //power of two int power_of_two(int n) { if (n <= 0) return 0; return (n & (n - 1)) == 0; } #define BMP_Header_Length 54 //load texture function bool load_texture(const char* file_name, GLuint &texture) { GLint width, height, total_bytes; GLubyte* pixels = 0; FILE* pFile = fopen(file_name, "rb"); if (pFile == 0) return 0; fseek(pFile, 0x0012, SEEK_SET); fread(&width, 4, 1, pFile); fread(&height, 4, 1, pFile); fseek(pFile, BMP_Header_Length, SEEK_SET); { GLint line_bytes = width * 3; while (line_bytes % 4 != 0) ++line_bytes; total_bytes = line_bytes * height; } //{ pixels = (GLubyte*)malloc(total_bytes); if (pixels == 0) { fclose(pFile); return 0; } //if if (fread(pixels, total_bytes, 1, pFile) <= 0) { free(pixels); fclose(pFile); return 0; } //if { GLint max; glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max); if (!power_of_two(width) || !power_of_two(height) || width > max || height > max) { const GLint new_width = 256; const GLint new_height = 256; GLint new_line_bytes, new_total_bytes; GLubyte* new_pixels = 0; new_line_bytes = new_width * 3; while (new_line_bytes % 4 != 0) ++new_line_bytes; new_total_bytes = new_line_bytes * new_height; new_pixels = (GLubyte*)malloc(new_total_bytes); if (new_pixels == 0) { free(pixels); fclose(pFile); return 0; }//if gluScaleImage(GL_RGB, width, height, GL_UNSIGNED_BYTE, pixels, new_width, new_height, GL_UNSIGNED_BYTE, new_pixels); free(pixels); pixels = new_pixels; width = new_width; height = new_height; }//if }//{ glGenTextures(1, &texture); if (texture == 0) { free(pixels); fclose(pFile); return 0; } //if glGenTextures(1, &texture); glBindTexture(GL_TEXTURE_2D, texture); gluBuild2DMipmaps(GL_TEXTURE_2D, 4, width, height, GL_RGB, GL_UNSIGNED_BYTE, pixels); free(pixels); return true; } BaseGraph::BaseGraph() { g_eye[0]= MAP;// g_eye[2]=-MAP;// g_Angle=0; g_elev=-0; char appdir[256]; GetCurrentDirectory(256,appdir); CString dir=appdir; if(dir.Right(8)!="运行程序") SetCurrentDirectory("../运行程序"); //////////////////////////////////////////////////////////////////////// load_texture("data/images/sand0.bmp", g_cactus[0]); //地面贴图 //天空贴图 load_texture("data/images/4RBack.bmp", g_cactus[2]); load_texture("data/images/4Front.bmp", g_cactus[3]); load_texture("data/images/4Top.bmp", g_cactus[4]); load_texture("data/images/4Left.bmp", g_cactus[5]); load_texture("data/images/4Right.bmp", g_cactus[6]); /* g_imageData = LoadBit("data/images/Terrain1.bmp",&g_bit); //调等高地形图 LoadT8("data/images/sand0.bmp", g_cactus[0]); //地面贴图 //天空贴图 LoadT8("data/images/4RBack.bmp", g_cactus[2]); LoadT8("data/images/4Front.bmp", g_cactus[3]); LoadT8("data/images/4Top.bmp", g_cactus[4]); LoadT8("data/images/4Left.bmp", g_cactus[5]); LoadT8("data/images/4Right.bmp", g_cactus[6]); LoadT16("data/images/CACTUS0.BMP",g_cactus[11]); //树1帖图 LoadT16("data/images/CACTUS1.BMP",g_cactus[12]); //树2帖图 LoadT16("data/images/CACTUS2.BMP",g_cactus[13]); //树3帖图 LoadT16("data/images/CACTUS5.BMP",g_cactus[14]); //树4帖图 */ InitTerrain(5); //初始化地面 m_3ds=new CLoad3DS(); load3dobj("data/3ds/","航天发射台.3DS",0); load3dobj("data/3ds/","直升机0.3ds",1);//car.3ds load3dobj("data/3ds/","飞机1.3ds",2);//car.3ds glEnable(GL_TEXTURE_2D); } BaseGraph::~BaseGraph() { for(int i=0;i<16;i++) glDeleteTextures(1, &g_cactus[i]); glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); } void BaseGraph::light0() { GLfloat light_position[] = {1.0,5.0,1.0,1.0}; glLightfv(GL_LIGHT0, GL_POSITION, light_position); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_DEPTH_TEST); glEnable(GL_COLOR_MATERIAL); } BOOL BaseGraph::DisplayScene() { float speed=0.3f; float x=g_eye[0],y=g_eye[2],z=g_eye[2]; if (KEY_DOWN(VK_SHIFT)) speed =speed*3; if (KEY_DOWN(VK_LEFT)) g_Angle-=speed*3; if (KEY_DOWN(VK_RIGHT)) g_Angle+=speed*3; rad_xz = float (3.13149* g_Angle/180.0f); if (KEY_DOWN(33)) g_elev +=speed; if (KEY_DOWN(34)) g_elev -=speed; if (g_elev<-360) g_elev =-360; if (g_elev> 360) g_elev = 360; if (KEY_DOWN(VK_UP)) { g_eye[2]+=(float)sin(rad_xz)*speed*3; g_eye[0]+=(float)cos(rad_xz)*speed*3; } if (KEY_DOWN(VK_DOWN)) { g_eye[2]-=(float)sin(rad_xz)*speed*3; g_eye[0]-=(float)cos(rad_xz)*speed*3; } if(g_eye[0]< MAP_SCALE) g_eye[0]= MAP_SCALE; if(g_eye[0]> (MAP_W-2)*MAP_SCALE) g_eye[0]= (MAP_W-2)*MAP_SCALE; if(g_eye[2]<-(MAP_W-2)*MAP_SCALE) g_eye[2]=-(MAP_W-2)*MAP_SCALE; if(g_eye[2]> -MAP_SCALE) g_eye[2]= -MAP_SCALE; g_eye[1] =GetHeight((float)g_eye[0],(float)g_eye[2])+2*gao; g_look[0] = (float)(g_eye[0] +100*cos(rad_xz)); g_look[2] = (float)(g_eye[2] +100*sin(rad_xz)); g_look[1] = g_eye[1] +g_elev; gluLookAt(g_eye[0],g_eye[1],g_eye[2], g_look[0],g_look[1],g_look[2], 0.0,1.0,0.0 ); int r0=abs((int)g_Angle); test.Format("[方位=%03d X=%3.0f y=%3.0f 高=%2.1f 俯仰角=%2.0f,re=%03.0f]", r0%360,g_eye[0],-g_eye[2],g_eye[1],g_elev,r); return TRUE; } float BaseGraph::GetHeight(float x, float z) { float CameraX = x/MAP_SCALE; float CameraZ =-z/MAP_SCALE; int Col0 = int(CameraX); //列 int Row0 = int(CameraZ); //行 int Col1 = Col0 + 1; int Row1 = Row0 + 1; if (Col1 > MAP_W) Col1 = 0; if (Row1 > MAP_W) Row1 = 0; float h00=g_terrain[Col0 + Row0*MAP_W][1]; float h01=g_terrain[Col1 + Row0*MAP_W][1]; float h11=g_terrain[Col1 + Row1*MAP_W][1]; float h10=g_terrain[Col0 + Row1*MAP_W][1]; float tx =CameraX - int(CameraX); float ty =CameraZ - int(CameraZ); float txty = tx * ty; return h00*(1.0f-ty-tx+txty) + h01*(tx-txty) + h11*txty + h10*(ty-txty); } void BaseGraph::CreateSkyBox(int a,int wi,int he,int le) { float width =MAP*wi; float height=MAP*he; float length=MAP*le; float x = MAP -width /2; float y = MAP/a-height/2; float z = -MAP -length/2; /////////////////////////////////////////////////////////////////////////////// texture(g_cactus[2]); glBegin(GL_QUADS); glTexCoord2f(1.0f,0.0f); glVertex3f(x+width,y, z); glTexCoord2f(1.0f,1.0f); glVertex3f(x+width,y+height,z); glTexCoord2f(0.0f,1.0f); glVertex3f(x, y+height,z); glTexCoord2f(0.0f,0.0f); glVertex3f(x, y, z); glEnd(); texture(g_cactus[3]); glBegin(GL_QUADS); glTexCoord2f(1.0f,0.0f); glVertex3f(x, y, z+length); glTexCoord2f(1.0f,1.0f); glVertex3f(x, y+height,z+length); glTexCoord2f(0.0f,1.0f); glVertex3f(x+width,y+height,z+length); glTexCoord2f(0.0f,0.0f); glVertex3f(x+width,y, z+length); glEnd(); texture(g_cactus[4]); glBegin(GL_QUADS); glTexCoord2f(0.0f,1.0f); glVertex3f(x+width,y+height,z); glTexCoord2f(0.0f,0.0f); glVertex3f(x+width,y+height,z+length); glTexCoord2f(1.0f,0.0f); glVertex3f(x, y+height,z+length); glTexCoord2f(1.0f,1.0f); glVertex3f(x, y+height,z); glEnd(); texture(g_cactus[5]); glBegin(GL_QUADS); glTexCoord2f(1.0f,1.0f); glVertex3f(x, y+height,z); glTexCoord2f(0.0f,1.0f); glVertex3f(x, y+height,z+length); glTexCoord2f(0.0f,0.0f); glVertex3f(x, y, z+length); glTexCoord2f(1.0f,0.0f); glVertex3f(x, y, z); glEnd(); texture(g_cactus[6]); glBegin(GL_QUADS); glTexCoord2f(0.0f,0.0f); glVertex3f(x+width,y, z); glTexCoord2f(1.0f,0.0f); glVertex3f(x+width,y, z+length); glTexCoord2f(1.0f,1.0f); glVertex3f(x+width,y+height,z+length); glTexCoord2f(0.0f,1.0f); glVertex3f(x+width,y+height,z); glEnd(); } void BaseGraph::texture(UINT textur) { glBindTexture (GL_TEXTURE_2D, textur); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); } void BaseGraph::picter(float x,float y,float z) { y=GetHeight(x,z); glDisable(GL_TEXTURE_2D); glPushAttrib(GL_CURRENT_BIT); glPushMatrix(); glTranslatef(x,y+0.5f,z); glColor3f(0.0f,1.0f,0.2f); auxSolidCube(1); glTranslatef(0.0f,0.8f,0.0f); glColor3f(0.0f,0.0f,1.0f); auxSolidBox(.2f,1.3f,.2f); glPopMatrix(); glPushMatrix(); glTranslatef(x,y+2.5f,z); glRotatef(r-90,0.0,1.0,0.0); //======================================= glColor3f(1.0f,1.0f,1.0f); glRotatef(45, 1.0, 0.0, 0.0); auxWireCone(1.5,0.6f); //======================================= glRotatef(180, 1.0, 0.0, 0.0); glTranslatef(0.0f,0.0f,-0.7f); auxWireCone(0.2f,2.0f); glColor3f(FRAND,0,0); glTranslatef(0.0f,0.0f,2.0f); auxSolidSphere(0.1f); glPopMatrix(); glPushMatrix(); glTranslatef(x,y+10.0f,z); glRotatef(r, 0.0, 1.0, 0.0); glTranslatef(x/15,0,0); //============================================= glColor3f(1.0f,0.0f,0.0f); glRotatef(180, 0.0, 1.0, 0.0); auxSolidCone(.2,0.6); //============================================= glColor3f(1.0f,1.0f,1.0f); glRotatef(90, 1.0, 0.0, 0.0); glTranslatef(0.0f,-1.0f,0); auxSolidCylinder(.2f,1); glRotatef(-270, 1.0, 0.0, 0.0); glColor3f(FRAND+.6f,0.2f,0.0f); glTranslatef(0.0f,-0.0f,-0.2f); auxSolidCone(.2,1.5); glPopMatrix(); glEnable(GL_TEXTURE_2D); glPopAttrib(); r+=0.5f; if(r>360) r=0; glEnable(GL_TEXTURE_2D); } void BaseGraph::InitTerrain(float h) { int index = 0; int Vertex; for (int z = 0; z < MAP_W; z++) for (int x = 0; x < MAP_W; x++) { Vertex = z * MAP_W + x; g_terrain [Vertex][0] = float(x)*MAP_SCALE; g_terrain [Vertex][1] = (float)(g_imageData[(z*MAP_W+x)*3]/3); g_terrain [Vertex][2] = -float(z)*MAP_SCALE; g_texcoord[Vertex][0] = (float) x; g_texcoord[Vertex][1] = (float) z; g_index [index++] = Vertex; g_index [index++] = Vertex+ MAP_W; } glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer (3,GL_FLOAT,0,g_terrain); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glTexCoordPointer (2,GL_FLOAT,0,g_texcoord); } void BaseGraph::DrawSand() { glBindTexture(GL_TEXTURE_2D, g_cactus[0]); glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); for (int z = 0; z < MAP_W-1; z++) glDrawElements(GL_TRIANGLE_STRIP,MAP_W*2,GL_UNSIGNED_INT,&g_index[z*MAP_W*2]); } /* bool BaseGraph::LoadT8(char *filename, GLuint &texture) { AUX_RGBImageRec *pImage = NULL; pImage = auxDIBImageLoad(filename); if(pImage == NULL) return false; glGenTextures(1, &texture); glBindTexture(GL_TEXTURE_2D,texture); gluBuild2DMipmaps(GL_TEXTURE_2D,4, pImage->sizeX, pImage->sizeY,GL_RGB, GL_UNSIGNED_BYTE,pImage->data); free(pImage->data); free(pImage); return true; } void BaseGraph::LoadT16(char *filename, GLuint &texture) { glGenTextures(1, &texture); glBindTexture(GL_TEXTURE_2D, texture); BITMAPINFOHEADER bitHeader; unsigned char *buffer; buffer=LoadBitmapFileWithAlpha(filename,&bitHeader); gluBuild2DMipmaps ( GL_TEXTURE_2D, 4, bitHeader.biWidth, bitHeader.biHeight, GL_RGBA, GL_UNSIGNED_BYTE, buffer ); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); free(buffer); } */ /* unsigned char * BaseGraph::LoadBit(char *filename, BITMAPINFOHEADER *bitmap) { FILE *filePtr; // the file pointer BITMAPFILEHEADER Header; // bitmap file header unsigned char *Image; // bitmap image data unsigned int imageIdx = 0; // image index counter unsigned char tempRGB; // swap variable // open filename in "read binary" mode filePtr = fopen(filename, "rb"); if (filePtr == NULL)return NULL; // read the bitmap file header fread(&Header, sizeof(BITMAPFILEHEADER), 1, filePtr); // verify that this is a bitmap by checking for the universal bitmap id if (Header.bfType != BITMAP_ID) { fclose(filePtr); return NULL; } // read the bitmap information header fread(bitmap, sizeof(BITMAPINFOHEADER), 1, filePtr); // move file pointer to beginning of bitmap data fseek(filePtr, Header.bfOffBits, SEEK_SET); // allocate enough memory for the bitmap image data Image = (unsigned char*)malloc(bitmap->biSizeImage); // verify memory allocation if (!Image) { free(Image); fclose(filePtr); return NULL; } // read in the bitmap image data fread(Image, 1, bitmap->biSizeImage, filePtr); if (Image == NULL) // make sure bitmap image data was read { fclose(filePtr); return NULL; } // swap the R and B values to get RGB since the bitmap color format is in BGR for (imageIdx = 0; imageIdx < bitmap->biSizeImage; imageIdx+=3) { tempRGB = Image[imageIdx]; Image[imageIdx] = Image[imageIdx + 2]; Image[imageIdx + 2] = tempRGB; } fclose(filePtr); return Image; } */ /* void BaseGraph::ShowTree(float x, float z, float h, float s, int cactus) { glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_ALPHA_TEST); glAlphaFunc(GL_GREATER, 0); float mat[16]; //the modelview matrix glGetFloatv(GL_MODELVIEW_MATRIX, mat); vector3_t X(mat[0], mat[4], mat[8]); vector3_t Z(mat[1], mat[5], mat[9]); glBindTexture(GL_TEXTURE_2D, g_cactus[cactus]); vector3_t pos(x,0.0,-z); pos.y = GetHeight(x, -z) + h + s; glBegin(GL_QUADS); glTexCoord2f(0.0,0.0);glVertex3fv((pos+(X+Z)*-h).v);//左下点 glTexCoord2f(1.0,0.0);glVertex3fv((pos+(X-Z)* h).v);//右下点 glTexCoord2f(1.0,1.0);glVertex3fv((pos+(X+Z)* h).v);//右上点 glTexCoord2f(0.0,1.0);glVertex3fv((pos+(Z-X)* h).v);//左上点 glEnd(); glDisable(GL_ALPHA); glDisable(GL_BLEND); } */ void BaseGraph::ShowTree0(float x, float z, float h, float s, int cactus) { glPushMatrix();// float y = GetHeight(x,-z) + h + s; glTranslatef(x,y, -z); glRotatef(180, 1.0, 0.0, 0.0); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_ALPHA_TEST); glAlphaFunc(GL_GREATER, 0); glBindTexture(GL_TEXTURE_2D, g_cactus[cactus]); // glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);// glBegin(GL_QUADS); glTexCoord2f(1.0f, 0.0f); glVertex3f(-h, h, 0.0f); // 右上点 glTexCoord2f(0.0f, 0.0f); glVertex3f( h, h, 0.0f); // 右上点 glTexCoord2f(0.0f, 1.0f); glVertex3f( h,-h, 0.0f); // 右下点 glTexCoord2f(1.0f, 1.0f); glVertex3f(-h,-h, 0.0f); // 左下点 glEnd(); glDisable(GL_ALPHA); glDisable(GL_BLEND); glPopMatrix(); } //////////////////////////////////////////////////////////////////// void BaseGraph::load3dobj(char* dir,char* cn,int a) { char appdir[256]; GetCurrentDirectory(256,appdir); //The GetCurrentDirectory function retrieves the current //directory for the current process. SetCurrentDirectory(dir); m_3ds->Init(cn,a); SetCurrentDirectory(appdir); } void BaseGraph::Scene(int obj,float x,float h,float z,float r,int re,float size) { glPushMatrix(); int y=GetHeight(x,z)+h; glTranslatef(x,y,z); glRotatef(re, 0.0, 1.0, 0.0); if(obj>0) glRotatef(-20, 1.0, 0.0, 0.0); m_3ds->show3ds(obj,0,0.0f,r,size); glPopMatrix(); }
时间: 2024-11-10 13:58:07