📄 baiscobj.cpp
字号:
// 学程序编游戏系列丛书
// 唐明理 E_mail: cqtmL@163.com
//====================================================================
#include "stdafx.h"
#include "baiscobj.h"
#include "anmobj.h"
#include "../include/BITMAP.H"
#include "mdlobj.h"
extern mdlobj m_mdlobj;
extern GLfloat r; //飞机盘旋角度
float gao=1.8f;
extern CString test; //场景信息
extern anmobj* m_anmobj;
extern HWND hWnd; //窗口句柄,主定义在主程序
extern bool Lbutdown;//鼠标左键,主定义在主程序
int rnshu=0; //人数计数
//////////////////////////////////////////////////////////////////////
baiscobj::baiscobj()
{ g_eye[0]= MAP;//
g_eye[2]=-MAP;//
g_Angle=0;//
g_elev=-0;//
//A、设置数据目录
char appdir[256];
GetCurrentDirectory(256,appdir);
CString dir=appdir;
if(dir.Right(8)!="运行程序")
SetCurrentDirectory("../运行程序");
m_mdlobj.InitGL(0,"data/mdl模型/qian1.mdl");
//B、调入场景文件和相关贴图
g_imageData = LoadBit("data/images/Terrain1.bmp",&g_bit); //调等高地形图
LoadT8("data/images/sand0.bmp", g_cactus[0]); //地面帖图
LoadT8("data/images/1RBack.bmp",g_cactus[2]); //天空贴图后
LoadT8("data/images/1Front.bmp",g_cactus[3]); //天空贴图前
LoadT8("data/images/1Top.bmp", g_cactus[4]); //天空贴图顶
LoadT8("data/images/1Left.bmp", g_cactus[5]); //天空贴图左
LoadT8("data/images/1Right.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/CACTUS3.BMP",g_cactus[14]); //树4帖图
InitTerrain(5);//初始化地面
//D、调入3DS模型
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
//C、初始化3D动画模型
m_anmobj->model[0]=NULL; m_anmobj->model[1]=NULL;
m_anmobj->texture[0]=NULL; m_anmobj->texture[1]=NULL;
m_anmobj->getobj("data/模型/士兵0/"); //士兵模型士兵0
for(int i=0;i<RNSHU;i++)
{m_anmobj->man[i].qd[0]=MAP+80+rand()%20; //起点manqdx
m_anmobj->man[i].qd[1]=MAP-10+i*1;//
m_anmobj->man[i].zd[0]=MAP+20-rand()%5; //终点manzdx
m_anmobj->man[i].zd[1]=MAP-10+i*1;//
m_anmobj->man[i].dz=1; //初始动作,跑。
m_anmobj->man[i].death=0;
}
//E、射击、爆炸初始化
LoadT16("data/images/explosion.bmp",g_cactus[15]); //粒子帖图
isExplosion = true; //
explosion=NULL; //
Explosion(0,0,0,1,1); //爆炸初始化
//F、
inputSys = new CInputSystem; //初始化鼠标类变量
bool useDInput =
inputSys->Initialize(hWnd,(HINSTANCE)GetModuleHandle(NULL),
true,IS_USEKEYBOARD|IS_USEMOUSE);//初始化鼠标接口
Lbutdown=false; //没按鼠标左键
rocketX=0,rocketZ=0,rocketY=2000; //子弹位置初值
rad_xz=0; //视角(弧度)清0
Expl=0; //子弹距离计数清0
//G、
srand(100);//产生树的固定随机数种子
for(i=0;i<TREESL;i++) //树的数量
{objposi[i].x= RAND_COORD((MAP_W-1)*MAP_SCALE); //位置x
objposi[i].z= RAND_COORD((MAP_W-1)*MAP_SCALE); //位置z
objposi[i].size=5.0f+rand()%5; //大小2-4随机
objposi[i].h=-objposi[i].size/10; //深浅
objposi[i].cactus=rand()%4+11; //树形随机4种
}
glEnable(GL_TEXTURE_2D);
}
baiscobj::~baiscobj()
{ for(int i=0;i<16;i++) glDeleteTextures(1, &g_cactus[i]);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
//场景===========================================================
void baiscobj::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 baiscobj::DisplayScene()//摄像漫游
{ float speed=0.5f; //步长
int mouseX, mouseY; //定义鼠标的轨迹变化量X、Y
inputSys->Update(); //清除鼠标接口
inputSys->GetMouseMovement(mouseX,mouseY);//获取鼠标的轨迹变化量X、Y
g_Angle += mouseX*.2f; //场景方位角加上鼠标轨迹变化量X
g_elev += -mouseY*.2f; //场景俯仰角加上鼠标轨迹变化量Y
float x=g_eye[0],y=g_eye[2],z=g_eye[2];
if (KEY_DOWN(VK_SHIFT)) speed =speed*2;//按SHIFT时的加速true
if (KEY_DOWN(VK_LEFT)) g_Angle-=speed*2;//左转,方位角-
if (KEY_DOWN(VK_RIGHT)) g_Angle+=speed*2;//右转,方位角+
rad_xz = float (3.13149* g_Angle/180.0f); //计算左右旋转角度
if (KEY_DOWN(33)) g_elev +=speed; //Page UP 键
if (KEY_DOWN(34)) g_elev -=speed; //Page Down键
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; //视点的x分量
g_eye[0]+=(float)cos(rad_xz)*speed; //视点的Z分量
}
if (KEY_DOWN(VK_DOWN)) //后退
{ g_eye[2]-=(float)sin(rad_xz)*speed; //视点的x分量
g_eye[0]-=(float)cos(rad_xz)*speed; //视点的Z分量
}
//控制到摄像机不离开地面
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])+gao;//设置摄像机对地位置高
//摄像机的方向
g_look[0] = (float)(g_eye[0] +100*cos(rad_xz)); //目标点X分量
g_look[2] = (float)(g_eye[2] +100*sin(rad_xz)); //目标点Z分量
g_look[1] = g_eye[1] +g_elev; //目标点Y分量
//建立modelview矩阵方向
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);
r+=1.0f;if(r>360) r=0;
if (KEY_DOWN(' ')||Lbutdown==true) //空格或鼠标左键射击
{rocketX=g_eye[0],rocketZ=g_eye[2];
rocketY=GetHeight(rocketX, rocketZ)+1.6f;
m_mdlobj.fire(1);
fire(); //射击
sndPlaySound("data/images/explode1.wav",SND_ASYNC);//枪声
}
zangan(x,z);//碰撞绕行
return TRUE;
}
//==========================================================================
void baiscobj::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; //地域数据X分量
// g_terrain [Vertex][1] = (float)(g_imageData[(z*MAP_W+x)*3]/3);//Y分量,山的高度
g_terrain [Vertex][1] = h + FRAND * h; //Y分量,随机产生山的高度
g_terrain [Vertex][2] = -float(z)*MAP_SCALE; //地域数据Z分量
g_texcoord[Vertex][0] = (float) x; //索引数组x
g_texcoord[Vertex][1] = (float) z; //索引数组z
g_index [index++] = Vertex; //顶点数组1维
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 baiscobj::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]);
//显示由顶点数组指定的面。
}
float baiscobj::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; //相邻行大于地块数,取首行
if (Col0 < 0) Col0 = 0; //相邻列大于地块数,取首列
if (Row0 < 0) Row0 = 0; //相邻行大于地块数,取首行
if (Col1 < 0) Col1 = 0; //相邻列大于地块数,取首列
if (Row1 < 0) 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); //求块内X偏移位置
float ty =CameraZ - int(CameraZ); //求块内Z偏移位置
float txty = tx * ty; //以下为双线性插值(内插)计算
return h00*(1.0f-ty-tx+txty)
+ h01*(tx-txty)
+ h11*txty
+ h10*(ty-txty); //返回插值计算值,为所求点的高度。
}
void baiscobj::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; // 天空的位置x
float y = MAP/a-height/2; // 天空的位置y
float z = -MAP -length/2; // 天空的位置z
///////////////////////////////////////////////////////////////////////////////
texture(g_cactus[2]); // 设置BACK贴图左
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]); // 设置FRONT贴图右
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[1]); // 设置BOTTOM贴图底
glBegin(GL_QUADS); // 多组独立填充四边形
glTexCoord2f(1.0f,0.0f); glVertex3f(x, y, z);
glTexCoord2f(1.0f,1.0f); glVertex3f(x, y, z+length);
glTexCoord2f(0.0f,1.0f); glVertex3f(x+width,y, z+length);
glTexCoord2f(0.0f,0.0f); glVertex3f(x+width,y, z);
glEnd();*/
texture(g_cactus[4]); // 设置TOP贴图顶
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]); // 设置LEFT贴图前
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]); // 设置RIGHT贴图后
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 baiscobj::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_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);
}
//组合图形=================================================================
void baiscobj::picter(float x,float y,float z)//组合图形
{y=GetHeight(x,z);
glPushAttrib(GL_CURRENT_BIT);//保存现有颜色属实性
glDisable(GL_TEXTURE_2D);
glPushMatrix();//平台==============================
glTranslatef(x,y+0.5f,z); //平台的定位
glColor3f(0.0f,1.0f,0.2f); //绿色
auxSolidCube(1); //方台(边长)
glTranslatef(0.0f,0.8f,0.0f); //架的位置调整,上升0.8
glColor3f(0.0f,0.0f,1.0f); //蓝色
auxSolidBox(.2f,1.3f,.2f); //长方架(宽、高、长)
glPopMatrix();
glPushMatrix();//雷达==============================
glTranslatef(x,y+2.5f,z); //雷达的定位1
glRotatef(r-90,0.0,1.0,0.0); //雷达旋转2
//=======================================
glColor3f(1.0f,1.0f,1.0f); //白色
glRotatef(45, 1.0, 0.0, 0.0); //盘的角度调整,仰30度
auxWireCone(1.5,0.6f); //线园锥盘(底半径、高)
//=======================================
glRotatef(180, 1.0, 0.0, 0.0); //杆的角度调整,反方向转
glTranslatef(0.0f,0.0f,-0.7f); //杆的位置调整,缩进一点
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -