计算机图形学实验————漫游三维迷宫

来源:互联网 发布:鳄鱼皮 知乎 编辑:程序博客网 时间:2024/05/16 17:08

(我们方向课的实验,发出来跟大家交流下)

设计一个OpenGL程序,创建一个三维迷宫,支持替身通过一定交互手段在迷宫中漫游。

基本功能包括: 

1、 迷宫应当至少包含10 * 10 个Cell,不能过于简单,下图给出一种示例。 

2、 读取给定的替身模型,加载到场景中。 

3、 键盘方向键控制替身转向与漫游。 

4、 有碰撞检测,替身不应当穿墙。 

5、 支持切换第一视角和第三视角进行观察。 

6、 迷宫场景中的墙、地面等应贴上纹理。 

扩展功能包括(至少选择一个): 

1. 同时加入二维辅助地图,替身在三维迷宫探索的同时,在小地图中显示已经探索的区域;(本文实际选择)

2. 在俯视状态下,可以通过鼠标点选替身需要到达的目的地,通过寻径算法,控制替身自 动到达目的地; 

3. 迷宫地图交互编辑功能,例如,可以设计一个二维地图编辑器,根据用户的绘制,拉伸 得到三维迷宫场景; 

4. 其他相当难度,可以增加迷宫游戏趣味性的功能(需要通过指导老师认可) 

完成一份实验报告,说明你所实现的一个扩展功能。

下面放一下主要代码

main.cpp

