Skip to content

Commit b1fd815

Browse files
* 漏传代码
1 parent 0feb6ba commit b1fd815

File tree

1 file changed

+132
-51
lines changed

1 file changed

+132
-51
lines changed

Chapter 8 Lighting/GameApp.cpp

Lines changed: 132 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include "GeometryGenerator.h"
77

88
#include <DirectXColors.h>
9+
#include <fstream>
910
#include "GameInput.h"
1011
#include "CompiledShaders/defaultVS.h"
1112
#include "CompiledShaders/defaultPS.h"
@@ -35,18 +36,20 @@ using namespace Graphics;
3536
void GameApp::Startup(void)
3637
{
3738
buildShapesData();
39+
buildSkull();
3840
buildLandAndWaves();
3941

4042
// 根签名
41-
m_RootSignature.Reset(2, 0);
43+
m_RootSignature.Reset(3, 0);
4244
m_RootSignature[0].InitAsConstantBuffer(0, D3D12_SHADER_VISIBILITY_VERTEX);
4345
m_RootSignature[1].InitAsConstantBuffer(1, D3D12_SHADER_VISIBILITY_ALL);
46+
m_RootSignature[2].InitAsConstantBuffer(2, D3D12_SHADER_VISIBILITY_PIXEL);
4447
m_RootSignature.Finalize(L"box signature", D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT);
4548

4649
D3D12_INPUT_ELEMENT_DESC mInputLayout[] =
4750
{
4851
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
49-
{ "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }
52+
{ "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }
5053
};
5154

5255
DXGI_FORMAT ColorFormat = g_SceneColorBuffer.GetFormat();
@@ -74,6 +77,8 @@ void GameApp::Cleanup(void)
7477
{
7578
m_VertexBuffer.Destroy();
7679
m_IndexBuffer.Destroy();
80+
m_VertexBufferSkull.Destroy();
81+
m_IndexBufferSkull.Destroy();
7782

7883
m_VertexBufferLand.Destroy();
7984
m_IndexBufferLand.Destroy();
@@ -179,7 +184,6 @@ void GameApp::RenderScene(void)
179184
gfxContext.TransitionResource(g_SceneDepthBuffer, D3D12_RESOURCE_STATE_DEPTH_WRITE, true);
180185
gfxContext.ClearDepth(g_SceneDepthBuffer);
181186

182-
gfxContext.TransitionResource(g_SceneDepthBuffer, D3D12_RESOURCE_STATE_DEPTH_READ, true);
183187
gfxContext.SetRenderTarget(g_SceneColorBuffer.GetRTV(), g_SceneDepthBuffer.GetDSV());
184188

185189
// 设置渲染流水线
@@ -193,18 +197,6 @@ void GameApp::RenderScene(void)
193197
// 设置顶点拓扑结构
194198
gfxContext.SetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
195199

196-
// 设置VS、PS通用的常量缓冲区
197-
__declspec(align(16)) struct
198-
{
199-
Matrix4 viewProj; // 从世界坐标转为投影坐标的矩阵
200-
}passConstants;
201-
202-
// https://www.cnblogs.com/X-Jun/p/9808727.html
203-
// C++代码端进行转置,HLSL中使用matrix(列矩阵)
204-
// mul函数让向量放在左边(行向量),实际运算是(行向量 X 行矩阵) 然后行矩阵为了使用dp4运算发生了转置成了列矩阵
205-
passConstants.viewProj = Transpose(m_ViewProjMatrix);
206-
gfxContext.SetDynamicConstantBufferView(1, sizeof(passConstants), &passConstants);
207-
208200
// 开始绘制
209201
if (m_bRenderShapes)
210202
renderShapes(gfxContext);
@@ -237,25 +229,25 @@ void GameApp::buildShapesData()
237229
for (size_t i = 0; i < box.Vertices.size(); ++i, ++k)
238230
{
239231
vertices[k].Pos = box.Vertices[i].Position;
240-
vertices[k].Color = XMFLOAT4(DirectX::Colors::LemonChiffon);
232+
vertices[k].Normal = box.Vertices[i].Normal;
241233
}
242234

243235
for (size_t i = 0; i < grid.Vertices.size(); ++i, ++k)
244236
{
245237
vertices[k].Pos = grid.Vertices[i].Position;
246-
vertices[k].Color = XMFLOAT4(DirectX::Colors::ForestGreen);
238+
vertices[k].Normal = grid.Vertices[i].Normal;
247239
}
248240

249241
for (size_t i = 0; i < sphere.Vertices.size(); ++i, ++k)
250242
{
251243
vertices[k].Pos = sphere.Vertices[i].Position;
252-
vertices[k].Color = XMFLOAT4(DirectX::Colors::Crimson);
244+
vertices[k].Normal = sphere.Vertices[i].Normal;
253245
}
254246

255247
for (size_t i = 0; i < cylinder.Vertices.size(); ++i, ++k)
256248
{
257249
vertices[k].Pos = cylinder.Vertices[i].Position;
258-
vertices[k].Color = XMFLOAT4(DirectX::Colors::SteelBlue);
250+
vertices[k].Normal = cylinder.Vertices[i].Normal;
259251
}
260252

261253
std::vector<std::uint16_t> indices;
@@ -287,13 +279,19 @@ void GameApp::buildShapesData()
287279
item.indexCount = (UINT)box.Indices32.size();
288280
item.startIndex = boxIndexOffset;
289281
item.baseVertex = boxVertexOffset;
282+
item.diffuseAlbedo = XMFLOAT4(Colors::LightSteelBlue);
283+
item.fresnelR0 = XMFLOAT3(0.05f, 0.05f, 0.05f);
284+
item.roughness = 0.3f;
290285
m_vecShapes.push_back(item);
291286

292287
// grid
293288
item.modelToWorld = Transpose(Matrix4(kIdentity));
294289
item.indexCount = (UINT)grid.Indices32.size();
295290
item.startIndex = gridIndexOffset;
296291
item.baseVertex = gridVertexOffset;
292+
item.diffuseAlbedo = XMFLOAT4(Colors::LightGray);
293+
item.fresnelR0 = XMFLOAT3(0.02f, 0.02f, 0.02f);
294+
item.roughness = 0.2f;
297295
m_vecShapes.push_back(item);
298296

299297
for (int i = 0; i < 5; ++i)
@@ -309,6 +307,9 @@ void GameApp::buildShapesData()
309307
item.startIndex = cylinderIndexOffset;
310308
item.baseVertex = cylinderVertexOffset;
311309
item.modelToWorld = leftCylWorld;
310+
item.diffuseAlbedo = XMFLOAT4(Colors::ForestGreen);
311+
item.fresnelR0 = XMFLOAT3(0.02f, 0.02f, 0.02f);
312+
item.roughness = 0.1f;
312313
m_vecShapes.push_back(item);
313314
item.modelToWorld = rightCylWorld;
314315
m_vecShapes.push_back(item);
@@ -318,14 +319,83 @@ void GameApp::buildShapesData()
318319
item.startIndex = sphereIndexOffset;
319320
item.baseVertex = sphereVertexOffset;
320321
item.modelToWorld = leftSphereWorld;
322+
item.diffuseAlbedo = XMFLOAT4(Colors::LightSteelBlue);
323+
item.fresnelR0 = XMFLOAT3(0.05f, 0.05f, 0.05f);
324+
item.roughness = 0.3f;
321325
m_vecShapes.push_back(item);
322326
item.modelToWorld = rightSphereWorld;
323327
m_vecShapes.push_back(item);
324328
}
325329
}
326330

331+
void GameApp::buildSkull()
332+
{
333+
// create skull
334+
std::ifstream fin("Models/skull.txt");
335+
336+
if (!fin)
337+
{
338+
MessageBox(0, L"Models/skull.txt not found.", 0, 0);
339+
return;
340+
}
341+
342+
UINT vcount = 0;
343+
UINT tcount = 0;
344+
std::string ignore;
345+
346+
fin >> ignore >> vcount;
347+
fin >> ignore >> tcount;
348+
fin >> ignore >> ignore >> ignore >> ignore;
349+
350+
std::vector<Vertex> vertices(vcount);
351+
for (UINT i = 0; i < vcount; ++i)
352+
{
353+
fin >> vertices[i].Pos.x >> vertices[i].Pos.y >> vertices[i].Pos.z;
354+
fin >> vertices[i].Normal.x >> vertices[i].Normal.y >> vertices[i].Normal.z;
355+
}
356+
357+
fin >> ignore;
358+
fin >> ignore;
359+
fin >> ignore;
360+
361+
std::vector<std::int32_t> indices(3 * tcount);
362+
for (UINT i = 0; i < tcount; ++i)
363+
{
364+
fin >> indices[i * 3 + 0] >> indices[i * 3 + 1] >> indices[i * 3 + 2];
365+
}
366+
367+
fin.close();
368+
369+
// GPUBuff类,自动把对象通过上传缓冲区传到了对应的默认堆中
370+
m_VertexBufferSkull.Create(L"vertex buff", (UINT)vertices.size(), sizeof(Vertex), vertices.data());
371+
m_IndexBufferSkull.Create(L"index buff", (UINT)indices.size(), sizeof(std::int32_t), indices.data());
372+
373+
m_skull.modelToWorld = Transpose(Matrix4(AffineTransform(Matrix3::MakeScale(0.5f, 0.5f, 0.5f), Vector3(0.0f, 1.0f, 0.0f))));
374+
m_skull.indexCount = (UINT)indices.size();
375+
m_skull.startIndex = 0;
376+
m_skull.baseVertex = 0;
377+
m_skull.diffuseAlbedo = XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f);
378+
m_skull.fresnelR0 = XMFLOAT3(0.05f, 0.05f, 0.05f);
379+
m_skull.roughness = 0.3f;
380+
}
381+
327382
void GameApp::renderShapes(GraphicsContext& gfxContext)
328383
{
384+
PassConstants psc;
385+
// https://www.cnblogs.com/X-Jun/p/9808727.html
386+
// C++代码端进行转置,HLSL中使用matrix(列矩阵)
387+
// mul函数让向量放在左边(行向量),实际运算是(行向量 X 行矩阵) 然后行矩阵为了使用dp4运算发生了转置成了列矩阵
388+
psc.viewProj = Transpose(m_ViewProjMatrix);
389+
psc.eyePosW = m_Camera.GetPosition();
390+
psc.ambientLight = { 0.25f, 0.25f, 0.35f, 1.0f };
391+
psc.Lights[0].Direction = { 0.57735f, -0.57735f, 0.57735f };
392+
psc.Lights[0].Strength = { 0.6f, 0.6f, 0.6f };
393+
psc.Lights[1].Direction = { -0.57735f, -0.57735f, 0.57735f };
394+
psc.Lights[1].Strength = { 0.3f, 0.3f, 0.3f };
395+
psc.Lights[2].Direction = { 0.0f, -0.707f, -0.707f };
396+
psc.Lights[2].Strength = { 0.15f, 0.15f, 0.15f };
397+
gfxContext.SetDynamicConstantBufferView(1, sizeof(psc), &psc);
398+
329399
// 设置顶点视图
330400
gfxContext.SetVertexBuffer(0, m_VertexBuffer.VertexBufferView());
331401
// 设置索引视图
@@ -334,10 +404,36 @@ void GameApp::renderShapes(GraphicsContext& gfxContext)
334404
for (auto& item : m_vecShapes)
335405
{
336406
// 设置常量缓冲区数据
337-
gfxContext.SetDynamicConstantBufferView(0, sizeof(item.modelToWorld), &item.modelToWorld);
407+
ObjectConstants obc;
408+
obc.World = item.modelToWorld;
409+
gfxContext.SetDynamicConstantBufferView(0, sizeof(obc), &obc);
410+
411+
MaterialConstants mc;
412+
mc.DiffuseAlbedo = { item.diffuseAlbedo.x, item.diffuseAlbedo.y, item.diffuseAlbedo.z, item.diffuseAlbedo.w };
413+
mc.FresnelR0 = item.fresnelR0;
414+
mc.Roughness = item.roughness;
415+
gfxContext.SetDynamicConstantBufferView(2, sizeof(mc), &mc);
416+
338417
// 绘制
339418
gfxContext.DrawIndexedInstanced(item.indexCount, 1, item.startIndex, item.baseVertex, 0);
340419
}
420+
421+
// 绘制skull
422+
gfxContext.SetVertexBuffer(0, m_VertexBufferSkull.VertexBufferView());
423+
gfxContext.SetIndexBuffer(m_IndexBufferSkull.IndexBufferView());
424+
425+
ObjectConstants obc;
426+
obc.World = m_skull.modelToWorld;
427+
gfxContext.SetDynamicConstantBufferView(0, sizeof(obc), &obc);
428+
429+
MaterialConstants mc;
430+
mc.DiffuseAlbedo = { m_skull.diffuseAlbedo.x, m_skull.diffuseAlbedo.y, m_skull.diffuseAlbedo.z, m_skull.diffuseAlbedo.w };
431+
mc.FresnelR0 = m_skull.fresnelR0;
432+
mc.Roughness = m_skull.roughness;
433+
gfxContext.SetDynamicConstantBufferView(2, sizeof(mc), &mc);
434+
435+
// 绘制
436+
gfxContext.DrawIndexedInstanced(m_skull.indexCount, 1, m_skull.startIndex, m_skull.baseVertex, 0);
341437
}
342438

343439
void GameApp::buildLandAndWaves()
@@ -357,33 +453,7 @@ void GameApp::buildLandAndWaves()
357453
auto& p = grid.Vertices[i].Position;
358454
vertices[i].Pos = p;
359455
vertices[i].Pos.y = GetHillsHeight(p.x, p.z);
360-
361-
// Color the vertex based on its height.
362-
if (vertices[i].Pos.y < -10.0f)
363-
{
364-
// Sandy beach color.
365-
vertices[i].Color = XMFLOAT4(1.0f, 0.96f, 0.62f, 1.0f);
366-
}
367-
else if (vertices[i].Pos.y < 5.0f)
368-
{
369-
// Light yellow-green.
370-
vertices[i].Color = XMFLOAT4(0.48f, 0.77f, 0.46f, 1.0f);
371-
}
372-
else if (vertices[i].Pos.y < 12.0f)
373-
{
374-
// Dark yellow-green.
375-
vertices[i].Color = XMFLOAT4(0.1f, 0.48f, 0.19f, 1.0f);
376-
}
377-
else if (vertices[i].Pos.y < 20.0f)
378-
{
379-
// Dark brown.
380-
vertices[i].Color = XMFLOAT4(0.45f, 0.39f, 0.34f, 1.0f);
381-
}
382-
else
383-
{
384-
// White snow.
385-
vertices[i].Color = XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f);
386-
}
456+
vertices[i].Normal = GetHillsNormal(p.x, p.z);
387457
}
388458

