-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathCubeScene.cpp
241 lines (195 loc) · 8.43 KB
/
CubeScene.cpp
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
#include "CubeScene.h"
#include "Common.h"
#include "ShaderManager.h"
#include "ShaderStage.h"
using namespace DirectX;
CubeScene::CubeScene(): m_indexCount(0)
{
}
CubeScene::~CubeScene()
{
SAFE_RELEASE(vertex_buffer_);
SAFE_RELEASE(index_buffer_);
SAFE_RELEASE(input_layout_);
SAFE_RELEASE(input_layout_extended_);
SAFE_RELEASE(constant_buffer_);
}
bool CubeScene::Initialize(Renderer* renderer)
{
auto device = renderer->Device();
// initialize world, view, and projection matrices
world_ = renderer->GetWorldMatrix();
view_ = renderer->GetViewMatrix();
projection_ = renderer->GetProjectionMatrix();
// Create vertex buffer
VertexPositionNormal vertices[] =
{
{DirectX::XMFLOAT3(-1.0f, 1.0f, -1.0f), DirectX::XMFLOAT3(0.0f, 1.0f, 0.0f) },
{DirectX::XMFLOAT3(1.0f, 1.0f, -1.0f), DirectX::XMFLOAT3(0.0f, 1.0f, 0.0f) },
{ DirectX::XMFLOAT3(1.0f, 1.0f, 1.0f), DirectX::XMFLOAT3(0.0f, 1.0f, 0.0f) },
{ DirectX::XMFLOAT3(-1.0f, 1.0f, 1.0f), DirectX::XMFLOAT3(0.0f, 1.0f, 0.0f) },
{ DirectX::XMFLOAT3(-1.0f, -1.0f, -1.0f), DirectX::XMFLOAT3(0.0f, -1.0f, 0.0f) },
{ DirectX::XMFLOAT3(1.0f, -1.0f, -1.0f), DirectX::XMFLOAT3(0.0f, -1.0f, 0.0f) },
{ DirectX::XMFLOAT3(1.0f, -1.0f, 1.0f), DirectX::XMFLOAT3(0.0f, -1.0f, 0.0f) },
{ DirectX::XMFLOAT3(-1.0f, -1.0f, 1.0f), DirectX::XMFLOAT3(0.0f, -1.0f, 0.0f) },
{ DirectX::XMFLOAT3(-1.0f, -1.0f, 1.0f), DirectX::XMFLOAT3(-1.0f, 0.0f, 0.0f) },
{ DirectX::XMFLOAT3(-1.0f, -1.0f, -1.0f), DirectX::XMFLOAT3(-1.0f, 0.0f, 0.0f) },
{ DirectX::XMFLOAT3(-1.0f, 1.0f, -1.0f), DirectX::XMFLOAT3(-1.0f, 0.0f, 0.0f) },
{ DirectX::XMFLOAT3(-1.0f, 1.0f, 1.0f), DirectX::XMFLOAT3(-1.0f, 0.0f, 0.0f) },
{ DirectX::XMFLOAT3(1.0f, -1.0f, 1.0f), DirectX::XMFLOAT3(1.0f, 0.0f, 0.0f) },
{ DirectX::XMFLOAT3(1.0f, -1.0f, -1.0f), DirectX::XMFLOAT3(1.0f, 0.0f, 0.0f) },
{ DirectX::XMFLOAT3(1.0f, 1.0f, -1.0f), DirectX::XMFLOAT3(1.0f, 0.0f, 0.0f) },
{ DirectX::XMFLOAT3(1.0f, 1.0f, 1.0f), DirectX::XMFLOAT3(1.0f, 0.0f, 0.0f) },
{ DirectX::XMFLOAT3(-1.0f, -1.0f, -1.0f), DirectX::XMFLOAT3(0.0f, 0.0f, -1.0f) },
{ DirectX::XMFLOAT3(1.0f, -1.0f, -1.0f), DirectX::XMFLOAT3(0.0f, 0.0f, -1.0f) },
{ DirectX::XMFLOAT3(1.0f, 1.0f, -1.0f), DirectX::XMFLOAT3(0.0f, 0.0f, -1.0f) },
{ DirectX::XMFLOAT3(-1.0f, 1.0f, -1.0f), DirectX::XMFLOAT3(0.0f, 0.0f, -1.0f) },
{ DirectX::XMFLOAT3(-1.0f, -1.0f, 1.0f), DirectX::XMFLOAT3(0.0f, 0.0f, 1.0f) },
{ DirectX::XMFLOAT3(1.0f, -1.0f, 1.0f), DirectX::XMFLOAT3(0.0f, 0.0f, 1.0f) },
{ DirectX::XMFLOAT3(1.0f, 1.0f, 1.0f), DirectX::XMFLOAT3(0.0f, 0.0f, 1.0f) },
{ DirectX::XMFLOAT3(-1.0f, 1.0f, 1.0f), DirectX::XMFLOAT3(0.0f, 0.0f, 1.0f) },
};
// Create vertex buffer:
CD3D11_BUFFER_DESC vDesc(
sizeof(VertexPositionNormal) * 24,
D3D11_BIND_VERTEX_BUFFER,
D3D11_USAGE_IMMUTABLE
);
D3D11_SUBRESOURCE_DATA vData;
ZeroMemory(&vData, sizeof(vData));
vData.pSysMem = vertices;
vData.SysMemPitch = 0;
vData.SysMemSlicePitch = 0;
HRESULT hr = device->CreateBuffer(&vDesc, &vData, &vertex_buffer_);
if (FAILED(hr))
return false;
// Create index buffer:
WORD CubeIndices[] =
{
3,1,0,
2,1,3,
6,4,5,
7,4,6,
11,9,8,
10,9,11,
14,12,13,
15,12,14,
19,17,16,
18,17,19,
22,20,21,
23,20,22
};
m_indexCount = ARRAYSIZE(CubeIndices);
CD3D11_BUFFER_DESC iDesc(
sizeof(WORD) * 36,
D3D11_BIND_INDEX_BUFFER,
D3D11_USAGE_IMMUTABLE
);
D3D11_SUBRESOURCE_DATA iData;
ZeroMemory(&iData, sizeof(D3D11_SUBRESOURCE_DATA));
iData.pSysMem = CubeIndices;
iData.SysMemPitch = 0;
iData.SysMemSlicePitch = 0;
device->CreateBuffer(&iDesc, &iData, &index_buffer_);
// Create the constant buffer
D3D11_BUFFER_DESC bd;
ZeroMemory(&bd, sizeof(bd));
bd.Usage = D3D11_USAGE_DEFAULT;
bd.ByteWidth = sizeof(ConstantBufferStruct);
bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
bd.CPUAccessFlags = 0;
hr = device->CreateBuffer(&bd, nullptr, &constant_buffer_);
if (FAILED(hr))
return false;
D3D11_INPUT_ELEMENT_DESC layout[] =
{
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
};
const auto source = ShaderManager::Instance().GetShaderSource("Cube_VS");
if (source == nullptr)
return false;
ID3D11InputLayout* input_layout = nullptr;
hr = device->CreateInputLayout(layout, ARRAYSIZE(layout), source->Blob()->GetBufferPointer(), source->Blob()->GetBufferSize(), &input_layout);
input_layout_ = input_layout;
return !FAILED(hr);
}
bool CubeScene::Update(Renderer* renderer, float elapsed)
{
// Rotate the cube.
static float t = 0.0f;
static ULONGLONG timeStart = 0;
ULONGLONG timeCur = GetTickCount64();
if (timeStart == 0)
{
timeStart = timeCur;
}
t = (timeCur - timeStart) / 1000.0f;
// Rotate cube around the origin
world_ = DirectX::XMMatrixRotationY(t);
// Setup our lighting parameters
DirectX::XMFLOAT4 vLightDirs[2] =
{
DirectX::XMFLOAT4(-0.577f, 0.577f, -0.577f, 1.0f),
DirectX::XMFLOAT4(0.0f, 0.0f, -1.0f, 1.0f),
};
// Rotate the second light around the origin
DirectX::XMMATRIX mRotate = DirectX::XMMatrixRotationY(-2.0f * t);
XMVECTOR vLightDir = XMLoadFloat4(&vLightDirs[1]);
vLightDir = DirectX::XMVector3Transform(vLightDir, mRotate);
DirectX::XMStoreFloat4(&vLightDirs[1], vLightDir);
m_lightDirs[0] = vLightDirs[0];
m_lightDirs[1] = vLightDirs[1];
// update member constant buffer
// The transpose is used below because HLSL stores matrices in column-major order.
// To make sure wold matrix is used inside shader as it is here, we transpose.
// To disable HLSL to use column-major matrix storage, set D3D10_SHADER_PACK_MATRIX_ROW_MAJOR during
// shader compilation
m_constantBufferData.world = XMMatrixTranspose(world_);
m_constantBufferData.view = XMMatrixTranspose(view_);
m_constantBufferData.projection = XMMatrixTranspose(projection_);
m_constantBufferData.vLightDir[0] = m_lightDirs[0];
m_constantBufferData.vLightDir[1] = m_lightDirs[1];
m_constantBufferData.vLightColor[0] = m_lightColors[0];
m_constantBufferData.vLightColor[1] = m_lightColors[1];
m_constantBufferData.vOutputColor = XMFLOAT4(0, 0, 0, 0);
return true;
}
bool CubeScene::Render(Renderer* renderer)
{
auto pipeline = renderer->RenderingPipeline();
auto ia_stage = pipeline->GetInputAssemblerStage();
auto context = renderer->Context();
// Set up the IA stage by setting the input topology and layout.
UINT stride = sizeof(VertexPositionNormal);
UINT offset = 0;
ia_stage->SetVertexBuffers(0, 1, &vertex_buffer_, &stride, &offset);
ia_stage->SetIndexBuffer(index_buffer_, DXGI_FORMAT_R16_UINT, 0);
ia_stage->SetInputLayout(input_layout_);
ia_stage->SetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
context->UpdateSubresource(constant_buffer_, 0, nullptr, &m_constantBufferData, 0, 0);
const auto vertex_shader = ShaderManager::Instance().GetShader("Cube_VS");
auto vs_stage = pipeline->GetVertexShaderStage();
vs_stage->State()->SetShader(vertex_shader);
vs_stage->State()->SetConstantBuffers(0, 1, &constant_buffer_);
const auto pixel_shader = ShaderManager::Instance().GetShader("Cube_PS");
auto ps_stage = pipeline->GetPixelShaderStage();
ps_stage->State()->SetShader(pixel_shader);
ps_stage->State()->SetConstantBuffers(0, 1, &constant_buffer_);
renderer->DrawIndexed(m_indexCount, 0, 0);
// Render each light
const auto pixel_shader_solid = ShaderManager::Instance().GetShader("Cube_PSSolid");
for (int m = 0; m < 2; m++)
{
XMMATRIX mLight = XMMatrixTranslationFromVector(5.0f * XMLoadFloat4(&m_lightDirs[m]));
XMMATRIX mLightScale = XMMatrixScaling(0.2f, 0.2f, 0.2f);
mLight = mLightScale * mLight;
// Update the world variable to reflect the current light
m_constantBufferData.world = XMMatrixTranspose(mLight);
m_constantBufferData.vOutputColor = m_lightColors[m];
renderer->UpdateSubresource(constant_buffer_, 0, nullptr, &m_constantBufferData, 0, 0);
ps_stage->State()->SetShader(pixel_shader_solid);
renderer->DrawIndexed(36, 0, 0);
}
return true;
}