#include <windows.h>  #include <GL/glu.h>  #include <GL/gl.h>  #include <GL/glut.h>  #include <math.h>   #include <stdio.h>  #include<iostream>#include <ctime>#include <cstdlib>#include "MD2Model.h"using namespace std;float Cx = 0;float Cy = 0;float Cz = 0; //球的初始位置int isWall[20][20];int x1 = Cx;int Y1 = 0;int z1 = Cz;int x2 = Cx;int y2 = 0;int z2 = 100;int x3 = 0;int y3 = 1;int z3 = 0;//改变视角后的参数int hit = 0;int direction = 0;void GL_display();GLuint texWall;static GLint imagewidth;static GLint imageheight;static GLint pixellength;static GLubyte* pixeldata;void loadTexture(char* filename){FILE* pfile = fopen(filename, "rb");if (pfile == 0){cout << "can not open" << filename << endl;}//读取图像大小fseek(pfile, 0x0012, SEEK_SET);fread(&imagewidth, sizeof(imagewidth), 1, pfile);fread(&imageheight, sizeof(imageheight), 1, pfile);//计算像素数据长度pixellength = imagewidth * 3;while (pixellength % 4 != 0)pixellength++;pixellength *= imageheight;//读取像素数据pixeldata = (GLubyte*)malloc(pixellength);if (pixeldata == 0) exit(0);fseek(pfile, 54, SEEK_SET);fread(pixeldata, pixellength, 1, pfile);glGenTextures(1, &texWall);glBindTexture(GL_TEXTURE_2D, texWall);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_MAG_FILTER, GL_NEAREST);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, imagewidth, imageheight, 0, GL_BGR_EXT, GL_UNSIGNED_BYTE, pixeldata);glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);}CMD2Model Ogro;//模型对象 //从模型文件装入模型数据  void drawsolider(float x, float y, float z){glPushMatrix();glTranslatef(x, y, z);glRotatef(90,1, 0, 0);Ogro.loadModel("models/tris.md2");//装入模型纹理  Ogro.loadSkin("wall.bmp");//设置模型动作  Ogro.setAnim(0);//设置模型比例  Ogro.scaleModel(0.25);//绘制模型  Ogro.drawModel(0.0);glPopMatrix();}void drawWall(int x, int y, int z){glPushMatrix();//画立方体的6个面    glBindTexture(GL_TEXTURE_2D, texWall);glBegin(GL_QUADS);glNormal3f(0.0F, 0.0F, 1.0F);glTexCoord2f(0.0, 0.0);glVertex3f(5 + x, 5 + y, 5 + z);glTexCoord2f(0.0, 1.0);glVertex3f(-5 + x, 5 + y, 5 + z);glTexCoord2f(1.0, 1.0);glVertex3f(-5 + x, -5 + y, 5 + z);glTexCoord2f(1.0, 0.0);glVertex3f(5 + x, -5 + y, 5 + z);glEnd();//1----------------------------    glBegin(GL_QUADS);glNormal3f(0.0F, 0.0F, -1.0F);glTexCoord2f(0.0, 0.0);glVertex3f(-5 + x, -5 + y, -5 + z);glTexCoord2f(0.0, 1.0);glVertex3f(-5 + x, 5 + y, -5 + z);glTexCoord2f(1.0, 1.0);glVertex3f(5 + x, 5 + y, -5 + z);glTexCoord2f(1.0, 0.0);glVertex3f(5 + x, -5 + y, -5 + z);glEnd();//2----------------------------    glBegin(GL_QUADS);glNormal3f(0.0F, 1.0F, 0.0F);glTexCoord2f(0.0, 0.0);glVertex3f(5 + x, 5 + y, 5 + z);glTexCoord2f(0.0, 1.0);glVertex3f(5 + x, 5 + y, -5 + z);glTexCoord2f(1.0, 1.0);glVertex3f(-5 + x, 5 + y, -5 + z);glTexCoord2f(1.0, 0.0);glVertex3f(-5 + x, 5 + y, 5 + z);glEnd();//3----------------------------    glBegin(GL_QUADS);glNormal3f(0.0F, -1.0F, 0.0F);glTexCoord2f(0.0, 0.0);glVertex3f(-5 + x, -5 + y, -5 + z);glTexCoord2f(0.0, 1.0);glVertex3f(5 + x, -5 + y, -5 + z);glTexCoord2f(1.0, 1.0);glVertex3f(5 + x, -5 + y, 5 + z);glTexCoord2f(1.0, 0.0);glVertex3f(-5 + x, -5 + y, 5 + z);glEnd();//4----------------------------    glBegin(GL_QUADS);glNormal3f(1.0F, 0.0F, 0.0F);glTexCoord2f(0.0, 0.0);glVertex3f(5 + x, 5 + y, 5 + z);glTexCoord2f(0.0, 1.0);glVertex3f(5 + x, -5 + y, 5 + z);glTexCoord2f(1.0, 1.0);glVertex3f(5 + x, -5 + y, -5 + z);glTexCoord2f(1.0, 0.0);glVertex3f(5 + x, 5 + y, -5 + z);glEnd();//5----------------------------    glBegin(GL_QUADS);glNormal3f(-1.0F, 0.0F, 0.0F);glTexCoord2f(0.0, 0.0);glVertex3f(-5 + x, -5 + y, -5 + z);glTexCoord2f(0.0, 1.0);glVertex3f(-5 + x, -5 + y, 5 + z);glTexCoord2f(1.0, 1.0);glVertex3f(-5 + x, 5 + y, 5 + z);glTexCoord2f(1.0, 0.0);glVertex3f(-5 + x, 5 + y, -5 + z);glEnd();//6----------------------------*/    glPopMatrix();}void drawInsideWall(int x, int y, int z){glPushMatrix();glTranslatef(-100.0f, 0, -100.0f);for (int i = 20; i < x; i += 10){for (int j = 0; j < 10; j += 10){for (int l = 0; l < 10; l += 10){drawWall(i, j, l);isWall[i / 10][l / 10] = 1;}}}for (int i = 0; i < 10; i += 10){for (int j = 0; j < 10; j += 10){for (int l = 0; l < z; l += 10){drawWall(i, j, l);isWall[i / 10][l / 10] = 1;}}}for (int i = 190; i < x; i += 10){for (int j = 0; j < 10; j += 10){for (int l = 0; l < z; l += 10){drawWall(i, j, l);isWall[i / 10][l / 10] = 1;}}}for (int i = 0; i < 180; i += 10){for (int j = 0; j < 10; j += 10){for (int l = 190; l < 200; l += 10){drawWall(i, j, l);isWall[i / 10][l / 10] = 1;}}}for (int i = 20; i < 30; i += 10){for (int j = 0; j < 10; j += 10){for (int l = 10; l < 180; l += 10){drawWall(i, j, l);isWall[i / 10][l / 10] = 1;}}}for (int i = 20; i < 180; i += 10){for (int j = 0; j < 10; j += 10){for (int l = 170; l < 180; l += 10){drawWall(i, j, l);isWall[i / 10][l / 10] = 1;}}}for (int i = 170; i < 180; i += 10){for (int j = 0; j < 10; j += 10){for (int l = 20; l < 180; l += 10){drawWall(i, j, l);isWall[i / 10][l / 10] = 1;}}}for (int i = 20; i < 160; i += 10){for (int j = 0; j < 10; j += 10){for (int l = 20; l < 30; l += 10){drawWall(i, j, l);isWall[i / 10][l / 10] = 1;}}}for (int i = 40; i < 170; i += 10){for (int j = 0; j < 10; j += 10){for (int l = 40; l < 50; l += 10){drawWall(i, j, l);isWall[i / 10][l / 10] = 1;}}}for (int i = 40; i < 50; i += 10){for (int j = 0; j < 10; j += 10){for (int l = 40; l < 160; l += 10){drawWall(i, j, l);isWall[i / 10][l / 10] = 1;}}}for (int i = 60; i < 70; i += 10){for (int j = 0; j < 10; j += 10){for (int l = 60; l < 170; l += 10){drawWall(i, j, l);isWall[i / 10][l / 10] = 1;}}}for (int i = 60; i < 160; i += 10){for (int j = 0; j < 10; j += 10){for (int l = 150; l < 160; l += 10){drawWall(i, j, l);isWall[i / 10][l / 10] = 1;}}}for (int i = 80; i < 170; i += 10){for (int j = 0; j < 10; j += 10){for (int l = 130; l < 140; l += 10){drawWall(i, j, l);isWall[i / 10][l / 10] = 1;}}}for (int i = 130; i < 140; i += 10){for (int j = 0; j < 10; j += 10){for (int l = 60; l < 140; l += 10){drawWall(i, j, l);isWall[i / 10][l / 10] = 1;}}}for (int i = 110; i < 130; i += 10){for (int j = 0; j < 10; j += 10){for (int l = 110; l < 120; l += 10){drawWall(i, j, l);isWall[i / 10][l / 10] = 1;}}}for (int i = 120; i < 160; i += 10){for (int j = 0; j < 10; j += 10){for (int l = 60; l < 70; l += 10){drawWall(i, j, l);isWall[i / 10][l / 10] = 1;}}}for (int i = 150; i < 170; i += 10){for (int j = 0; j < 10; j += 10){for (int l = 100; l < 110; l += 10){drawWall(i, j, l);isWall[i / 10][l / 10] = 1;}}}for (int i = 140; i < 160; i += 10){for (int j = 0; j < 10; j += 10){for (int l = 80; l < 90; l += 10){drawWall(i, j, l);isWall[i / 10][l / 10] = 1;}}}for (int i = 100; i < 130; i += 10){for (int j = 0; j < 10; j += 10){for (int l = 80; l < 90; l += 10){drawWall(i, j, l);isWall[i / 10][l / 10] = 1;}}}for (int i = 70; i < 100; i += 10){for (int j = 0; j < 10; j += 10){for (int l = 110; l < 120; l += 10){drawWall(i, j, l);isWall[i / 10][l / 10] = 1;}}}for (int i = 110; i < 120; i += 10){for (int j = 0; j < 10; j += 10){for (int l = 100; l < 110; l += 10){drawWall(i, j, l);isWall[i / 10][l / 10] = 1;}}}for (int i = 70; i < 110; i += 10){for (int j = 0; j < 10; j += 10){for (int l = 60; l < 70; l += 10){drawWall(i, j, l);isWall[i / 10][l / 10] = 1;}}}for (int i = 70; i < 90; i += 10){for (int j = 0; j < 10; j += 10){for (int l = 80; l < 90; l += 10){drawWall(i, j, l);isWall[i / 10][l / 10] = 1;}}}//for (int i = 0; i < 20; i++){//for (int j = 0; j < 20; j++){//cout << isWall[i][j];//}//cout << endl;//}glPopMatrix();}void coutisWall(){for (int i = 0; i < 20; i++){for (int j = 0; j < 20; j++){cout << isWall[i][j];}cout << endl;}}void drawC(float x, float y, float z){glPushMatrix();glColor3f(1.0f, 0.0f, 0.0f);glTranslatef(x, y, z);glutSolidSphere(4, 20, 20);glPopMatrix();}void mySpecial1(int key, int x, int y){int step = 10;switch (key){case GLUT_KEY_UP:if (isWall[x1 / 10 + 10][z1 / 10 + 11] == 1){return;}else{Cz += step;x1 = Cx;z1 = Cz;x2 = Cx;z2 = 100;}glutPostRedisplay();break;case GLUT_KEY_DOWN:if (isWall[x1 / 10 + 10][z1 / 10 + 9] == 1){return;}else{Cz -= step;x1 = Cx;z1 = Cz;x2 = Cx;z2 = -100;}glutPostRedisplay();break;case GLUT_KEY_LEFT:if (isWall[x1 / 10 + 11][z1 / 10 + 10] == 1){return;}else{Cx += step;x1 = Cx;z1 = Cz;x2 = 100;z2 = Cz;}glutPostRedisplay();break;case GLUT_KEY_RIGHT:if (isWall[x1 / 10 + 9][z1 / 10 + 10] == 1){return;}else{Cx -= step;x1 = Cx;z1 = Cz;x2 = -100;z2 = Cz;}glutPostRedisplay();break;case GLUT_KEY_F1:hit++;glutPostRedisplay();break;}}void mySpecial2(int key, int x, int y){int step = 10;switch (key){case GLUT_KEY_F1:hit++;glutPostRedisplay();break;case GLUT_KEY_DOWN:direction += 2;if (direction % 4 == 0){x1 = Cx;z1 = Cz;x2 = Cx;z2 = 100;glutPostRedisplay();}if (direction % 4 == 1){x1 = Cx;z1 = Cz;x2 = -100;z2 = Cz;glutPostRedisplay();}if (direction % 4 == 2){x1 = Cx;z1 = Cz;x2 = Cx;z2 = -100;glutPostRedisplay();}if (direction % 4 == 3){x1 = Cx;z1 = Cz;x2 = 100;z2 = Cz;glutPostRedisplay();}break;case GLUT_KEY_LEFT:direction += 3;if (direction % 4 == 0){x1 = Cx;z1 = Cz;x2 = Cx;z2 = 100;glutPostRedisplay();}if (direction % 4 == 1){x1 = Cx;z1 = Cz;x2 = -100;z2 = Cz;glutPostRedisplay();}if (direction % 4 == 2){x1 = Cx;z1 = Cz;x2 = Cx;z2 = -100;glutPostRedisplay();}if (direction % 4 == 3){x1 = Cx;z1 = Cz;x2 = 100;z2 = Cz;glutPostRedisplay();}break;case GLUT_KEY_RIGHT:direction += 1;if (direction % 4 == 0){x1 = Cx;z1 = Cz;x2 = Cx;z2 = 100;glutPostRedisplay();}if (direction % 4 == 1){x1 = Cx;z1 = Cz;x2 = -100;z2 = Cz;glutPostRedisplay();}if (direction % 4 == 2){x1 = Cx;z1 = Cz;x2 = Cx;z2 = -100;glutPostRedisplay();}if (direction % 4 == 3){x1 = Cx;z1 = Cz;x2 = 100;z2 = Cz;glutPostRedisplay();}break;case GLUT_KEY_UP:if (direction % 4 == 0){if (isWall[x1 / 10 + 10][z1 / 10 + 11] == 1){return;}else{Cz += step;x1 = Cx;z1 = Cz;x2 = Cx;z2 = 100;}glutPostRedisplay();break;}if (direction % 4 == 1){if (isWall[x1 / 10 + 9][z1 / 10 + 10] == 1){return;}else{Cx -= step;x1 = Cx;z1 = Cz;x2 = -100;z2 = Cz;}glutPostRedisplay();break;}if (abs(direction % 4) == 2){if (isWall[x1 / 10 + 10][z1 / 10 + 9] == 1){return;}else{Cz -= step;x1 = Cx;z1 = Cz;x2 = Cx;z2 = -100;}glutPostRedisplay();break;}if (abs(direction % 4) == 3){if (isWall[x1 / 10 + 11][z1 / 10 + 10] == 1){return;}else{Cx += step;x1 = Cx;z1 = Cz;x2 = 100;z2 = Cz;}glutPostRedisplay();break;}}}void drawBottom(){glPushMatrix();glTranslatef(-120, 0, -120);glColor3f(0.0, 0.0, 0.0);//glBindTexture(GL_TEXTURE_2D, texWall);glBegin(GL_QUADS);glNormal3f(0.0F, 1.0F, 0.0F);//glTexCoord2f(0.0, 0.0);glVertex3f(0, -5, 0);//glTexCoord2f(0.0, 1.0);glVertex3f(0, -5, 240);//glTexCoord2f(1.0, 1.0);glVertex3f(240, -5, 240);//glTexCoord2f(1.0, 0.0);glVertex3f(240, -5, 0);glEnd();glPopMatrix();}void mydisplay(){glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);glMatrixMode(GL_PROJECTION);if (hit % 2 == 0){glViewport(0, 0, 700, 700);glLoadIdentity();gluPerspective(75, 1, 2, 500);glMatrixMode(GL_MODELVIEW);glLoadIdentity();gluLookAt(0, 180, 0, 0, 0, 0, 0, 0, 1);glEnable(GL_LIGHT1);glEnable(GL_TEXTURE_2D);glEnable(GL_LIGHTING);glDepthFunc(GL_LESS);glEnable(GL_DEPTH_TEST);glPushMatrix();//drawC(Cx, Cy, Cz);drawsolider(Cx, Cy, Cz);drawInsideWall(200, 10, 200);glPopMatrix();glDisable(GL_LIGHT1);glPushMatrix();drawBottom();glPopMatrix();glEnable(GL_LIGHT1);/*glPushMatrix();glBindTexture(GL_TEXTURE_2D, texWall);drawOutsideWall(200, 10, 200);glPopMatrix();*/glutSpecialFunc(mySpecial1);glDisable(GL_LIGHT1);}else{glEnable(GL_LIGHTING);glEnable(GL_LIGHT0);glEnable(GL_TEXTURE_2D);glViewport(700, 500, 200, 200);glLoadIdentity();gluPerspective(75, 1, 2, 500);glMatrixMode(GL_MODELVIEW);glLoadIdentity();gluLookAt(0, 180, 0, 0, 0, 0, 0, 0, 1);{// 指定光源位置的数组 GLfloat lightPos[] = { Cx, 100.0f, Cz, 1.0f };// 设置光源0的位置GLfloat ambientLight[] = { 1.0f, 1.0f, 1.0f, 1.0f };GLfloat specular[] = { 1.0f, 1.0f, 1.0f, 1.0f };GLfloat specref[] = { 1.0f, 1.0f, 1.0f, 1.0f };GLfloat spotDir[] = { 0.0f, -1.0f, 0.0f };// 启用光照计算//glEnable(GL_LIGHTING);// 设置微弱的环境光,使物体可见//glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambientLight);// 设置光源0的散射光和镜面光成分/* glLightfv(GL_LIGHT0, GL_DIFFUSE, ambientLight);glLightfv(GL_LIGHT0, GL_SPECULAR, specular);*/// 设置光源0的位置glLightfv(GL_LIGHT0, GL_POSITION, lightPos);// 设置光源0的聚光灯效果,切角30度glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, spotDir);glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, 30.0f);// 启用光源0//glEnable(GL_LIGHT0);// 启用颜色追踪//glEnable(GL_COLOR_MATERIAL);glDepthFunc(GL_LESS);glEnable(GL_DEPTH_TEST);}//drawOutsideWall(200, 10, 200);glPushMatrix();drawC(Cx, Cy, Cz);glPopMatrix();glPushMatrix();drawBottom();glPopMatrix();glPushMatrix();drawInsideWall(200, 10, 200);glPopMatrix();//glDisable(GL_LIGHT1);glDisable(GL_LIGHT0);//glDisable(GL_LIGHT2);glEnable(GL_LIGHTING);glEnable(GL_LIGHT1);//glEnable(GL_LIGHT1);glEnable(GL_TEXTURE_2D);glViewport(0, 0, 700, 700);glLoadIdentity();gluPerspective(70, 1, 1, 200);glMatrixMode(GL_MODELVIEW);glLoadIdentity();gluLookAt(x1, Y1, z1, x2, y2, z2, x3, y3, z3);glPushMatrix();drawInsideWall(200, 10, 200);glPopMatrix();/*glPushMatrix();drawOutsideWall(200, 10, 200);glPopMatrix();*/glPushMatrix();drawBottom();glPopMatrix();glDisable(GL_LIGHT1);glutSpecialFunc(mySpecial2);}coutisWall();glutSwapBuffers();}void myinit(void){{GLfloat light_position[] = { 5.0, 4.0, 5.0, 0.0 };GLfloat light_ambient[] = { 1.0, 1.0, 1.0, 1.0 };GLfloat light_diffuse[] = { 1.0, 1.0, 1.0, 1.0 };GLfloat light_specular[] = { 1.0, 1.0, 1.0, 1.0 };glLightfv(GL_LIGHT1, GL_POSITION, light_position);glLightfv(GL_LIGHT1, GL_AMBIENT, light_ambient);glLightfv(GL_LIGHT1, GL_DIFFUSE, light_diffuse);glLightfv(GL_LIGHT1, GL_SPECULAR, light_specular);}{// 指定光源位置的数组 GLfloat lightPos[] = { Cx, 100.0f, Cz, 1.0f };// 设置光源0的位置GLfloat ambientLight[] = { 1.0f, 1.0f, 1.0f, 1.0f };GLfloat specular[] = { 1.0f, 1.0f, 1.0f, 1.0f };GLfloat specref[] = { 1.0f, 1.0f, 1.0f, 1.0f };GLfloat spotDir[] = { 0.0f, -1.0f, 0.0f };// 启用光照计算//glEnable(GL_LIGHTING);// 设置微弱的环境光,使物体可见//glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambientLight);// 设置光源0的散射光和镜面光成分/* glLightfv(GL_LIGHT0, GL_DIFFUSE, ambientLight);glLightfv(GL_LIGHT0, GL_SPECULAR, specular);*/// 设置光源0的位置glLightfv(GL_LIGHT0, GL_POSITION, lightPos);// 设置光源0的聚光灯效果,切角30度glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, spotDir);glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, 30.0f);// 启用光源0//glEnable(GL_LIGHT0);// 启用颜色追踪//glEnable(GL_COLOR_MATERIAL);glDepthFunc(GL_LESS);glEnable(GL_DEPTH_TEST);}{// 指定光源位置的数组 GLfloat light_Pos[] = { x1, Y1, z1, 1.0f };// 设置光源2的位置GLfloat ambientLight[] = { 1.0f, 1.0f, 1.0f, 1.0f };GLfloat specu_lar[] = { 1.0f, 1.0f, 1.0f, 1.0f };GLfloat specref[] = { 1.0f, 1.0f, 1.0f, 1.0f };GLfloat spot_Dir[] = { x2, y2, z2 };// 启用光照计算glLightfv(GL_LIGHT2, GL_POSITION, light_Pos);// 设置光源2的聚光灯效果,切角90度glLightfv(GL_LIGHT2, GL_SPOT_DIRECTION, spot_Dir);glLightf(GL_LIGHT2, GL_SPOT_CUTOFF, 90.0f);glDepthFunc(GL_LESS);glEnable(GL_DEPTH_TEST);}glEnable(GL_BLEND);glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST);glEnable(GL_POLYGON_SMOOTH);glEnable(GL_POINT_SMOOTH);glEnable(GL_LINE_SMOOTH);glClearColor(0.5, 0.5, 0.5, 0.5);glEnable(GL_DEPTH_TEST);glEnable(GL_TEXTURE_2D);//启用二维纹理glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);glShadeModel(GL_FLAT);     //使用平滑明暗处理  glEnable(GL_DEPTH_TEST);     //剔除隐藏面  glEnable(GL_CULL_FACE);      //不计算多边形背面  glFrontFace(GL_CCW);      //多边形逆时针方向为正面  }void main(int argc, char* argv[]){//loadTexture("555.bmp");glutInit(&argc, argv);glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);//glClearColor(0.0, 0.0, 0.0, 1.0);glutInitWindowSize(900, 700);glutInitWindowPosition(200, 0);glutCreateWindow("3D迷宫");loadTexture("ice.bmp");//GL_myInitial();myinit();glutDisplayFunc(mydisplay);glutMainLoop();}

