图形学

#include<gl/glut.h>
#include<windows.h>
#include<math.h>
#include <stdio.h>
#include <stdlib.h> 

GLfloat light_position1[]={0,28,-20,1.0};
GLfloat model_ambient[]={0.05f,0.05f,0.05f,1.0f};

GLfloat mat_specular[]={0.8,1.0,1.0,1.0};
GLfloat mat_shininess[]={5.0};
GLfloat mat_ambient[]={0.1,0.1,0.1,1}; 

GLfloat white_light[]={1.0,1.0,1.0,1.0}; 

GLfloat light[]={1.0,1.0,1.0,1}; 

GLfloat light_position0[]={0,28,20,1.0}; 

GLint WinWidth;
GLint WinHeight; 

//define the eyepoint
typedef struct EyePoint
{
    GLfloat x;
    GLfloat y;
    GLfloat z;
}EyePoint;

EyePoint myEye;
EyePoint vPoint;
GLfloat vAngle=0; 

//the function about the texture
#define BMP_Header_Length 54
void grab(void) { 

    FILE* pDummyFile; FILE* pWritingFile;
    GLubyte* pPixelData;
    GLubyte BMP_Header[BMP_Header_Length];
    GLint i, j;
    GLint PixelDataLength; 

    i = WinWidth * 3;
    while( i%4 != 0 )
            ++i;
    PixelDataLength = i * WinHeight;
    pPixelData = (GLubyte*)malloc(PixelDataLength);
    if( pPixelData == 0 )
        exit(0);
    pDummyFile = fopen("dummy.bmp", "rb");
    if( pDummyFile == 0 )
        exit(0);
    pWritingFile = fopen("grab.bmp", "wb");
    if( pWritingFile == 0 )
        exit(0);
    glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
    glReadPixels(0, 0, WinWidth, WinHeight,GL_BGR_EXT, GL_UNSIGNED_BYTE, pPixelData); 

    fread(BMP_Header, sizeof(BMP_Header), 1, pDummyFile);
    fwrite(BMP_Header, sizeof(BMP_Header), 1, pWritingFile);
    fseek(pWritingFile, 0x0012, SEEK_SET);
    i = WinWidth;
    j = WinHeight;
    fwrite(&i, sizeof(i), 1, pWritingFile);
    fwrite(&j, sizeof(j), 1, pWritingFile);
    fseek(pWritingFile, 0, SEEK_END);
    fwrite(pPixelData, PixelDataLength, 1, pWritingFile);
    fclose(pDummyFile); fclose(pWritingFile); free(pPixelData);
} 

//power of two
int power_of_two(int n)
{
    if( n <= 0 )
    return 0;
    return (n & (n-1)) == 0;
} 

//load texture function
GLuint load_texture(const char* file_name)
{
    GLint width, height, total_bytes;
    GLubyte* pixels = 0;
    GLint last_texture_ID=0;
    GLuint texture_ID = 0; 

    FILE* pFile = fopen(file_name, "rb");
    if( pFile == 0 )
        return 0; 

    fseek(pFile, 0x0012, SEEK_SET);
    fread(&width, 4, 1, pFile);
    fread(&height, 4, 1, pFile);
    fseek(pFile, BMP_Header_Length, SEEK_SET); 

    {
        GLint line_bytes = width * 3;
        while( line_bytes % 4 != 0 )
        ++line_bytes;
        total_bytes = line_bytes * height;
    } //{

    pixels = (GLubyte*)malloc(total_bytes);
    if( pixels == 0 ){
        fclose(pFile);
    return 0;
    } //if

    if( fread(pixels, total_bytes, 1, pFile) <= 0 ){
        free(pixels);
        fclose(pFile);
    return 0;
    } //if

    {
        GLint max;
        glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max);
        if( !power_of_two(width)|| !power_of_two(height)|| width > max|| height > max ){
            const GLint new_width = 256;
            const GLint new_height = 256;
            GLint new_line_bytes, new_total_bytes;
            GLubyte* new_pixels = 0; 

            new_line_bytes = new_width * 3;
            while( new_line_bytes % 4 != 0 )
                ++new_line_bytes;
            new_total_bytes = new_line_bytes * new_height; 

            new_pixels = (GLubyte*)malloc(new_total_bytes);
            if( new_pixels == 0 ){
                free(pixels);
                fclose(pFile);
            return 0;
    }//if 

    gluScaleImage(GL_RGB,width, height, GL_UNSIGNED_BYTE, pixels,new_width, new_height, GL_UNSIGNED_BYTE, new_pixels);
    free(pixels);
    pixels = new_pixels;
    width = new_width;
    height = new_height;
    }//if
}//{

glGenTextures(1, &texture_ID);
    if( texture_ID == 0 ) {
        free(pixels);
        fclose(pFile);
    return 0;
} //if

    glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture_ID);
    glBindTexture(GL_TEXTURE_2D, texture_ID);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_BGR_EXT, GL_UNSIGNED_BYTE, pixels);
    glBindTexture(GL_TEXTURE_2D, last_texture_ID); 

    free(pixels);
    return texture_ID;
} 

//set the names of the texture objects
GLuint texblackboard,texwindow,texceiling,
       texdoor,texbackwall,texgaodi,textdesk; 

//draw the scene of the classroom
void drawscence()
{ 

    //draw the ceiling
    glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, texceiling);
    glColor3f(0.3,0.3,0.3); 

    glBegin(GL_QUADS);
    glNormal3f(0.0f, -1.0f, 0.0f); 

    glTexCoord2f(0.0f, 0.0f);
    glVertex3f(-40.0f,30.0f, 30.0f); 

    glTexCoord2f(0.0f, 3.0f);
    glVertex3f(-40.0f, 30.0f, -30.0f); 

    glTexCoord2f(6.0f, 3.0f);
    glVertex3f(40.0f, 30.0f, -30.0f); 

    glTexCoord2f(6.0f, 0.0f);
    glVertex3f(40.0f, 30.0f, 30.0f); 

    glEnd();
    glDisable(GL_TEXTURE_2D); 

    //draw the floor
    glColor3f(1.0f, 1.0f, 1.0f);
    glBegin(GL_QUADS);
    glNormal3f(0.0f, 1.0f, 0.0f); 

    glVertex3f(-40.0f,0.0f, 30.0f);
    glVertex3f(-40.0f, 0.0f, -30.0f);
    glVertex3f(40.0f, 0.0f, -30.0f);
    glVertex3f(40.0f, 0.0f, 30.0f);
    glEnd(); 

    //the wall and the windows in left
    glColor3f(0.8f,0.8f, 0.8f);
    glBegin(GL_QUADS);
    glNormal3f(1.0f, 0.0f, 0.0f);
    glVertex3f(-40.0f,0.0f, 30.0f);
    glVertex3f(-40.0f, 30.0f, 30.0f);
    glVertex3f(-40.0f, 30.0f, -30.0f);
    glVertex3f(-40.0f, 0.0f, -30.0f);
    glEnd();
    glEnable(GL_TEXTURE_2D); 

    glBindTexture(GL_TEXTURE_2D, texwindow); 

    for(int n=0;n<=1;n++)
    {
        glBegin(GL_QUADS);
        glNormal3f(1.0, 0.0f, 0.0f);
        glTexCoord2f(1.0f, 0.0f);glVertex3f(-39.9, 10, -8+n*18);
        glTexCoord2f(1.0f, 1.0f);glVertex3f(-39.9, 20, -8+n*18);
        glTexCoord2f(0.0f, 1.0f);glVertex3f(-39.9, 20, -18+n*18);
        glTexCoord2f(0.0f, 0.0f);glVertex3f(-39.9, 10, -18+n*18);
        glEnd();
    }
    glDisable(GL_TEXTURE_2D); 

    //the wall and the window in right
    glColor3f(0.8f,0.8f, 0.8f);
    glBegin(GL_QUADS);
    glNormal3f(-1.0f, 0.0f, 0.0f);
    glVertex3f(40.0f,0.0f, 30.0f);
    glVertex3f(40.0f, 30.0f, 30.0f);
    glVertex3f(40.0f, 30.0f, -30.0f);
    glVertex3f(40.0f, 0.0f, -30.0f);
    glEnd();
    glEnable(GL_TEXTURE_2D); 

    glBindTexture(GL_TEXTURE_2D, texwindow);
    glBegin(GL_QUADS);
    glNormal3f(-1.0, 0.0f, 0.0f);
    glTexCoord2f(1.0f, 0.0f);glVertex3f(39.5, 10, 10);
    glTexCoord2f(1.0f, 1.0f);glVertex3f(39.5, 20, 10);
    glTexCoord2f(0.0f, 1.0f);glVertex3f(39.5, 20, 0);
    glTexCoord2f(0.0f, 0.0f);glVertex3f(39.5, 10, 0);
    glEnd();
    glDisable(GL_TEXTURE_2D); 

    //backwall
    glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, texbackwall);
    glColor3f(0.8f,0.8f, 0.8f);
    glBegin(GL_QUADS);
    glNormal3f(0.0f, 0.0f, 1.0f); 

    glTexCoord2f(0.0f, 0.0f);
    glVertex3f(-40.0f,0.0f, 30.0f);
    glTexCoord2f(0.0f, 1.0f);
    glVertex3f(-40.0f, 30.0f, 30.0f);
    glTexCoord2f(1.0f, 1.0f);
    glVertex3f(40.0f, 30.0f, 30.0f);
    glTexCoord2f(1.0f, 0.0f);
    glVertex3f(40.0f, 0.0f, 30.0f);
    glEnd(); 

    //frontwall
    glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, texbackwall);
    glColor3f(0.8f,0.8f, 0.8f);
    glBegin(GL_QUADS);
    glNormal3f(0.0f, 0.0f, 1.0f);
    glTexCoord2f(0.0f, 0.0f);
    glVertex3f(-40.0f,0.0f, -30.0f);
    glTexCoord2f(0.0f, 1.0f);
    glVertex3f(-40.0f, 30.0f, -30.0f);
    glTexCoord2f(1.0f, 1.0f);
    glVertex3f(40.0f, 30.0f, -30.0f);
    glTexCoord2f(1.0f, 0.0f);
    glVertex3f(40.0f, 0.0f, -30.0f);
    glEnd(); 

    //blackboard
    glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, texblackboard);
    glBegin(GL_QUADS);
    glNormal3f(0.0f, 0.0f, 1.0f);
    glTexCoord2f(0.0f, 0.0f);glVertex3f(-20.0,8.0f, -29.9f);
    glTexCoord2f(0.0f, 1.0f);glVertex3f(-20.0, 18.0f, -29.9f);
    glTexCoord2f(1.0f, 1.0f);glVertex3f(20.0, 18.0f, -29.9f);
    glTexCoord2f(1.0f, 0.0f);glVertex3f(20.0, 8.0f, -29.9f);
    glEnd();
    glDisable(GL_TEXTURE_2D); 

    //gaodi
    glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, texgaodi); 

    //top
    glBegin(GL_QUADS);
    glNormal3f(0.0f, 1.0f, 0.0f);
    glTexCoord2f(0.0f, 0.0f);glVertex3f(-30.0f, 1.5f, -22.0f);
    glTexCoord2f(0.0f, 1.0f);glVertex3f(-30.0f, 1.5f, -30.0f);
    glTexCoord2f(1.0f, 1.0f);glVertex3f(30.0f, 1.5f, -30.0f);
    glTexCoord2f(1.0f, 0.0f);glVertex3f(30.0f, 1.5f, -22.0f);
    glEnd();

    //down
    glBegin(GL_QUADS);
    glNormal3f(0.0f, 0.0f, 1.0f);
    glTexCoord2f(0.0f, 0.0f);glVertex3f(-30.0f, 0, -22.0f);
    glTexCoord2f(0.0f, 1.0f);glVertex3f(-30.0f, 1.5f, -22.0f);
    glTexCoord2f(1.0f, 1.0f);glVertex3f(-30.0f, 1.5f, -30.0f);
    glTexCoord2f(1.0f, 0.0f);glVertex3f(-30.0f, 0, -30.0f);
    glEnd();

    //front
    glBegin(GL_QUADS);
    glNormal3f(0.0f, 1.0f, 0.0f);
    glTexCoord2f(0.0f, 0.0f);glVertex3f(-30.0f, 0, -22.0f);
    glTexCoord2f(0.0f, 1.0f);glVertex3f(-30.0f, 1.5f, -22.0f);
    glTexCoord2f(1.0f, 1.0f);glVertex3f(30.0f, 1.5f, -22.0f);
    glTexCoord2f(1.0f, 0.0f);glVertex3f(30.0f, 0, -22.0f);
    glEnd();

    //back
    glBegin(GL_QUADS);
    glNormal3f(0.0f, 1.0f, 0.0f);
    glTexCoord2f(0.0f, 0.0f);glVertex3f(30.0f, 0, -22.0f);
    glTexCoord2f(0.0f, 1.0f);glVertex3f(30.0f, 1.5f, -22.0f);
    glTexCoord2f(1.0f, 1.0f);glVertex3f(30.0f, 1.5f, -30.0f);
    glTexCoord2f(1.0f, 0.0f);glVertex3f(30.0f, 0, -30.0f);
    glEnd();
    glDisable(GL_TEXTURE_2D); 

    //jiangtai 

    glBindTexture(GL_TEXTURE_2D, textdesk);
    glEnable(GL_TEXTURE_2D);
    glBegin(GL_QUADS);
    glNormal3f(0.0f, 1.0f, 0.0f);  

    glTexCoord2f(0.0f, 0.0f);glVertex3f(-7.5f, 1.5f, -24.0f);
    glTexCoord2f(0.0f, 1.0f);glVertex3f(-7.5f, 9.5f, -24.0f);
    glTexCoord2f(1.0f, 1.0f);glVertex3f(7.5f, 9.5f, -24.0f);
    glTexCoord2f(1.0f, 0.0f);glVertex3f(7.5f, 1.5f, -24.0f);
    glEnd();
    glBegin(GL_QUADS);
    glNormal3f(0.0f, 1.0f, 0.0f);
    glTexCoord2f(0.0f, 0.0f);glVertex3f(7.5f, 1.5f, -24.0f);
    glTexCoord2f(0.0f, 1.0f);glVertex3f(7.5f, 9.5f, -24.0f);
    glTexCoord2f(1.0f, 1.0f);glVertex3f(7.5f, 9.5f, -28.0f);
    glTexCoord2f(1.0f, 0.0f);glVertex3f(7.5f, 1.5f, -28.0f);
    glEnd();
    glBegin(GL_QUADS);
    glNormal3f(0.0f, 1.0f, 0.0f);
    glTexCoord2f(0.0f, 0.0f);glVertex3f(-7.5f, 1.5f, -24.0f);
    glTexCoord2f(0.0f, 1.0f);glVertex3f(-7.5f, 9.5f, -24.0f);
    glTexCoord2f(1.0f, 1.0f);glVertex3f(-7.5f, 9.5f, -28.0f);
    glTexCoord2f(1.0f, 0.0f);glVertex3f(-7.5f, 1.5f, -28.0f);
    glEnd();
    glBegin(GL_QUADS);
    glNormal3f(0.0f, 1.0f, 0.0f);
    glTexCoord2f(0.0f, 0.0f);glVertex3f(-7.5f, 9.5f, -24.0f);
    glTexCoord2f(0.0f, 1.0f);glVertex3f(-7.5f, 9.5f, -26.0f);
    glTexCoord2f(1.0f, 1.0f);glVertex3f(7.5f, 9.5f, -26.0f);
    glTexCoord2f(1.0f, 0.0f);glVertex3f(7.5f, 9.5f, -24.0f);
    glEnd();  

    //door
    glColor3f(0.521f,0.121f,0.0547f);
    glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, texdoor);
    glBegin(GL_QUADS);
    glNormal3f(-1.0f, 0.0f, 0.0f);
    glTexCoord2f(0.0f, 0.0f);glVertex3f(39.9f, 0.0f, -25.0f);
    glTexCoord2f(0.0f, 1.0f);glVertex3f(39.9f, 14.0f, -25.0f);
    glTexCoord2f(1.0f, 1.0f);glVertex3f(39.9f, 14.0f, -19.0f);
    glTexCoord2f(1.0f, 0.0f);glVertex3f(39.9f, 0.0f, -19.0f);
    glEnd();
    glDisable(GL_TEXTURE_2D); 

} 

 //draw the desks
 void drawdesks()
{ 

    GLfloat desk[]={1,0.9647,0.56078};
    for(int y=0;y<=2;y++) {
        for(int x=0;x<=1;x++) {
        //top
        glColor4f(1,0.9647,0.56078,1);
        glPushMatrix();
        glTranslatef(-20.0+x*40,8.1,-17.5+y*8);
        glScalef(10,0.2,3);
        glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE,desk);
        glutSolidCube(1.0f);
        glPopMatrix(); 

        //down
        glColor4f(1,0.9647,0.56078,1);
        glPushMatrix();
        glTranslatef(-20.0+x*40,6.1,-17.5+y*8);
        glScalef(9,0.2,3);
        glutSolidCube(1.0f);
        glPopMatrix(); 

        //front
        glColor4f(1,0.9647,0.56078,1);
        glPushMatrix();
        glTranslatef(-20.0+x*40,7,-18.9+y*8);
        glScalef(10,2,0.2);
        glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE,desk);
        glutSolidCube(1.0f);
        glPopMatrix(); 

        //leg
        glColor3f(0.0,0.0,0.0);
        glBegin(GL_LINES);
        glLineWidth(3.0f);
        glVertex3f(-25.0+x*40,6.0f, -19+y*8);
        glVertex3f(-25.0+x*40,0.0f, -19+y*8);
        glEnd();
        glBegin(GL_LINES); 

        glLineWidth(3.0f);
        glVertex3f(-15.0+x*40,6.0f, -19+y*8);
        glVertex3f(-15.0+x*40,0.0f, -19+y*8);
        glEnd();
        glBegin(GL_LINES);
        glLineWidth(3.0f);
        glVertex3f(-25.0+x*40,0.0f, -18+y*8);
        glVertex3f(-25.0+x*40,0.0f, -20+y*8);
        glEnd();
        glBegin(GL_LINES);
        glLineWidth(3.0f);
        glVertex3f(-15.0+x*40,0.0f, -18+y*8);
        glVertex3f(-15.0+x*40,0.0f, -20+y*8);
        glEnd();
} //for

        //the desks in the middle
        //top
        glColor3f(1,0.9647,0.56078);
        glPushMatrix();
        glTranslatef(0,8.1,-17.5+y*8);
        glScalef(20,0.2,3);
        glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE,desk);
        glutSolidCube(1.0f);
        glPopMatrix(); 

        //down
        glColor3f(1,0.9647,0.56078);
        glPushMatrix();
        glTranslatef(0,6.1,-17.5+y*8);
        glScalef(19,0.2,3);
        glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE,desk);
        glutSolidCube(1.0f);
        glPopMatrix(); 

        //front
        glColor3f(1,0.9647,0.56078);
        glPushMatrix();
        glTranslatef(0,7,-18.9+y*8);
        glScalef(20,2,0.2);
        glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE,desk);
        glutSolidCube(1.0f);
        glPopMatrix(); 

        //leg
        glColor3f(0.0,0.0,0.0);
        glBegin(GL_LINES);
        glLineWidth(3.0f);
        glVertex3f(-10.0,6.0f, -19+y*8);
        glVertex3f(-10.0,0.0f, -19+y*8);
        glEnd();
        glBegin(GL_LINES);
        glLineWidth(3.0f);
        glVertex3f(10.0,6.0f, -19+y*8);
        glVertex3f(10.0,0.0f, -19+y*8);
        glEnd();
        glBegin(GL_LINES);
        glLineWidth(3.0f);
        glVertex3f(-10.0,0.0f, -18+y*8);
        glVertex3f(-10,0.0f, -20+y*8);
        glEnd();
        glBegin(GL_LINES);
        glLineWidth(3.0f);
        glVertex3f(10,0.0f, -18+y*8);
        glVertex3f(10,0.0f, -20+y*8);
        glEnd();
}//for 

} 

