网络游戏课程设计
计算机游戏编程课程设计题目1
一、设计目的
a)掌握DirectX SDK的安装和设置方法。
b)了解DirectX系统架构,掌握使用Direct3D编写程序的步骤和原理。
c)学习使用Direct3D编写三角形渲染程序。
二、设计步骤
(1)DirectX是一种应用程序接口(API),它可以让Windows平台上的游戏或多媒体程序获得更高的执行效率。加强3D图形和声音效果,并提供给设计人员一个统一
的硬件驱动标准,让游戏开发者不必为不同品牌的硬件编写不同的驱动程序,
也降低了用户安装及设置硬件的复杂度。也就是说:只要游戏是依照和使用
DirectX来开发的,不管你使用的是什么显卡、声卡,都统统能玩。
(2)DirectX由很多API组成,按照性质分类,可以分为四大部分:显示部分、声音部分、输入部分和网络部分。显示部分进行图形处理,分为DirectDraw和
Direct3D,前者负责2D图形加速。后者主要负责3D效果的显示。声音部分中
最主要的API是DirectSound,除了播放声音和处理混音之外,还加强了3D音
效,并提供了录音功能。输入部分DirectInput可以支持多种游戏输入设备,除
了键盘和鼠标之外还可以连接手柄、游戏操纵杆和模拟器等,它可以充分发挥
这些设备的全部功能。网络部分DirectPlay主要是为了具有网络功能的游戏而开
发的,提供了多种连接方式,如TCP/IP、IPX、Modem、串口等,让玩家可以用
各种连网方式进行对战。
(3)DirectX的安装和设置步骤:
①、使用DirectX之前,必须先安装DirectX开发包,DirectX开发包可以从微软的
官方网站(https://www.360docs.net/doc/2b18552593.html,)免费下载,安装分两部分进行,安装运行时库和
安装SDK组件,直接运行DirectX安装程序就可以自动完成这两步。安装DirectX
之后,需要对编程环境中的头文件和库文件进行设置,设置步骤如下:
②、如果使用VC++6.0编程,则设置步骤如下:
A、启动VC++6.0,打开所要设置的项目,选择“Tools”→“Options”命令打开
Options对话框,如图1所示
B、在Options对话框中选择“Directories”,对话框状态如图2所示
C、在“Show directories for:”下拉列表中选择“Include files”,然后单击下面的
“文件夹图标”按钮,接着通过查找DirectX安装目录下的Include子目录
来设置头文件子目录,添加后的对话框如图3所示
D、在“Show directories for:”下拉列表中选择“Library files”再单击下面的“文
件夹图标”按钮,接着通过查找DirectX安装目录下的Lib文件夹设置库
文件目录,添加后的对话框如图4所示
E、选择“Project”菜单下的“Settings”命令打开“Project Settings”如图5所
示
F、选择“Link”选项卡,在“Object/Library modules”一栏最后插入d3d9.lib
d3dx9.lib,注意不要将原来的内容删除。插入后的对话框如图6所示
③、如果使用的编程环境是Visual Studio .NET 2003,设置步骤如下:
a、打开Visual Studio .NET界面,选择菜单命令“工具”→“选项”,打开“选
项”对话框,如图7所示
b、在左侧窗格中选择“项目”下的“VC++目录”,对话框状态如图8所示
c、在“显示以下内容的目录”下拉列表框中选择“包含文件”,然后单击下面
的文件夹图标,接着通过查找DirectX安装目录下的Include子目录添加头
文件目录,设置后的对话框如图9所示
d、在“显示以下内容的目录”下拉列表框中选择“库文件”,然后单击下面的
文件夹图标,接着通过查找DirectX安装目录下的Lib文件夹下的x86文
件夹,添加库文件目录,设置后的对话框如图10
e、这一步要设置支持DirectX运行的静态库,方法是:用Visual Studio .NET打
开程序项目(也可以新建一个程序项目),假设项目名称为pro1,选择菜单命
令“项目”→“pro1属性”打开“pro1属性页”对话框,如图11
f、在左侧窗格中选择“配置属性”→“链接器”→“输入”,对话框状态如图
12
g、在“附加依赖项”中添入d3dx9.lib d3d9.lib,单击“确定”按钮,设置结
束。
(4)以下介绍使用Direct3D API编写“三角形渲染”程序的步骤:
a、首先创建一个VC++ Win32空项目,并在主函数WinMain中创建一个窗口,
同时创建窗体消息的处理函数。
b、要在程序中使用DirectX3D API,应包含头文件d3d9.h和strsafe.h。格式为:#include
#pragmawarning(disable:4996)
#include
#pragmawarning(default:4996)
c、创建3个全局变量g_pD3D、g_pd3dDevice、g_pVB,它们的类型分别为
LPDIRECT3D9、LPDIRECT3DDEVICE9和LPDIRECT3DVERTEXBUFFER9。它们分
别是指向Direct3D对象的指针、指向D3DDevice(D3D设备)的指针和指向
顶点缓冲区的指针。
d、创建结构体类型CUSTOMVERTEX表示顶点,该结构体中包含4个float型
成员x、y、z、rhw,表示顶点的位置信息,一个DWORD类型的成员color,
表示顶点的颜色。
e、设计函数InitD3D来初始化D3D,该函数的签名为HRESULT InitD3D(HWND
hWnd),参数hWnd为窗体句柄。函数中先调用函数Direct3DCreate9创建D3D
对象,再调用函数CreateDevice创建D3D设备。函数代码如下:
HRESULT InitD3D(HWND hWnd)
{
if(NULL==(g_pD3D=Direct3DCreate9(D3D_SDK_VERSION)))
return E_FAIL;
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory(&d3dpp,sizeof(d3dpp));
d3dpp.Windowed=TRUE;
d3dpp.SwapEffect=D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat=D3DFMT_UNKNOWN;
if(FAILED(g_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
hWnd,D3DCREATE_SOFTWARE_VERTEXPROCESSING,&d3dpp,&g_pd3dDevice))) {
return E_FAIL;
}
return S_OK;
}
f、设计函数InitVB用来设置和锁定三角形顶点。函数代码如下:
HRESULT InitVB()
{
CUSTOMVERTEX vertices[]=
{
{350.0f,50.0f,0.5f,1.0f,0xffff0000,},
{450.0f,250.0f,0.5f,1.0f,0xff00ff00,},
{50.0f,250.0f,0.5f,1.0f,0xff00ffff,},
};
if(FAILED(g_pd3dDevice->CreateVertexBuffer(3*sizeof(CUSTOMVERTEX),0,D3DFVF
_CUSTOMVERTEX,D3DPOOL_DEFAULT,&g_pVB,NULL)))
{
return E_FAIL;
}
void* pVertices;
if(FAILED(g_pVB->Lock(0,sizeof(vertices),(void**)&pVertices,0)))
return E_FAIL;
memcpy(pVertices,vertices,sizeof(vertices));
g_pVB->Unlock();
return S_OK;
}
CreateVertexBuffer函数的参数D3DFVF_CUSTOMVERTEX为一个宏,可在函数前面进
行如下宏定义:
#define D3DFVF_CUSTOMVERTEX D3DFVF_XYZRHW|D3DFVF_DIFFUSE
g、设计函数Cleanup在程序结束时释放D3D对象和设备极其占用的内存。函
数代码如下:
void Cleanup()
{
if(g_pVB!=NULL)
g_pVB->Release();
if(g_pd3dDevice!=NULL)
g_pd3dDevice->Release();
if(g_pD3D!=NULL)
g_pD3D->Release();
}
h、设计函数Render来绘制和渲染场景。函数代码如下:
void Render()
{
g_pd3dDevice->Clear(0,NULL,D3DCLEAR_TARGET,D3DCOLOR_XRGB(255,0,255),1.0f,0);
if(SUCCEEDED(g_pd3dDevice->BeginScene()))
{
g_pd3dDevice->SetStreamSource(0,g_pVB,0,sizeof(CUSTOMVERTEX));
g_pd3dDevice->SetFVF(D3DFVF_CUSTOMVERTEX);
g_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLELIST,0,1);
g_pd3dDevice->EndScene();
}
g_pd3dDevice->Present(NULL,NULL,NULL,NULL);
}
i、编写完整的程序,得到运行结果。修改顶点坐标,观察结果的变化。
三、设计结果
四、设计总结
通过本次课设,我掌握了DirectX SDK的安装和设置方法,了解了它们旨在使基于Windows 的计算机成为运行和显示具有丰富多媒体元素(例如全色图形、视频、3D 动画和丰富音频)的应用程序的理想平台。初次使用,感觉很陌生,编写了一个渲染三角形的小程序,加深了我对Direct的理解。
计算机游戏编程课程设计题目2
一、设计目的
a)理解Direct3D实现几何变换的原理。
b)学习使用Direct3D API编写程序实现三角形旋转的几何变换。
c)学习使用Direct3D API编写程序实现对光照明和物体材质的模拟。
二、设计步骤
(5)一旦构造了物体极其模型,它们都位于自身坐标系之中。需要把它们都放到同一个世界坐标系中,这个过程称为世界变换。世界变换是通过对物体的平移、
旋转和缩放矩阵进行变换来实现的。在Direct3D中,通过调用函数
IDirect3DDevice::SetT ransform来设置和实现世界变换。函数原型如下:
HRESULT SetTransform(
D3DTRANSFORMSTATETYPE State,
CONST D3DMATRIX *pMatrix );
第一个参数是一个枚举类型,它在这里的取值应为D3DTS_WORLD;第二个参数是一个指针,指向要进行世界变换的变换矩阵。
如果要对三角形进行旋转,可以先通过D3DX库中的下列函数获得旋转变换矩阵:
D3DXMATIRX *D3DXMatrixRotationX(
D3DXMATRIX *pOut,
float Angle );
D3DXMATIRX *D3DXMatrixRotationY(
D3DXMATRIX *pOut,
float Angle );
D3DXMATIRX *D3DXMatrixRotationZ(
D3DXMATRIX *pOut,
float Angle );
D3DXMATIRX *D3DXMatrixRotationAxis(
D3DXMATRIX *pOut,
CONST D3DXVECTOR3 *pV,
float Angle );
前3个函数分别获得绕X轴、Y轴和Z轴旋转的旋转矩阵,参数Angle表示旋转的角度,参数pOut返回指向旋转矩阵的指针。第四个函数获得绕任意轴旋转的矩阵,参数pV是指向旋转轴向量的指针。
实现在世界坐标系中旋转的代码如下:
D3DXMATIRX matWorld;
D3DXMatrixRotationY(&matWorld, timeGetTime()%150.0f);
g_pd3Device->SetTransform(D3DTS_WORLD, &matWorld);
以上代码实现绕Y轴旋转,通过Windows API函数timeGetTime()返回的时间值对150。0取余来设置旋转的角度,实现了随时间不停地旋转。
(6)世界变换定义了物体在世界空间中的位置和取向,但是只有确定了视点(相机)的位置和取向,才能确定物体相对视点的位置坐标。一旦物体位于视点坐标系(相机坐标系)中,就可以知道物体和观察者之间的相对几何关系。形象地说,世界变换用来构建一个3D世界,而视点变换用来移动和旋转观察者的眼睛。
在D3DX中,视点变换也是由函数SetTransform来设置和实现的。此时第一个参数的值应为D3DTS_VIEW。那么如何获得作为其第二个参数的视点变换矩阵呢?为此,D3DX提供了两个函数D3DXMATRIXLookAtLH()和D3DXMATRIXLookAtRH(),函数原型如下:
D3DXMATIRX *D3DXMATRIXLookAtLH(
D3DXMATIRX *pOut,
CONST D3DXVECTOR3 *pEye,
CONST D3DXVECTOR3 *pAt,
CONST D3DXVECTOR3 *pUp );
参数pOut返回指向视点变换矩阵的指针,pEye是视点的位置,往pAt点看过去,pUp为视点位置向上的向量。此函数是按照左手定则来构造视点变换矩阵的。而D3DXMATRIXLookAtRH函数按右手定则构造视点变换矩阵。
下面一段代码构造一个位于(0,3,-5)点,往原点(0,0,0)看去,向上向量为(0,1,0)的
视点空间。
D3DXVECTOR3 vEyePt(0.0f, 3.0f, -5.0f);
D3DXVECTOR3 vLookatPt(0.0f, 0.0f, 0.0f);
D3DXVECTOR3 vUpVec(0.0f, 1.0f, 0.0f);
D3DXMATIRX16 matView;
D3DXMATRIXLookAtLH(&matView, &vEyePt, &vLookatPt, &vUpVec);
g_pd3Device->SetTransform(D3DTS_VIEW, &matView);
(7)视点变换设定相机的位置和方向,而投影变换设定相机的属性,如视野范围、近平面和远平面。这些属性创建了一个三棱锥的截头体,它定义了相机可观察
的空间范围。
投影变换使用的投影矩阵决定了在视域体中的顶点如何被映射到屏幕坐标系
中。D3DX库中包含了创建投影矩阵的10个不同的函数。其中5个创建基于左
手坐标系的投影矩阵,另外5个创建基于右手坐标系的投影矩阵。这里只介绍
程序中使用的创建基于左手坐标系投影矩阵的函数D3DXMatrixPerspectiveForLH。函
数原型如下:
D3DXMATIRX *D3DXMatrixPerspectiveForLH(
D3DXMATIRX *pOut;
float fovy;
float Aspect;
float zn;
float zf );
参数pOut返回指向投影变换矩阵的指针,fovy是表示视野的一个角度,Aspect
是视口的高宽比(一般为1),zn和zf分别是近平面和远平面的距离。
创建了投影矩阵之后,还要调用SetTransform函数设置和实现投影变换。此时
函数第一个参数的取值应为D3DTS_PROJECTION。
下面的一段代码定义了一个视野范围为90度,高宽比为1,近平面距离为1,
远平面距离为100的投影变换。
D3DXMATIRX matProj;
D3DXMatrixPerspectiveForLH(&matProj, D3DX_PI/4, 1.0f, 1.0f, 100.0f);
g_pd3Device->SetTransform(D3DTS_PROJECTION, &matProj);
(8)本次实验只能使用Visual Studio .NET来完成。设置步骤如下:
①、设置项目的包含文件目录和库文件目录,设置过程和实验1相同。
②、设置项目使用的静态库,步骤如下:
h、用Visual Studio .NET打开程序项目(也可以新建一个程序项目),假设项目名
称为pro2,选择菜单命令“项目”→“pro2属性”打开“pro2属性页”对
话框,如图1
i、在左侧窗格中选择“配置属性”→“链接器”→“输入”,在“附加依赖项”
中添入d3d9.lib d3dx9.lib winmm.lib,单击“确定”按钮,设置结束。如
图2
(9)以下介绍使用Direct3D API编写“几何变换”程序的步骤:
a、首先创建一个Win32项目,并在主函数WinMain中创建一个窗口,同时
创建窗体消息的处理函数。
b、程序中应包含以下头文件和预编译指令:
#include
#include
#include
#include
#pragmawarning(disable:4996)
#include
#pragmawarning(default:4996)
c、创建3个全局变量g_pD3D、g_pd3dDevice、g_pVB,它们的类型分别为
LPDIRECT3D9、LPDIRECT3DDEVICE9和LPDIRECT3DVERTEXBUFFER9。它们分
别是指向Direct3D对象的指针、指向D3DDevice(D3D设备)的指针和指向
顶点缓冲区的指针。
d、创建结构体类型CUSTOMVERTEX表示顶点:
struct CUSTOMVERTEX
{float x,y,z;
DWORD color;};
e、创建在InitVB中使用的宏D3DFVF_CUSTOMVERTEX:
#define D3DFVF_CUSTOMVERTEX D3DFVF_XYZ|D3DFVF_DIFFUSE
f、设计函数InitD3D来初始化D3D,该函数的签名为HRESULT InitD3D(HWND
hWnd),参数hWnd为窗体句柄。函数中先调用函数Direct3DCreate9创建D3D
对象,再调用函数CreateDevice创建D3D设备。函数代码如下:
HRESULT InitD3D(HWND hWnd)
{
if(NULL==(g_pD3D=Direct3DCreate9(D3D_SDK_VERSION)))
return E_FAIL;
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory(&d3dpp,sizeof(d3dpp));
d3dpp.Windowed=TRUE;
d3dpp.SwapEffect=D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat=D3DFMT_UNKNOWN;
if(FAILED(g_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
hWnd,D3DCREATE_SOFTWARE_VERTEXPROCESSING,&d3dpp,&g_pd3dDevice))) {
return E_FAIL;
}
g_pd3dDevice->SetRenderState(D3DRS_CULLMODE,D3DCULL_NONE);
g_pd3dDevice->SetRenderState(D3DRS_LIGHTING,FALSE);
return S_OK;
}
g、设计函数InitVB用来初始化三角形顶点并创建顶点缓冲。函数代码如下:
HRESULT InitVB()
{
CUSTOMVERTEX vertices[]=
{
{-2.0f,-1.0f,0.0f,0xffff0000,},
{1.0f,-1.0f,0.0f,0xff0000ff,},
{0.0f,1.0f,0.0f,0xffffffff,},
};if(FAILED(g_pd3dDevice->CreateVertexBuffer(3*sizeof(CUSTOMVERTEX),0,D3
DFVF_CUSTOMVERTEX,D3DPOOL_DEFAULT,&g_pVB,NULL)))
{
return E_FAIL;
}
void* pVertices;
if(FAILED(g_pVB->Lock(0,sizeof(vertices),(void**)&pVertices,0)))
return E_FAIL;
memcpy(pVertices,vertices,sizeof(vertices));
g_pVB->Unlock();
return S_OK;
}
h、设计函数Cleanup在程序结束时释放D3D对象和设备极其占用的内存。函
数代码如下:
void Cleanup()
{
if(g_pVB!=NULL)
g_pVB->Release();
if(g_pd3dDevice!=NULL)
g_pd3dDevice->Release();
if(g_pD3D!=NULL)
g_pD3D->Release();
}
i、设计函数Render来绘制和渲染场景。函数代码如下:
void Render()
{
g_pd3dDevice->Clear(0,NULL,D3DCLEAR_TARGET,D3DCOLOR_XRGB(0,0,0),1.0f,0);
if(SUCCEEDED(g_pd3dDevice->BeginScene()))
{
D3DXMATRIXA16 matWorld;
UINT iTime=timeGetTime()%1000;
float fAngle=iTime*(2.0f*D3DX_PI)/1000.0f;
D3DXMatrixRotationY(&matWorld,fAngle);
g_pd3dDevice->SetTransform(D3DTS_WORLD,&matWorld);
D3DXVECTOR3 vEyePt(0.0f,3.0f,-5.0f);
D3DXVECTOR3 vLookatPt(0.0f,0.0f,0.0f);
D3DXVECTOR3 vUpVec(0.0f,1.0f,0.0f);
D3DXMATRIXA16 matView;
D3DXMatrixLookAtLH(&matView,&vEyePt,&vLookatPt,&vUpVec);
g_pd3dDevice->SetTransform(D3DTS_VIEW,&matView);
D3DXMATRIXA16 matProj;
D3DXMatrixPerspectiveFovLH(&matProj,D3DX_PI/4,1.0f,1.0f,100.0f);
g_pd3dDevice->SetTransform(D3DTS_PROJECTION,&matProj);
g_pd3dDevice->SetStreamSource(0,g_pVB,0,sizeof(CUSTOMVERTEX));//指明
将渲染的顶点缓冲区
g_pd3dDevice->SetFVF(D3DFVF_CUSTOMVERTEX);//将设置的顶点格式告知D3D
g_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLELIST,0,1);//绘制并渲染
g_pd3dDevice->EndScene();
}
g_pd3dDevice->Present(NULL,NULL,NULL,NULL);
}
j、编写完整的程序,得到运行结果。
(10)以下几步介绍Direct3D的光照明计算和材质模拟的方法。
(11)Direct3D中使用结构体类型D3DCOLORVALUE来表示颜色。结构体类型D3DCOLORVALUE的定义如下:
typedefstruct D3DCOLORVALUE{
float r; //红色部分光的亮度
float g; //绿色部分光的亮度
float b; //蓝色部分光的亮度
float a; //表示透明度的Alpha值。
}D3DCOLORVALUE, *LPD3DCOLORVALUE;
(12)Direct3D采用简单光照模型。用结构体类型D3DLIGHT9来描述光源属性,结构体D3DLIGHT9的定义如下:
typedefstruct D3DLIGHT9{
D3DLIGHTTYPE Type;
D3DCOLORVALUE Diffuse;
D3DCOLORVALUE Specular;
D3DCOLORVALUE Ambient;
D3DVECTOR Position;
D3DVECTOR Direction;
float Range;
float Falloff;
float Attenuation0;
float Attenuation1;
float Attenuation2;
float Theta;
float Phi;
} D3DLIGHT9, *LPD3DLIGHT;
其中:
Type:定义光源类型,能使用以下三种类型之一:D3DLIGHT_POINT(点光源)、
D3DLIGHT_SPOT、D3DLIGHT_DIRECTIONAL;
Diffuse:此光源发出的漫射光颜色。
Specular:此光源发出的镜面光颜色。
Ambient:此光源发出的环境光颜色。
Position:光源在世界坐标系中的位置。
Direction:光源在世界坐标系中的照射方向。此值对点光源无意义。
Range:光线能够传播的最大范围。对于方向光源无意义。
Attenuation0、Attenuation1、Attenuation2:这三个衰减变量定义光线随传播距
离的衰减。
其他几个属性只用在聚光灯类型的光源上,在此不做介绍。
(13)用D3DLIGHT9结构体定义了一个光源后,还必须调用IDirect3DDevice9类的SetLight函数设置该光源,表示渲染管道将加入该光源。函数原型如下:
HRESULT SetLight(DWORD Index, CONST D3DLIGHT9 *pLight);
Direct3D最多可以设置8个光源,参数Index的取值范围是0~7,表示8个光源
中的一个;参数pLight是指向光源结构体类型的指针。
(14)使用SetLight函数设置了光源之后,默认的情况下,所有光源都不起作用,要使某个光源起作用,必须使用IDirect3DDevice9类的LightEnable函数启用它。
函数原型如下:
HRESULT LightEnable(DWORD LightIndex, BOOL bEnable);
参数LightIndex表示要启用的光源号,取值范围是0~7;参数bEnable的值为true
时,表示启用该光源,其值为false时,表示关闭该光源。
(15)Direct3D中使用结构体类型D3DMATERIAL9来描述物体表面的材质属性。
D3DMATERIAL9类型定义如下:
typedefstruct D3DMATERIAL9{
D3DCOLORVALUE Diffuse;
D3DCOLORVALUE Ambient;
D3DCOLORVALUE Specular;
D3DCOLORVALUE Emissive;
float Power;
}D3DMATERIAL9, *LPD3DMATERIAL9;
其中前面4个D3DCOLORVALUE型变量分别定义了材质的漫反射、环境光反射、
镜面反射和自发光的颜色属性,值越大表示材质反射这种光的能力越强。Power
定义了物体表面的镜面反射高光属性,这个值越大,镜面高光越锐利。
(16)以下介绍使用Direct3D API编写“光照和材质模拟”程序的步骤:
a、首先创建一个Win32项目,并在主函数WinMain中创建一个窗口,同时
创建窗体消息的处理函数。
b、程序中应包含以下头文件和预编译指令:
#include
#include
#include
#pragmawarning(disable:4996)
#include
#pragmawarning(default:4996)
c、创建3个全局变量g_pD3D、g_pd3dDevice、g_pVB,它们的类型分别为
LPDIRECT3D9、LPDIRECT3DDEVICE9和LPDIRECT3DVERTEXBUFFER9。它们分
别是指向Direct3D对象的指针、指向D3DDevice(D3D设备)的指针和指向
顶点缓冲区的指针。
d、创建结构体类型CUSTOMVERTEX表示顶点:
struct CUSTOMVERTEX
{
D3DXVECTOR3 position;
D3DXVECTOR3 normal;
};
其中position表示顶点的位置,normal是顶点的法向量。
e、创建程序中使用的宏D3DFVF_CUSTOMVERTEX表示顶点结构的格式:
#define D3DFVF_CUSTOMVERTEX D3DFVF_XYZ|D3DFVF_NORMAL
f、设计函数InitD3D创建D3D对象、创建D3D设备,并进行必要的设置,函
数代码如下:
HRESULT InitD3D(HWND hWnd)
{
if(NULL==(g_pD3D=Direct3DCreate9(D3D_SDK_VERSION)))
return E_FAIL;
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory(&d3dpp,sizeof(d3dpp));
d3dpp.Windowed=TRUE;
d3dpp.SwapEffect=D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat=D3DFMT_UNKNOWN;
d3dpp.EnableAutoDepthStencil=TRUE;
d3dpp.AutoDepthStencilFormat=D3DFMT_D16;
if(FAILED(g_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
hWnd,D3DCREATE_SOFTWARE_VERTEXPROCESSING,&d3dpp,&g_pd3dDevice))) {
return E_FAIL;
}
g_pd3dDevice->SetRenderState(D3DRS_CULLMODE,D3DCULL_NONE);
g_pd3dDevice->SetRenderState(D3DRS_ZENABLE,TRUE);
return S_OK;
}
g、编写函数InitGeometry创建空心圆柱体的顶点缓冲区,并设置顶点信息。
函数代码如下:
HRESULT InitGeometry()
{
if(FAILED(g_pd3dDevice->CreateVertexBuffer(50*2*sizeof(CUSTOMVERTEX),0,D3
DFVF_CUSTOMVERTEX,D3DPOOL_DEFAULT,&g_pVB,NULL)))
{
return E_FAIL;
}
CUSTOMVERTEX *pVertices;
if(FAILED(g_pVB->Lock(0,0,(void**)&pVertices,0)))
return E_FAIL;
for(DWORD i=0;i<50;i++)
{
float theta=(2*D3DX_PI*i)/(50-1);
pVertices[2*i+0].position=D3DXVECTOR3(sinf(theta),-1.0f,cosf(theta));
pVertices[2*i+0].normal=D3DXVECTOR3(sinf(theta),0.0f,cosf(theta));
pVertices[2*i+1].position=D3DXVECTOR3(sinf(theta),1.0f,cosf(theta));
pVertices[2*i+1].normal=D3DXVECTOR3(sinf(theta),0.0f,cosf(theta));
}
g_pVB->Unlock();
return S_OK;
}
h、设计函数Cleanup在程序结束时释放D3D对象和设备极其占用的内存。函
数代码如下:
void Cleanup()
{
if(g_pVB!=NULL)
g_pVB->Release();
if(g_pd3dDevice!=NULL)
g_pd3dDevice->Release();
if(g_pD3D!=NULL)
g_pD3D->Release();
}
i、设计函数SetupMatrices来设置世界变换矩阵、相机变换矩阵和投影变换矩
阵。其中世界变换矩阵设置为随时间绕X轴的旋转矩阵。函数代码如下:void SetupMatrices()
{
D3DXMATRIXA16 matWorld;
D3DXMatrixIdentity(&matWorld);
D3DXMatrixRotationX(&matWorld,timeGetTime()/500.0f);
g_pd3dDevice->SetTransform(D3DTS_WORLD,&matWorld);
D3DXVECTOR3 vEyePt(0.0f,3.0f,-5.0f);
D3DXVECTOR3 vLookatPt(0.0f,0.0f,0.0f);
D3DXVECTOR3 vUpVec(0.0f,1.0f,0.0f);
D3DXMATRIXA16 matView;
D3DXMatrixLookAtLH(&matView,&vEyePt,&vLookatPt,&vUpVec);
g_pd3dDevice->SetTransform(D3DTS_VIEW,&matView);
D3DXMATRIXA16 matProj;
D3DXMatrixPerspectiveFovLH(&matProj,D3DX_PI/4,1.0f,1.0f,100.0f);
g_pd3dDevice->SetTransform(D3DTS_PROJECTION,&matProj);
}
j、编写函数SetupLights设置物体材质和光源属性。函数代码如下:
void SetupLights()
{
D3DMATERIAL9 mtrl;
ZeroMemory(&mtrl,sizeof(D3DMATERIAL9));
mtrl.Diffuse.r=mtrl.Ambient.r=1.0f;
mtrl.Diffuse.g=mtrl.Ambient.g=1.0f;
mtrl.Diffuse.b=mtrl.Ambient.b=0.0f;
mtrl.Diffuse.a=mtrl.Ambient.a=1.0f;
g_pd3dDevice->SetMaterial(&mtrl);
D3DXVECTOR3 vecDir;
D3DLIGHT9 light;
ZeroMemory(&light,sizeof(D3DLIGHT9));
light.Type=D3DLIGHT_DIRECTIONAL;
light.Diffuse.r=1.0f;
light.Diffuse.g=1.0f;
light.Diffuse.b=1.0f;
vecDir=D3DXVECTOR3(cosf(timeGetTime()/350.0f),1.0f,sinf(timeGetTime()/350.0f));
D3DXVec3Normalize((D3DXVECTOR3*)&light.Direction,&vecDir);
light.Range=1000.0f;
g_pd3dDevice->SetLight(0,&light);
g_pd3dDevice->LightEnable(0,TRUE);
g_pd3dDevice->SetRenderState(D3DRS_LIGHTING,TRUE);
g_pd3dDevice->SetRenderState(D3DRS_AMBIENT,0x00202020);
}
k、编写函数Render按前面已设置的各种变换矩阵和光照材质模型绘制并渲染场景物体。函数代码如下:
void Render()
{
g_pd3dDevice->Clear(0,NULL,D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,D3DCOLOR_XRGB(0,0,255),1.0f,0); if(SUCCEEDED(g_pd3dDevice->BeginScene()))
{
SetupLights(); //设置光照和材质
SetupMatrices(); //设置各种变换矩阵
g_pd3dDevice->SetStreamSource(0,g_pVB,0,sizeof(CUSTOMVERTEX));//指明将渲染的顶点缓冲区
g_pd3dDevice->SetFVF(D3DFVF_CUSTOMVERTEX);//将设置的顶点格式告知D3D
g_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP,0,2*50-2);//绘制并渲染
g_pd3dDevice->EndScene();
}
g_pd3dDevice->Present(NULL,NULL,NULL,NULL);
}
(17)按第(4)步设置程序项目的属性。运行程序,输出结果。
三、设计结果
四、设计总结
第一次设计是使我们掌握DirectX的原理,结构以及使用方法的,本次课设则更进一步,使我掌握了Direct3D实现几何变换的原理,了解到DirectX并不是一个单纯的图形API,它是由微软公司开发的用途广泛的API,它包含有Direct Graphics(Direct 3D+Direct Draw)、Direct Input、Direct Play、Direct Sound、Direct Show、Direct Setup、Direct Media Objects等多个组件,它提供了一整套的多媒体接口方案。学会了使用Direct3D API编写程序实现三角形旋转的几何变换,以及实现对光照明和物体材质的模拟。