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