//drawchairs
void drawchairs()
{
    GLfloat chair[]={0.1,0.67,0.62};
    for(int j=0;j<=2;j++){
        for(int i=0;i<=1;i++){
    //down
    glColor3f(0.1,0.67,0.62); 

    glPushMatrix();
    glTranslatef(-20+i*40,3.1,-14.5+j*8);
    glScalef(10,0.2,3);
    glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE,chair);
    glutSolidCube(1.0f);
    glPopMatrix();
    //back
    glColor3f(0.1,0.67,0.62);
    glPushMatrix();
    glTranslatef(-20+i*40,5,-13+j*8); 

    glScalef(10,4,0.2);
    glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE,chair);
    glutSolidCube(1.0f);
    glPopMatrix();
    //leg
    glColor3f(0.0,0.0,0.0);
    glBegin(GL_LINES);
    glLineWidth(3.0f);
    glVertex3f(-25+i*40,3.0f, -13+j*8);
    glVertex3f(-25+i*40,0.0f, -13+j*8);
    glEnd();
    glColor3f(0.0,0.0,0.0);
    glBegin(GL_LINES);
    glLineWidth(3.0f);
    glVertex3f(-15.0+i*40,3.0f, -13+j*8);
    glVertex3f(-15.0+i*40,0.0f, -13+j*8);
    glEnd();
    glColor3f(0.0,0.0,0.0);
    glBegin(GL_LINES);
    glLineWidth(3.0f);
    glVertex3f(-25.0+i*40,0.0f, -12.5+j*8);
    glVertex3f(-25+i*40,0.0f, -13.5+j*8);
    glEnd();
    glColor3f(0.0,0.0,0.0);
    glBegin(GL_LINES);
    glLineWidth(3.0f);
    glVertex3f(-15+i*40,0.0f, -12.5+j*8);
    glVertex3f(-15+i*40,0.0f, -13.5+j*8);
    glEnd();
    }
    //down
    glColor3f(0.1,0.67,0.62);
    glPushMatrix();
    glTranslatef(0,3.1,-14.5+j*8);
    glScalef(20,0.2,3);
    glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE,chair);
    glutSolidCube(1.0f);
    glPopMatrix();
    //back
    glColor3f(0.1,0.67,0.62);
    glPushMatrix(); 

    glTranslatef(0,5,-13+j*8);
    glScalef(20,4,0.2);
    glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE,chair);
    glutSolidCube(1.0f);
    glPopMatrix();
    //leg
    glColor3f(0.0,0.0,0.0);
    glBegin(GL_LINES);
    glLineWidth(3.0f);
    glVertex3f(-10,3.0f, -13+j*8);
    glVertex3f(-10,0.0f, -13+j*8);
    glEnd();
    glColor3f(0.0,0.0,0.0);
    glBegin(GL_LINES);
    glLineWidth(3.0f);
    glVertex3f(10,3.0f, -13+j*8);
    glVertex3f(10,0.0f, -13+j*8);
    glEnd();
    glColor3f(0.0,0.0,0.0);
    glBegin(GL_LINES);
    glLineWidth(3.0f);
    glVertex3f(-10,0.0f, -12.5+j*8);
    glVertex3f(-10,0.0f, -13.5+j*8);
    glEnd();
    glColor3f(0.0,0.0,0.0);
    glBegin(GL_LINES);
    glLineWidth(3.0f);
    glVertex3f(10,0.0f, -12.5+j*8);
    glVertex3f(10,0.0f, -13.5+j*8);
    glEnd();
}
} 

//reshape
void reshape(int we,int he)
{
    WinWidth=we;
    WinHeight=he; 

    glViewport(0,0,(GLsizei) we, (GLsizei) he);
    glMatrixMode(GL_PROJECTION); 

    glLoadIdentity();
    gluPerspective(90.0f, (GLfloat)we/(GLfloat)he, 0.01f,100.0f);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    gluLookAt(myEye.x, myEye.y, myEye.z, vPoint.x+30*sin(vAngle), vPoint.y,-30*cos(vAngle), 0.0f, 1.0f, 0.0f);
}
void display()
{
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); 

    //the function of drawing
    drawscence();
    //drawprojector();
    drawdesks();
    drawchairs(); 

    glFlush();
} 

//the action of the keyboard
GLvoid OnKeyboard(unsigned char key, int x, int y)
{
    switch(key){
        //left
        case 97:
            myEye.x-=0.5;
            vPoint.x-=0.5;
            if(myEye.x<=-40)
            myEye.x=-40;
            break;
        //right
        case 100:
            myEye.x+=0.5;
            vPoint.x+=0.5;
            if(myEye.x>=40)
            myEye.x=40;
            break;
        //down
        case 119:
            myEye.z-=0.5;
            if(myEye.z<=-30)
            myEye.z=-30;
        break;
        //up
        case 115:
            myEye.z+=0.5;
            if(myEye.z>=30)
            myEye.z=30;
        break;
        case 27:
        exit(0);
    }
    reshape(WinWidth,WinHeight);
    glutPostRedisplay();
} 

// the action of the special
GLvoid OnSpecial(int key, int x, int y)
{
        switch(key){ 

            case GLUT_KEY_LEFT:
            vAngle-=0.5;
            break;
            case GLUT_KEY_RIGHT:
            vAngle+=0.5;
            break; 

            case GLUT_KEY_UP:
            myEye.y+=0.5;
            if(myEye.y>=30)
            myEye.y=30;
            break; 

            case GLUT_KEY_DOWN:
            myEye.y-=0.5;
            if(myEye.y<=0)
            myEye.y=30;
            break; 

            case GLUT_KEY_PAGE_DOWN:
            myEye.z+=0.5;
            if(myEye.z>=30)
            myEye.z=30;
            break; 

            case GLUT_KEY_PAGE_UP:
            myEye.z-=0.5;
            if(myEye.z<=-30)
            myEye.z=-30;
            break;
    }
    reshape(WinWidth,WinHeight);
    glutPostRedisplay();
}

//idle function
GLvoid OnIdle()
{
    glutPostRedisplay();
} 

//initial function,initial many parameters including the light and so on
void initial(){ 

    glClearColor(0,0,0,0); 

    glEnable(GL_TEXTURE_2D); 

    glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_REPLACE);//set the mode of the current texture mapping 

    glLightModelfv(GL_LIGHT_MODEL_AMBIENT,model_ambient);
    glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER,GL_TRUE); 

    glMaterialfv(GL_FRONT,GL_SPECULAR,mat_specular);
    glMaterialfv(GL_FRONT,GL_SHININESS,mat_shininess); 

    glLightfv(GL_LIGHT0,GL_POSITION,light_position0);
    glLightfv(GL_LIGHT0,GL_AMBIENT,mat_ambient);
    glLightfv(GL_LIGHT0,GL_DIFFUSE,light);
    glLightfv(GL_LIGHT0,GL_SPECULAR,light);
    glLightfv(GL_LIGHT1,GL_POSITION,light_position1);
    glLightfv(GL_LIGHT1,GL_AMBIENT,mat_ambient);
    glLightfv(GL_LIGHT1,GL_DIFFUSE,white_light);
    glLightfv(GL_LIGHT1,GL_SPECULAR,white_light); 

    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);
    glEnable(GL_COLOR_MATERIAL); 

    glShadeModel(GL_SMOOTH); //set the mode of the color(flat or smooth)
    glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
    glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
    glEnable(GL_DEPTH_TEST);
} 

int main(int argc, char* argv[])
{
    myEye.x=0;
    myEye.y=15;
    myEye.z=25; 

    vPoint.x=0;
    vPoint.y=15;
    vPoint.z=-30;
    vAngle=0; 

    glEnable(GL_DEPTH_TEST); 

    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_RGBA | GLUT_SINGLE);
    glutInitWindowPosition(400, 0);
    glutInitWindowSize(800, 600);
    glutCreateWindow("Demo by zhpmatrix"); 

    initial(); 

    glutDisplayFunc(&display);
    glutReshapeFunc(reshape);
    glutKeyboardFunc(OnKeyboard);
    glutSpecialFunc(OnSpecial);
    glutIdleFunc(OnIdle); 

    /* set the texture */
    texblackboard=load_texture("blackboard.bmp");
    texwindow=load_texture("window.bmp");
    texgaodi=load_texture("gaodi.bmp");
    texceiling=load_texture("Stone.jpg");
    texdoor=load_texture("door.bmp");
    texbackwall=load_texture("backwall.bmp");
    textdesk=load_texture("tdesk.bmp"); 

    glutMainLoop(); 

    return 0;
} 
#include <windows.h>        // Windows的头文件
#include <GL/glut.h>
#include <stdio.h>
#include <glaux.h>
#include <math.h>            // 数学库
#pragma comment(lib, "glaux.lib")
#pragma comment(lib, "advapi32.lib")
#pragma comment(lib, "legacy_stdio_definitions.lib")

