#include
<
d3dx9.h
>
//
-----------------------------------------------------------------------------
//
Desc: 全局变量
//
-----------------------------------------------------------------------------
LPDIRECT3D9 g_pD3D
=
NULL;
//
Direct3D对象
LPDIRECT3DDEVICE9 g_pd3dDevice
=
NULL;
//
Direct3D设备对象
LPDIRECT3DVERTEXBUFFER9 g_pVB_Index
=
NULL;
//
顶点缓冲区对象
LPDIRECT3DINDEXBUFFER9 g_pIB_Index
=
NULL;
LPDIRECT3DVERTEXBUFFER9 g_pVB
=
NULL;
//
顶点缓冲区对象
LPDIRECT3DINDEXBUFFER9 g_pIB
=
NULL;
//
-----------------------------------------------------------------------------
//
Desc: 顶点结构
//
-----------------------------------------------------------------------------
struct
CUSTOMVERTEX
{
FLOAT x, y, z;
//
顶点位置
DWORD diffuse;
//
public:
//
CUSTOMVERTEX():diffuse(0xffffffff){}
};
#define
D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE)
const
int
g_edgeVertexCnts
=
101
;
//
每边顶点数目
CUSTOMVERTEX
*
g_pVertex_Index;
//
顶点
int
*
g_pIndexes_Index;
//
索引
CUSTOMVERTEX
*
g_pVertex;
//
顶点
//
-----------------------------------------------------------------------------
//
Desc: 渲染类型
//
-----------------------------------------------------------------------------
enum
Draw_Prim_Type
{
DPT_INDEX
=
0
,
//
drawindexedprimitive
DPT_INDEX_UP,
//
drawindexedprimitiveup
DPT_PRIM,
//
drawprimitive
DPT_PRIM_UP,
//
drawprimitiveup
};
Draw_Prim_Type g_kDrawType
=
DPT_INDEX;
//
-----------------------------------------------------------------------------
//
Desc: 设置变换矩阵
//
-----------------------------------------------------------------------------
VOID SetupMatrices()
{
D3DXMATRIX matWorld;
D3DXMatrixIdentity(
&
matWorld);
g_pd3dDevice
->
SetTransform(D3DTS_WORLD,
&
matWorld);
D3DXMATRIX matView;
D3DXVECTOR3 vecEyeat(
0
,
100
,
-
100
);
D3DXVECTOR3 vecLookat(
0
,
0
,
10
);
D3DXVECTOR3 vecUp(
0
,
1
,
0
);
D3DXMatrixLookAtLH(
&
matView,
&
vecEyeat,
&
vecLookat,
&
vecUp);
g_pd3dDevice
->
SetTransform(D3DTS_VIEW,
&
matView);
D3DXMATRIX matProj;
D3DXMatrixPerspectiveFovLH(
&
matProj, D3DX_PI
/
2
,
4.0f
/
3.0f
,
1.0f
,
1000.0f
);
g_pd3dDevice
->
SetTransform(D3DTS_PROJECTION,
&
matProj);
}
//
-----------------------------------------------------------------------------
//
Desc: 初始化Direct3D
//
-----------------------------------------------------------------------------
HRESULT InitD3D( HWND hWnd )
{
//
创建d3d对象
g_pD3D
=
Direct3DCreate9(D3D_SDK_VERSION);
//
初始化设置参数
D3DPRESENT_PARAMETERS parm;
ZeroMemory(
&
parm,
sizeof
(D3DPRESENT_PARAMETERS));
parm.BackBufferWidth
=
800
;
parm.BackBufferHeight
=
600
;
parm.BackBufferCount
=
2
;
parm.BackBufferFormat
=
D3DFMT_UNKNOWN;
parm.MultiSampleType
=
D3DMULTISAMPLE_NONE;
parm.SwapEffect
=
D3DSWAPEFFECT_DISCARD;
parm.Windowed
=
true
;
parm.hDeviceWindow
=
hWnd;
parm.EnableAutoDepthStencil
=
false
;
parm.PresentationInterval
=
D3DPRESENT_INTERVAL_IMMEDIATE;
//
创建设备
HRESULT hr
=
g_pD3D
->
CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,hWnd,
D3DCREATE_HARDWARE_VERTEXPROCESSING,
&
parm,
&
g_pd3dDevice);
if
(FAILED(hr))
{
return
S_FALSE;
}
//
禁用light
g_pd3dDevice
->
SetRenderState(D3DRS_LIGHTING,
false
);
g_pd3dDevice
->
SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
SetupMatrices();
return
S_OK;
}
//
-----------------------------------------------------------------------------
//
Desc: 创建场景图形
//
-----------------------------------------------------------------------------
HRESULT InitGriphics()
{
//
--------------vertex buffer for index
const
float
fGridLenth
=
0.10f
;
g_pVertex_Index
=
new
CUSTOMVERTEX[g_edgeVertexCnts
*
g_edgeVertexCnts];
for
(
int
j
=
0
; j
<
g_edgeVertexCnts; j
+=
1
)
{
for
(
int
i
=
0
; i
<
g_edgeVertexCnts; i
+=
1
)
{
g_pVertex_Index[j
*
g_edgeVertexCnts
+
i].x
=
fGridLenth
*
i;
g_pVertex_Index[j
*
g_edgeVertexCnts
+
i].y
=
0
;
g_pVertex_Index[j
*
g_edgeVertexCnts
+
i].z
=
0.5f
*
fGridLenth
*
(g_edgeVertexCnts
-
1
)
-
fGridLenth
*
j;
}
}
HRESULT hr
=
g_pd3dDevice
->
CreateVertexBuffer(
g_edgeVertexCnts
*
g_edgeVertexCnts
*
sizeof
(CUSTOMVERTEX),
D3DUSAGE_WRITEONLY,
//
非常影响新能
D3DFVF_CUSTOMVERTEX,
D3DPOOL_DEFAULT,
&
g_pVB_Index,
NULL);
if
(FAILED(hr))
{
return
S_FALSE;
}
//
写入数据
void
*
pData;
g_pVB_Index
->
Lock(
0
, g_edgeVertexCnts
*
g_edgeVertexCnts
*
sizeof
(CUSTOMVERTEX), (
void
**
)
&
pData, D3DLOCK_DISCARD);
memcpy(pData, g_pVertex_Index, g_edgeVertexCnts
*
g_edgeVertexCnts
*
sizeof
(CUSTOMVERTEX));
g_pVB_Index
->
Unlock();
//
--------------index buffer for index
int
iIndexCount
=
(g_edgeVertexCnts
-
1
)
*
(g_edgeVertexCnts
-
1
)
*
6
;
g_pIndexes_Index
=
new
int
[iIndexCount];
for
(
int
j
=
0
;j
<
g_edgeVertexCnts
-
1
;j
+=
1
)
{
for
(
int
i
=
0
;i
<
g_edgeVertexCnts
-
1
;i
+=
1
)
{
g_pIndexes_Index[j
*
(g_edgeVertexCnts
-
1
)
*
6
+
i
*
6
+
0
]
=
(
int
)(j
*
g_edgeVertexCnts
+
i);
g_pIndexes_Index[j
*
(g_edgeVertexCnts
-
1
)
*
6
+
i
*
6
+
1
]
=
(
int
)(j
*
g_edgeVertexCnts
+
i
+
g_edgeVertexCnts
+
1
);
g_pIndexes_Index[j
*
(g_edgeVertexCnts
-
1
)
*
6
+
i
*
6
+
2
]
=
(
int
)(j
*
g_edgeVertexCnts
+
i
+
g_edgeVertexCnts);
g_pIndexes_Index[j
*
(g_edgeVertexCnts
-
1
)
*
6
+
i
*
6
+
3
]
=
(
int
)(j
*
g_edgeVertexCnts
+
i);
g_pIndexes_Index[j
*
(g_edgeVertexCnts
-
1
)
*
6
+
i
*
6
+
4
]
=
(
int
)(j
*
g_edgeVertexCnts
+
i
+
1
);
g_pIndexes_Index[j
*
(g_edgeVertexCnts
-
1
)
*
6
+
i
*
6
+
5
]
=
(
int
)(j
*
g_edgeVertexCnts
+
i
+
g_edgeVertexCnts
+
1
);
}
}
g_pd3dDevice
->
CreateIndexBuffer(iIndexCount
*
sizeof
(
int
),
D3DUSAGE_WRITEONLY,
D3DFMT_INDEX32,
D3DPOOL_DEFAULT,
&
g_pIB_Index,
NULL);
void
*
pp;
if
(FAILED(g_pIB_Index
->
Lock(
0
, iIndexCount
*
sizeof
(
int
), (
void
**
)
&
pp,
0
)))
{
//
add code
return
S_FALSE;
}
memcpy(pp, g_pIndexes_Index, iIndexCount
*
sizeof
(
int
));
g_pIB_Index
->
Unlock();
//
--------------vertex buffer
int
prim_list_vertex_cnts
=
(g_edgeVertexCnts
-
1
)
*
(g_edgeVertexCnts
-
1
)
*
6
;
g_pVertex
=
new
CUSTOMVERTEX[prim_list_vertex_cnts];
for
(
int
j
=
0
; j
<
g_edgeVertexCnts
-
1
; j
+=
1
)
{
for
(
int
i
=
0
; i
<
g_edgeVertexCnts
-
1
; i
+=
1
)
{
g_pVertex[j
*
(g_edgeVertexCnts
-
1
)
*
6
+
i
*
6
+
0
].x
=
i
*
fGridLenth;
g_pVertex[j
*
(g_edgeVertexCnts
-
1
)
*
6
+
i
*
6
+
0
].y
=
0
;
g_pVertex[j
*
(g_edgeVertexCnts
-
1
)
*
6
+
i
*
6
+
0
].z
=
0.5f
*
fGridLenth
*
(g_edgeVertexCnts
-
1
)
-
j
*
fGridLenth;
g_pVertex[j
*
(g_edgeVertexCnts
-
1
)
*
6
+
i
*
6
+
1
].x
=
(i
+
1
)
*
fGridLenth;
g_pVertex[j
*
(g_edgeVertexCnts
-
1
)
*
6
+
i
*
6
+
1
].y
=
0
;
g_pVertex[j
*
(g_edgeVertexCnts
-
1
)
*
6
+
i
*
6
+
1
].z
=
0.5f
*
fGridLenth
*
(g_edgeVertexCnts
-
1
)
-
j
*
fGridLenth;
g_pVertex[j
*
(g_edgeVertexCnts
-
1
)
*
6
+
i
*
6
+
2
].x
=
(i
+
1
)
*
fGridLenth;
g_pVertex[j
*
(g_edgeVertexCnts
-
1
)
*
6
+
i
*
6
+
2
].y
=
0
;
g_pVertex[j
*
(g_edgeVertexCnts
-
1
)
*
6
+
i
*
6
+
2
].z
=
0.5f
*
fGridLenth
*
(g_edgeVertexCnts
-
1
)
-
(j
+
1
)
*
fGridLenth;
g_pVertex[j
*
(g_edgeVertexCnts
-
1
)
*
6
+
i
*
6
+
3
].x
=
i
*
fGridLenth;
g_pVertex[j
*
(g_edgeVertexCnts
-
1
)
*
6
+
i
*
6
+
3
].y
=
0
;
g_pVertex[j
*
(g_edgeVertexCnts
-
1
)
*
6
+
i
*
6
+
3
].z
=
0.5f
*
fGridLenth
*
(g_edgeVertexCnts
-
1
)
-
j
*
fGridLenth;
g_pVertex[j
*
(g_edgeVertexCnts
-
1
)
*
6
+
i
*
6
+
4
].x
=
(i
+
1
)
*
fGridLenth;
g_pVertex[j
*
(g_edgeVertexCnts
-
1
)
*
6
+
i
*
6
+
4
].y
=
0
;
g_pVertex[j
*
(g_edgeVertexCnts
-
1
)
*
6
+
i
*
6
+
4
].z
=
0.5f
*
fGridLenth
*
(g_edgeVertexCnts
-
1
)
-
(j
+
1
)
*
fGridLenth;
g_pVertex[j
*
(g_edgeVertexCnts
-
1
)
*
6
+
i
*
6
+
5
].x
=
i
*
fGridLenth;
g_pVertex[j
*
(g_edgeVertexCnts
-
1
)
*
6
+
i
*
6
+
5
].y
=
0
;
g_pVertex[j
*
(g_edgeVertexCnts
-
1
)
*
6
+
i
*
6
+
5
].z
=
0.5f
*
fGridLenth
*
(g_edgeVertexCnts
-
1
)
-
(j
+
1
)
*
fGridLenth;
}
}
if
( FAILED( g_pd3dDevice
->
CreateVertexBuffer(
prim_list_vertex_cnts
*
sizeof
(CUSTOMVERTEX),
D3DUSAGE_WRITEONLY,
D3DFVF_CUSTOMVERTEX,
D3DPOOL_DEFAULT,
&
g_pVB,
NULL ) ) )
{
return
E_FAIL;
}
VOID
*
pVertices;
if
( FAILED( g_pVB
->
Lock(
0
, prim_list_vertex_cnts
*
sizeof
(CUSTOMVERTEX), (
void
**
)
&
pVertices,
0
) ) )
return
E_FAIL;
memcpy( pVertices, g_pVertex, prim_list_vertex_cnts
*
sizeof
(CUSTOMVERTEX) );
g_pVB
->
Unlock();
return
S_OK;
}
//
-----------------------------------------------------------------------------
//
Desc: 释放创建的对象
//
-----------------------------------------------------------------------------
VOID Cleanup()
{
//
释放顶点缓冲区对象
if
( g_pVB_Index
!=
NULL )
g_pVB_Index
->
Release();
//
释放Direct3D设备对象
if
( g_pd3dDevice
!=
NULL )
g_pd3dDevice
->
Release();
//
释放Direct3D对象
if
( g_pD3D
!=
NULL )
g_pD3D
->
Release();
}
//
-----------------------------------------------------------------------------
//
Desc: 渲染图形
//
-----------------------------------------------------------------------------
VOID Render()
{
g_pd3dDevice
->
Clear(
0
, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(
0
,
0
,
255
),
1
,
0
);
g_pd3dDevice
->
BeginScene();
g_pd3dDevice
->
SetFVF(D3DFVF_CUSTOMVERTEX);
switch
(g_kDrawType)
{
case
DPT_INDEX:
g_pd3dDevice
->
SetStreamSource(
0
,g_pVB_Index,
0
,
sizeof
(CUSTOMVERTEX));
g_pd3dDevice
->
SetIndices(g_pIB_Index);
g_pd3dDevice
->
DrawIndexedPrimitive( D3DPT_TRIANGLELIST,
0
,
0
,
g_edgeVertexCnts
*
g_edgeVertexCnts,
0
,
(g_edgeVertexCnts
-
1
)
*
(g_edgeVertexCnts
-
1
)
*
2
);
break
;
case
DPT_INDEX_UP:
g_pd3dDevice
->
SetStreamSource(
0
,g_pVB_Index,
0
,
sizeof
(CUSTOMVERTEX));
g_pd3dDevice
->
SetIndices(g_pIB_Index);
g_pd3dDevice
->
DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST,
0
, g_edgeVertexCnts
*
g_edgeVertexCnts,
(g_edgeVertexCnts
-
1
)
*
(g_edgeVertexCnts
-
1
)
*
2
, g_pIndexes_Index,
D3DFMT_INDEX32, g_pVertex_Index,
sizeof
(CUSTOMVERTEX));
break
;
case
DPT_PRIM:
g_pd3dDevice
->
SetStreamSource(
0
,g_pVB,
0
,
sizeof
(CUSTOMVERTEX));
g_pd3dDevice
->
DrawPrimitive(D3DPT_TRIANGLELIST,
0
, (g_edgeVertexCnts
-
1
)
*
(g_edgeVertexCnts
-
1
)
*
2
);
break
;
case
DPT_PRIM_UP:
g_pd3dDevice
->
SetStreamSource(
0
,g_pVB,
0
,
sizeof
(CUSTOMVERTEX));
g_pd3dDevice
->
DrawPrimitiveUP(D3DPT_TRIANGLELIST, (g_edgeVertexCnts
-
1
)
*
(g_edgeVertexCnts
-
1
)
*
2
,
g_pVertex,
sizeof
(CUSTOMVERTEX));
break
;
}
g_pd3dDevice
->
EndScene();
g_pd3dDevice
->
Present(NULL,NULL,NULL,NULL);
}
//
-----------------------------------------------------------------------------
//
Desc: 消息处理
//
-----------------------------------------------------------------------------
LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
switch
( msg )
{
case
WM_DESTROY:
Cleanup();
PostQuitMessage(
0
);
case
WM_KEYDOWN:
{
switch
((WORD)wParam)
{
case
'
W
'
:
g_pd3dDevice
->
SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME);
break
;
case
'
S
'
:
g_pd3dDevice
->
SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
break
;
case
'
1
'
:
g_kDrawType
=
DPT_INDEX;
break
;
case
'
2
'
:
g_kDrawType
=
DPT_INDEX_UP;
break
;
case
'
3
'
:
g_kDrawType
=
DPT_PRIM;
break
;
case
'
4
'
:
g_kDrawType
=
DPT_PRIM_UP;
break
;
case
'
Q
'
:
exit(
0
);
break
;
}
}
return
0
;
}
return
DefWindowProc( hWnd, msg, wParam, lParam );
}
//
-----------------------------------------------------------------------------
//
Desc: 入口函数
//
-----------------------------------------------------------------------------
INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, INT )
{
//
注册窗口类
WNDCLASSEX wc
=
{
sizeof
(WNDCLASSEX), CS_CLASSDC, MsgProc,
0L
,
0L
,
GetModuleHandle(NULL), NULL, NULL, NULL, NULL,
L
"
ClassName
"
, NULL };
RegisterClassEx(
&
wc );
RECT rc;
rc.left
=
0
;
rc.top
=
0
;
rc.right
=
800
;
rc.bottom
=
600
;
AdjustWindowRect(
&
rc, WS_VISIBLE
|
WS_CLIPCHILDREN
|
WS_OVERLAPPEDWINDOW,
false
);
//
创建窗口
HWND hWnd
=
CreateWindow( L
"
ClassName
"
, L
"
纹理影射基础
"
,
WS_OVERLAPPEDWINDOW,
200
,
100
,
rc.right
-
rc.left,
rc.bottom
-
rc.top,
GetDesktopWindow(), NULL, wc.hInstance, NULL );
//
初始化Direct3D
if
( SUCCEEDED( InitD3D( hWnd ) ) )
{
//
创建场景图形
if
( SUCCEEDED( InitGriphics() ) )
{
//
显示窗口
ShowWindow( hWnd, SW_SHOWDEFAULT );
UpdateWindow( hWnd );
//
进入消息循环
MSG msg;
ZeroMemory(
&
msg,
sizeof
(msg) );
while
( msg.message
!=
WM_QUIT )
{
if
( PeekMessage(
&
msg, NULL,
0U
,
0U
, PM_REMOVE ) )
{
TranslateMessage(
&
msg );
DispatchMessage(
&
msg );
}
else
{
Render();
//
渲染图形
}
}
}
}
UnregisterClass( L
"
ClassName
"
, wc.hInstance );
return
0
;
}