图形学

#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] == '
'));    // 考察是否有必要进行处理
    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
", &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,"全屏模式在当前显卡上设置失败!
使用窗口模式?","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();
}
原文地址:https://www.cnblogs.com/qlky/p/6210081.html