const float piover180 = 0.0174532925f;  //  π/180=0.0174532925用于乘以头部旋转角度heading
float heading;                            //  头部旋转角度
float xpos;                                //    x方向坐标
float zpos;                                //    z方向坐标
GLfloat    z=0.0f;                            //  头部上下旋转

typedef struct tagVERTEX// 创建Vertex顶点结构
{
    float x, y, z;   // 3D 坐标
    float u, v;        // 纹理坐标
} VERTEX;

typedef struct tagTRIANGLE//一个sector(区段)包含了一系列的多边形,所以我就定义了一个triangle(我的墙体、地板和天花板用三角形构成)
{
    VERTEX vertex[3];  // VERTEX矢量数组,大小为3
} TRIANGLE;

typedef struct tagSECTOR//每个3D世界基本上可以看作是sector(区段)的集合。一个sector可以是一个房间、一个立方体、或者任意一个闭合的区间
{
    int numtriangles;  // Sector中的三角形个数
    TRIANGLE* triangle;// 指向三角数组的指针
} SECTOR;

SECTOR sector1;                //创建一个世界

GLfloat        xrot;            // X 旋转量
GLfloat        yrot;            // Y 旋转量

BOOL    light;                // 光源的开/关
BOOL    lp;                    // L键按下了么?
bool    blend;                // 是否混合?
bool    bp;                    // B 键按下了么?

GLfloat LightAmbient[]= { 0.5f, 0.5f, 0.5f, 1.0f };     // 环境光参数
GLfloat LightDiffuse[]= { 1.0f, 1.0f, 1.0f, 1.0f };        // 漫射光参数
GLfloat LightPosition[]= { 0.0f, 0.0f, 2.0f, 1.0f };    // 光源位置

GLuint    texture[18];                                        // 18种纹理的储存空间
HDC            hDC=NULL;        // 窗口着色描述表句柄
HGLRC        hRC=NULL;        // OpenGL渲染描述表句柄
HWND        hWnd=NULL;        // 保存我们的窗口句柄
HINSTANCE    hInstance;        // 保存程序的实例

bool    keys[256];            // 保存键盘按键的数组
bool    active=TRUE;        // 窗口的活动标志,缺省为TRUE
bool    fullscreen=TRUE;    // 全屏标志缺省,缺省设定成全屏模式

LRESULT    CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);    // WndProc的定义

//---------------读入字符串函数---------------------

void readstr(FILE *f,char *string)                            //  读入一个字符串

{
    do                                                        // 循环开始
    {
        fgets(string, 255, f);                                // 读入一行
    } while ((string[0] == ‘/‘) || (string[0] == ‘\n‘));    // 考察是否有必要进行处理
    return;                                                    // 返回
}

//-----------------------设置世界函数-------------------------

void SetupWorld()                                            // 设置我们的世界
{
    FILE *filein;                                            // 工作文件
    filein = fopen("data/world.txt", "rt");                    // 打开文件

    int numtriangles;                                        // 区段中的三角形数量
    char oneline[255];                                        // 存储数据的字符串
    float x, y, z, u, v;                                    // 3D 和 纹理坐标

    readstr(filein,oneline);                                // 读入一行数据
    sscanf(oneline, "NUMPOLLIES %d\n", &numtriangles);        // 读入三角形数量

    sector1.triangle = new TRIANGLE[numtriangles];            // 为numtriangles个三角形分配内存并设定指针
    sector1.numtriangles = numtriangles;                    // 定义区段1中的三角形数量
    // 遍历区段中的每个三角形
    for (int triloop = 0; triloop < numtriangles; triloop++)// 遍历所有的三角形
    {
        // 遍历三角形的每个顶点
        for (int vertloop = 0; vertloop < 3; vertloop++)    // 遍历所有的顶点
        {
            readstr(filein,oneline);                        // 读入一行数据
            // 读入各自的顶点数据
            sscanf(oneline, "%f %f %f %f %f", &x, &y, &z, &u, &v);
            // 将顶点数据存入各自的顶点
            sector1.triangle[triloop].vertex[vertloop].x = x;    // 区段 1,  第 triloop 个三角形, 第  vertloop 个顶点, 值 x =x
            sector1.triangle[triloop].vertex[vertloop].y = y;    // 区段 1,  第 triloop 个三角形, 第  vertloop 个顶点, 值 y =y
            sector1.triangle[triloop].vertex[vertloop].z = z;    // 区段 1,  第 triloop 个三角形, 第  vertloop 个顶点, 值  z =z
            sector1.triangle[triloop].vertex[vertloop].u = u;    // 区段 1,  第 triloop 个三角形, 第  vertloop 个顶点, 值  u =u
            sector1.triangle[triloop].vertex[vertloop].v = v;    // 区段 1,  第 triloop 个三角形, 第  vertloop 个顶点, 值  e=v
        }
    }
    fclose(filein);
    return;                                                    // 返回
}

AUX_RGBImageRec *LoadBMP(CHAR *Filename)                // 载入位图图象
{
    FILE *File=NULL;                                    // 文件句柄
    if (!Filename)                                        // 确保文件名已提供
    {
        return NULL;                                    // 如果没提供,返回 NULL
    }
    File=fopen(Filename,"r");                            // 尝试打开文件
    if (File)                                            // 文件存在么?
    {
        fclose(File);                                    // 关闭句柄
        return auxDIBImageLoadA(Filename);                // 载入位图并返回指针
    }
    return NULL;                                        // 如果载入失败,返回 NULL
}

int LoadGLTextures()                                    // 载入位图(调用上面的代码)并转换成纹理
{
    int Status=FALSE;                                    // 状态指示器
    AUX_RGBImageRec *TextureImage[18];                    // 创建纹理的存储空间
    memset(TextureImage,0,sizeof(void *)*1);            // 将指针设为 NULL

//------------------------载入纹理图片------------------------//

    if (TextureImage[0]=LoadBMP("Data/ceiling.bmp"))
    {
        Status=TRUE;                                    // 状态设为 TRUE
        glGenTextures(1, &texture[0]);                    // 创建纹理
        // 创建线性滤波纹理
        glBindTexture(GL_TEXTURE_2D, texture[0]);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
        glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);
      }

        if (TextureImage[1]=LoadBMP("Data/door.bmp"))
    {
        Status=TRUE;                                    // 状态设为 TRUE
        glGenTextures(1, &texture[1]);                    // 创建纹理
        // 创建线性滤波纹理
        glBindTexture(GL_TEXTURE_2D, texture[1]);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
        glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[1]->sizeX, TextureImage[1]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[1]->data);
      }
            if (TextureImage[2]=LoadBMP("Data/floor.bmp"))
    {
        Status=TRUE;                                    // 状态设为 TRUE
        glGenTextures(1, &texture[2]);                    // 创建纹理
        // 创建线性滤波纹理
        glBindTexture(GL_TEXTURE_2D, texture[2]);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
        glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[2]->sizeX, TextureImage[2]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[2]->data);
      }
            if (TextureImage[3]=LoadBMP("Data/lblackboard.bmp"))
    {
        Status=TRUE;                                    // 状态设为 TRUE
        glGenTextures(1, &texture[3]);                    // 创建纹理
        // 创建线性滤波纹理
        glBindTexture(GL_TEXTURE_2D, texture[3]);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
        glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[3]->sizeX, TextureImage[3]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[3]->data);
      }
            if (TextureImage[4]=LoadBMP("Data/rblackboard.bmp"))
    {
        Status=TRUE;                                    // 状态设为 TRUE
        glGenTextures(1, &texture[4]);                    // 创建纹理
        // 创建线性滤波纹理
        glBindTexture(GL_TEXTURE_2D, texture[4]);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
        glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[4]->sizeX, TextureImage[4]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[4]->data);
      }
            if (TextureImage[5]=LoadBMP("Data/wall.bmp"))
    {
        Status=TRUE;                                    // 状态设为 TRUE
        glGenTextures(1, &texture[5]);                    // 创建纹理
        // 创建线性滤波纹理
        glBindTexture(GL_TEXTURE_2D, texture[5]);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
        glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[5]->sizeX, TextureImage[5]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[5]->data);
      }
            if (TextureImage[6]=LoadBMP("Data/window.bmp"))
    {
        Status=TRUE;                                    // 状态设为 TRUE
        glGenTextures(1, &texture[6]);                    // 创建纹理
        // 创建线性滤波纹理
        glBindTexture(GL_TEXTURE_2D, texture[6]);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
        glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[6]->sizeX, TextureImage[6]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[6]->data);
      }
            if (TextureImage[7]=LoadBMP("Data/desk.bmp"))
    {
        Status=TRUE;                                    // 状态设为 TRUE
        glGenTextures(1, &texture[7]);                    // 创建纹理
        // 创建线性滤波纹理
        glBindTexture(GL_TEXTURE_2D, texture[7]);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
        glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[7]->sizeX, TextureImage[7]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[7]->data);
      }
            if (TextureImage[8]=LoadBMP("Data/air.bmp"))
    {
        Status=TRUE;                                    // 状态设为 TRUE
        glGenTextures(1, &texture[8]);                    // 创建纹理
        // 创建线性滤波纹理
        glBindTexture(GL_TEXTURE_2D, texture[8]);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
        glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[8]->sizeX, TextureImage[8]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[8]->data);
      }
            if (TextureImage[9]=LoadBMP("Data/air-sides.bmp"))
    {
        Status=TRUE;                                    // 状态设为 TRUE
        glGenTextures(1, &texture[9]);                    // 创建纹理
        // 创建线性滤波纹理
        glBindTexture(GL_TEXTURE_2D, texture[9]);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
        glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[9]->sizeX, TextureImage[9]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[9]->data);
      }
            if (TextureImage[10]=LoadBMP("Data/laptop.bmp"))
    {
        Status=TRUE;                                    // 状态设为 TRUE
        glGenTextures(1, &texture[10]);                    // 创建纹理
        // 创建线性滤波纹理
        glBindTexture(GL_TEXTURE_2D, texture[10]);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
        glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[10]->sizeX, TextureImage[10]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[10]->data);
      }
            if (TextureImage[11]=LoadBMP("Data/laptop-sides.bmp"))
    {
        Status=TRUE;                                    // 状态设为 TRUE
        glGenTextures(1, &texture[11]);                    // 创建纹理
        // 创建线性滤波纹理
        glBindTexture(GL_TEXTURE_2D, texture[11]);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
        glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[11]->sizeX, TextureImage[11]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[11]->data);
      }
            if (TextureImage[12]=LoadBMP("Data/voice box.bmp"))
    {
        Status=TRUE;                                    // 状态设为 TRUE
        glGenTextures(1, &texture[12]);                    // 创建纹理
        // 创建线性滤波纹理
        glBindTexture(GL_TEXTURE_2D, texture[12]);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
        glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[12]->sizeX, TextureImage[12]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[12]->data);
      }
            if (TextureImage[13]=LoadBMP("Data/blackboard.bmp"))
    {
        Status=TRUE;                                    // 状态设为 TRUE
        glGenTextures(1, &texture[13]);                    // 创建纹理
        // 创建线性滤波纹理
        glBindTexture(GL_TEXTURE_2D, texture[13]);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
        glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[13]->sizeX, TextureImage[13]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[13]->data);
      }
            if (TextureImage[14]=LoadBMP("Data/blackboard-sides.bmp"))
    {
        Status=TRUE;                                    // 状态设为 TRUE
        glGenTextures(1, &texture[14]);                    // 创建纹理
        // 创建线性滤波纹理
        glBindTexture(GL_TEXTURE_2D, texture[14]);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
        glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[14]->sizeX, TextureImage[14]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[14]->data);
      }
            if (TextureImage[15]=LoadBMP("Data/projector.bmp"))
    {
        Status=TRUE;                                    // 状态设为 TRUE
        glGenTextures(1, &texture[15]);                    // 创建纹理
        // 创建线性滤波纹理
        glBindTexture(GL_TEXTURE_2D, texture[15]);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
        glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[15]->sizeX, TextureImage[15]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[15]->data);
      }
            if (TextureImage[16]=LoadBMP("Data/zhuzi.bmp"))
    {
        Status=TRUE;                                    // 状态设为 TRUE
        glGenTextures(1, &texture[16]);                    // 创建纹理
        // 创建线性滤波纹理
        glBindTexture(GL_TEXTURE_2D, texture[16]);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
        glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[16]->sizeX, TextureImage[16]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[16]->data);
      }
            if (TextureImage[17]=LoadBMP("Data/projector-sides.bmp"))
    {
        Status=TRUE;                                    // 状态设为 TRUE
        glGenTextures(1, &texture[17]);                    // 创建纹理
        // 创建线性滤波纹理
        glBindTexture(GL_TEXTURE_2D, texture[17]);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
        glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[17]->sizeX, TextureImage[17]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[17]->data);
      }
            for(char h=17;h>0;h--){
    if (TextureImage[h])                                // 纹理是否存在
    {
        if (TextureImage[h]->data)                        // 纹理图像是否存在
        {
            free(TextureImage[h]->data);                // 释放纹理图像占用的内存
        }

        free(TextureImage[h]);                            // 释放图像结构
    }
            }
    return Status;                                        // 返回 Status
}

GLvoid ReSizeGLScene(GLsizei width, GLsizei height)        // 重置OpenGL窗口大小
{
    if (height==0)                                        // 防止被零除
    {
        height=1;                                        // 将Height设为1
    }

    glViewport(0,0,width,height);                        // 重置当前的视口

    glMatrixMode(GL_PROJECTION);                        // 选择投影矩阵
    glLoadIdentity();                                    // 重置投影矩阵

    // 设置视口的大小
    gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f);

    glMatrixMode(GL_MODELVIEW);                            // 选择模型观察矩阵
    glLoadIdentity();                                    // 重置模型观察矩阵
}

int InitGL(GLvoid)                                        // 此处开始对OpenGL进行所有设置
{
    if (!LoadGLTextures())                                // 调用纹理载入子例程
    {
        return FALSE;                                    // 如果未能载入,返回FALSE
    }

    glLightfv(GL_LIGHT1, GL_AMBIENT, LightAmbient);        // 设置环境光
    glLightfv(GL_LIGHT1, GL_DIFFUSE, LightDiffuse);        // 设置漫射光
    glLightfv(GL_LIGHT1, GL_POSITION,LightPosition);    // 设置光源位置
    glEnable(GL_LIGHT1);                                // 启用一号光源
    glEnable(GL_TEXTURE_2D);                            // 启用纹理映射
    glShadeModel(GL_SMOOTH);                            // 启用阴影平滑
    glClearColor(0.0f, 0.0f, 0.0f, 0.5f);                // 黑色背景
    glClearDepth(1.0f);                                    // 设置深度缓存
    glEnable(GL_DEPTH_TEST);                            // 启用深度测试
    glDepthFunc(GL_LEQUAL);                                // 所作深度测试的类型
    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);    // 告诉系统对透视进行修正
    glColor4f(1.0f,1.0f,1.0f,0.5f);                        // 全亮度, 50% Alpha 混合
    glBlendFunc(GL_SRC_ALPHA,GL_ONE);                    // 基于源象素alpha通道值的半透明混合函数

    SetupWorld();
    return TRUE;                                        // 初始化 OK
}

