//=========================================================================
/**
* @file CollideDemo.cpp
*
* 项目描述: 碰撞检测演示
* 文件描述: 具体实例类
* 适用平台: Windows98/2000/NT/XP
*
* 作者: WWBOSS
* 电子邮件: wwboss123@gmail.com
* 创建日期: 2006-09-13
* 修改日期: 2006-10-10
*
* 在这个类中您必须重载如下几个虚函数
*
* virtual bool Init();
* 执行所有的初始化工作,如果成功函数返回true
*
* virtual void Uninit();
* 执行所有的卸载工作
*
* virtual void Update(DWORD milliseconds);
* 执行所有的更新操作,传入的参数为两次操作经过的时间,以毫秒为单位
*
* virtual void Draw();
* 执行所有的绘制操作
*/
//=========================================================================
#include "CollideDemo.h" /**< 包含头文件 */
///初始化摄像机参数
Vector3 dir(0,0,-10); /**< 方向 */
Vector3 pos(0,-50,1000); /**< 位置 */
float camera_rotation = 0; /**< 旋转速度 */
///初始化球的属性
Vector3 veloc(0.5,-0.1,0.5); /**< 速度 */
Vector3 accel(0,-0.05,0); /**< 重力加速度 */
Vector3 ArrayVel[10]; /**< 保存各个球的速度 */
Vector3 ArrayPos[10]; /**< 保存各个球的位置 */
Vector3 OldPos[10]; /**< 保存上一次球的位置 */
int NrOfBalls; /**< 设置球的个数 */
double Time = 0.6; /**< 设置模拟的时间精度 */
/** 创建一个程序的实例 */
GLApplication * GLApplication::Create(const char * class_name)
{
CDemo * demo = new CDemo(class_name);
return reinterpret_cast<GLApplication *>(demo);
}
/** 构造函数 */
CDemo::CDemo(const char * class_name) : GLApplication(class_name)
{
/// 初始化用户自定义的程序变量
m_Fps = 0;
}
/** 初始化变量 */
void CDemo::InitVars()
{
///构造平面
pl1._Position = Vector3(0,-300,0);
pl1._Normal = Vector3(0,1,0);
pl2._Position = Vector3(300,0,0);
pl2._Normal = Vector3(-1,0,0);
pl3._Position = Vector3(-300,0,0);
pl3._Normal = Vector3(1,0,0);
pl4._Position = Vector3(0,0,300);
pl4._Normal = Vector3(0,0,-1);
pl5._Position = Vector3(0,0,-300);
pl5._Normal = Vector3(0,0,1);
///构造圆柱体
cyl1._Position = Vector3(0,0,0);
cyl1._Axis = Vector3(0,1,0);
cyl1._Radius = 60 + 20;
cyl2._Position = Vector3(200,-300,0);
cyl2._Axis = Vector3(0,0,1);
cyl2._Radius = 60 + 20;
cyl3._Position = Vector3(-200,0,0);
cyl3._Axis = Vector3(0,1,1);
cyl3._Axis.unit();
cyl3._Radius = 30 + 20;
///构造二次几何体
cylinder_obj = gluNewQuadric();
gluQuadricTexture(cylinder_obj, GL_TRUE);
///设置球的初始属性,并初始化爆炸数组
NrOfBalls = 10;
ArrayVel[0] = veloc;
ArrayPos[0] = Vector3(199,180,10);
ExplosionArray[0]._Alpha = 0;
ExplosionArray[0]._Scale = 1;
ArrayVel[1] = veloc;
ArrayPos[1] = Vector3(0,150,100);
ExplosionArray[1]._Alpha = 0;
ExplosionArray[1]._Scale = 1;
ArrayVel[2] = veloc;
ArrayPos[2] = Vector3(-100,180,-100);
ExplosionArray[2]._Alpha = 0;
ExplosionArray[2]._Scale = 1;
for (int i = 3; i < 10; i++)
{
ArrayVel[i] = veloc;
ArrayPos[i] = Vector3(-500 + i*75, 300, -500 + i*50);
ExplosionArray[i]._Alpha = 0;
ExplosionArray[i]._Scale = 1;
}
for (int i = 10; i < 20; i++)
{
ExplosionArray[i]._Alpha = 0;
ExplosionArray[i]._Scale = 1;
}
}
/** 载入纹理 */
bool CDemo::LoadTexture()
{
glEnable(GL_TEXTURE_2D); /**< 启用纹理映射 */
char* file[] = {"data/marble.bmp","data/spark.bmp","data/boden.bmp","data/wand.bmp"};
/** 循环读入位图纹理 */
for(int i = 0; i < 4; i++)
{
if(!m_texture[i].Load(file[i])) /**< 载入位图文件 */
{
MessageBox(NULL,"装载位图文件失败!","错误",MB_OK); /**< 如果载入失败则弹出对话框 */
return false;
}
}
return true;
}
/** 初始化OpenGL */
bool CDemo::Init()
{
/** 用户自定义的初始化过程 */
glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
glClearDepth(1.0f);
glDepthFunc(GL_LEQUAL);
glEnable(GL_DEPTH_TEST);
glShadeModel(GL_SMOOTH);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
ResizeDraw(true);
/** 初始化输入系统 */
m_pInput = new CInputSystem();
m_pInput->Init(this->m_Window.GetHwnd(),(HINSTANCE)GetModuleHandle(NULL),
true,IS_USEKEYBOARD|IS_USEMOUSE);
/** 设置光源参数 */
GLfloat spec[] = { 1.0, 1.0 ,1.0 ,1.0 };
GLfloat posl[] = { 0, 400, 0, 1 };
GLfloat amb[] = { 0.2f, 0.2f, 0.2f ,1.0f };
GLfloat amb2[] = { 0.3f, 0.3f, 0.3f ,1.0f };
float df=100.0;
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glEnable(GL_DEPTH_TEST);
glShadeModel(GL_SMOOTH);
glEnable(GL_CULL_FACE);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
/** 设置材质属性 */
glMaterialfv(GL_FRONT,GL_SPECULAR,spec);
glMaterialfv(GL_FRONT,GL_SHININESS,&df);
/** 设置光源 */
glEnable(GL_LIGHTING);
glLightfv(GL_LIGHT0,GL_POSITION,posl);
glLightfv(GL_LIGHT0,GL_AMBIENT,amb2);
glEnable(GL_LIGHT0);
glLightModelfv(GL_LIGHT_MODEL_AMBIENT,amb);
glEnable(GL_COLOR_MATERIAL);
glColorMaterial(GL_FRONT,GL_AMBIENT_AND_DIFFUSE);
/** 开启混合 */
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
/** 开启纹理映射,并载入纹理 */
glEnable(GL_TEXTURE_2D);
LoadTexture();
/** 用两个互相垂直的平面模拟爆炸效果 */
glNewList( dlist = glGenLists(1), GL_COMPILE); /**< 创建显示列表 */
glBegin(GL_QUADS);
glRotatef(-45,0,1,0);
glNormal3f(0,0,1);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-50,-40,0);
glTexCoord2f(0.0f, 1.0f); glVertex3f(50,-40,0);
glTexCoord2f(1.0f, 1.0f); glVertex3f(50,40,0);
glTexCoord2f(1.0f, 0.0f); glVertex3f(-50,40,0);
glNormal3f(0,0,-1);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-50,40,0);
glTexCoord2f(0.0f, 1.0f); glVertex3f(50,40,0);
glTexCoord2f(1.0f, 1.0f); glVertex3f(50,-40,0);
glTexCoord2f(1.0f, 0.0f); glVertex3f(-50,-40,0);
glNormal3f(1,0,0);
glTexCoord2f(0.0f, 0.0f); glVertex3f(0,-40,50);
glTexCoord2f(0.0f, 1.0f); glVertex3f(0,-40,-50);
glTexCoord2f(1.0f, 1.0f); glVertex3f(0,40,-50);
glTexCoord2f(1.0f, 0.0f); glVertex3f(0,40,50);
glNormal3f(-1,0,0);
glTexCoord2f(0.0f, 0.0f); glVertex3f(0,40,50);
glTexCoord2f(0.0f, 1.0f); glVertex3f(0,40,-50);
glTexCoord2f(1.0f, 1.0f); glVertex3f(0,-40,-50);
glTexCoord2f(1.0f, 0.0f); glVertex3f(0,-40,50);
glEnd();
glEndList(); /**< 结束显示列表定义 */
/** 初始化变量 */
InitVars();
/** 初始化字体 */
if(!m_Font.InitFont())
MessageBox(NULL,"初始化字体失败!","错误",MB_OK);
return true;
}
/** 用户自定义的卸载函数 */
void CDemo::Uninit()
{
/** 用户自定义的卸载过程 */
if(m_pInput)
{
delete m_pInput;
m_pInput = NULL;
}
for(int i=0; i < 4; i++)
{
m_texture[i].FreeImage(); /**< 释放纹理图像占用的内存 */
glDeleteTextures(1, &m_texture[i].ID); /**< 删除纹理对象 */
}
/** 释放二次对象 */
if(cylinder_obj != NULL)
gluDeleteQuadric(cylinder_obj);
}
/** 程序更新函数 */
void CDemo::Update(DWORD milliseconds)
{
/** 用户自定义的更新过程 */
m_pInput->Update();
if(m_pInput->GetKeyboard()->KeyDown(DIK_ESCAPE))
{
TerminateApplication();
}
}
/** 计算帧速 */
void CDemo::CaculateFrameRate()
{
static float framesPerSecond = 0.0f; /**< 保存显示帧数 */
static float lastTime = 0.0f; /**< 记录上次时间 */
float currentTime = GetTickCount() * 0.001f; /**< 获得当前时间 */
++framesPerSecond; /**< 显示帧数递增1 */
/** 如果时间差大