MD2Model.cpp (参考了学OpenGl编3D游戏项目)

#include "MD2Model.h"#include <gl\glut.h>#include <iostream>#include<stdlib.h>#include<fstream>using namespace std;static GLint imagewidth;static GLint imageheight;static GLint pixellength;static GLubyte* pixeldata;#define MAX_MD2_VERTS 2048//魔术数“IDP2”或844121161#define MD2_IDENT (('2'<<24) + ('P'<<16) + ('D'<<8) + 'I')//模型版本#define MD2_VERSION 8vec3_t CMD2Model::anorms[NUMVERTEXNORMALS] = {#include "anorms.h"};static vec3_t lcolor;vec3_t g_lightcolor = { 1.0, 1.0, 1.0 };int g_ambientlight = 32;float g_shadelight = 128;float g_angle = 0.0;GLuint gamerTexture;void loadTexture1(char* filename){FILE* pfile = fopen(filename, "rb");if (pfile == 0){cout << "can not open" << filename << endl;}//读取图像大小fseek(pfile, 0x0012, SEEK_SET);fread(&imagewidth, sizeof(imagewidth), 1, pfile);fread(&imageheight, sizeof(imageheight), 1, pfile);//计算像素数据长度pixellength = imagewidth * 3;while (pixellength % 4 != 0)pixellength++;pixellength *= imageheight;//读取像素数据pixeldata = (GLubyte*)malloc(pixellength);if (pixeldata == 0) exit(0);fseek(pfile, 54, SEEK_SET);fread(pixeldata, pixellength, 1, pfile);glBindTexture(GL_TEXTURE_2D, gamerTexture);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_MAG_FILTER, GL_NEAREST);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, imagewidth, imageheight, 0, GL_BGR_EXT, GL_UNSIGNED_BYTE, pixeldata);}//初始化MD2 模型中的21 段动画anim_t CMD2Model::animlist[21] = {{ 0, 39, 9 }, // STAND{ 40, 45, 10 }, // RUN{ 46, 53, 10 }, // ATTACK{ 54, 57, 7 }, // PAIN_A{ 58, 61, 7 }, // PAIN_B{ 62, 65, 7 }, // PAIN_C{ 66, 71, 7 }, // JUMP{ 72, 83, 7 }, // FLIP{ 84, 94, 7 }, // SALUTE{ 95, 111, 10 }, // FALLBACK{ 112, 122, 7 }, // WAVE{ 123, 134, 6 }, // POINT{ 135, 153, 10 }, // CROUCH_STAND{ 154, 159, 7 }, // CROUCH_WALK{ 160, 168, 10 }, // CROUCH_ATTACK{ 196, 172, 7 }, // CROUCH_PAIN{ 173, 177, 5 }, // CROUCH_DEATH{ 178, 183, 7 }, // DEATH_FALLBACK{ 184, 189, 7 }, // DEATH_FALLFORWARD{ 190, 197, 7 }, // DEATH_FALLBACKSLOW{ 198, 198, 5 }, // BOOM};/*构造函数——重置所有变量:*将所有的成员变量(除了静态变量和m_scale)置为0。*这里将m_scale初始化为1.0,因为如果是0,则没有任何显示。*/CMD2Model::CMD2Model(void){m_vertices = 0;m_glcmds = 0;m_lightnormals = 0;num_frames = 0;num_xyz = 0;num_glcmds = 0;m_texid = 0;m_scale = 1.0;setAnim(0);}//析构函数‐‐‐‐‐‐释放申请的内存CMD2Model::~CMD2Model(void){delete[] m_vertices;delete[] m_glcmds;delete[] m_lightnormals;}//LoadModel()‐‐‐‐从文件装载MD2 模型bool CMD2Model::loadModel(const char*filename){ifstream file; //文件流md2_t header; //md2 文件头char *buffer; //帧数据缓冲区frame_t *frame; //临时变量vec3_t *ptrverts; //指向m_vertices 的指针int *ptrnormals; //指向m lightnormals 的指针//打开指定的文件file.open(filename, ios::in | ios::binary);if (file.fail())return false;//读入文件头file.read((char *)&header, sizeof(md2_t));//验证它是否是MD2 文件//检查魔术数和版本号if ((header.magic != MD2_IDENT) && (header.version != MD2_VERSION)){//这不是一个MD2 文件file.close();return false;}//初始化成员变量num_frames = header.num_frames;num_xyz = header.num_xyz;num_glcmds = header.num_glcmds;//申请内存m_vertices = new vec3_t[num_xyz * num_frames];m_glcmds = new int[num_glcmds];m_lightnormals = new int[num_xyz * num_frames];buffer = new char[num_frames * header.frameSize];//读入文件数据//读入帧数据file.seekg(header.ofs_frames, std::ios::beg);file.read((char *)buffer, num_frames * header.frameSize);//读入OpenGL 指令file.seekg(header.ofs_glcmds, std::ios::beg);file.read((char *)m_glcmds, num_glcmds * sizeof(int));//顶点数组初始化for (int j = 0; j < num_frames; j++){//调整指针frame = (frame_t *)&buffer[header.frameSize * j];ptrverts = &m_vertices[num_xyz * j];ptrnormals = &m_lightnormals[num_xyz * j];for (int i = 0; i < num_xyz; i++){ptrverts[i][0] = (frame->alias_vertices1[i].v[0] * frame->scale[0]) + frame->translate[0];ptrverts[i][1] = (frame->alias_vertices1[i].v[1] * frame->scale[1]) + frame->translate[1];ptrverts[i][2] = (frame->alias_vertices1[i].v[2] * frame->scale[2]) + frame->translate[2];ptrnormals[i] = frame->alias_vertices1[i].lightnormalindex;}}//释放buffer 内存delete[] buffer;//关闭文件,并返回file.close();return true;}//LoadSkin()‐‐‐‐装载模型纹理bool CMD2Model::loadSkin(char *filename){m_texid = 3;glGenTextures(1, &gamerTexture);loadTexture1(filename);return true;}//DrawModel()‐‐‐‐绘制模型//DrawModel()‐‐‐‐绘制MD2 模型void CMD2Model::drawModel(float time){//计算当前帧和下一帧if (time > 0.0)animate(time);glPushMatrix();// 旋转模型/*glRotatef(-90.0, 1.0, 0.0, 0.0);glRotatef(-90.0, 0.0, 0.0, 1.0);*/// 在屏幕上绘制模型renderFrame();glPopMatrix();}// Interpolate()‐‐‐‐使用当前帧和下一帧,插值和缩放顶点void CMD2Model::interpolate(vec3_t *vertlist){vec3_t *curr_v; // 当前帧顶点的指针vec3_t *next_v; // 下一帧顶点的指针// 从所有顶点列表中获得当前帧和下一帧的顶点列表curr_v = &m_vertices[num_xyz * m_anim.curr_frame];next_v = &m_vertices[num_xyz * m_anim.next_frame];// 为了避免粗陋的动画,对顶点进行插值和比例缩放for (int i = 0; i < num_xyz; i++){vertlist[i][0] = (curr_v[i][0] + m_anim.interpol * (next_v[i][0] - curr_v[i][0])) * m_scale;vertlist[i][1] = (curr_v[i][1] + m_anim.interpol * (next_v[i][1] - curr_v[i][1])) * m_scale;vertlist[i][2] = (curr_v[i][2] + m_anim.interpol * (next_v[i][2] - curr_v[i][2])) * m_scale;}}//ProcessLightlng()‐‐‐‐处理所有的光照计算void CMD2Model::processLighting(void){float lightvar = (float)((g_shadelight + g_ambientlight) / 256.0);lcolor[0] = g_lightcolor[0] * lightvar;lcolor[1] = g_lightcolor[1] * lightvar;lcolor[2] = g_lightcolor[2] * lightvar;//shadedots = anorms_dots[((int)(g_angle * (SHADEDOT_QUANT / 360.0))) &//(SHADEDOT_QUANT-1)];}//RenderFrame()‐‐‐‐使用OpenGL 指令绘制当前模型void CMD2Model::renderFrame(void){static vec3_t vertlist[MAX_MD2_VERTS]; //插值后的顶点int *ptricmds = m_glcmds; //指向OpenGL 指令的指针//反转多边形的前向面朝向,因为OpenGL 指令列表中的三角形为顺时针方向glPushAttrib(GL_POLYGON_BIT);glFrontFace(GL_CW);//打开背向面剔除glEnable(GL_CULL_FACE);glCullFace(GL_BACK);//处理光照processLighting();//插值interpolate(vertlist);//绑定模型纹理glBindTexture(GL_TEXTURE_2D, gamerTexture);//绘制每个三角形while (int i = *(ptricmds++)){if (i < 0){glBegin(GL_TRIANGLE_FAN);i = -i;}else{glBegin(GL_TRIANGLE_STRIP);}for ( /* nothing */; i > 0; i--, ptricmds += 3){//ptricmds[0]:纹理坐标s//ptricmds[1]:纹理坐标t//ptricmds[2]:需要绘制的顶点下标//float l = shadedots[m_lightnormals[ptricmds[2]]];////设置光照颜色//glColor3f(l * lcolor[0], l * lcolor[1], l * lcolor[2]);//使用纹理坐标glTexCoord2f(((float *)ptricmds)[0], ((float *)ptricmds)[1]);//使用三角形法向量(用于光照)//只在使用OpenGL 光照时使用glNormal3fv(anorms[m_lightnormals[ptricmds[2]]]);//绘制顶点glVertex3fv(vertlist[ptricmds[2]]);}glEnd();}glDisable(GL_CULL_FACE);glPopAttrib();}//SetAnim()‐‐‐‐由指定的动画对m_anim 初始化void CMD2Model::setAnim(int type){if ((type < 0) || (type > MAX_ANIMATIONS))type = 0;m_anim.startframe = animlist[type].first_frame;m_anim.endframe = animlist[type].last_frame;m_anim.next_frame = animlist[type].first_frame + 1;m_anim.fps = animlist[type].fps;m_anim.type = type;}//Animate() ‐‐‐‐计算当前帧、下一帧和插值百分率void CMD2Model::animate(float time){m_anim.curr_time = time;// 计算当前帧和下一帧if (m_anim.curr_time - m_anim.old_time > (1.0 / m_anim.fps)){m_anim.curr_frame = m_anim.next_frame;m_anim.next_frame++;if (m_anim.next_frame > m_anim.endframe)m_anim.next_frame = m_anim.startframe;m_anim.old_time = m_anim.curr_time;}// 防止当前帧或下一帧超出了总帧数…if (m_anim.curr_frame > (num_frames - 1))m_anim.curr_frame = 0;if (m_anim.next_frame > (num_frames - 1))m_anim.next_frame = 0;m_anim.interpol = m_anim.fps * (m_anim.curr_time - m_anim.old_time);}void CMD2Model::drawFrame(int frame){// 设置新的动画参数...m_anim.startframe = frame;m_anim.endframe = frame;m_anim.next_frame = frame;m_anim.fps = 1;m_anim.type = -1;// 绘制该模型drawModel(1.0);}

最后基本效果是这样的

上帝视角:

第一视角:

右上角还有战争迷雾安静


基本上就是这样了,存在问题就是战争迷雾总是在替身的周围消散,与题目要求中显示搜寻过的地域不符,正在想办法修正,也希望大家来给我提提意见。生气

2 1
原创粉丝点击