int DrawGLScene(GLvoid)                                                // 从这里开始进行所有的绘制
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);                // 清除屏幕和深度缓存
    glLoadIdentity();                                                // 重置当前的模型观察矩阵

    GLfloat x_m, y_m, z_m, u_m, v_m;                                // 顶点的临时 X, Y, Z, U 和 V 的数值
    GLfloat xtrans = -xpos;                                            // 用于游戏者沿X轴平移时的大小
    GLfloat ztrans = -zpos;                                            // 用于游戏者沿Z轴平移时的大小
    GLfloat ytrans = -0.7;                                            // 用于设置游戏者头部高度
    GLfloat sceneroty = 360.0f - yrot;                                // 位于游戏者方向的360度角

    int numtriangles;                                                // 保有三角形数量的整数

    glRotatef(z,1.0f,0,0);                                            // 上下旋转
    glRotatef(sceneroty,0,1.0f,0);                                    // 根据游戏者正面所对方向所作的旋转

    glTranslatef(xtrans, ytrans, ztrans);                            // 以游戏者为中心的平移场景
    numtriangles = sector1.numtriangles;                            // 取得Sector1的三角形数量

    // 逐个处理三角形
    for (int loop_m = 0; loop_m < numtriangles; loop_m++)            // 遍历所有的三角形
    {
            if(loop_m==0||loop_m==1) glBindTexture(GL_TEXTURE_2D, texture[2]);    //根据墙壁的位置绑定纹理
            if(loop_m==2||loop_m==3) glBindTexture(GL_TEXTURE_2D, texture[0]);
            if(loop_m==4||loop_m==5) glBindTexture(GL_TEXTURE_2D, texture[3]);
            if(loop_m==6||loop_m==7) glBindTexture(GL_TEXTURE_2D, texture[4]);
            if(loop_m==8||loop_m==9) glBindTexture(GL_TEXTURE_2D, texture[5]);
            if(loop_m==10||loop_m==11) glBindTexture(GL_TEXTURE_2D, texture[5]);
            if(loop_m==12||loop_m==13) glBindTexture(GL_TEXTURE_2D, texture[6]);
            if(loop_m==14||loop_m==15) glBindTexture(GL_TEXTURE_2D, texture[6]);
            if(loop_m==16||loop_m==17) glBindTexture(GL_TEXTURE_2D, texture[6]);
            if(loop_m==18||loop_m==19) glBindTexture(GL_TEXTURE_2D, texture[1]);

            glBegin(GL_TRIANGLES);                                        // 开始绘制三角形
            glNormal3f( 0.0f, 0.0f, 1.0f);                            // 指向前面的法线
            x_m = sector1.triangle[loop_m].vertex[0].x;                // 第一点的 X 分量
            y_m = sector1.triangle[loop_m].vertex[0].y;                // 第一点的 Y 分量
            z_m = sector1.triangle[loop_m].vertex[0].z;                // 第一点的 Z 分量
            u_m = sector1.triangle[loop_m].vertex[0].u;                // 第一点的 U  纹理坐标
            v_m = sector1.triangle[loop_m].vertex[0].v;                // 第一点的 V  纹理坐标
            glTexCoord2f(u_m,v_m); glVertex3f(x_m,y_m,z_m);            // 设置纹理坐标和顶点

            x_m = sector1.triangle[loop_m].vertex[1].x;                // 第二点的 X 分量
            y_m = sector1.triangle[loop_m].vertex[1].y;                // 第二点的 Y 分量
            z_m = sector1.triangle[loop_m].vertex[1].z;                // 第二点的 Z 分量
            u_m = sector1.triangle[loop_m].vertex[1].u;                // 第二点的 U  纹理坐标
            v_m = sector1.triangle[loop_m].vertex[1].v;                // 第二点的 V  纹理坐标
            glTexCoord2f(u_m,v_m); glVertex3f(x_m,y_m,z_m);            // 设置纹理坐标和顶点

            x_m = sector1.triangle[loop_m].vertex[2].x;                // 第三点的 X 分量
            y_m = sector1.triangle[loop_m].vertex[2].y;                // 第三点的 Y 分量
            z_m = sector1.triangle[loop_m].vertex[2].z;                // 第三点的 Z 分量
            u_m = sector1.triangle[loop_m].vertex[2].u;                // 第二点的 U  纹理坐标
            v_m = sector1.triangle[loop_m].vertex[2].v;                // 第二点的 V  纹理坐标
            glTexCoord2f(u_m,v_m); glVertex3f(x_m,y_m,z_m);            // 设置纹理坐标和顶点
        glEnd();// 三角形绘制结束
    }

            //绘制其他的物体:

            glBindTexture(GL_TEXTURE_2D, texture[7]);
            glBegin(GL_QUADS);
            glTexCoord2f(0,1);glVertex3f(-1.0f, 0.4f, -2.0f);                    // 课桌上面
            glTexCoord2f(0,0);glVertex3f(-1.0f, 0.4f, -1.0f);                    //
            glTexCoord2f(1,0);glVertex3f( 1.0f, 0.4f, -1.0f);                    //
            glTexCoord2f(1,1);glVertex3f( 1.0f, 0.4f, -2.0f);                    // 

            glTexCoord2f(0,1);glVertex3f(-1.0f, 0.0f, -2.0f);                    // 课桌下面
            glTexCoord2f(0,0);glVertex3f(-1.0f, 0.0f, -1.0f);                    //
            glTexCoord2f(1,0);glVertex3f( 1.0f,-0.0f, -1.0f);                    //
            glTexCoord2f(1,1);glVertex3f( 1.0f,-0.0f, -2.0f);                    // 

            glTexCoord2f(0,1);glVertex3f(-1.0f, 0.4f, -2.0f);                    // 课桌后面
            glTexCoord2f(0,0);glVertex3f(-1.0f, 0.0f, -2.0f);                    //
            glTexCoord2f(1,0);glVertex3f( 1.0f, 0.0f, -2.0f);                    //
            glTexCoord2f(1,1);glVertex3f( 1.0f, 0.4f, -2.0f);                    // 

            glTexCoord2f(0,1);glVertex3f(-1.0f, 0.4f, -1.0f);                    // 课桌前面
            glTexCoord2f(0,0);glVertex3f(-1.0f, 0.0f, -1.0f);                    //
            glTexCoord2f(1,0);glVertex3f( 1.0f, 0.0f, -1.0f);                    //
            glTexCoord2f(1,1);glVertex3f( 1.0f, 0.4f, -1.0f);                    // 

            glTexCoord2f(0,1);glVertex3f(-1.0f, 0.4f, -2.0f);                    // 课桌左面
            glTexCoord2f(0,0);glVertex3f(-1.0f, 0.0f, -2.0f);                    //
            glTexCoord2f(1,0);glVertex3f(-1.0f, 0.0f, -1.0f);                    //
            glTexCoord2f(1,1);glVertex3f(-1.0f, 0.4f, -1.0f);                    // 

            glTexCoord2f(0,1);glVertex3f( 1.0f, 0.4f, -1.0f);                    // 课桌右面
            glTexCoord2f(0,0);glVertex3f( 1.0f, 0.0f, -1.0f);                    //
            glTexCoord2f(1,0);glVertex3f( 1.0f, 0.0f, -2.0f);                    //
            glTexCoord2f(1,1);glVertex3f( 1.0f, 0.4f, -2.0f);                    //
            glEnd();

            glBindTexture(GL_TEXTURE_2D, texture[8]);
            glBegin(GL_QUADS);
            glTexCoord2f(0,1);glVertex3f( 3.0f, 2.0f,  2.6f);                    // 空调前面
            glTexCoord2f(0,0);glVertex3f( 3.0f, 1.6f,  2.6f);                    //
            glTexCoord2f(1,0);glVertex3f( 1.0f, 1.6f,  2.6f);                    //
            glTexCoord2f(1,1);glVertex3f( 1.0f, 2.0f,  2.6f);                    //
            glEnd();

            glBindTexture(GL_TEXTURE_2D, texture[9]);
            glBegin(GL_QUADS);
            glTexCoord2f(0,1);glVertex3f( 3.0f, 1.6f,  2.6f);                    // 空调下面
            glTexCoord2f(0,0);glVertex3f( 3.0f, 1.6f,  3.0f);                    //
            glTexCoord2f(1,0);glVertex3f( 1.0f, 1.6f,  3.0f);                    //
            glTexCoord2f(1,1);glVertex3f( 1.0f, 1.6f,  2.6f);                    // 

            glTexCoord2f(0,1);glVertex3f( 1.0f, 2.0f,  2.6f);                    // 空调右面
            glTexCoord2f(0,0);glVertex3f( 1.0f, 1.6f,  2.6f);                    //
            glTexCoord2f(1,0);glVertex3f( 1.0f, 1.6f,  3.0f);                    //
            glTexCoord2f(1,1);glVertex3f( 1.0f, 2.0f,  3.0f);                    //
            glEnd();

            glBindTexture(GL_TEXTURE_2D, texture[10]);
            glBegin(GL_QUADS);
            glTexCoord2f(0,1);glVertex3f( 0.8f, 0.41f,  -1.7f);                    // 电脑正面
            glTexCoord2f(0,0);glVertex3f( 0.8f, 0.41f,  -1.9f);                    //
            glTexCoord2f(1,0);glVertex3f( 0.5f, 0.41f,  -1.9f);                    //
            glTexCoord2f(1,1);glVertex3f( 0.5f, 0.41f,  -1.7f);                //
            glEnd();

            glBindTexture(GL_TEXTURE_2D, texture[11]);
            glBegin(GL_QUADS);
            glTexCoord2f(0,1);glVertex3f( 0.8f, 0.41f,  -1.7f);                    // 电脑侧面
            glTexCoord2f(0,0);glVertex3f( 0.8f, 0.40f,  -1.7f);                    //
            glTexCoord2f(1,0);glVertex3f( 0.8f, 0.40f,  -1.9f);                    //
            glTexCoord2f(1,1);glVertex3f( 0.8f, 0.41f,  -1.9f);                // 

            glTexCoord2f(0,1);glVertex3f( 0.5f, 0.41f,  -1.7f);                    // 电脑侧面
            glTexCoord2f(0,0);glVertex3f( 0.5f, 0.40f,  -1.7f);                    //
            glTexCoord2f(1,0);glVertex3f( 0.8f, 0.40f,  -1.7f);                    //
            glTexCoord2f(1,1);glVertex3f( 0.8f, 0.41f,  -1.7f);                // 

            glTexCoord2f(0,1);glVertex3f( 0.5f, 0.41f,  -1.9f);                    // 电脑侧面
            glTexCoord2f(0,0);glVertex3f( 0.5f, 0.40f,  -1.9f);                    //
            glTexCoord2f(1,0);glVertex3f( 0.5f, 0.40f,  -1.7f);                    //
            glTexCoord2f(1,1);glVertex3f( 0.5f, 0.41f,  -1.7f);                // 

            glTexCoord2f(0,1);glVertex3f( 0.8f, 0.41f,  -1.9f);                    // 电脑侧面
            glTexCoord2f(0,0);glVertex3f( 0.8f, 0.40f,  -1.9f);                    //
            glTexCoord2f(1,0);glVertex3f( 0.5f, 0.40f,  -1.9f);                    //
            glTexCoord2f(1,1);glVertex3f( 0.5f, 0.41f,  -1.9f);                //
            glEnd();

            glBindTexture(GL_TEXTURE_2D, texture[12]);
            glBegin(GL_QUADS);
            glTexCoord2f(0,1);glVertex3f( 2.8f, 2.0f,  -2.8f);                    // 右音箱正面
            glTexCoord2f(0,0);glVertex3f( 2.8f, 1.7f,  -2.8f);                    //
            glTexCoord2f(1,0);glVertex3f( 3.0f, 1.7f,  -2.8f);                    //
            glTexCoord2f(1,1);glVertex3f( 3.0f, 2.0f,  -2.8f);                    //

            glTexCoord2f(0,1);glVertex3f( -2.8f, 2.0f,  -2.8f);                    // 左音箱正面
            glTexCoord2f(0,0);glVertex3f( -2.8f, 1.7f,  -2.8f);                    //
            glTexCoord2f(1,0);glVertex3f( -3.0f, 1.7f,  -2.8f);                    //
            glTexCoord2f(1,1);glVertex3f( -3.0f, 2.0f,  -2.8f);                    //
            glEnd();

            glBindTexture(GL_TEXTURE_2D, texture[2]);
            glBegin(GL_QUADS);
            glTexCoord2f(0,1);glVertex3f( 2.8f, 2.0f,  -3.0f);                    // 右音箱侧面
            glTexCoord2f(0,0);glVertex3f( 2.8f, 1.7f,  -3.0f);                    //
            glTexCoord2f(1,0);glVertex3f( 2.8f, 1.7f,  -2.8f);                    //
            glTexCoord2f(1,1);glVertex3f( 2.8f, 2.0f,  -2.8f);                    //

            glTexCoord2f(0,1);glVertex3f( -2.8f, 2.0f,  -3.0f);                    // 左音箱侧面
            glTexCoord2f(0,0);glVertex3f( -2.8f, 1.7f,  -3.0f);                    //
            glTexCoord2f(1,0);glVertex3f( -2.8f, 1.7f,  -2.8f);                    //
            glTexCoord2f(1,1);glVertex3f( -2.8f, 2.0f,  -2.8f);                    //

            glTexCoord2f(0,1);glVertex3f( 2.8f, 1.7f,  -3.0f);                    // 右音箱下面
            glTexCoord2f(0,0);glVertex3f( 2.8f, 1.7f,  -2.8f);                    //
            glTexCoord2f(1,0);glVertex3f( 3.0f, 1.7f,  -2.8f);                    //
            glTexCoord2f(1,1);glVertex3f( 3.0f, 1.7f,  -3.0f);                    //

            glTexCoord2f(0,1);glVertex3f( -2.8f, 1.7f,  -3.0f);                    // 左音箱下面
            glTexCoord2f(0,0);glVertex3f( -2.8f, 1.7f,  -2.8f);                    //
            glTexCoord2f(1,0);glVertex3f( -3.0f, 1.7f,  -2.8f);                    //
            glTexCoord2f(1,1);glVertex3f( -3.0f, 1.7f,  -3.0f);                    //
            glEnd();

            glBindTexture(GL_TEXTURE_2D, texture[13]);
            glBegin(GL_QUADS);
            glTexCoord2f(0,1);glVertex3f( -2.1f, 1.8f,  -2.95f);                    // 黑板正面
            glTexCoord2f(0,0);glVertex3f( -2.1f, 0.5f,  -2.95f);                    //
            glTexCoord2f(1,0);glVertex3f(  2.1f, 0.5f,  -2.95f);                    //
            glTexCoord2f(1,1);glVertex3f(  2.1f, 1.8f,  -2.95f);                    //
            glEnd();

            glBindTexture(GL_TEXTURE_2D, texture[14]);
            glBegin(GL_QUADS);
            glTexCoord2f(0,1);glVertex3f(  2.1f, 1.8f,  -2.95f);                    // 黑板侧面
            glTexCoord2f(0,0);glVertex3f(  2.1f, 0.5f,  -2.95f);                    //
            glTexCoord2f(1,0);glVertex3f(  2.1f, 0.5f,  -3.0f);                    //
            glTexCoord2f(1,1);glVertex3f(  2.1f, 1.8f,  -3.0f);                    //

            glTexCoord2f(0,1);glVertex3f( -2.1f, 1.8f,  -3.0f);                    // 黑板侧面
            glTexCoord2f(0,0);glVertex3f( -2.1f, 1.8f,  -2.95f);                    //
            glTexCoord2f(1,0);glVertex3f(  2.1f, 1.8f,  -2.95f);                    //
            glTexCoord2f(1,1);glVertex3f(  2.1f, 1.8f,  -3.0f);                    //

            glTexCoord2f(0,1);glVertex3f( -2.1f, 1.8f,  -3.0f);                    // 黑板侧面
            glTexCoord2f(0,0);glVertex3f( -2.1f, 0.5f,  -3.0f);                    //
            glTexCoord2f(1,0);glVertex3f( -2.1f, 0.5f,  -2.95f);                    //
            glTexCoord2f(1,1);glVertex3f( -2.1f, 1.8f,  -2.95f);                    //

            glTexCoord2f(0,1);glVertex3f( -2.1f, 0.5f,  -3.0f);                    // 黑板侧面
            glTexCoord2f(0,0);glVertex3f( -2.1f, 0.5f,  -2.95f);                    //
            glTexCoord2f(1,0);glVertex3f(  2.1f, 0.5f,  -2.95f);                    //
            glTexCoord2f(1,1);glVertex3f(  2.1f, 0.5f,  -3.0f);                    //
            glEnd();

            glBindTexture(GL_TEXTURE_2D, texture[14]);
            glBegin(GL_QUADS);
            glTexCoord2f(0,1);glVertex3f(  -0.6f, 2.0f,  -2.90f);                    // 投影仪画布右
            glTexCoord2f(0,0);glVertex3f(  -0.6f, 1.9f,  -2.90f);                    //
            glTexCoord2f(1,0);glVertex3f(  -0.6f, 1.9f,  -3.0f);                    //
            glTexCoord2f(1,1);glVertex3f(  -0.6f, 2.0f,  -3.0f);                    //

            glTexCoord2f(0,1);glVertex3f( -2.6f, 2.0f,  -2.9f);                    // 投影仪画布前
            glTexCoord2f(0,0);glVertex3f( -2.6f, 1.9f,  -2.9f);                    //
            glTexCoord2f(1,0);glVertex3f( -0.6f, 1.9f,  -2.9f);                    //
            glTexCoord2f(1,1);glVertex3f( -0.6f, 2.0f,  -2.9f);                    //

            glTexCoord2f(0,1);glVertex3f( -2.6f, 1.9f,  -2.9f);                    // 投影仪画布下
            glTexCoord2f(0,0);glVertex3f( -2.6f, 1.9f,  -3.0f);                    //
            glTexCoord2f(1,0);glVertex3f( -0.6f, 1.9f,  -3.0f);                    //
            glTexCoord2f(1,1);glVertex3f( -0.6f, 1.9f,  -2.9f);                    //

            glTexCoord2f(0,1);glVertex3f( -2.6f, 2.0f,  -3.0f);                    // 投影仪画布左
            glTexCoord2f(0,0);glVertex3f( -2.6f, 1.9f,  -3.0f);                    //
            glTexCoord2f(1,0);glVertex3f( -2.6f, 1.9f,  -2.9f);                    //
            glTexCoord2f(1,1);glVertex3f( -2.6f, 2.0f,  -2.9f);                    //
            glEnd();

            glBindTexture(GL_TEXTURE_2D, texture[16]);
            glBegin(GL_QUADS);
            glTexCoord2f(0,1);glVertex3f(  -1.55f, 2.0f,  -0.1f);                    // 投影仪柱子前
            glTexCoord2f(0,0);glVertex3f(  -1.55f, 1.6f,  -0.1f);                    //
            glTexCoord2f(1,0);glVertex3f(  -1.65f, 1.6f,  -0.1f);                    //
            glTexCoord2f(1,1);glVertex3f(  -1.65f, 2.0f,  -0.1f);                    //

            glTexCoord2f(0,1);glVertex3f( -1.65f, 2.0f,  -0.0f);                    // 投影仪柱子后
            glTexCoord2f(0,0);glVertex3f( -1.65f, 1.6f,  -0.0f);                    //
            glTexCoord2f(1,0);glVertex3f( -1.55f, 1.6f,  -0.0f);                    //
            glTexCoord2f(1,1);glVertex3f( -1.55f, 2.0f,  -0.0f);                    //

            glTexCoord2f(0,1);glVertex3f( -1.65f, 2.0f,  -0.1f);                    // 投影仪柱子左
            glTexCoord2f(0,0);glVertex3f( -1.65f, 1.6f,  -0.1f);                    //
            glTexCoord2f(1,0);glVertex3f( -1.65f, 1.6f,  -0.0f);                    //
            glTexCoord2f(1,1);glVertex3f( -1.65f, 2.0f,  -0.0f);                    //

            glTexCoord2f(0,1);glVertex3f( -1.55f, 2.0f,  -0.0f);                    // 投影仪柱子右
            glTexCoord2f(0,0);glVertex3f( -1.55f, 1.6f,  -0.0f);                    //
            glTexCoord2f(1,0);glVertex3f( -1.55f, 1.6f,  -0.1f);                    //
            glTexCoord2f(1,1);glVertex3f( -1.55f, 2.0f,  -0.1f);                    //
            glEnd();

            glBindTexture(GL_TEXTURE_2D, texture[15]);
            glBegin(GL_QUADS);
            glTexCoord2f(0,1);glVertex3f(  -1.25f, 1.6f,  -0.4f);                    // 投影仪前
            glTexCoord2f(0,0);glVertex3f(  -1.25f, 1.5f,  -0.4f);                    //
            glTexCoord2f(1,0);glVertex3f(  -1.85f, 1.5f,  -0.4f);                    //
            glTexCoord2f(1,1);glVertex3f(  -1.85f, 1.6f,  -0.4f);                    //
            glEnd();

            glBindTexture(GL_TEXTURE_2D, texture[17]);
            glBegin(GL_QUADS);
            glTexCoord2f(0,1);glVertex3f(  -1.85f, 1.6f,  0.2f);                    // 投影仪后
            glTexCoord2f(0,0);glVertex3f(  -1.85f, 1.5f,  0.2f);                    //
            glTexCoord2f(1,0);glVertex3f(  -1.25f, 1.5f,  0.2f);                    //
            glTexCoord2f(1,1);glVertex3f(  -1.25f, 1.6f,  0.2f);                    //

            glTexCoord2f(0,1);glVertex3f( -1.85f, 1.6f,  -0.4f);                    // 投影仪左
            glTexCoord2f(0,0);glVertex3f( -1.85f, 1.5f,  -0.4f);                    //
            glTexCoord2f(1,0);glVertex3f( -1.85f, 1.5f,   0.2f);                    //
            glTexCoord2f(1,1);glVertex3f( -1.85f, 1.6f,   0.2f);                    //

            glTexCoord2f(0,1);glVertex3f( -1.25f, 1.6f,   0.2f);                    // 投影仪右
            glTexCoord2f(0,0);glVertex3f( -1.25f, 1.5f,   0.2f);                    //
            glTexCoord2f(1,0);glVertex3f( -1.25f, 1.5f,  -0.4f);                    //
            glTexCoord2f(1,1);glVertex3f( -1.25f, 1.6f,  -0.4f);                    //

            glTexCoord2f(0,1);glVertex3f( -1.85f, 1.6f,  -0.4f);                    // 投影仪上
            glTexCoord2f(0,0);glVertex3f( -1.85f, 1.6f,   0.2f);                    //
            glTexCoord2f(1,0);glVertex3f( -1.25f, 1.6f,   0.2f);                    //
            glTexCoord2f(1,1);glVertex3f( -1.25f, 1.6f,  -0.4f);                    //

            glTexCoord2f(0,1);glVertex3f( -1.85f, 1.5f,  -0.4f);                    // 投影仪下
            glTexCoord2f(0,0);glVertex3f( -1.85f, 1.5f,   0.2f);                    //
            glTexCoord2f(1,0);glVertex3f( -1.25f, 1.5f,   0.2f);                    //
            glTexCoord2f(1,1);glVertex3f( -1.25f, 1.5f,  -0.4f);                    //
            glEnd();

    return TRUE;                                        // 一切 OK
}

