资源描述
天津理工大学实验报告
学院(系)名称:计算机与通信工程学院
姓名
学号
专业
计算机科学与技术
班级
实验项目
课程名称
计算机图形学
课程代码
实验时间
实验地点
计算机软件实验室
批改意见
成绩
教师签字:
实验目的:
1. 采用glut创建图形窗口和实现人机交互功能。
2. 情节合理,交互操作简便灵活,动作过程平滑、真实。
实验内容:
1、 设计一主题场景
2、 场景中包括地形、天空和人物造型。
3、 至少实现人物沿着地形行走的动作。
4、 实现行走运动过程中的碰撞检测(可选做)。
5、 实现交互式场景的浏览。
实验过程记录
虚拟校园漫游设计流程:
实景照片
Milkshape 3d
.3d
纹理材质
场景数据
.ms3d
OpenGL开发工具
漫游功能
在VS2008中制作虚拟校园漫游系统
模块设计
公共基础模块:
提供场景视角变换,基本数学算法。
提供读入INI文件接口。
场景设计模块
设计场景模型、地形布局。
设计地形,计算地形高度。
文件、资源管理模块:
向上提供模型、图片、纹理载入接口。
输入系统模块:
管理输入设备,提供交互系统接口。
对象管理模块:
管理静态动态实体,渲染图形。
控制动态实体动作。设计相关操作。
设计碰撞检测,漫游算法。
主要类的属性和方法的功能说明
class Ccamera 摄像机类
static CCamera *m_pCamera;
float dist_to_role; 到英雄的矩离
vector3d position; 摄像机的位置
vector3d role_pos; 英雄的位置
float direction; 旋转角度
float pitch; 倾斜
int va;视角模式
int vm; 旋转模式
void FrameMove(void); 根据当前摄像机的位置角度变换矩阵
void Update(void); 更新摄像的参数,把它放到主循环中
class CTerrain地形类
unsigned int m_nWidth; 地形大小为m_iWidth*m_iWidth
short* heightMap; 动态高程映射 定义地形高度、为m_iWidth*m_iWidth矩阵
unsigned int m_nCellWidth; 每个格子的宽度
CTexture terrainTex; 地形上的多重纹理
void Render(void);插值计算地形高度并渲染
BOOL Init(int _width,char* TexFile);初始化高程映射和多重纹理
class CKeyboard键盘类
BOOL KeyDown(int key); key键是否按下
BOOL Update();更新键盘数据,放在主循环中
class CMouse鼠标类
BOOL ButtonDown(int button) 鼠标某键是否按下,0-左键,1-右键;/
void GetMovement(int &dx, int &dy); 获得光标坐标变化
SPoint2 GetMousePos();获得光标位置
void setmousepos(int dx, int dy) 设置光标位置
int GetWheelState();获得鼠标滚轮状态
BOOL Update();更新鼠标参数
struct SActiveObjPro动态实体的信息结构
void ChangeCurrFrame();改变当前帧
Update() 更新实体的信息结构
class Object游戏实体类的基类
float r1,r2;包围盒的半径,分别是x,y上的分量
class CActiveObj:public Object游戏中的活动实体
BOOL IsArrive(void);是否到达目的地
void SetActive(BOOL _active) 设定人物动作
class CRole:public CActiveObj游戏中的人物
virtual void EndRender(void);渲染后操作
virtual void OnRender(void)渲染人物
说明类的继承关系
功能函数的流程图
这里主要列举了几个功能的流程图:
1.声音播放函数:
Play(DWORD loop)
{
if( bEnable==FALSE || !DSSoundFX )
return;
DWORD *Status1=NULL;
if( (DSSoundFX->GetStatus(Status1))!=DS_OK )
goto _next;
if( (*Status1 & DSBSTATUS_PLAYING) == DSBSTATUS_PLAYING )
return;
_next:
DSSoundFX->SetCurrentPosition(0);
if( loop==-1 )
loop=DSBPLAY_LOOPING; //循环播放
DSSoundFX->Play(0,0,loop);
}
声音播放功能函数的流程图:
2.用鼠标实现输入功能的函数:
Update(){
if (FAILED(m_pDIDev->GetDeviceState(sizeof(DIMOUSESTATE), &m_state)))
{
if (FAILED(m_pDIDev->Acquire()))
{
return FALSE;
}
if (FAILED(m_pDIDev->GetDeviceState(sizeof(DIMOUSESTATE), &m_state)))
{
return FALSE;
}
}
m_sMousePos.x+=m_state.lX;
m_sMousePos.y-=m_state.lY;
if(m_sMousePos.x<0)m_sMousePos.x=0;
if(m_sMousePos.x>m_iWidth)m_sMousePos.x=m_iWidth;
if(m_sMousePos.y<0)m_sMousePos.y=0;
if(m_sMousePos.y>m_iHeight)m_sMousePos.y=m_iHeight;
return TRUE;
}
用鼠标实现输入功能的流程图:
3. 3d图片文件的显示功能的函数:
Render()
{
glEnable(GL_TEXTURE_2D);
glColor3f(1.f,1.f,1.f);
int triangleIndex;
int index;
for (unsigned short i = 0; i < m_numMeshes; ++i )
{
m_pTexture[m_pMeshes[i].m_textureIndex].Bind(0);
glBegin( GL_TRIANGLES );
for (unsigned short j = 0; j < m_pMeshes[i].m_numTriangles; ++j )
{
triangleIndex = m_pMeshes[i].m_pTriangleIndices[j];
for (unsigned int k = 0; k < 3; ++k )
{
index = m_pTriangles[triangleIndex].m_vertexIndices[k];
glNormal3fv( m_pTriangles[triangleIndex].m_normal );
glTexCoord2f( m_pTriangles[triangleIndex].m_u[k], m_pTriangles[triangleIndex].m_v[k] );
glVertex3fv( m_pVertices[index].m_location );
}
}
glEnd();
}
glDisable(GL_TEXTURE_2D);
}
3d图片文件的显示功能的流程图:
4.游戏场景天空的场景显示函数:
Render()
{
CCamera::GetCameraPointer()->GetCameraPos(&m_sCameraPos);
texture.Bind(0);
glDisable(GL_DEPTH_TEST);
glEnable(GL_TEXTURE_2D);
glPushMatrix();
glTranslatef(m_sCameraPos.x,-40,m_sCameraPos.z-CCamera::GetCameraPointer()->GetDestToRole());
glRotatef(yrot,0.f,1.f,0.f);
glColor3f(1.f,1.f,1.f);
glBegin(GL_TRIANGLE_FAN);
glTexCoord2f(0.5,0.5);
glVertex3f(0,300,0);
glTexCoord2f(0,0);
glVertex3f(-300,0, 300);
glTexCoord2f(1,0);
glVertex3f(-300,0,-300);
glTexCoord2f(1,1);
glVertex3f( 300,0,-300);
glTexCoord2f(0,1);
glVertex3f( 300,0, 300);
glTexCoord2f(0,0);
glVertex3f(-300,0, 300);
glEnd();
glPopMatrix();
glDisable(GL_TEXTURE_2D);
glEnable(GL_DEPTH_TEST);
yrot += 0.04f;
if(yrot > 360.0f)yrot -= 360.0f;
}
游戏场景天空的场景显示的流程图:
5. 消息处理功能函数:
Run()
{
if(GetMsgNum()<=0)return;
switch(m_dQueue[0].msg)
{
case MSG_PLAY_MUSIC:
if(CMusic::GetSysMusic()->IsPlay())CMusic::GetSysMusic()->Stop();
CMusic::GetSysMusic()->LoadMusic(m_dQueue[0].str1);
CMusic::GetSysMusic()->Play();
Delete();
break;
case MSG_STOP_MUSIC:
if(CMusic::GetSysMusic()->IsPlay())CMusic::GetSysMusic()->Stop();
Delete();
break;
case MSG_PAUSE_MUSIC:
if(CMusic::GetSysMusic()->IsPlay())CMusic::GetSysMusic()->Pause();
Delete();
break;
case MSG_RESUME_MUSIC:
if(!CMusic::GetSysMusic()->IsPlay())CMusic::GetSysMusic()->Resume();
Delete();
break;
case MSG_FADE:
GUIMgr::GetSysGUIMgr()->BeginFade();
Delete();
break;
case MSG_PLAYAVI:
SceneMgr::GetSysSceneMgr()->SetScene(SCE_AVI);
SceneMgr::GetSysSceneMgr()->LoadIni(m_dQueue[0].str1,m_dQueue[0].str2);
Delete();
break;
case MSG_TITLE:
SceneMgr::GetSysSceneMgr()->SetScene(SCE_TITLE);
SceneMgr::GetSysSceneMgr()->LoadIni(m_dQueue[0].str1,m_dQueue[0].str2);
Delete();
break;
case MSG_SELCHAR:
SceneMgr::GetSysSceneMgr()->SetScene(SCE_SELCHAR);
SceneMgr::GetSysSceneMgr()->LoadIni(m_dQueue[0].str1,m_dQueue[0].str2);
Delete();
break;
case MSG_OPENAIR:
SceneMgr::GetSysSceneMgr()->SetScene(SCE_OPENAIR);
SceneMgr::GetSysSceneMgr()->LoadIni(m_dQueue[0].str1,m_dQueue[0].str2);
Delete();
break;
case MSG_EXIT:
PostQuitMessage(0);
Delete();
break;
}
消息处理功能的流程图:
第10页 共10页
展开阅读全文