389459
std::vector<std::uint16_t> indices = grid.GetIndices16();
@@ -423,11 +493,22 @@ float GameApp::GetHillsHeight(float x, float z) const
423493
return 0.3f* (z * sinf(0.1f * x) + x * cosf(0.1f * z));
424494
}
425495

426-
void GameApp::renderLandAndWaves(GraphicsContext& gfxContext)
496+
XMFLOAT3 GameApp::GetHillsNormal(float x, float z)const
427497
{
428-
// 设置常量缓冲区数据
429-
gfxContext.SetDynamicConstantBufferView(0, sizeof(m_waveWorld), &m_waveWorld);
498+
// n = (-df/dx, 1, -df/dz)
499+
XMFLOAT3 n(
500+
-0.03f * z * cosf(0.1f * x) - 0.3f * cosf(0.1f * z),
501+
1.0f,
502+
-0.3f * sinf(0.1f * x) + 0.03f * x * sinf(0.1f * z));
503+
504+
XMVECTOR unitNormal = XMVector3Normalize(XMLoadFloat3(&n));
505+
XMStoreFloat3(&n, unitNormal);
506+
507+
return n;
508+
}
430509

510+
void GameApp::renderLandAndWaves(GraphicsContext& gfxContext)
511+
{
431512
// land
432513
// 设置顶点视图
433514
gfxContext.SetVertexBuffer(0, m_VertexBufferLand.VertexBufferView());
@@ -477,7 +558,7 @@ void GameApp::UpdateWaves(float deltaT)
477558
Vertex v;
478559

479560
v.Pos = m_waves.Position(i);
480-
v.Color = XMFLOAT4(DirectX::Colors::Blue);
561+
v.Normal = m_waves.Normal(i);
481562

482563
m_verticesWaves.push_back(v);
483564
}

0 commit comments

Comments
 (0)