GLvoid KillGLWindow(GLvoid)                                // 正常销毁窗口
{
    if (fullscreen)                                        // 我们处于全屏模式吗?
    {
        ChangeDisplaySettings(NULL,0);                    // 是的话,切换回桌面
        ShowCursor(TRUE);                                // 显示鼠标指针
    }

    if (hRC)                                            //我们拥有OpenGL描述表吗?
    {
        if (!wglMakeCurrent(NULL,NULL))                    // 我们能否释放DC和RC描述表?
        {
            MessageBox(NULL,"释放DC或RC失败。","关闭错误",MB_OK | MB_ICONINFORMATION);
        }

        if (!wglDeleteContext(hRC))                        // 我们能否删除RC?
        {
            MessageBox(NULL,"释放RC失败。","关闭错误",MB_OK | MB_ICONINFORMATION);
        }
        hRC=NULL;                                        // 将RC设为 NULL
    }

    if (hDC && !ReleaseDC(hWnd,hDC))                    // 我们能否释放 DC?
    {
        MessageBox(NULL,"释放DC失败。","关闭错误",MB_OK | MB_ICONINFORMATION);
        hDC=NULL;                                        // 将 DC 设为 NULL
    }

    if (hWnd && !DestroyWindow(hWnd))                    // 能否销毁窗口?
    {
        MessageBox(NULL,"释放窗口句柄失败。","关闭错误",MB_OK | MB_ICONINFORMATION);
        hWnd=NULL;                                        // 将 hWnd 设为 NULL
    }

    if (!UnregisterClass("OpenG",hInstance))            // 能否注销类?
    {
        MessageBox(NULL,"不能注销窗口类。","关闭错误",MB_OK | MB_ICONINFORMATION);
        hInstance=NULL;                                    // 将 hInstance 设为 NULL
    }
}

/*    这个函数创建我们OpenGL窗口,参数为:                                    *
 *    title            - 窗口标题                                                *
 *    width            - 窗口宽度                                                *
 *    height            - 窗口高度                                                *
 *    bits            - 颜色的位深(8/16/32)                                    *
 *    fullscreenflag    - 是否使用全屏模式,全屏模式(TRUE),窗口模式(FALSE)        */

