#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();
}