Direct基础学习系列3 绘制+实例
3.1.1顶点缓存 索引缓存
放置在显存中能够加快绘制速度
创建顶点缓存
HRESULT CreateVertexBuffer( UINT Length, //为缓存分配的字节数 DWORD Usage, //缓存附加属性,可为0 DWORD FVF, //顶点格式 D3DPOOL Pool, //缓存的内存池 IDirect3DVertexBuffer9** ppVertexBuffer, //返回的结构 HANDLE* pSharedHandle //不用 设置为0 );
创建索引缓存
HRESULT CreateIndexBuffer( UINT Length, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, IDirect3DIndexBuffer9** ppIndexBuffer, HANDLE* pSharedHandle );
Usage != D3DUSAGE_DYNAMIC 放置在静态缓存中,适合处理运行中不需要修改的数据
Usage = D3DUSAGE_DYNAMIC 放置在动态缓存,适合频繁更新内容,如粒子系统,动态缓存放置在内存AGP区域,可以很快的被更新
3.1.2访问数据
HRESULT Lock(
UINT OffsetToLock, //缓存中的起始点 UINT SizeToLock, //需要锁定的数目
VOID ** ppbData, //返回的被锁定的缓存区起始位置 DWORD Flags //锁定方式:
);
BOOL Unlock();
3.1.3获得顶点缓存信息
typedef struct D3DVERTEXBUFFER_DESC { D3DFORMAT Format; D3DRESOURCETYPE Type; DWORD Usage; D3DPOOL Pool; UINT Size; DWORD FVF; } D3DVERTEXBUFFER_DESC, *LPD3DVERTEXBUFFER_DESC;
typedef struct D3DINDEXBUFFER_DESC { D3DFORMAT Format; D3DRESOURCETYPE Type; DWORD Usage; D3DPOOL Pool; UINT Size; } D3DINDEXBUFFER_DESC, *LPD3DINDEXBUFFER_DESC;
IDirect3DIndexBuffer9::GetDesc();
3.2 绘制状态
HRESULT SetRenderState(
[in] D3DRENDERSTATETYPE State,
[in] DWORD Value
);
3.3绘制准备工作
(1)制定数据流输入源
HRESULT SetStreamSource( UINT StreamNumber, //数据流 可以是多个 IDirect3DVertexBuffer9 * pStreamData,//建立数据流的缓存 UINT OffsetInBytes, //被传送到绘制流水线顶点数据的起始位置 UINT Stride //顶点缓存的大小 );
(2)设置顶点格式
HRESULT SetFVF( DWORD FVF); 顶点格式如下:
(3)设置使用的索引,任意时刻只能有一个索引缓存,如果不同索引绘制物体时,必须进行切换
HRESULT SetIndices( IDirect3DIndexBuffer9 * pIndexData );
3.4 绘制方法
使用顶点绘制
HRESULT DrawPrimitive(
D3DPRIMITIVETYPE PrimitiveType, //绘制的图元类型,TRIANGLELIST
UINT StartVertex, //绘制起点索引 UINT PrimitiveCount //绘制的图元数量
);
采用索引绘制
HRESULT DrawIndexedPrimitive( D3DPRIMITIVETYPE Type, INT BaseVertexIndex, //物体顶点在全局缓存中的起始位置偏移 UINT MinIndex, UINT NumVertices, UINT StartIndex, UINT PrimitiveCount );
绘制在下列函数之间进行
IDirect3DDevice9::BeginScene()
IDirect3DDevice9::EndScene()
实例:看完代码之后 多的一层了解:
(1)世界变换矩阵,取景变换矩阵,投影变换矩阵设置后 在绘图中起作用
(2)缓存中其实就在准备数据
1:
2: #include "d3dUtility.h"
3:
4: IDirect3DDevice9* Device = 0;
5:
6: const int Width = 640;
7: const int Height = 480;
8:
9: IDirect3DVertexBuffer9* VB = 0;
10: IDirect3DIndexBuffer9* IB = 0;
11:
12: //顶点格式定义
13: struct Vertex
14: {
15: Vertex(){}
16: Vertex(float x, float y, float z)
17: {
18: _x = x; _y = y; _z = z;
19: }
20: float _x, _y, _z;
21: static const DWORD FVF;
22: };
23: //全局定点格式
24: const DWORD Vertex::FVF = D3DFVF_XYZ;
25:
26: //
27: // Framework Functions
28: //
29: bool Setup()
30: {
31: // Create vertex and index buffers.
32: Device->CreateVertexBuffer(
33: 8 * sizeof(Vertex),
34: D3DUSAGE_WRITEONLY,
35: Vertex::FVF,
36: D3DPOOL_MANAGED,
37: &VB,
38: 0);
39: Device->CreateIndexBuffer(
40: 36 * sizeof(WORD),
41: D3DUSAGE_WRITEONLY,
42: D3DFMT_INDEX16,
43: D3DPOOL_MANAGED,
44: &IB,
45: 0);
46:
47:
48: // 填充数据
49: Vertex* vertices;
50: VB->Lock(0, 0, (void**)&vertices, 0);
51:
52: // vertices of a unit cube
53: vertices[0] = Vertex(-1.0f, -1.0f, -1.0f);
54: vertices[1] = Vertex(-1.0f, 1.0f, -1.0f);
55: vertices[2] = Vertex( 1.0f, 1.0f, -1.0f);
56: vertices[3] = Vertex( 1.0f, -1.0f, -1.0f);
57: vertices[4] = Vertex(-1.0f, -1.0f, 1.0f);
58: vertices[5] = Vertex(-1.0f, 1.0f, 1.0f);
59: vertices[6] = Vertex( 1.0f, 1.0f, 1.0f);
60: vertices[7] = Vertex( 1.0f, -1.0f, 1.0f);
61:
62: VB->Unlock();
63:
64: // define the triangles of the cube:
65: WORD* indices = 0;
66: IB->Lock(0, 0, (void**)&indices, 0);
67:
68: // front side
69: indices[0] = 0; indices[1] = 1; indices[2] = 2;
70: indices[3] = 0; indices[4] = 2; indices[5] = 3;
71:
72: // back side
73: indices[6] = 4; indices[7] = 6; indices[8] = 5;
74: indices[9] = 4; indices[10] = 7; indices[11] = 6;
75:
76: // left side
77: indices[12] = 4; indices[13] = 5; indices[14] = 1;
78: indices[15] = 4; indices[16] = 1; indices[17] = 0;
79:
80: // right side
81: indices[18] = 3; indices[19] = 2; indices[20] = 6;
82: indices[21] = 3; indices[22] = 6; indices[23] = 7;
83:
84: // top
85: indices[24] = 1; indices[25] = 5; indices[26] = 6;
86: indices[27] = 1; indices[28] = 6; indices[29] = 2;
87:
88: // bottom
89: indices[30] = 4; indices[31] = 0; indices[32] = 3;
90: indices[33] = 4; indices[34] = 3; indices[35] = 7;
91:
92: IB->Unlock();
93:
94: D3DXVECTOR3 position(0.0f, 0.0f, -5.0f);
95: D3DXVECTOR3 target(0.0f, 0.0f, 0.0f);
96: D3DXVECTOR3 up(0.0f, 1.0f, 0.0f);
97: D3DXMATRIX V;
98:
99: D3DXMatrixLookAtLH(&V, &position, &target, &up);
100: //设置取景变换矩阵
101: Device->SetTransform(D3DTS_VIEW, &V);
102:
103: // Set the projection matrix.
104: D3DXMATRIX proj;
105: D3DXMatrixPerspectiveFovLH(
106: &proj,
107: D3DX_PI * 0.5f, // 90 - degree
108: (float)Width / (float)Height,
109: 1.0f,
110: 1000.0f);
111:
112: //设置投影变换矩阵
113: Device->SetTransform(D3DTS_PROJECTION, &proj);
114:
115: //设置绘图模式
116: Device->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME);
117:
118: return true;
119: }
120:
121: void Cleanup()
122: {
123: d3d::Release<IDirect3DVertexBuffer9*>(VB);
124: d3d::Release<IDirect3DIndexBuffer9*>(IB);
125: }
126:
127: bool Display(float timeDelta)
128: {
129: if( Device )
130: {
131: // spin the cube:
132: D3DXMATRIX Rx, Ry;
133:
134: // rotate 45 degrees on x-axis
135: D3DXMatrixRotationX(&Rx, 3.14f / 4.0f);
136:
137: // incremement y-rotation angle each frame
138: static float y = 0.0f;
139: D3DXMatrixRotationY(&Ry, y);
140: y += timeDelta; // 每帧增加旋转量
141:
142: // reset angle to zero when angle reaches 2*PI
143: if( y >= 6.28f )
144: y = 0.0f;
145:
146: // combine x- and y-axis rotation transformations.
147: D3DXMATRIX p = Rx * Ry;
148:
149: //设置世界变换矩阵
150: Device->SetTransform(D3DTS_WORLD, &p);
151:
152: //
153: // draw the scene:
154:
155: //清除背景
156: Device->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
157: Device->BeginScene();
158:
159: //设置数据源
160: Device->SetStreamSource(0, VB, 0, sizeof(Vertex));
161:
162: //设置使用的索引
163: Device->SetIndices(IB);
164:
165: //
166: Device->SetFVF(Vertex::FVF);
167:
168: // Draw cube.
169: Device->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, 8, 0, 12);
170:
171: Device->EndScene();
172: Device->Present(0, 0, 0, 0);
173: }
174: return true;
175: }
176:
177:
178: //
179: // WndProc
180: //
181: LRESULT CALLBACK d3d::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
182: {
183: switch( msg )
184: {
185: case WM_DESTROY:
186: ::PostQuitMessage(0);
187: break;
188:
189: case WM_KEYDOWN:
190: if( wParam == VK_ESCAPE )
191: ::DestroyWindow(hwnd);
192: break;
193: }
194: return ::DefWindowProc(hwnd, msg, wParam, lParam);
195: }
196:
197: //
198: // WinMain
199: //
200: int WINAPI WinMain(HINSTANCE hinstance,
201: HINSTANCE prevInstance,
202: PSTR cmdLine,
203: int showCmd)
204: {
205: if(!d3d::InitD3D(hinstance,
206: Width, Height, true, D3DDEVTYPE_HAL, &Device))
207: {
208: ::MessageBox(0, "InitD3D() - FAILED", 0, 0);
209: return 0;
210: }
211:
212: if(!Setup())
213: {
214: ::MessageBox(0, "Setup() - FAILED", 0, 0);
215: return 0;
216: }
217:
218: d3d::EnterMsgLoop( Display );
219:
220: Cleanup();
221:
222: Device->Release();
223:
224: return 0;
225: }