BOOL CreateGLWindow(char* title, int width, int height, int bits, bool fullscreenflag)
{
    GLuint        PixelFormat;            // 保存查找匹配的结果
    WNDCLASS    wc;                        // 窗口类结构
    DWORD        dwExStyle;                // 扩展窗口风格
    DWORD        dwStyle;                // 窗口风格
    RECT        WindowRect;                // 取得矩形的左上角和右下角的坐标值
    WindowRect.left=(long)0;            // 将Left   设为 0
    WindowRect.right=(long)width;        // 将Right  设为要求的宽度
    WindowRect.top=(long)0;                // 将Top    设为 0
    WindowRect.bottom=(long)height;        // 将Bottom 设为要求的高度

    fullscreen=fullscreenflag;            // 设置全局全屏标志

    hInstance            = GetModuleHandle(NULL);                // 取得我们窗口的实例
    wc.style            = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;    // 移动时重画,并为窗口取得DC
    wc.lpfnWndProc        = (WNDPROC) WndProc;                    // WndProc处理消息
    wc.cbClsExtra        = 0;                                    // 无额外窗口数据
    wc.cbWndExtra        = 0;                                    // 无额外窗口数据
    wc.hInstance        = hInstance;                            // 设置实例
    wc.hIcon            = LoadIcon(NULL, IDI_WINLOGO);            // 装入缺省图标
    wc.hCursor            = LoadCursor(NULL, IDC_ARROW);            // 装入鼠标指针
    wc.hbrBackground    = NULL;                                    // GL不需要背景
    wc.lpszMenuName        = NULL;                                    // 不需要菜单
    wc.lpszClassName    = "OpenG";                            // 设定类名字

    if (!RegisterClass(&wc))                                    // 尝试注册窗口类
    {
        MessageBox(NULL,"注册窗口失败","错误",MB_OK|MB_ICONEXCLAMATION);
        return FALSE;                                            // 退出并返回FALSE
    }

    if (fullscreen)                                                // 要尝试全屏模式吗?
    {
        DEVMODE dmScreenSettings;                                // 设备模式
        memset(&dmScreenSettings,0,sizeof(dmScreenSettings));    // 确保内存清空为零
        dmScreenSettings.dmSize=sizeof(dmScreenSettings);        // Devmode 结构的大小
        dmScreenSettings.dmPelsWidth    = width;                // 所选屏幕宽度
        dmScreenSettings.dmPelsHeight    = height;                // 所选屏幕高度
        dmScreenSettings.dmBitsPerPel    = bits;                    // 每象素所选的色彩深度
        dmScreenSettings.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT;

        // 尝试设置显示模式并返回结果。注: CDS_FULLSCREEN 移去了状态条
        if (ChangeDisplaySettings(&dmScreenSettings,CDS_FULLSCREEN)!=DISP_CHANGE_SUCCESSFUL)
        {
            // 若模式失败,提供两个选项:退出或在窗口内运行。
            if (MessageBox(NULL,"全屏模式在当前显卡上设置失败!\n使用窗口模式?","NeHe G",MB_YESNO|MB_ICONEXCLAMATION)==IDYES)
            {
                //如果用户选择窗口模式,变量fullscreen 的值变为FALSE,程序继续运行
                fullscreen=FALSE;        // 选择窗口模式(Fullscreen=FALSE)
            }
            else
            {
                //如果用户选择退出,弹出消息窗口告知用户程序将结束。并返回FALSE告诉程序窗口未能成功创建。程序退出。
                MessageBox(NULL,"程序将被关闭","错误",MB_OK|MB_ICONSTOP);
                return FALSE;                                    // 退出并返回 FALSE
            }
        }
    }

    if (fullscreen)                                                // 仍处于全屏模式吗?
    {
        dwExStyle=WS_EX_APPWINDOW;                                // 扩展窗体风格
        dwStyle=WS_POPUP;                                        // 窗体风格
        ShowCursor(FALSE);                                        // 隐藏鼠标指针
    }
    else
    {
        dwExStyle=WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;            // 扩展窗体风格
        dwStyle=WS_OVERLAPPEDWINDOW;                            // 窗体风格
    }

    AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle);        // 调整窗口达到真正要求的大小

    // 创建窗口
    if (!(hWnd=CreateWindowEx(    dwExStyle,                            // 扩展窗体风格
                                "OpenG",                            // 类名字
                                title,                                // 窗口标题
                                dwStyle |                            // 必须的窗体风格属性
                                WS_CLIPSIBLINGS |                    // 必须的窗体风格属性
                                WS_CLIPCHILDREN,                    // 必须的窗体风格属性
                                0, 0,                                // 窗口位置
                                WindowRect.right-WindowRect.left,    // 计算调整好的窗口宽度
                                WindowRect.bottom-WindowRect.top,    // 计算调整好的窗口高度
                                NULL,                                // 无父窗口
                                NULL,                                // 无菜单
                                hInstance,                            // 实例
                                NULL)))                                // 不向WM_CREATE传递任何东东
    {
        KillGLWindow();                                // 重置显示区
        MessageBox(NULL,"窗口创建错误","错误",MB_OK|MB_ICONEXCLAMATION);
        return FALSE;                                // 返回 FALSE
    }

    static    PIXELFORMATDESCRIPTOR pfd=                //pfd 告诉窗口我们所希望的东东,即窗口使用的像素格式
    {
        sizeof(PIXELFORMATDESCRIPTOR),                // 上述格式描述符的大小
        1,                                            // 版本号
        PFD_DRAW_TO_WINDOW |                        // 格式支持窗口
        PFD_SUPPORT_OPENGL |                        // 格式必须支持OpenGL
        PFD_DOUBLEBUFFER,                            // 必须支持双缓冲
        PFD_TYPE_RGBA,                                // 申请 RGBA 格式
        bits,                                        // 选定色彩深度
        0, 0, 0, 0, 0, 0,                            // 忽略的色彩位
        0,                                            // 无Alpha缓存
        0,                                            // 忽略Shift Bit
        0,                                            // 无累加缓存
        0, 0, 0, 0,                                    // 忽略聚集位
        16,                                            // 16位 Z-缓存 (深度缓存)
        0,                                            // 无蒙板缓存
        0,                                            // 无辅助缓存
        PFD_MAIN_PLANE,                                // 主绘图层
        0,                                            // 不使用重叠层
        0, 0, 0                                        // 忽略层遮罩
    };

    if (!(hDC=GetDC(hWnd)))                            // 取得设备描述表了么?
    {
        KillGLWindow();                                // 重置显示区
        MessageBox(NULL,"不能创建一个窗口设备描述表","错误",MB_OK|MB_ICONEXCLAMATION);
        return FALSE;                                // 返回 FALSE
    }

    if (!(PixelFormat=ChoosePixelFormat(hDC,&pfd)))    // Windows 找到相应的象素格式了吗?
    {
        KillGLWindow();                                // 重置显示区
        MessageBox(NULL,"不能创建一种相匹配的像素格式","错误",MB_OK|MB_ICONEXCLAMATION);
        return FALSE;                                // 返回 FALSE
    }

    if(!SetPixelFormat(hDC,PixelFormat,&pfd))        // 能够设置象素格式么?
    {
        KillGLWindow();                                // 重置显示区
        MessageBox(NULL,"不能设置像素格式","错误",MB_OK|MB_ICONEXCLAMATION);
        return FALSE;                                // 返回 FALSE
    }

    if (!(hRC=wglCreateContext(hDC)))                // 能否取得OpenGL渲染描述表?
    {
        KillGLWindow();                                // 重置显示区
        MessageBox(NULL,"不能创建OpenGL渲染描述表","错误",MB_OK|MB_ICONEXCLAMATION);
        return FALSE;                                // 返回 FALSE
    }

    if(!wglMakeCurrent(hDC,hRC))                    // 尝试激活着色描述表
    {
        KillGLWindow();                                // 重置显示区
        MessageBox(NULL,"不能激活当前的OpenGL渲然描述表","错误",MB_OK|MB_ICONEXCLAMATION);
        return FALSE;                                // 返回 FALSE
    }

    ShowWindow(hWnd,SW_SHOW);                        // 显示窗口
    SetForegroundWindow(hWnd);                        // 略略提高优先级
    SetFocus(hWnd);                                    // 设置键盘的焦点至此窗口
    ReSizeGLScene(width, height);                    // 设置透视 GL 屏幕

    if (!InitGL())                                    // 初始化新建的GL窗口
    {
        KillGLWindow();                                // 重置显示区
        MessageBox(NULL,"初始化失败","错误",MB_OK|MB_ICONEXCLAMATION);
        return FALSE;                                // 返回 FALSE
    }

    return TRUE;                                    // 成功
}

LRESULT CALLBACK WndProc(    HWND    hWnd,            // 窗口的句柄
                            UINT    uMsg,            // 窗口的消息
                            WPARAM    wParam,            // 附加的消息内容
                            LPARAM    lParam)            // 附加的消息内容
{
    switch (uMsg)                                    // 检查Windows消息
    {
        case WM_ACTIVATE:                            // 监视窗口激活消息
        {
            if (!HIWORD(wParam))                    // 检查最小化状态
            {
                active=TRUE;                        // 程序处于激活状态
            }
            else
            {
                active=FALSE;                        // 程序不再激活
            }

            return 0;                                // 返回消息循环
        }

        case WM_SYSCOMMAND:                            // 系统中断命令
        {
            switch (wParam)                            // 检查系统调用
            {
                case SC_SCREENSAVE:                    // 屏保要运行?
                case SC_MONITORPOWER:                // 显示器要进入节电模式?
                return 0;                            // 阻止发生
            }
            break;                                    // 退出
        }

        case WM_CLOSE:                                // 收到Close消息?
        {
            PostQuitMessage(0);                        // 发出退出消息
            return 0;                                // 返回
        }

        case WM_KEYDOWN:                            // 有键按下么?
        {
            keys[wParam] = TRUE;                    // 如果是,设为TRUE
            return 0;                                // 返回
        }

        case WM_KEYUP:                                // 有键放开么?
        {
            keys[wParam] = FALSE;                    // 如果是,设为FALSE
            return 0;                                // 返回
        }

        case WM_SIZE:                                // 调整OpenGL窗口大小
        {
            ReSizeGLScene(LOWORD(lParam),HIWORD(lParam));  // LoWord=Width,HiWord=Height
            return 0;                                // 返回
        }
    }

    // 向 DefWindowProc传递所有未处理的消息。
    return DefWindowProc(hWnd,uMsg,wParam,lParam);
}

int WINAPI WinMain(HINSTANCE    hInstance,            // 当前窗口实例
                    HINSTANCE    hPrevInstance,        // 前一个窗口实例
                    LPSTR        lpCmdLine,            // 命令行参数
                    int            nCmdShow)            // 窗口显示状态
{
    MSG        msg;                                    // Windowsx消息结构
    BOOL    done=FALSE;                                // 用来退出循环的Bool 变量

    // 提示用户选择运行模式
    if (MessageBox(NULL,"你想在全屏模式下运行么?", "设置全屏模式",MB_YESNO|MB_ICONQUESTION)==IDNO)
    {
        fullscreen=FALSE;                            // FALSE为窗口模式
    }

    // 创建OpenGL窗口

    if (!CreateGLWindow("我的世界",640,480,16,fullscreen))

    {
        return 0;                                    // 失败退出
    }

    while(!done)                                    // 保持循环直到 done=TRUE
    {
        if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))    // 有消息在等待吗?
        {
            if (msg.message==WM_QUIT)                // 收到退出消息?
            {
                done=TRUE;                            // 是,则done=TRUE
            }
            else                                    // 不是,处理窗口消息
            {
                TranslateMessage(&msg);                // 翻译消息
                DispatchMessage(&msg);                // 发送消息
            }
        }
        else                                        // 如果没有消息
        {
            // 绘制场景。监视ESC键和来自DrawGLScene()的退出消息
            if (active)                                // 程序激活的么?
            {
                if (keys[VK_ESCAPE])                // ESC 按下了么?
                {
                    done=TRUE;                        // ESC 发出退出信号
                }
                else                                // 不是退出的时候,刷新屏幕
                {
                    DrawGLScene();                    // 绘制场景
                    SwapBuffers(hDC);                // 交换缓存 (双缓存)

                        if (keys[‘L‘] && !lp)                // L 键已按下并且松开了?
                        {
                            lp=TRUE;                        // lp 设为 TRUE
                            light=!light;                    // 切换光源的 TRUE/FALSE
                            if (!light)                        // 如果没有光源
                            {
                                glDisable(GL_LIGHTING);        // 禁用光源
                            }
                            else                            // 否则
                            {
                                glEnable(GL_LIGHTING);        // 启用光源
                            }
                        }

                        if (!keys[‘L‘])                        // L键松开了么?
                        {
                            lp=FALSE;                        // 若是,则将lp设为FALSE
                        }

               //上下视角变换
                        if (keys[VK_PRIOR])                    // PageUp按下了?
                        {
                            if(z>-20) z-=0.02f;                        // 若按下,将木箱移向屏幕内部
                        }

                        if (keys[VK_NEXT])                    // PageDown按下了么
                        {
                            if(z<20)    z+=0.02f;                        // 若按下的话,将木箱移向观察者
                    }

                //左右视角变换

                        if (keys[VK_RIGHT])                                    // 右方向键按下了么?
                        {    

                            yrot -= 0.1f;                                    // 向左旋转场景

                        }

                        if (keys[VK_LEFT])                                    // 左方向键按下了么?
                        {
                            yrot += 0.1f;                                    // 向右侧旋转场景
                        }

                //前进后退
                        if (keys[VK_UP])                                    // 向上方向键按下了么?
                        {
                            heading=yrot;
                //判断是否碰到墙壁和桌子
                        if(xpos<=2.8&&xpos>=-2.8&& (zpos>-1||zpos<-2||(zpos>=-2&&zpos<=-1&&(xpos>=1||xpos<=-1)))){
                            xpos -= (float)sin(heading*piover180) * 0.002f;    // 沿游戏者所在的X平面移动
                            }
                            if(xpos<1&&xpos>0.9&&sin(heading*piover180)<0)  xpos -= (float)sin(heading*piover180) * 0.002f;//到达C平面可以转身
                            if(xpos<=-0.9&&xpos>-1&&sin(heading*piover180)>0)  xpos -= (float)sin(heading*piover180) * 0.002f;//到达D平面可以转身
                            if(xpos>2.8&&sin(heading*piover180)>0) xpos -= (float)sin(heading*piover180) * 0.002f;//到达墙4可以转身
                            if(xpos<-2.8&&sin(heading*piover180)<0) xpos -= (float)sin(heading*piover180) * 0.002f;//到达墙2可以转身

                            if(zpos>=-2.8&&zpos<=2.8&& (zpos>-1||zpos<-2||(zpos>=-2&&zpos<=-1&&(xpos>=1||xpos<=-1)))  ){  //在整个框架内

                                zpos -= (float)cos(heading*piover180) * 0.002f;    // 沿游戏者所在的Z平面移动

                            }
                            if(zpos<-1&&zpos>-1.1&&cos(heading*piover180)<0)  zpos -= (float)cos(heading*piover180) * 0.002f;//到达A平面可以转身
                            if(zpos<=-1.9&&zpos>-2&&cos(heading*piover180)>0)  zpos -= (float)cos(heading*piover180) * 0.002f;//到达B平面可以转身
                            if(zpos<-2.8&&cos(heading*piover180)<0) zpos -= (float)cos(heading*piover180) * 0.002f;//到达墙1可以转身
                            if(zpos>2.8&&cos(heading*piover180)>0) zpos -= (float)cos(heading*piover180) * 0.002f;//到达墙3可以转身

                        }

                        if (keys[VK_DOWN])                                    // 向下方向键按下了么?
                        {
                            heading=yrot;
                            if(xpos<=2.8&&xpos>=-2.8&& (zpos>-1||zpos<-2||(zpos>=-2&&zpos<=-1&&(xpos>=1||xpos<=-1)))){
                            xpos += (float)sin(heading*piover180) * 0.002f;    // 沿游戏者所在的X平面移动
                            }
                            if(xpos<1&&xpos>0.9&&sin(heading*piover180)>0)  xpos += (float)sin(heading*piover180) * 0.002f;//到达C平面可以转身
                            if(xpos<=-0.9&&xpos>-1&&sin(heading*piover180)<0)  xpos += (float)sin(heading*piover180) * 0.002f;//到达D平面可以转身
                            if(xpos>2.8&&sin(heading*piover180)<0) xpos += (float)sin(heading*piover180) * 0.002f;
                            if(xpos<-2.8&&sin(heading*piover180)>0) xpos += (float)sin(heading*piover180) * 0.002f;

                            if(zpos>=-2.8&&zpos<=2.8&& (zpos>-1||zpos<-2||(zpos>=-2&&zpos<=-1&&(xpos>=1||xpos<=-1)))){
                            zpos += (float)cos(heading*piover180) * 0.002f;    // 沿游戏者所在的Z平面移动
                            }
                            if(zpos<-1&&zpos>-1.1&&cos(heading*piover180)>0)  zpos += (float)cos(heading*piover180) * 0.002f;//到达A平面可以转身
                            if(zpos<=-1.9&&zpos>-2&&cos(heading*piover180)<0)  zpos += (float)cos(heading*piover180) * 0.002f;//到达B平面可以转身
                            if(zpos<-2.8&&cos(heading*piover180)>0) zpos += (float)cos(heading*piover180) * 0.002f;
                            if(zpos>2.8&&cos(heading*piover180)<0) zpos += (float)cos(heading*piover180) * 0.002f;
                        }
                        if (keys[‘B‘] && !bp)                // B 健按下且bp为 FALSE么?
                        {
                            bp=TRUE;                        // 若是, bp 设为 TRUE
                            blend = !blend;                    // 切换混合选项的 TRUE / FALSE
                            if(blend)                        // 混合打开了么?
                            {
                                glEnable(GL_BLEND);            // 打开混合
                                glDisable(GL_DEPTH_TEST);    // 关闭深度测试
                            }
                            else                            // 否则
                            {
                                glDisable(GL_BLEND);        // 关闭混合
                                glEnable(GL_DEPTH_TEST);    // 打开深度测试
                            }
                        }

                        if (!keys[‘B‘])                        //  B 键松开了么?
                        {
                            bp=FALSE;                        // 若是, bp设为 FALSE
                        }
                }
            }

            if (keys[VK_F1])                        // F1键按下了么?
            {
                keys[VK_F1]=FALSE;                    // 若是,使对应的Key数组中的值为 FALSE
                KillGLWindow();                        // 销毁当前的窗口
                fullscreen=!fullscreen;                // 切换 全屏 / 窗口 模式
                // 重建 OpenGL 窗口

                if (!CreateGLWindow("我的世界",640,480,16,fullscreen))

                {
                    return 0;                        // 如果窗口未能创建,程序退出
                }
            }
        }
    }

    // 关闭程序
    KillGLWindow();                                    // 销毁窗口
    return (msg.wParam);                            // 退出程序
}
// BaseGraph.cpp: implementation of the BaseGraph class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "BaseGraph.h"
#pragma comment(lib, "legacy_stdio_definitions.lib")
//#include "bitmap.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
extern GLfloat    r;       //飞机盘旋角度
float  gao=1.8f;
extern CString    test;    //场景信息
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

