Khaotic Engine Reborn
Loading...
Searching...
No Matches
depth_shader_class.cpp
1#include "depth_shader_class.h"
2
3
4depth_shader_class::depth_shader_class()
5{
6 vertex_shader_ = 0;
7 pixel_shader_ = 0;
8 layout_ = 0;
9 matrix_buffer_ = 0;
10 sample_state_ = 0;
11}
12
13
14depth_shader_class::depth_shader_class(const depth_shader_class& other)
15{
16}
17
18
19depth_shader_class::~depth_shader_class()
20{
21}
22
23
24bool depth_shader_class::initialize(ID3D11Device* device, HWND hwnd)
25{
26 Logger::Get().Log("Initializing texture shader", __FILE__, __LINE__, Logger::LogLevel::Initialize);
27
28 bool result;
29 wchar_t vsFilename[128];
30 wchar_t psFilename[128];
31 int error;
32 // Set the filename of the vertex shader.
33 error = wcscpy_s(vsFilename, 128, L"src/hlsl/depth.vs");
34 if (error != 0)
35 {
36 Logger::Get().Log("Error copying stirng", __FILE__, __LINE__, Logger::LogLevel::Error);
37 return false;
38 }
39
40 // Set the filename of the pixel shader.
41 error = wcscpy_s(psFilename, 128, L"src/hlsl/depth.ps");
42 if (error != 0)
43 {
44 Logger::Get().Log("Error copying stirng", __FILE__, __LINE__, Logger::LogLevel::Error);
45 return false;
46 }
47
48 // initialize the vertex and pixel shaders.
49 result = initialize_shader(device, hwnd, vsFilename, psFilename);
50 if (!result)
51 {
52 Logger::Get().Log("Error initializing shader", __FILE__, __LINE__, Logger::LogLevel::Error);
53 return false;
54 }
55
56 Logger::Get().Log("Texture shader initialized", __FILE__, __LINE__, Logger::LogLevel::Initialize);
57
58 return true;
59}
60
61void depth_shader_class::shutdown()
62{
63 // shutdown the vertex and pixel shaders as well as the related objects.
64 shutdown_shader();
65
66 return;
67}
68
69bool depth_shader_class::render(ID3D11DeviceContext* deviceContext, int indexCount, XMMATRIX worldMatrix, XMMATRIX viewMatrix,
70 XMMATRIX projectionMatrix, ID3D11ShaderResourceView* texture)
71{
72 bool result;
73
74
75 // Set the shader parameters that it will use for rendering.
76 result = set_shader_parameters(deviceContext, worldMatrix, viewMatrix, projectionMatrix, texture);
77 if (!result)
78 {
79 Logger::Get().Log("Error setting shader parameters", __FILE__, __LINE__, Logger::LogLevel::Error);
80 return false;
81 }
82
83 // Now render the prepared buffers with the shader.
84 render_shader(deviceContext, indexCount);
85
86 return true;
87}
88
89bool depth_shader_class::initialize_shader(ID3D11Device* device, HWND hwnd, WCHAR* vsFilename, WCHAR* psFilename)
90{
91 Logger::Get().Log("Initializing shader", __FILE__, __LINE__, Logger::LogLevel::Initialize);
92
93 HRESULT result;
94 ID3D10Blob* errorMessage;
95 ID3D10Blob* vertexShaderBuffer;
96 ID3D10Blob* pixelShaderBuffer;
97 D3D11_INPUT_ELEMENT_DESC polygonLayout[2];
98 unsigned int numElements;
99 D3D11_BUFFER_DESC matrixBufferDesc;
100 D3D11_SAMPLER_DESC samplerDesc;
101
102
103 // initialize the pointers this function will use to null.
104 errorMessage = 0;
105 vertexShaderBuffer = 0;
106 pixelShaderBuffer = 0;
107 // Compile the vertex shader code.
108 result = D3DCompileFromFile(vsFilename, NULL, NULL, "DepthVertexShader", "vs_5_0", D3D10_SHADER_ENABLE_STRICTNESS, 0,
109 &vertexShaderBuffer, &errorMessage);
110 if (FAILED(result))
111 {
112 // If the shader failed to compile it should have writen something to the error message.
113 if (errorMessage)
114 {
115 output_shader_error_message(errorMessage, hwnd, vsFilename);
116 }
117 // If there was nothing in the error message then it simply could not find the shader file itself.
118 else
119 {
120 Logger::Get().Log("Error compiling shader", __FILE__, __LINE__, Logger::LogLevel::Error);
121 }
122
123 return false;
124 }
125
126 // Compile the pixel shader code.
127 result = D3DCompileFromFile(psFilename, NULL, NULL, "DepthPixelShader", "ps_5_0", D3D10_SHADER_ENABLE_STRICTNESS, 0,
128 &pixelShaderBuffer, &errorMessage);
129 if (FAILED(result))
130 {
131 // If the shader failed to compile it should have writen something to the error message.
132 if (errorMessage)
133 {
134 output_shader_error_message(errorMessage, hwnd, psFilename);
135 }
136 // If there was nothing in the error message then it simply could not find the file itself.
137 else
138 {
139 Logger::Get().Log("Error compiling shader", __FILE__, __LINE__, Logger::LogLevel::Error);
140 }
141
142 return false;
143 }
144
145 // Create the vertex shader from the buffer.
146 result = device->CreateVertexShader(vertexShaderBuffer->GetBufferPointer(), vertexShaderBuffer->GetBufferSize(), NULL, &vertex_shader_);
147 if (FAILED(result))
148 {
149 Logger::Get().Log("Error creating vertex shader", __FILE__, __LINE__, Logger::LogLevel::Error);
150 return false;
151 }
152
153 // Create the pixel shader from the buffer.
154 result = device->CreatePixelShader(pixelShaderBuffer->GetBufferPointer(), pixelShaderBuffer->GetBufferSize(), NULL, &pixel_shader_);
155 if (FAILED(result))
156 {
157 Logger::Get().Log("Error creating pixel shader", __FILE__, __LINE__, Logger::LogLevel::Error);
158 return false;
159 }
160 // Create the vertex input layout description.
161 // This setup needs to match the VertexType stucture in the ModelClass and in the shader.
162 polygonLayout[0].SemanticName = "POSITION";
163 polygonLayout[0].SemanticIndex = 0;
164 polygonLayout[0].Format = DXGI_FORMAT_R32G32B32_FLOAT;
165 polygonLayout[0].InputSlot = 0;
166 polygonLayout[0].AlignedByteOffset = 0;
167 polygonLayout[0].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
168 polygonLayout[0].InstanceDataStepRate = 0;
169
170 polygonLayout[1].SemanticName = "TEXCOORD";
171 polygonLayout[1].SemanticIndex = 0;
172 polygonLayout[1].Format = DXGI_FORMAT_R32G32_FLOAT;
173 polygonLayout[1].InputSlot = 0;
174 polygonLayout[1].AlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT;
175 polygonLayout[1].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
176 polygonLayout[1].InstanceDataStepRate = 0;
177
178 // Get a count of the elements in the layout.
179 numElements = sizeof(polygonLayout) / sizeof(polygonLayout[0]);
180
181 // Create the vertex input layout.
182 result = device->CreateInputLayout(polygonLayout, numElements, vertexShaderBuffer->GetBufferPointer(),
183 vertexShaderBuffer->GetBufferSize(), &layout_);
184 if (FAILED(result))
185 {
186 Logger::Get().Log("Error creating input layout", __FILE__, __LINE__, Logger::LogLevel::Error);
187 return false;
188 }
189
190 // Release the vertex shader buffer and pixel shader buffer since they are no longer needed.
191 vertexShaderBuffer->Release();
192 vertexShaderBuffer = 0;
193
194 pixelShaderBuffer->Release();
195 pixelShaderBuffer = 0;
196
197 // Setup the description of the dynamic matrix constant buffer that is in the vertex shader.
198 matrixBufferDesc.Usage = D3D11_USAGE_DYNAMIC;
199 matrixBufferDesc.ByteWidth = sizeof(matrix_buffer_type);
200 matrixBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
201 matrixBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
202 matrixBufferDesc.MiscFlags = 0;
203 matrixBufferDesc.StructureByteStride = 0;
204
205 // Create the constant buffer pointer so we can access the vertex shader constant buffer from within this class.
206 result = device->CreateBuffer(&matrixBufferDesc, NULL, &matrix_buffer_);
207 if (FAILED(result))
208 {
209 Logger::Get().Log("Error creating constant buffer", __FILE__, __LINE__, Logger::LogLevel::Error);
210 return false;
211 }
212 // Create a texture sampler state description.
213 samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
214 samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
215 samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
216 samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
217 samplerDesc.MipLODBias = 0.0f;
218 samplerDesc.MaxAnisotropy = 1;
219 samplerDesc.ComparisonFunc = D3D11_COMPARISON_ALWAYS;
220 samplerDesc.BorderColor[0] = 0;
221 samplerDesc.BorderColor[1] = 0;
222 samplerDesc.BorderColor[2] = 0;
223 samplerDesc.BorderColor[3] = 0;
224 samplerDesc.MinLOD = 0;
225 samplerDesc.MaxLOD = D3D11_FLOAT32_MAX;
226
227 // Create the texture sampler state.
228 result = device->CreateSamplerState(&samplerDesc, &sample_state_);
229 if (FAILED(result))
230 {
231 Logger::Get().Log("Error creating sampler state", __FILE__, __LINE__, Logger::LogLevel::Error);
232 return false;
233 }
234
235 Logger::Get().Log("Shader initialized", __FILE__, __LINE__, Logger::LogLevel::Initialize);
236
237 return true;
238}
239
240void depth_shader_class::shutdown_shader()
241{
242 Logger::Get().Log("Shutting down shader", __FILE__, __LINE__, Logger::LogLevel::Shutdown);
243
244 // Release the sampler state.
245 if (sample_state_)
246 {
247 sample_state_->Release();
248 sample_state_ = 0;
249 }
250
251 // Release the matrix constant buffer.
252 if (matrix_buffer_)
253 {
254 matrix_buffer_->Release();
255 matrix_buffer_ = 0;
256 }
257
258 // Release the layout.
259 if (layout_)
260 {
261 layout_->Release();
262 layout_ = 0;
263 }
264
265 // Release the pixel shader.
266 if (pixel_shader_)
267 {
268 pixel_shader_->Release();
269 pixel_shader_ = 0;
270 }
271
272 // Release the vertex shader.
273 if (vertex_shader_)
274 {
275 vertex_shader_->Release();
276 vertex_shader_ = 0;
277 }
278
279 Logger::Get().Log("Shader shut down", __FILE__, __LINE__, Logger::LogLevel::Shutdown);
280
281 return;
282}
283
284void depth_shader_class::output_shader_error_message(ID3D10Blob* errorMessage, HWND hwnd, WCHAR* shaderFilename)
285{
286 char* compileErrors;
287 unsigned long long bufferSize, i;
288 ofstream fout;
289
290
291 // Get a pointer to the error message text buffer.
292 compileErrors = (char*)(errorMessage->GetBufferPointer());
293
294 // Get the length of the message.
295 bufferSize = errorMessage->GetBufferSize();
296
297 // Open a file to write the error message to.
298 fout.open("shader-error.txt");
299
300 // Write out the error message.
301 for (i = 0; i < bufferSize; i++)
302 {
303 fout << compileErrors[i];
304 }
305
306 // Close the file.
307 fout.close();
308
309 // Release the error message.
310 errorMessage->Release();
311 errorMessage = 0;
312
313 // Pop a message up on the screen to notify the user to check the text file for compile errors.
314 MessageBox(hwnd, L"Error compiling shader. Check shader-error.txt for message.", shaderFilename, MB_OK);
315
316 return;
317}
318
319bool depth_shader_class::set_shader_parameters(ID3D11DeviceContext* deviceContext, XMMATRIX worldMatrix, XMMATRIX viewMatrix,
320 XMMATRIX projectionMatrix, ID3D11ShaderResourceView* texture)
321{
322 HRESULT result;
323 D3D11_MAPPED_SUBRESOURCE mappedResource;
324 matrix_buffer_type* dataPtr;
325 unsigned int bufferNumber;
326
327
328 // Transpose the matrices to prepare them for the shader.
329 worldMatrix = XMMatrixTranspose(worldMatrix);
330 viewMatrix = XMMatrixTranspose(viewMatrix);
331 projectionMatrix = XMMatrixTranspose(projectionMatrix);
332
333 // Lock the constant buffer so it can be written to.
334 result = deviceContext->Map(matrix_buffer_, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
335 if (FAILED(result))
336 {
337 Logger::Get().Log("Error mapping constant buffer", __FILE__, __LINE__, Logger::LogLevel::Error);
338 return false;
339 }
340
341 // Get a pointer to the data in the constant buffer.
342 dataPtr = (matrix_buffer_type*)mappedResource.pData;
343
344 // Copy the matrices into the constant buffer.
345 dataPtr->world = worldMatrix;
346 dataPtr->view = viewMatrix;
347 dataPtr->projection = projectionMatrix;
348
349 // Unlock the constant buffer.
350 deviceContext->Unmap(matrix_buffer_, 0);
351
352 // Set the position of the constant buffer in the vertex shader.
353 bufferNumber = 0;
354
355 // Finanly set the constant buffer in the vertex shader with the updated values.
356 deviceContext->VSSetConstantBuffers(bufferNumber, 1, &matrix_buffer_);
357 // Set shader texture resource in the pixel shader.
358 deviceContext->PSSetShaderResources(0, 1, &texture);
359
360 return true;
361}
362
363void depth_shader_class::render_shader(ID3D11DeviceContext* deviceContext, int indexCount)
364{
365 // Set the vertex input layout.
366 deviceContext->IASetInputLayout(layout_);
367
368 // Set the vertex and pixel shaders that will be used to render this triangle.
369 deviceContext->VSSetShader(vertex_shader_, NULL, 0);
370 deviceContext->PSSetShader(pixel_shader_, NULL, 0);
371 // Set the sampler state in the pixel shader.
372 deviceContext->PSSetSamplers(0, 1, &sample_state_);
373
374 // render the triangle.
375 deviceContext->DrawIndexed(indexCount, 0, 0);
376
377 return;
378}
static Logger & Get()
Definition Logger.h:20
void Log(const std::string &message, const std::string &fileName, int lineNumber, LogLevel level=LogLevel::Info)
Definition Logger.h:158