Contents
  1. 1. Demo Debug
  2. 2. Src
  3. 3. About

123

人算不如天算

龙书第六章中间的一个例子,用到了前几节所有的知识点。把这几百行行代码读懂就基本了解渲染管线的工作流程(日常读源码

Demo Debug

Front
Back

Src

BoxDemo.cpp (使用D3DApp框架结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
//***************************************************************************************
// BoxDemo.cpp by Frank Luna (C) 2011 All Rights Reserved.
//
// Demonstrates rendering a colored box.
//
// Controls:
// Hold the left mouse button down and move the mouse to rotate.
// Hold the right mouse button down to zoom in and out.
//
//***************************************************************************************
#include "d3dApp.h"
#include "d3dx11Effect.h"
#include "MathHelper.h"
struct Vertex
{
XMFLOAT3 Pos;
XMFLOAT4 Color;
};
class BoxApp : public D3DApp
{
public:
BoxApp(HINSTANCE hInstance);
~BoxApp();
bool Init();
void OnResize();
void UpdateScene(float dt);
void DrawScene();
void OnMouseDown(WPARAM btnState, int x, int y);
void OnMouseUp(WPARAM btnState, int x, int y);
void OnMouseMove(WPARAM btnState, int x, int y);
private:
void BuildGeometryBuffers();
void BuildFX();
void BuildVertexLayout();
private:
ID3D11Buffer* mBoxVB; // [vertex buffer]
ID3D11Buffer* mBoxIB; // [index buffer]
ID3DX11Effect* mFX; // update in BuildFX()
ID3DX11EffectTechnique* mTech;
ID3DX11EffectMatrixVariable* mfxWorldViewProj;
ID3D11InputLayout* mInputLayout; // update in BuildVertexLayout();
XMFLOAT4X4 mWorld;
XMFLOAT4X4 mView;
XMFLOAT4X4 mProj; // 3 for DrawScene()
float mTheta;
float mPhi;
float mRadius; // 3 for rotation
POINT mLastMousePos; // record the mouse postion for update scene
};
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE prevInstance,
PSTR cmdLine, int showCmd)
{
// Enable run-time memory check for debug builds.
#if defined(DEBUG) | defined(_DEBUG)
_CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
#endif
BoxApp theApp(hInstance);
if( !theApp.Init() ) // minit
return 0;
return theApp.Run();
}
BoxApp::BoxApp(HINSTANCE hInstance)
: D3DApp(hInstance), mBoxVB(0), mBoxIB(0), mFX(0), mTech(0),
mfxWorldViewProj(0), mInputLayout(0),
mTheta(1.5f*MathHelper::Pi), mPhi(0.25f*MathHelper::Pi), mRadius(5.0f)
{
mMainWndCaption = L"Box Demo";
mLastMousePos.x = 0;
mLastMousePos.y = 0;
XMMATRIX I = XMMatrixIdentity();
XMStoreFloat4x4(&mWorld, I);
XMStoreFloat4x4(&mView, I);
XMStoreFloat4x4(&mProj, I); // init these m-args
}
BoxApp::~BoxApp()
{
ReleaseCOM(mBoxVB);
ReleaseCOM(mBoxIB);
ReleaseCOM(mFX);
ReleaseCOM(mInputLayout);
}
bool BoxApp::Init() //dinit
{
if(!D3DApp::Init())
return false;
BuildGeometryBuffers(); //mbgb
BuildFX(); //mbfx
BuildVertexLayout(); //mbvl
return true;
}
//******************************** Scene map (d3dapp methods) ********************************
void BoxApp::OnResize()
{
D3DApp::OnResize();
// The window resized, so update the aspect ratio and recompute the projection matrix.
XMMATRIX P = XMMatrixPerspectiveFovLH(0.25f*MathHelper::Pi, AspectRatio(), 1.0f, 1000.0f);
XMStoreFloat4x4(&mProj, P); // update mProj
}
void BoxApp::UpdateScene(float dt)
{
// Convert Spherical to Cartesian coordinates.
float x = mRadius*sinf(mPhi)*cosf(mTheta);
float z = mRadius*sinf(mPhi)*sinf(mTheta);
float y = mRadius*cosf(mPhi);
// Build the view matrix.
XMVECTOR pos = XMVectorSet(x, y, z, 1.0f);
XMVECTOR target = XMVectorZero();
XMVECTOR up = XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f);
XMMATRIX V = XMMatrixLookAtLH(pos, target, up);
XMStoreFloat4x4(&mView, V); // update mView
}
void BoxApp::DrawScene()
{
md3dImmediateContext->ClearRenderTargetView(mRenderTargetView, reinterpret_cast<const float*>(&Colors::LightSteelBlue));
md3dImmediateContext->ClearDepthStencilView(mDepthStencilView, D3D11_CLEAR_DEPTH|D3D11_CLEAR_STENCIL, 1.0f, 0);
md3dImmediateContext->IASetInputLayout(mInputLayout);
md3dImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
UINT stride = sizeof(Vertex);
UINT offset = 0;
md3dImmediateContext->IASetVertexBuffers(0, 1, &mBoxVB, &stride, &offset);
md3dImmediateContext->IASetIndexBuffer(mBoxIB, DXGI_FORMAT_R32_UINT, 0);
// Set constants
XMMATRIX world = XMLoadFloat4x4(&mWorld);
XMMATRIX view = XMLoadFloat4x4(&mView);
XMMATRIX proj = XMLoadFloat4x4(&mProj);
XMMATRIX worldViewProj = world*view*proj;
mfxWorldViewProj->SetMatrix(reinterpret_cast<float*>(&worldViewProj));
D3DX11_TECHNIQUE_DESC techDesc;
mTech->GetDesc( &techDesc );
for(UINT p = 0; p < techDesc.Passes; ++p)
{
mTech->GetPassByIndex(p)->Apply(0, md3dImmediateContext);
// 36 indices for the box.
md3dImmediateContext->DrawIndexed(36, 0, 0);
}
HR(mSwapChain->Present(0, 0));
}
//************************* Mouse Control ***********************************************
void BoxApp::OnMouseDown(WPARAM btnState, int x, int y)
{
mLastMousePos.x = x;
mLastMousePos.y = y;
SetCapture(mhMainWnd);
}
void BoxApp::OnMouseUp(WPARAM btnState, int x, int y)
{
ReleaseCapture();
}
void BoxApp::OnMouseMove(WPARAM btnState, int x, int y)
{
if( (btnState & MK_LBUTTON) != 0 )
{
// Make each pixel correspond to a quarter of a degree.
float dx = XMConvertToRadians(0.25f*static_cast<float>(x - mLastMousePos.x));
float dy = XMConvertToRadians(0.25f*static_cast<float>(y - mLastMousePos.y));
// Update angles based on input to orbit camera around box.
mTheta += dx;
mPhi += dy;
// Restrict the angle mPhi.
mPhi = MathHelper::Clamp(mPhi, 0.1f, MathHelper::Pi-0.1f);
}
else if( (btnState & MK_RBUTTON) != 0 )
{
// Make each pixel correspond to 0.005 unit in the scene.
float dx = 0.005f*static_cast<float>(x - mLastMousePos.x);
float dy = 0.005f*static_cast<float>(y - mLastMousePos.y);
// Update the camera radius based on input.
mRadius += dx - dy;
// Restrict the radius.
mRadius = MathHelper::Clamp(mRadius, 3.0f, 15.0f);
}
mLastMousePos.x = x;
mLastMousePos.y = y;
}
//******************************* rendering pipeline *****************************************
void BoxApp::BuildGeometryBuffers() //dbgb
{
// directx use left-handed like this:
//
// |y
// | /z
// | /
// |/_____x
// Create vertex buffer
Vertex vertices[] =
{
{ XMFLOAT3(-1.0f, -1.0f, -1.0f), (const float*)&Colors::White },
{ XMFLOAT3(-1.0f, +1.0f, -1.0f), (const float*)&Colors::Black },
{ XMFLOAT3(+1.0f, +1.0f, -1.0f), (const float*)&Colors::Red },
{ XMFLOAT3(+1.0f, -1.0f, -1.0f), (const float*)&Colors::Green },
{ XMFLOAT3(-1.0f, -1.0f, +1.0f), (const float*)&Colors::Blue },
{ XMFLOAT3(-1.0f, +1.0f, +1.0f), (const float*)&Colors::Yellow },
{ XMFLOAT3(+1.0f, +1.0f, +1.0f), (const float*)&Colors::Cyan },
{ XMFLOAT3(+1.0f, -1.0f, +1.0f), (const float*)&Colors::Magenta }
};
// color map:
// Yellow---Cyan
// /| /|
// Black---Red |
// | | | |
// |Blue---|-Magenta
// |/ |/
// White---Green
D3D11_BUFFER_DESC vbd; // buffer description [vertex buffer]
vbd.Usage = D3D11_USAGE_IMMUTABLE;
vbd.ByteWidth = sizeof(Vertex) * 8;
vbd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
vbd.CPUAccessFlags = 0;
vbd.MiscFlags = 0;
vbd.StructureByteStride = 0;
D3D11_SUBRESOURCE_DATA vinitData; // zone for init buffer
vinitData.pSysMem = vertices; // set buffer container
HR(md3dDevice->CreateBuffer(&vbd, &vinitData, &mBoxVB)); // [vertex buffer created]
// index map: Clockwise
//
// 5-------6 1→2 1→2 2 2 1→2 7--6
// /| /| ↑ ↓ LR: ↑ ↗↓ RL: ↗↓ ↑ backRL: | |
// 1-------2 | 0←3 0 0 3 0 3 0 4--5
// | | | |
// | 4-----|-7
// |/ |/
// 0-------3
// Create the index buffer
UINT indices[] = {
// front face ↙LR 1--2
0, 1, 2, // | |
0, 2, 3, // 0--3
// back face ↙LR 5--6 ↘RL 6--5 ↙RL 7--6
4, 6, 5, // (front) | | (back) | | (rotate) | |
4, 7, 6, // (anti-cw) 4--7 7--4 4--5
// left face ↙LR 5--1
4, 5, 1, // | |
4, 1, 0, // 4--0
// right face ↙LR 2--6
3, 2, 6, // | |
3, 6, 7, // 3--7
// top face ↙LR 5--6
1, 5, 6, // | |
1, 6, 2, // 1--2
// bottom face ↙LR 0--3
4, 0, 3, // | |
4, 3, 7 // 4--7
};
D3D11_BUFFER_DESC ibd; // buffer description [index buffer]
ibd.Usage = D3D11_USAGE_IMMUTABLE;
ibd.ByteWidth = sizeof(UINT) * 36;
ibd.BindFlags = D3D11_BIND_INDEX_BUFFER;
ibd.CPUAccessFlags = 0;
ibd.MiscFlags = 0;
ibd.StructureByteStride = 0; // set ibd args
D3D11_SUBRESOURCE_DATA iinitData; // zone for init buffer
iinitData.pSysMem = indices; // set buffer container
HR(md3dDevice->CreateBuffer(&ibd, &iinitData, &mBoxIB)); // [index buffer created]
}
void BoxApp::BuildFX() //dbfx use color.fx
{
DWORD shaderFlags = 0;
#if defined( DEBUG ) || defined( _DEBUG )
shaderFlags |= D3D10_SHADER_DEBUG;
shaderFlags |= D3D10_SHADER_SKIP_OPTIMIZATION;
#endif
ID3D10Blob* compiledShader = 0; // compiling shader pointer
ID3D10Blob* compilationMsgs = 0; // store errs or wanrings
// main method <D3DX11CompileFromFile>
HRESULT hr = D3DX11CompileFromFile(L"FX/color.fx", 0, 0, 0, "fx_5_0", shaderFlags,
0, 0, &compiledShader, &compilationMsgs, 0);
// and check method<D3DX11CompileFromFile> result below
// compilationMsgs can store errors or warnings.
if( compilationMsgs != 0 )
{
MessageBoxA(0, (char*)compilationMsgs->GetBufferPointer(), 0, 0);
ReleaseCOM(compilationMsgs);
}
// Even if there are no compilationMsgs, check to make sure there were no other errors.
if(FAILED(hr))
{
DXTrace(__FILE__, (DWORD)__LINE__, hr, L"D3DX11CompileFromFile", true);
}
// main method <D3DX11CreateEffectFromMemory>
HR(D3DX11CreateEffectFromMemory(compiledShader->GetBufferPointer(), compiledShader->GetBufferSize(),
0, md3dDevice, &mFX)); // update mFX
// Done with compiled shader.
ReleaseCOM(compiledShader);
mTech = mFX->GetTechniqueByName("ColorTech");
mfxWorldViewProj = mFX->GetVariableByName("gWorldViewProj")->AsMatrix();
}
void BoxApp::BuildVertexLayout() //dbvl
{
// Create the vertex input layout.
D3D11_INPUT_ELEMENT_DESC vertexDesc[] =
{
{"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0},
{"COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0}
};
// Create the input layout
D3DX11_PASS_DESC passDesc;
mTech->GetPassByIndex(0)->GetDesc(&passDesc);
HR(md3dDevice->CreateInputLayout(vertexDesc, 2, passDesc.pIAInputSignature,
passDesc.IAInputSignatureSize, &mInputLayout)); // update mInputLayout
}

color.fx (没啥好说的,一个顶点着色器和一个像素着色器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
//***************************************************************************************
// color.fx by Frank Luna (C) 2011 All Rights Reserved.
//
// Transforms and colors geometry.
//***************************************************************************************
cbuffer cbPerObject
{
float4x4 gWorldViewProj;
};
struct VertexIn
{
float3 Pos : POSITION;
float4 Color : COLOR;
};
struct VertexOut
{
float4 PosH : SV_POSITION;
float4 Color : COLOR;
};
VertexOut VS(VertexIn vin)
{
VertexOut vout;
// Transform to homogeneous clip space.
vout.PosH = mul(float4(vin.Pos, 1.0f), gWorldViewProj);
// Just pass vertex color into the pixel shader.
vout.Color = vin.Color;
return vout;
}
float4 PS(VertexOut pin) : SV_Target
{
return pin.Color;
}
technique11 ColorTech
{
pass P0
{
SetVertexShader( CompileShader( vs_5_0, VS() ) );
SetGeometryShader( NULL );
SetPixelShader( CompileShader( ps_5_0, PS() ) );
}
}

About

DirectX的官网只有一个sdk下载链接,没有实例,木有文档,正常开发者下了根本没卵用。所以没有办法,只能使用各种书籍的随书源码作为参考。不过书籍上的项目一般历史久远,想要run起来还是会有一定的挑战。

vs的sln工程个有说法,不同版本的工程策略不同。不同版本vs构建的工程之间兼容性会有一定的问题,主要表现在开发工具(包括面向平台)、c++库等的更新迭代。当你需要打开一个远古时期的工程时,最简单粗暴的方法是下载构建版本时的vs(vs允许多版本共存)和相应的SDK,设置添加SDK的path include includepath lib 和源文件路径到项目的vc++目录中(绝大多数搜索引擎出来的vs兼容性问题的根源)。使用新的vs去跑老版本的工程会修改老工程中的配置,这样就无法再使用旧版本的vs去打开工程,而且新vs也不一定能够跑起来,可能会遇到各种问题(经常出现难以解决的情况),吃力不讨好。(突然感觉用unix-like的人控制欲都好强啊

bin路径一般放二进制文件(.exe),即path环境路径;lib路径放库文件(.lib),有时候需要用sdk工程手动build出来,因为有时候为了区分debug和release出来的库,会在debug下出来的lib文件名后加个d(比如Effects11.libEffects11d.lib其实是同一个项目Effects11build出来的库);include路径中存放需要被#include的文件;一般使用src路径存放源文件;vs的工程文件把不管你乱七八糟存放的文件路径整理成它自己的一套映射路径,这种方案可能一些人很舒服,一些人很不舒服(比如我,乱七八糟路径太多,一个工程一个沙盒不好么)

Contents
  1. 1. Demo Debug
  2. 2. Src
  3. 3. About