//power of two
int power_of_two(int n)
{
    if (n <= 0)
        return 0;
    return (n & (n - 1)) == 0;
}

#define BMP_Header_Length 54
//load texture function
bool load_texture(const char* file_name, GLuint &texture)
{
    GLint width, height, total_bytes;
    GLubyte* pixels = 0;

    FILE* pFile = fopen(file_name, "rb");
    if (pFile == 0)
        return 0;

    fseek(pFile, 0x0012, SEEK_SET);
    fread(&width, 4, 1, pFile);
    fread(&height, 4, 1, pFile);
    fseek(pFile, BMP_Header_Length, SEEK_SET);

    {
        GLint line_bytes = width * 3;
        while (line_bytes % 4 != 0)
            ++line_bytes;
        total_bytes = line_bytes * height;
    } //{

    pixels = (GLubyte*)malloc(total_bytes);
    if (pixels == 0) {
        fclose(pFile);
        return 0;
    } //if

    if (fread(pixels, total_bytes, 1, pFile) <= 0) {
        free(pixels);
        fclose(pFile);
        return 0;
    } //if

    {
        GLint max;
        glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max);
        if (!power_of_two(width) || !power_of_two(height) || width > max || height > max) {
            const GLint new_width = 256;
            const GLint new_height = 256;
            GLint new_line_bytes, new_total_bytes;
            GLubyte* new_pixels = 0;

            new_line_bytes = new_width * 3;
            while (new_line_bytes % 4 != 0)
                ++new_line_bytes;
            new_total_bytes = new_line_bytes * new_height;

            new_pixels = (GLubyte*)malloc(new_total_bytes);
            if (new_pixels == 0) {
                free(pixels);
                fclose(pFile);
                return 0;
            }//if 

            gluScaleImage(GL_RGB, width, height, GL_UNSIGNED_BYTE, pixels, new_width, new_height, GL_UNSIGNED_BYTE, new_pixels);
            free(pixels);
            pixels = new_pixels;
            width = new_width;
            height = new_height;
        }//if
    }//{

    glGenTextures(1, &texture);
    if (texture == 0) {
        free(pixels);
        fclose(pFile);
        return 0;
    } //if

    glGenTextures(1, &texture);
    glBindTexture(GL_TEXTURE_2D, texture);
    gluBuild2DMipmaps(GL_TEXTURE_2D, 4, width, height, GL_RGB, GL_UNSIGNED_BYTE, pixels);

    free(pixels);
    return true;
}

BaseGraph::BaseGraph()
{
    g_eye[0]= MAP;//
    g_eye[2]=-MAP;//
    g_Angle=0;
    g_elev=-0;
    char    appdir[256];
    GetCurrentDirectory(256,appdir);
    CString dir=appdir;
    if(dir.Right(8)!="运行程序")
    SetCurrentDirectory("../运行程序");
////////////////////////////////////////////////////////////////////////

    load_texture("data/images/sand0.bmp", g_cactus[0]);        //地面贴图

                                                        //天空贴图
    load_texture("data/images/4RBack.bmp", g_cactus[2]);
    load_texture("data/images/4Front.bmp", g_cactus[3]);
    load_texture("data/images/4Top.bmp", g_cactus[4]);
    load_texture("data/images/4Left.bmp", g_cactus[5]);
    load_texture("data/images/4Right.bmp", g_cactus[6]);
    /*
    g_imageData = LoadBit("data/images/Terrain1.bmp",&g_bit);  //调等高地形图
    LoadT8("data/images/sand0.bmp",     g_cactus[0]);        //地面贴图

    //天空贴图
    LoadT8("data/images/4RBack.bmp", g_cactus[2]);
    LoadT8("data/images/4Front.bmp", g_cactus[3]);
    LoadT8("data/images/4Top.bmp",     g_cactus[4]);
    LoadT8("data/images/4Left.bmp",  g_cactus[5]);
    LoadT8("data/images/4Right.bmp", g_cactus[6]);

    LoadT16("data/images/CACTUS0.BMP",g_cactus[11]);    //树1帖图
    LoadT16("data/images/CACTUS1.BMP",g_cactus[12]);    //树2帖图
    LoadT16("data/images/CACTUS2.BMP",g_cactus[13]);    //树3帖图
    LoadT16("data/images/CACTUS5.BMP",g_cactus[14]);    //树4帖图
    */

    InitTerrain(5);                                        //初始化地面

    m_3ds=new CLoad3DS();
    load3dobj("data/3ds/","航天发射台.3DS",0);
    load3dobj("data/3ds/","直升机0.3ds",1);//car.3ds
    load3dobj("data/3ds/","飞机1.3ds",2);//car.3ds
    glEnable(GL_TEXTURE_2D);
}

BaseGraph::~BaseGraph()
{
    for(int i=0;i<16;i++)
        glDeleteTextures(1, &g_cactus[i]);
    glDisableClientState(GL_VERTEX_ARRAY);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}

void BaseGraph::light0()
{
    GLfloat light_position[] = {1.0,5.0,1.0,1.0};
    glLightfv(GL_LIGHT0, GL_POSITION, light_position);
    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_COLOR_MATERIAL);
}

BOOL BaseGraph::DisplayScene()
{
    float speed=0.3f;
    float x=g_eye[0],y=g_eye[2],z=g_eye[2];

    if (KEY_DOWN(VK_SHIFT))  speed   =speed*3;
    if (KEY_DOWN(VK_LEFT))   g_Angle-=speed*3;
    if (KEY_DOWN(VK_RIGHT))  g_Angle+=speed*3;
    rad_xz = float (3.13149* g_Angle/180.0f);

    if (KEY_DOWN(33))           g_elev +=speed;
    if (KEY_DOWN(34))           g_elev -=speed;
    if (g_elev<-360)           g_elev  =-360;
    if (g_elev> 360)           g_elev  = 360;

    if (KEY_DOWN(VK_UP))
    {
        g_eye[2]+=(float)sin(rad_xz)*speed*3;
        g_eye[0]+=(float)cos(rad_xz)*speed*3;
    }
    if (KEY_DOWN(VK_DOWN))
    {
        g_eye[2]-=(float)sin(rad_xz)*speed*3;
        g_eye[0]-=(float)cos(rad_xz)*speed*3;
    }
    if(g_eye[0]<  MAP_SCALE)            g_eye[0]=  MAP_SCALE;
    if(g_eye[0]> (MAP_W-2)*MAP_SCALE)    g_eye[0]= (MAP_W-2)*MAP_SCALE;
    if(g_eye[2]<-(MAP_W-2)*MAP_SCALE)    g_eye[2]=-(MAP_W-2)*MAP_SCALE;
    if(g_eye[2]> -MAP_SCALE)            g_eye[2]= -MAP_SCALE;
    g_eye[1] =GetHeight((float)g_eye[0],(float)g_eye[2])+2*gao;

    g_look[0] = (float)(g_eye[0] +100*cos(rad_xz));
    g_look[2] = (float)(g_eye[2] +100*sin(rad_xz));
    g_look[1] = g_eye[1] +g_elev;    

    gluLookAt(g_eye[0],g_eye[1],g_eye[2],
        g_look[0],g_look[1],g_look[2],
        0.0,1.0,0.0
        );

    int r0=abs((int)g_Angle);
    test.Format("[方位=%03d X=%3.0f y=%3.0f 高=%2.1f 俯仰角=%2.0f,re=%03.0f]",
          r0%360,g_eye[0],-g_eye[2],g_eye[1],g_elev,r);

    return TRUE;
}

float BaseGraph::GetHeight(float x, float z)
{
    float CameraX = x/MAP_SCALE;
    float CameraZ =-z/MAP_SCALE;
    int Col0 = int(CameraX);     //列
    int Row0 = int(CameraZ);     //行
    int Col1 = Col0 + 1;
    int Row1 = Row0 + 1;
    if (Col1 > MAP_W)    Col1 = 0;
    if (Row1 > MAP_W)    Row1 = 0;
    float h00=g_terrain[Col0 + Row0*MAP_W][1];
    float h01=g_terrain[Col1 + Row0*MAP_W][1];
    float h11=g_terrain[Col1 + Row1*MAP_W][1];
    float h10=g_terrain[Col0 + Row1*MAP_W][1];
    float tx =CameraX - int(CameraX);
    float ty =CameraZ - int(CameraZ);
    float txty = tx * ty;
    return h00*(1.0f-ty-tx+txty)
            + h01*(tx-txty)
            + h11*txty
            + h10*(ty-txty);
}

void BaseGraph::CreateSkyBox(int a,int wi,int he,int le)
{
    float width =MAP*wi;
    float height=MAP*he;
    float length=MAP*le;
    float x = MAP  -width /2;
    float y = MAP/a-height/2;
    float z = -MAP -length/2;
///////////////////////////////////////////////////////////////////////////////
    texture(g_cactus[2]);
    glBegin(GL_QUADS);
        glTexCoord2f(1.0f,0.0f); glVertex3f(x+width,y,         z);
        glTexCoord2f(1.0f,1.0f); glVertex3f(x+width,y+height,z);
        glTexCoord2f(0.0f,1.0f); glVertex3f(x,        y+height,z);
        glTexCoord2f(0.0f,0.0f); glVertex3f(x,        y,         z);
    glEnd();

    texture(g_cactus[3]);
    glBegin(GL_QUADS);
        glTexCoord2f(1.0f,0.0f); glVertex3f(x,        y,         z+length);
        glTexCoord2f(1.0f,1.0f); glVertex3f(x,        y+height,z+length);
        glTexCoord2f(0.0f,1.0f); glVertex3f(x+width,y+height,z+length);
        glTexCoord2f(0.0f,0.0f); glVertex3f(x+width,y,         z+length);
    glEnd();

    texture(g_cactus[4]);
    glBegin(GL_QUADS);
        glTexCoord2f(0.0f,1.0f); glVertex3f(x+width,y+height,z);
        glTexCoord2f(0.0f,0.0f); glVertex3f(x+width,y+height,z+length);
        glTexCoord2f(1.0f,0.0f); glVertex3f(x,        y+height,z+length);
        glTexCoord2f(1.0f,1.0f); glVertex3f(x,        y+height,z);
    glEnd();

    texture(g_cactus[5]);
    glBegin(GL_QUADS);
        glTexCoord2f(1.0f,1.0f); glVertex3f(x,        y+height,z);
        glTexCoord2f(0.0f,1.0f); glVertex3f(x,        y+height,z+length);
        glTexCoord2f(0.0f,0.0f); glVertex3f(x,        y,         z+length);
        glTexCoord2f(1.0f,0.0f); glVertex3f(x,        y,         z);
    glEnd();

    texture(g_cactus[6]);
    glBegin(GL_QUADS);
        glTexCoord2f(0.0f,0.0f); glVertex3f(x+width,y,         z);
        glTexCoord2f(1.0f,0.0f); glVertex3f(x+width,y,         z+length);
        glTexCoord2f(1.0f,1.0f); glVertex3f(x+width,y+height,z+length);
        glTexCoord2f(0.0f,1.0f); glVertex3f(x+width,y+height,z);
    glEnd();
}
void BaseGraph::texture(UINT textur)
{
    glBindTexture  (GL_TEXTURE_2D, textur);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
}

void BaseGraph::picter(float x,float y,float z)
{
    y=GetHeight(x,z);
    glDisable(GL_TEXTURE_2D);

    glPushAttrib(GL_CURRENT_BIT);
    glPushMatrix();
    glTranslatef(x,y+0.5f,z);
    glColor3f(0.0f,1.0f,0.2f);
    auxSolidCube(1);
    glTranslatef(0.0f,0.8f,0.0f);
    glColor3f(0.0f,0.0f,1.0f);
    auxSolidBox(.2f,1.3f,.2f);
    glPopMatrix();

    glPushMatrix();
    glTranslatef(x,y+2.5f,z);
    glRotatef(r-90,0.0,1.0,0.0);
    //=======================================
    glColor3f(1.0f,1.0f,1.0f);
    glRotatef(45, 1.0, 0.0, 0.0);
    auxWireCone(1.5,0.6f);
    //=======================================
    glRotatef(180, 1.0, 0.0, 0.0);
    glTranslatef(0.0f,0.0f,-0.7f);
    auxWireCone(0.2f,2.0f);
    glColor3f(FRAND,0,0);
    glTranslatef(0.0f,0.0f,2.0f);
    auxSolidSphere(0.1f);
    glPopMatrix();
    glPushMatrix();
    glTranslatef(x,y+10.0f,z);
    glRotatef(r, 0.0, 1.0, 0.0);
    glTranslatef(x/15,0,0);
    //=============================================
    glColor3f(1.0f,0.0f,0.0f);
    glRotatef(180, 0.0, 1.0, 0.0);
    auxSolidCone(.2,0.6);
    //=============================================
    glColor3f(1.0f,1.0f,1.0f);
    glRotatef(90, 1.0, 0.0, 0.0);
    glTranslatef(0.0f,-1.0f,0);
    auxSolidCylinder(.2f,1);
    glRotatef(-270, 1.0, 0.0, 0.0);
    glColor3f(FRAND+.6f,0.2f,0.0f);
    glTranslatef(0.0f,-0.0f,-0.2f);
    auxSolidCone(.2,1.5);
    glPopMatrix();
    glEnable(GL_TEXTURE_2D);
    glPopAttrib();
    r+=0.5f;
    if(r>360)
        r=0;
    glEnable(GL_TEXTURE_2D);
}

