#include
<
d3dx9.h
>
#pragma
comment(lib,"d3d9.lib")
#pragma
comment(lib,"d3dx9.lib")
#pragma
comment(lib,"winmm.lib")
D3DXVECTOR3CubeLookAt[]
=
{
D3DXVECTOR3(
0.0f
,
-
30.0f
,
-
30.0f
),
D3DXVECTOR3(
0.0f
,
0.0f
,
0.0f
),
D3DXVECTOR3(
0.0f
,
1.0f
,
0.0f
)
};
LPDIRECT3D9g_pD3D
=
NULL;
//
Direct3D对象
LPDIRECT3DDEVICE9g_pD3DDevice
=
NULL;
//
Direct3D设备对象
LPDIRECT3DVERTEXBUFFER9g_pVertexBuffer
=
NULL;
//
Buffertoholdvertices
PDIRECT3DTEXTURE9g_pTexture
=
NULL;
//
纹理指针
LPD3DXMESHg_pMesh
=
NULL;
//
网格模型对象
D3DMATERIAL9
*
g_pMeshMaterials
=
NULL;
//
网格模型材质
LPDIRECT3DTEXTURE9
*
g_pMeshTextures
=
NULL;
//
网格模型纹理
DWORDg_dwNumMaterials
=
0L
;
//
网格模型材质数量
struct
CUSTOMVERTEX
//
自定义的顶点格式
{
FLOATx,y,z;
//
顶点坐标
DWORDcolor;
//
顶点颜色
FLOATtu,tv;
//
纹理坐标
};
//
FlexibleVertexFormat(FVF)灵活顶点格式
#define
D3DFVF_CUSTOMVERTEX(D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1)
//
释放对象
#define
SafeRelease(pObject)if(pObject!=NULL){pObject->Release();pObject=NULL;}
//
释放对象数组
#define
SafeDelete(pObjectArray)if(pObjectArray!=NULL){delete[]pObjectArray;}
//
键盘控制
#define
KeyDown(vk_code)((GetAsyncKeyState(vk_code)&0x8000)?1:0)
#define
KeyUp(vk_code)((GetAsyncKeyState(vk_code)&0x8000)?0:1)
/*
*************************************************************
*Desc:初始化Direct3D
*************************************************************
*/
HRESULTInitialiseD3D(HWNDhWnd)
{
//
Firstofall,createthemainD3Dobject.Ifitiscreatedsuccessfullywe
//
shouldgetapointertoanIDirect3D8interface.
g_pD3D
=
Direct3DCreate9(D3D_SDK_VERSION);
if
(g_pD3D
==
NULL)
{
return
E_FAIL;
}
//
Getthecurrentdisplaymode
/*
D3DDISPLAYMODEd3ddm;
if(FAILED(g_pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT,&d3ddm)))
{
returnE_FAIL;
}
*/
//
Createastructuretoholdthesettingsforourdevice
D3DPRESENT_PARAMETERSd3dpp;
ZeroMemory(
&
d3dpp,
sizeof
(d3dpp));
//
Fillthestructure.
//
Wewantourprogramtobewindowed,andsetthebackbuffertoaformat
//
thatmatchesourcurrentdisplaymode
d3dpp.Windowed
=
TRUE;
d3dpp.SwapEffect
=
D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat
=
D3DFMT_UNKNOWN;
//
深度缓冲
d3dpp.AutoDepthStencilFormat
=
D3DFMT_D16;
d3dpp.EnableAutoDepthStencil
=
TRUE;
//
CreateaDirect3Ddevice.
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_CCW);
//
去除灯光
//
g_pD3DDevice->SetRenderState(D3DRS_LIGHTING,FALSE);
//
激活深度缓冲
//
g_pD3DDevice->SetRenderState(D3DRS_ZENABLE,D3DZB_TRUE);
//
设置环境灯光
g_pD3DDevice
->
SetRenderState(D3DRS_AMBIENT,
0xFFFFFFFF
);
return
S_OK;
}
/*
*************************************************************
*Desc:初始化顶点缓冲(立方体)
*************************************************************
*/
HRESULTInitVertexBuffer()
{
VOID
*
pVertices;
//
Storeeachpointofthecubetogetherwithit'scolour
//
Makesurethatthepointsofapolygonarespecifiedinaclockwisedirection,
//
thisisbecauseanti-clockwisefaceswillbeculled
//
Wewilluseathreetrianglestripstorenderthesepolygons
//
(Top,Sides,Bottom).
CUSTOMVERTEXcvVertices[]
=
{
//
TopFace
{
-
5.0f
,
5.0f
,
-
5.0f
,D3DCOLOR_XRGB(
0
,
0
,
255
),
0.0f
,
1.0f
},
//
Vertex0-Blue
{
-
5.0f
,
5.0f
,
5.0f
,D3DCOLOR_XRGB(
255
,
0
,
0
),
0.0f
,
0.0f
},
//
Vertex1-Red
{
5.0f
,
5.0f
,
-
5.0f
,D3DCOLOR_XRGB(
255
,
0
,
0
),
1.0f
,
1.0f
},
//
Vertex2-Red
{
5.0f
,
5.0f
,
5.0f
,D3DCOLOR_XRGB(
0
,
255
,
0
),
1.0f
,
0.0f
},
//
Vertex3-Green
//
Face1
{
-
5.0f
,
-
5.0f
,
-
5.0f
,D3DCOLOR_XRGB(
255
,
0
,
0
),
0.0f
,
1.0f
},
//
Vertex4-Red
{
-
5.0f
,
5.0f
,
-
5.0f
,D3DCOLOR_XRGB(
0
,
0
,
255
),
0.0f
,
0.0f
},
//
Vertex5-Blue
{
5.0f
,
-
5.0f
,
-
5.0f
,D3DCOLOR_XRGB(
0
,
255
,
0
),
1.0f
,
1.0f
},
//
Vertex6-Green
{
5.0f
,
5.0f
,
-
5.0f
,D3DCOLOR_XRGB(
255
,
0
,
0
),
1.0f
,
0.0f
},
//
Vertex7-Red
//
Face2
{
5.0f
,
-
5.0f
,
5.0f
,D3DCOLOR_XRGB(
0
,
0
,
255
),
0.0f
,
1.0f
},
//
Vertex8-Blue
{
5.0f
,
5.0f
,
5.0f
,D3DCOLOR_XRGB(
0
,
255
,
0
),
0.0f
,
0.0f
},
//
Vertex9-Green
//
Face3
{
-
5.0f
,
-
5.0f
,
5.0f
,D3DCOLOR_XRGB(
0
,
255
,
0
),
1.0f
,
1.0f
},
//
Vertex10-Green
{
-
5.0f
,
5.0f
,
5.0f
,D3DCOLOR_XRGB(
255
,
0
,
0
),
1.0f
,
0.0f
},
//
Vertex11-Red
//
Face4
{
-
5.0f
,
-
5.0f
,
-
5.0f
,D3DCOLOR_XRGB(
255
,
0
,
0
),
0.0f
,
1.0f
},
//
Vertex12-Red
{
-
5.0f
,
5.0f
,
-
5.0f
,D3DCOLOR_XRGB(
0
,
0
,
255
),
0.0f
,
0.0f
},
//
Vertex13-Blue
//
BottomFace
{
5.0f
,
-
5.0f
,
-
5.0f
,D3DCOLOR_XRGB(
0
,
255
,
0
),
0.0f
,
1.0f
},
//
Vertex14-Green
{
5.0f
,
-
5.0f
,
5.0f
,D3DCOLOR_XRGB(
0
,
0
,
255
),
0.0f
,
0.0f
},
//
Vertex15-Blue
{
-
5.0f
,
-
5.0f
,
-
5.0f
,D3DCOLOR_XRGB(
255
,
0
,
0
),
1.0f
,
1.0f
},
//
Vertex16-Red
{
-
5.0f
,
-
5.0f
,
5.0f
,D3DCOLOR_XRGB(
0
,
255
,
0
),
1.0f
,
0.0f
},
//
Vertex17-Green
};
//
Createthetexturefromfile
if
(FAILED(D3DXCreateTextureFromFile(g_pD3DDevice,
"
1.bmp
"
,
&
g_pTexture)))
{
return
E_FAIL;
}
//
Createthevertexbufferfromourdevice.
if
(FAILED(g_pD3DDevice
->
CreateVertexBuffer(
18
*
sizeof
(CUSTOMVERTEX),
0
,D3DFVF_CUSTOMVERTEX,
D3DPOOL_DEFAULT,
&
g_pVertexBuffer,NULL)))
{
return
E_FAIL;
}
//
Getapointertothevertexbufferverticesandlockthevertexbuffer
if
(FAILED(g_pVertexBuffer
->
Lock(
0
,
sizeof
(cvVertices),(
void
**
)
&
pVertices,
0
)))
{
return
E_FAIL;
}
//
Copyourstoredverticesvaluesintothevertexbuffer
memcpy(pVertices,cvVertices,
sizeof
(cvVertices));
//
Unlockthevertexbuffer
g_pVertexBuffer
->
Unlock();
return
S_OK;
}
/*
*************************************************************
*Desc:响应键盘事件
*************************************************************
*/
VOIDProcInput()
{
if
(KeyDown(VK_DOWN))
{
CubeLookAt[
0
].z
-=
0.2f
;
CubeLookAt[
1
].z
-=
0.2f
;
}
if
(KeyDown(VK_UP))
{
CubeLookAt[
0
].z
+=
0.2f
;
CubeLookAt[
1
].z
+=
0.2f
;
}
if
(KeyDown(VK_RIGHT))
{
CubeLookAt[
1
].x
+=
0.2f
;
}
if
(KeyDown(VK_LEFT))
{
CubeLookAt[
1
].x
-=
0.2f
;
}
}
/*
*************************************************************
*Desc:初始化网格模型
*************************************************************
*/
HRESULTInitMesh()
{
LPD3DXBUFFERpMaterialsBuffer;
//
从磁盘文件加载网格模型
if
(FAILED(D3DXLoadMeshFromX(
"
SKULL.x
"
,D3DXMESH_MANAGED,g_pD3DDevice,NULL,
&
pMaterialsBuffer,NULL,
&
g_dwNumMaterials,
&
g_pMesh)))
{
MessageBox(NULL,
"
Couldnotfindcorrespondingmeshfile
"
,
"
Mesh
"
,MB_OK);
return
E_FAIL;
}
//
从网格模型中提取材质属性和纹理文件名
D3DXMATERIAL
*
matMaterials
=
(D3DXMATERIAL
*
)pMaterialsBuffer
->
GetBufferPointer();
//
Createtwoarrays.Onetoholdthematerialsandothertoholdthetextures
g_pMeshMaterials
=
new
D3DMATERIAL9[g_dwNumMaterials];
g_pMeshTextures
=
new
LPDIRECT3DTEXTURE9[g_dwNumMaterials];
//
逐块提取网格模型材质属性和纹理文件名
for
(DWORDi
=
0
;i
<
g_dwNumMaterials;i
++
)
{
//
材料属性
g_pMeshMaterials[i]
=
matMaterials[i].MatD3D;
//
设置模型材料的环境光反射系数,因为模型材料本身没有设置
g_pMeshMaterials[i].Ambient
=
g_pMeshMaterials[i].Diffuse;
//
创建纹理
if
(FAILED(D3DXCreateTextureFromFile(g_pD3DDevice,
matMaterials[i].pTextureFilename,
&
g_pMeshTextures[i])))
{
g_pMeshTextures[i]
=
NULL;
}
}
//
We'vefinishedwiththematerialbuffer,soreleaseit
SafeRelease(pMaterialsBuffer);
return
S_OK;
}
/*
*************************************************************
*Desc:渲染立方体
*************************************************************
*/
void
RenderCube()
{
ProcInput();
/*
***************************
*Desc:创建并设置世界矩阵*
***************************
*/
D3DXMATRIXmatWorld,matWorldX,matWorldY,matWorldZ;
//
Createthetransformationmatrices
D3DXMatrixRotationX(
&
matWorldX,timeGetTime()
/
400.0f
);
D3DXMatrixRotationY(
&
matWorldY,timeGetTime()
/
400.0f
);
D3DXMatrixRotationZ(
&
matWorldZ,timeGetTime()
/
400.0f
);
/*
我们调用了D3DXMatrixRotationX、D3DXMatrixRotationY和D3DXMatrixRotationZ
函数产生了3个矩阵而且分别将它们保存在了3个D3DXMATRIX结构中
然后我们将它们相乘后形成了世界矩阵
*/
D3DXMatrixMultiply(
&
matWorld,
&
matWorldX,
&
matWorldY);
D3DXMatrixMultiply(
&
matWorld,
&
matWorld,
&
matWorldZ);
//
我们又调用了SetTransform函数为我们的顶点应用了此变换
g_pD3DDevice
->
SetTransform(D3DTS_WORLD,
&
matWorld);
/*
***************************
*Desc:创建并设置观察矩阵*
***************************
*/
D3DXMATRIXmatView;
D3DXMatrixLookAtLH(
&
matView,
&
CubeLookAt[
0
],
//
CameraPosition
&
CubeLookAt[
1
],
//
LookAtPosition
&
CubeLookAt[
2
]);
//
UpDirection
g_pD3DDevice
->
SetTransform(D3DTS_VIEW,
&
matView);
/*
***************************
*Desc:创建并设置投影矩阵*
***************************
*/
D3DXMATRIXmatProj;
/*
我们设置摄像机的镜头:我们确定了视界为PI/4(正常)而横纵比为1
我们还确定了前、后裁剪平面分别为1和500,这意味着范围之外的三角形将会被裁剪掉
*/
D3DXMatrixPerspectiveFovLH(
&
matProj,D3DX_PI
/
4
,
1.0f
,
1.0f
,
500.0f
);
g_pD3DDevice
->
SetTransform(D3DTS_PROJECTION,
&
matProj);
//
Sethowthetextureshouldberendered.
if
(g_pTexture
!=
NULL)
{
//
Atexturehasbeenset.Wedon'twanttoblendourtexturewith
//
thecoloursofourvertices,souseD3DTOP_SELECTARG1
g_pD3DDevice
->
SetTexture(
0
,g_pTexture);
g_pD3DDevice
->
SetTextureStageState(
0
,D3DTSS_COLOROP,D3DTOP_SELECTARG1);
}
else
{
//
Notexturehasbeenset.Sowewilldisabletexturerendering.
g_pD3DDevice
->
SetTextureStageState(
0
,D3DTSS_COLOROP,D3DTOP_DISABLE);
}
//
Renderingourobjects
g_pD3DDevice
->
SetStreamSource(
0
,g_pVertexBuffer,
0
,
sizeof
(CUSTOMVERTEX));
g_pD3DDevice
->
SetFVF(D3DFVF_CUSTOMVERTEX);
g_pD3DDevice
->
DrawPrimitive(D3DPT_TRIANGLESTRIP,
0
,
2
);
//
Top
g_pD3DDevice
->
DrawPrimitive(D3DPT_TRIANGLESTRIP,
4
,
8
);
//
Sides
g_pD3DDevice
->
DrawPrimitive(D3DPT_TRIANGLESTRIP,
14
,
2
);
//
Bottom
}
/*
*************************************************************
*Desc:渲染网格模型
*************************************************************
*/
DWORDRenderMesh()
{
//
创建并设置世界坐标系
D3DXMATRIXmatWorld;
D3DXMatrixRotationY(
&
matWorld,timeGetTime()
/
1000.0f
);
g_pD3DDevice
->
SetTransform(D3DTS_WORLD,
&
matWorld);
//
创建并设置观察矩阵
D3DXMATRIXmatView;
D3DXMatrixLookAtLH(
&
matView,
&
D3DXVECTOR3(
0.0f
,
0.0f
,
-
20.0f
),
&
D3DXVECTOR3(
0.0f
,
0.0f
,
0.0f
),
&
D3DXVECTOR3(
0.0f
,
1.0f
,
0.0f
));
g_pD3DDevice
->
SetTransform(D3DTS_VIEW,
&
matView);
//
创建并设置投影矩阵
D3DXMATRIXmatProj;
D3DXMatrixPerspectiveFovLH(
&
matProj,D3DX_PI
/
4
,
1.0f
,
1.0f
,
100.0f
);
g_pD3DDevice
->
SetTransform(D3DTS_PROJECTION,
&
matProj);
//
逐块渲染网格模型
if
(g_pMesh
!=
NULL)
{
for
(DWORDi
=
0
;i
<
g_dwNumMaterials;i
++
)
{
g_pD3DDevice
->
SetMaterial(
&
g_pMeshMaterials[i]);
g_pD3DDevice
->
SetTexture(
0
,g_pMeshTextures[i]);
g_pMesh
->
DrawSubset(i);
}
return
g_pMesh
->
GetNumFaces();
}
else
{
MessageBox(NULL,
"
Couldnotopenmeshfile
"
,
"
Mesh
"
,MB_OK);
return
0
;
}
}
/*
*************************************************************
*Desc:渲染主场景
*************************************************************
*/
void
Render()
{
if
(g_pD3DDevice
==
NULL)
{
return
;
}
//
清空深度缓冲
g_pD3DDevice
->
Clear(
0
,NULL,D3DCLEAR_TARGET
|
D3DCLEAR_ZBUFFER,D3DCOLOR_XRGB(
0
,
0
,
0
),
1.0f
,
0
);
//
Beginthescene
g_pD3DDevice
->
BeginScene();
//
RenderCube();
RenderMesh();
//
Endthescene
g_pD3DDevice
->
EndScene();
//
Filpthebackandfrontbufferssothatwhateverhasbeenrenderedonthe
//
backbufferwillnowbevisibleonscreen(frontbuffer).
g_pD3DDevice
->
Present(NULL,NULL,NULL,NULL);
}
/*
*************************************************************
*Desc:释放对象
*************************************************************
*/
void
CleanUp()
{
SafeDelete(g_pMeshMaterials);
if
(g_pMeshTextures
!=
NULL)
{
for
(DWORDi
=
0
;i
<
g_dwNumMaterials;i
++
)
{
if
(g_pMeshTextures[i])
{
SafeRelease(g_pMeshTextures[i]);
}
}
}
SafeDelete(g_pMeshTextures);
SafeRelease(g_pMesh);
SafeRelease(g_pTexture);
SafeRelease(g_pVertexBuffer);
SafeRelease(g_pD3DDevice);
SafeRelease(g_pD3D);
}
/*
*************************************************************
*Desc:游戏循环
*************************************************************
*/
void
GameLoop()
{
//
Enterthegameloop
MSGmsg;
BOOLfMessage;
PeekMessage(
&
msg,NULL,
0U
,
0U
,PM_NOREMOVE);
while
(msg.message
!=
WM_QUIT)
{
fMessage
=
PeekMessage(
&
msg,NULL,
0U
,
0U
,PM_REMOVE);
if
(fMessage)
{
//
Processmessage
TranslateMessage(
&
msg);
//
将虚拟键消息转换为字符消息
DispatchMessage(
&
msg);
//
将转换后的消息传送给windows
}
else
{
//
Nomessagetoprocess,sorenderthecurrentscene
Render();
}
}
}
/*
*************************************************************
*Desc:消息处理函数
*************************************************************
*/
LRESULTWINAPIWinProc(HWNDhWnd,UINTmsg,WPARAMwParam,LPARAMlParam)
{
switch
(msg)
{
case
WM_DESTROY:
PostQuitMessage(
0
);
return
0
;
break
;
case
WM_KEYUP:
switch
(wParam)
{
case
VK_ESCAPE:
//
Userhaspressedtheescapekey,soquit
DestroyWindow(hWnd);
return
0
;
break
;
}
break
;
}
return
DefWindowProc(hWnd,msg,wParam,lParam);
//
调用默认消息处理过程
}
/*
*************************************************************
*Desc:WIN32入口函数
*************************************************************
*/
INTWINAPIWinMain(HINSTANCEhInst,HINSTANCE,LPSTR,INT)
{
//
Registerthewindowclass
/*
WNDCLASSEXwc={sizeof(WNDCLASSEX),CS_CLASSDC,WinProc,0L,0L,
GetModuleHandle(NULL),NULL,NULL,NULL,NULL,
"DXProject3",NULL};
*/
WNDCLASSEXwc;
//
指定了结构的大小
wc.cbSize
=
sizeof
(WNDCLASSEX);
wc.style
=
CS_CLASSDC;
//
指定窗口类别的消息处理函数
wc.lpfnWndProc
=
WinProc;
//
指定窗口结构的额外空间
wc.cbClsExtra
=</
分享到:
评论