void BaseGraph::InitTerrain(float h)
{
    int index = 0;
    int Vertex;
    for (int z = 0; z < MAP_W; z++)
        for (int x = 0; x < MAP_W; x++)
        {
            Vertex = z * MAP_W + x;
            g_terrain [Vertex][0] = float(x)*MAP_SCALE;
            g_terrain [Vertex][1] = (float)(g_imageData[(z*MAP_W+x)*3]/3);
            g_terrain [Vertex][2] = -float(z)*MAP_SCALE;
            g_texcoord[Vertex][0] = (float) x;
            g_texcoord[Vertex][1] = (float) z;
            g_index [index++] = Vertex;
            g_index [index++] = Vertex+ MAP_W;
        }
    glEnableClientState(GL_VERTEX_ARRAY);
    glVertexPointer    (3,GL_FLOAT,0,g_terrain);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    glTexCoordPointer  (2,GL_FLOAT,0,g_texcoord);
}

void BaseGraph::DrawSand()
{
    glBindTexture(GL_TEXTURE_2D, g_cactus[0]);
    glTexEnvf    (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
    for (int z = 0; z < MAP_W-1; z++)
        glDrawElements(GL_TRIANGLE_STRIP,MAP_W*2,GL_UNSIGNED_INT,&g_index[z*MAP_W*2]);
}

/*
bool BaseGraph::LoadT8(char *filename, GLuint &texture)
{
    AUX_RGBImageRec *pImage = NULL;
    pImage = auxDIBImageLoad(filename);
    if(pImage == NULL)
        return false;
    glGenTextures(1, &texture);
    glBindTexture(GL_TEXTURE_2D,texture);
    gluBuild2DMipmaps(GL_TEXTURE_2D,4, pImage->sizeX, pImage->sizeY,GL_RGB, GL_UNSIGNED_BYTE,pImage->data);
    free(pImage->data);
    free(pImage);
    return true;
}

void BaseGraph::LoadT16(char *filename, GLuint &texture)
{
    glGenTextures(1, &texture);
    glBindTexture(GL_TEXTURE_2D, texture);
    BITMAPINFOHEADER bitHeader;
    unsigned char *buffer;
    buffer=LoadBitmapFileWithAlpha(filename,&bitHeader);
    gluBuild2DMipmaps    ( GL_TEXTURE_2D,
        4,
        bitHeader.biWidth,
        bitHeader.biHeight,
        GL_RGBA,
        GL_UNSIGNED_BYTE,
        buffer
        );
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
    free(buffer);
}
*/

/*
unsigned char * BaseGraph::LoadBit(char *filename, BITMAPINFOHEADER *bitmap)
{
    FILE *filePtr;                    // the file pointer
    BITMAPFILEHEADER  Header;       // bitmap file header
    unsigned char    *Image;        // bitmap image data
    unsigned int      imageIdx = 0; // image index counter
    unsigned char     tempRGB;        // swap variable

    // open filename in "read binary" mode
    filePtr = fopen(filename, "rb");
    if (filePtr == NULL)return NULL;

    // read the bitmap file header
    fread(&Header, sizeof(BITMAPFILEHEADER), 1, filePtr);

    // verify that this is a bitmap by checking for the universal bitmap id
    if (Header.bfType != BITMAP_ID)
    {
        fclose(filePtr);
        return NULL;
    }
    // read the bitmap information header
    fread(bitmap, sizeof(BITMAPINFOHEADER), 1, filePtr);

    // move file pointer to beginning of bitmap data
    fseek(filePtr, Header.bfOffBits, SEEK_SET);

    // allocate enough memory for the bitmap image data
    Image = (unsigned char*)malloc(bitmap->biSizeImage);

    // verify memory allocation
    if (!Image)
    {
        free(Image);
        fclose(filePtr);
        return NULL;
    }

    // read in the bitmap image data
    fread(Image, 1, bitmap->biSizeImage, filePtr);
    if (Image == NULL)            // make sure bitmap image data was read
    {
        fclose(filePtr);
        return NULL;
    }
    // swap the R and B values to get RGB since the bitmap color format is in BGR
    for (imageIdx = 0; imageIdx < bitmap->biSizeImage; imageIdx+=3)
    {
        tempRGB = Image[imageIdx];
        Image[imageIdx] = Image[imageIdx + 2];
        Image[imageIdx + 2] = tempRGB;
    }
    fclose(filePtr);
    return Image;
}
*/

/*
void BaseGraph::ShowTree(float x, float z, float h, float s, int cactus)
{
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glEnable(GL_ALPHA_TEST);
    glAlphaFunc(GL_GREATER, 0);

    float mat[16];                        //the modelview matrix
    glGetFloatv(GL_MODELVIEW_MATRIX, mat);
    vector3_t X(mat[0], mat[4], mat[8]);
    vector3_t Z(mat[1], mat[5], mat[9]);
    glBindTexture(GL_TEXTURE_2D, g_cactus[cactus]);
    vector3_t pos(x,0.0,-z);
    pos.y = GetHeight(x, -z) + h + s;

    glBegin(GL_QUADS);
    glTexCoord2f(0.0,0.0);glVertex3fv((pos+(X+Z)*-h).v);//左下点
    glTexCoord2f(1.0,0.0);glVertex3fv((pos+(X-Z)* h).v);//右下点
    glTexCoord2f(1.0,1.0);glVertex3fv((pos+(X+Z)* h).v);//右上点
    glTexCoord2f(0.0,1.0);glVertex3fv((pos+(Z-X)* h).v);//左上点
    glEnd();

    glDisable(GL_ALPHA);
    glDisable(GL_BLEND);
}
*/

void BaseGraph::ShowTree0(float x, float z, float h, float s, int cactus)
{
    glPushMatrix();//
    float y = GetHeight(x,-z) + h + s;
    glTranslatef(x,y, -z);
    glRotatef(180, 1.0, 0.0, 0.0);
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glEnable(GL_ALPHA_TEST);
    glAlphaFunc(GL_GREATER, 0);
    glBindTexture(GL_TEXTURE_2D, g_cactus[cactus]);
    //    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);//
    glBegin(GL_QUADS);
    glTexCoord2f(1.0f, 0.0f); glVertex3f(-h, h, 0.0f);        // 右上点
    glTexCoord2f(0.0f, 0.0f); glVertex3f( h, h, 0.0f);        // 右上点
    glTexCoord2f(0.0f, 1.0f); glVertex3f( h,-h, 0.0f);        // 右下点
    glTexCoord2f(1.0f, 1.0f); glVertex3f(-h,-h, 0.0f);        // 左下点
    glEnd();
    glDisable(GL_ALPHA);
    glDisable(GL_BLEND);
    glPopMatrix();
}

////////////////////////////////////////////////////////////////////
void BaseGraph::load3dobj(char* dir,char* cn,int a)
{
    char    appdir[256];
    GetCurrentDirectory(256,appdir);   //The GetCurrentDirectory function retrieves the current
    //directory for the current process. 

    SetCurrentDirectory(dir);
    m_3ds->Init(cn,a);
    SetCurrentDirectory(appdir);
}
void BaseGraph::Scene(int obj,float x,float h,float z,float r,int re,float size)
{
     glPushMatrix();
     int y=GetHeight(x,z)+h;
     glTranslatef(x,y,z);
     glRotatef(re, 0.0, 1.0, 0.0);
     if(obj>0)
         glRotatef(-20, 1.0, 0.0, 0.0);
     m_3ds->show3ds(obj,0,0.0f,r,size);
     glPopMatrix();
}
时间: 2024-11-10 13:58:07

图形学的相关文章

图形学_二维图形的剪裁_Sutherland-Hodgeman_Cohen—Sutherland

一.Cohen-Sutherland剪裁算法 1.基本思想 对于每条线段P1P2分为三种情况处理: (1)若P1P2完全在窗口内,则显示该线段P1P2. (2)若P1P2明显在窗口外,则丢弃该线段. (3)若线段不满足(1)或(2)的条件,则在交点处把线段分为两段.其中一段完全在窗口外,可弃之.然后对另一段重复上述处理. 为快速判断,采用如下编码方法: 将窗口边线两边沿长,得到九个区域,每一个区域都用一个四位二进制数标识,直线的端点都按其所处区域赋予相应的区域码,用来标识出端点相对于裁剪矩形边界

图形学_圆的扫描转换

1.中点画圆算法 (1)P为当前点亮象素,那么,下一个点亮的象素可能是P1(Xp+1,Yp) 或P2(Xp +1,Yp +1). (2)构造函数:F(X,Y)=X2  +  Y2 -  R2 :则 F(X,Y)=  0  (X,Y)在圆上: F(X,Y)< 0   (X,Y)在圆内: F(X,Y)> 0   (X,Y)在圆外. 设M为P1.P2间的中点,M=(Xp+1,Yp-0.5) 有如下结论: F(M)< 0  ->M在圆内->  取P1 F(M)>= 0 ->

图形学_画线算法(DDA、Bresenham)

1. DDA算法实现直线绘制(需先安装easyx,百度下载即可) 1 #include "easyx.h" 2 #include "math.h" 3 #include "windows.h" 4 #include "stdio.h" 5 #include "stdlib.h" 6 #include "conio.h" 7 #include "graphics.h"

图形学_多边形扫描转换_边界标志算法

边界标志算法 1. 对多边形的每一条边进行扫描转换,即对多边形边界所经过的象素作一个边界标志. 2.填充 对每条与多边形相交的扫描线,按从左到右的顺序,逐个访问该扫描线上的象素. 取一个布尔变量inside来指示当前点的状态,若点在多边形内,则inside为真.若点在多边形外,则inside为假. Inside 的初始值为假,每当当前访问象素为被打上标志的点,就把inside取反.对未打标志的点,inside不变. 1 #include "easyx.h" 2 #include &qu

计算机图形学研究领域分哪些

计算机图形学各个领域的目标或许不同,但最终的形式都是渲染(即绘制)在二维的显示设备上的图像.下面是一个简单(可能并不完全)的分类: ?计算机图形学-领域及分支: ?1 绘制1.1 真实感绘制(非实时)1.1.1 光线追踪(Ray-tracing)1.1.2 全局光照(Global Illumination)......1.2 实时绘制1.2.1 Shading(BRDF, Programmable Shading等)1.2.2 纹理(Texture Synthesis, 反走样, 采样等)1.2

【转载】计算机图形学框架

原文: 计算机图形学框架 应用 基本图形生成算法 图元光栅化标准 直线要直 图元终点要准 图元生成的亮度.色泽粗细要均匀 快速计算 直线光栅化算法 逐点比较法 数值微分法 中点Bresenham算法 圆的光栅化算法 简单方程产生圆弧 Bresenham算法产生圆弧 多边形填充 扫描线填充 宽图元 复制像素画宽图元 移动画笔画宽图元 3D数学基础 坐标系 向量 矩阵 空间集合运算 集合形体的表达 几何体之间的关系 图形变换 二维及三维图形几何变换 二维图形几何变换 平移变换 比例变换 旋转变换 错

图形学中的贴图采样、走样与反走样等

计算机图形学中不可避免的会涉及到图像分析与处理的相关知识,前些时间也重温了下常用到的采样.重建以及纹理贴图等内容,并对其中的走样与反走样有了更多的认识,这里小结一下. 1. 基本问题 信号的采样与重建过程中首先面临着两个基本的问题: 给定一个连续的信号g(x)以及它的离散采样信号gs(x),能否通过gs(x)来完整的描述g(x) 的信息: 如果可以,如何通过gs(x)来重建出原始信号g(x). 这些通过对信息进行频域的分析即可得到相应的结论. 2. 采样 将一处于空间域(或时域)内的信号向频域进

计算机图形学和OpenGL(二)坐标系和绘制点线函数

这节开始前我们先了解一下图元的概念.图形软件包中用来描述各种图形元素的函数称为图形输出原语,也称图元(primitive).而描述对象几何要素的输出图元一般称为几何图元.点和线是最简单的几何图元,本节就会简单介绍点和线段的绘制方法. 一.坐标系统. 坐标系统一般分为屏幕坐标和OpenGL中的绘图坐标. 在上一节中我们简单的写了个示例程序,程序中介绍了gluOrtho2D命令.我们可以利用该命令设定一个二维笛卡尔坐标系.该函数的四个变量制定的是显示图形x和y坐标范围.所以我们可以使用下面代码制定一

计算机图形学的学习资源

计算机图形学(Computer Graphics,简称CG)是一个令人着迷的领域,本文整理了一些图形学相关的学习资源. Wikipedia的介绍,及其后面附的"参考文献"和"外部链接"总是值得一看的: Computer graphics:主要介绍图形学的历史: Computer graphics (computer science):介绍图形学学科,后面附了知名研究者,以及著名大学的图形学小组: 3D computer graphics:这是图形学中最重要的部分:

Cocos2d-x 3.x 图形学渲染系列十五

笔者介绍:姜雪伟,IT公司技术合伙人,IT高级讲师,CSDN社区专家,特邀编辑,畅销书作者,国家专利发明人;已出版书籍:<手把手教你架构3D游戏引擎>电子工业出版社和<Unity3D实战核心技术详解>电子工业出版社等. 在游戏开发中或者是游戏程序员招聘中,都有关于图形学或者引擎高级程序职位.凡是涉及到这些职位的招聘,对于此职位的开发人员都需要会Shader编程或者说GPU编程,同时他们的薪资也是比较高的.目前国内掌握图形学编程的人不是很多,物以稀为贵.Shader编程的主要目的是协