aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src/others/irrlicht-1.8.1/source/Irrlicht/CD3D9HLSLMaterialRenderer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/others/irrlicht-1.8.1/source/Irrlicht/CD3D9HLSLMaterialRenderer.cpp')
-rw-r--r--src/others/irrlicht-1.8.1/source/Irrlicht/CD3D9HLSLMaterialRenderer.cpp428
1 files changed, 428 insertions, 0 deletions
diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CD3D9HLSLMaterialRenderer.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CD3D9HLSLMaterialRenderer.cpp
new file mode 100644
index 0000000..131bdf5
--- /dev/null
+++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CD3D9HLSLMaterialRenderer.cpp
@@ -0,0 +1,428 @@
1// Copyright (C) 2002-2012 Nikolaus Gebhardt
2// This file is part of the "Irrlicht Engine".
3// For conditions of distribution and use, see copyright notice in irrlicht.h
4
5#include "IrrCompileConfig.h"
6#ifdef _IRR_COMPILE_WITH_DIRECT3D_9_
7
8#include "CD3D9HLSLMaterialRenderer.h"
9#include "IShaderConstantSetCallBack.h"
10#include "IVideoDriver.h"
11#include "os.h"
12#include "irrString.h"
13
14#ifndef _IRR_D3D_NO_SHADER_DEBUGGING
15#include <stdio.h>
16#endif
17
18
19namespace irr
20{
21namespace video
22{
23
24
25//! Public constructor
26CD3D9HLSLMaterialRenderer::CD3D9HLSLMaterialRenderer(IDirect3DDevice9* d3ddev,
27 video::IVideoDriver* driver, s32& outMaterialTypeNr,
28 const c8* vertexShaderProgram,
29 const c8* vertexShaderEntryPointName,
30 E_VERTEX_SHADER_TYPE vsCompileTarget,
31 const c8* pixelShaderProgram,
32 const c8* pixelShaderEntryPointName,
33 E_PIXEL_SHADER_TYPE psCompileTarget,
34 IShaderConstantSetCallBack* callback,
35 IMaterialRenderer* baseMaterial,
36 s32 userData)
37 : CD3D9ShaderMaterialRenderer(d3ddev, driver, callback, baseMaterial, userData),
38 VSConstantsTable(0), PSConstantsTable(0)
39{
40
41 #ifdef _DEBUG
42 setDebugName("CD3D9HLSLMaterialRenderer");
43 #endif
44
45 outMaterialTypeNr = -1;
46
47 // now create shaders
48
49 if (vsCompileTarget < 0 || vsCompileTarget > EVST_COUNT)
50 {
51 os::Printer::log("Invalid HLSL vertex shader compilation target", ELL_ERROR);
52 return;
53 }
54
55 if (!createHLSLVertexShader(vertexShaderProgram,
56 vertexShaderEntryPointName, VERTEX_SHADER_TYPE_NAMES[vsCompileTarget]))
57 return;
58
59 if (!createHLSLPixelShader(pixelShaderProgram,
60 pixelShaderEntryPointName, PIXEL_SHADER_TYPE_NAMES[psCompileTarget]))
61 return;
62
63 // register myself as new material
64 outMaterialTypeNr = Driver->addMaterialRenderer(this);
65}
66
67
68//! Destructor
69CD3D9HLSLMaterialRenderer::~CD3D9HLSLMaterialRenderer()
70{
71 if (VSConstantsTable)
72 VSConstantsTable->Release();
73
74 if (PSConstantsTable)
75 PSConstantsTable->Release();
76}
77
78
79bool CD3D9HLSLMaterialRenderer::createHLSLVertexShader(const char* vertexShaderProgram,
80 const char* shaderEntryPointName,
81 const char* shaderTargetName)
82{
83 if (!vertexShaderProgram)
84 return true;
85
86 LPD3DXBUFFER buffer = 0;
87 LPD3DXBUFFER errors = 0;
88
89#ifdef _IRR_D3D_NO_SHADER_DEBUGGING
90
91 // compile without debug info
92 HRESULT h = stubD3DXCompileShader(
93 vertexShaderProgram,
94 strlen(vertexShaderProgram),
95 0, // macros
96 0, // no includes
97 shaderEntryPointName,
98 shaderTargetName,
99 0, // no flags
100 &buffer,
101 &errors,
102 &VSConstantsTable);
103
104#else
105
106 // compile shader and emitt some debug informations to
107 // make it possible to debug the shader in visual studio
108
109 static int irr_dbg_hlsl_file_nr = 0;
110 ++irr_dbg_hlsl_file_nr;
111 char tmp[32];
112 sprintf(tmp, "irr_d3d9_dbg_hlsl_%d.vsh", irr_dbg_hlsl_file_nr);
113
114 FILE* f = fopen(tmp, "wb");
115 fwrite(vertexShaderProgram, strlen(vertexShaderProgram), 1, f);
116 fflush(f);
117 fclose(f);
118
119 HRESULT h = stubD3DXCompileShaderFromFile(
120 tmp,
121 0, // macros
122 0, // no includes
123 shaderEntryPointName,
124 shaderTargetName,
125 D3DXSHADER_DEBUG | D3DXSHADER_SKIPOPTIMIZATION,
126 &buffer,
127 &errors,
128 &VSConstantsTable);
129
130#endif
131
132 if (FAILED(h))
133 {
134 os::Printer::log("HLSL vertex shader compilation failed:", ELL_ERROR);
135 if (errors)
136 {
137 os::Printer::log((c8*)errors->GetBufferPointer(), ELL_ERROR);
138 errors->Release();
139 if (buffer)
140 buffer->Release();
141 }
142 return false;
143 }
144
145 if (errors)
146 errors->Release();
147
148 if (buffer)
149 {
150 if (FAILED(pID3DDevice->CreateVertexShader((DWORD*)buffer->GetBufferPointer(),
151 &VertexShader)))
152 {
153 os::Printer::log("Could not create hlsl vertex shader.", ELL_ERROR);
154 buffer->Release();
155 return false;
156 }
157
158 buffer->Release();
159 return true;
160 }
161
162 return false;
163}
164
165
166bool CD3D9HLSLMaterialRenderer::createHLSLPixelShader(const char* pixelShaderProgram,
167 const char* shaderEntryPointName,
168 const char* shaderTargetName)
169{
170 if (!pixelShaderProgram)
171 return true;
172
173 LPD3DXBUFFER buffer = 0;
174 LPD3DXBUFFER errors = 0;
175
176 DWORD flags = 0;
177
178#ifdef D3DXSHADER_ENABLE_BACKWARDS_COMPATIBILITY
179 if (Driver->queryFeature(video::EVDF_VERTEX_SHADER_2_0) || Driver->queryFeature(video::EVDF_VERTEX_SHADER_3_0))
180 // this one's for newer DX SDKs which don't support ps_1_x anymore
181 // instead they'll silently compile 1_x as 2_x when using this flag
182 flags |= D3DXSHADER_ENABLE_BACKWARDS_COMPATIBILITY;
183#endif
184#if defined(_IRR_D3D_USE_LEGACY_HLSL_COMPILER) && defined(D3DXSHADER_USE_LEGACY_D3DX9_31_DLL)
185#ifdef D3DXSHADER_ENABLE_BACKWARDS_COMPATIBILITY
186 else
187#endif
188 flags |= D3DXSHADER_USE_LEGACY_D3DX9_31_DLL;
189#endif
190
191#ifdef _IRR_D3D_NO_SHADER_DEBUGGING
192
193 // compile without debug info
194 HRESULT h = stubD3DXCompileShader(
195 pixelShaderProgram,
196 strlen(pixelShaderProgram),
197 0, // macros
198 0, // no includes
199 shaderEntryPointName,
200 shaderTargetName,
201 flags,
202 &buffer,
203 &errors,
204 &PSConstantsTable);
205
206#else
207
208 // compile shader and emitt some debug informations to
209 // make it possible to debug the shader in visual studio
210
211 static int irr_dbg_hlsl_file_nr = 0;
212 ++irr_dbg_hlsl_file_nr;
213 char tmp[32];
214 sprintf(tmp, "irr_d3d9_dbg_hlsl_%d.psh", irr_dbg_hlsl_file_nr);
215
216 FILE* f = fopen(tmp, "wb");
217 fwrite(pixelShaderProgram, strlen(pixelShaderProgram), 1, f);
218 fflush(f);
219 fclose(f);
220
221 HRESULT h = stubD3DXCompileShaderFromFile(
222 tmp,
223 0, // macros
224 0, // no includes
225 shaderEntryPointName,
226 shaderTargetName,
227 flags | D3DXSHADER_DEBUG | D3DXSHADER_SKIPOPTIMIZATION,
228 &buffer,
229 &errors,
230 &PSConstantsTable);
231
232#endif
233
234 if (FAILED(h))
235 {
236 os::Printer::log("HLSL pixel shader compilation failed:", ELL_ERROR);
237 if (errors)
238 {
239 os::Printer::log((c8*)errors->GetBufferPointer(), ELL_ERROR);
240 errors->Release();
241 if (buffer)
242 buffer->Release();
243 }
244 return false;
245 }
246
247 if (errors)
248 errors->Release();
249
250 if (buffer)
251 {
252 if (FAILED(pID3DDevice->CreatePixelShader((DWORD*)buffer->GetBufferPointer(),
253 &PixelShader)))
254 {
255 os::Printer::log("Could not create hlsl pixel shader.", ELL_ERROR);
256 buffer->Release();
257 return false;
258 }
259
260 buffer->Release();
261 return true;
262 }
263
264 return false;
265}
266
267
268bool CD3D9HLSLMaterialRenderer::setVariable(bool vertexShader, const c8* name,
269 const f32* floats, int count)
270{
271 LPD3DXCONSTANTTABLE tbl = vertexShader ? VSConstantsTable : PSConstantsTable;
272 if (!tbl)
273 return false;
274
275 // currently we only support top level parameters.
276 // Should be enough for the beginning. (TODO)
277
278 D3DXHANDLE hndl = tbl->GetConstantByName(NULL, name);
279 if (!hndl)
280 {
281 core::stringc s = "HLSL Variable to set not found: '";
282 s += name;
283 s += "'. Available variables are:";
284 os::Printer::log(s.c_str(), ELL_WARNING);
285 printHLSLVariables(tbl);
286 return false;
287 }
288
289 D3DXCONSTANT_DESC Description;
290 UINT ucount = 1;
291 tbl->GetConstantDesc(hndl, &Description, &ucount);
292
293 if(Description.RegisterSet != D3DXRS_SAMPLER)
294 {
295 HRESULT hr = tbl->SetFloatArray(pID3DDevice, hndl, floats, count);
296 if (FAILED(hr))
297 {
298 os::Printer::log("Error setting float array for HLSL variable", ELL_WARNING);
299 return false;
300 }
301 }
302
303 return true;
304}
305
306
307bool CD3D9HLSLMaterialRenderer::setVariable(bool vertexShader, const c8* name,
308 const bool* bools, int count)
309{
310 LPD3DXCONSTANTTABLE tbl = vertexShader ? VSConstantsTable : PSConstantsTable;
311 if (!tbl)
312 return false;
313
314 // currently we only support top level parameters.
315 // Should be enough for the beginning. (TODO)
316
317 D3DXHANDLE hndl = tbl->GetConstantByName(NULL, name);
318 if (!hndl)
319 {
320 core::stringc s = "HLSL Variable to set not found: '";
321 s += name;
322 s += "'. Available variables are:";
323 os::Printer::log(s.c_str(), ELL_WARNING);
324 printHLSLVariables(tbl);
325 return false;
326 }
327
328 D3DXCONSTANT_DESC Description;
329 UINT ucount = 1;
330 tbl->GetConstantDesc(hndl, &Description, &ucount);
331
332 if(Description.RegisterSet != D3DXRS_SAMPLER)
333 {
334 HRESULT hr = tbl->SetBoolArray(pID3DDevice, hndl, (BOOL*)bools, count);
335 if (FAILED(hr))
336 {
337 os::Printer::log("Error setting bool array for HLSL variable", ELL_WARNING);
338 return false;
339 }
340 }
341
342 return true;
343}
344
345
346bool CD3D9HLSLMaterialRenderer::setVariable(bool vertexShader, const c8* name,
347 const s32* ints, int count)
348{
349 LPD3DXCONSTANTTABLE tbl = vertexShader ? VSConstantsTable : PSConstantsTable;
350 if (!tbl)
351 return false;
352
353 // currently we only support top level parameters.
354 // Should be enough for the beginning. (TODO)
355
356 D3DXHANDLE hndl = tbl->GetConstantByName(NULL, name);
357 if (!hndl)
358 {
359 core::stringc s = "HLSL Variable to set not found: '";
360 s += name;
361 s += "'. Available variables are:";
362 os::Printer::log(s.c_str(), ELL_WARNING);
363 printHLSLVariables(tbl);
364 return false;
365 }
366
367 D3DXCONSTANT_DESC Description;
368 UINT ucount = 1;
369 tbl->GetConstantDesc(hndl, &Description, &ucount);
370
371 if(Description.RegisterSet != D3DXRS_SAMPLER)
372 {
373 HRESULT hr = tbl->SetIntArray(pID3DDevice, hndl, ints, count);
374 if (FAILED(hr))
375 {
376 os::Printer::log("Error setting int array for HLSL variable", ELL_WARNING);
377 return false;
378 }
379 }
380
381 return true;
382}
383
384
385bool CD3D9HLSLMaterialRenderer::OnRender(IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype)
386{
387 if (VSConstantsTable)
388 VSConstantsTable->SetDefaults(pID3DDevice);
389
390 return CD3D9ShaderMaterialRenderer::OnRender(service, vtxtype);
391}
392
393
394void CD3D9HLSLMaterialRenderer::printHLSLVariables(LPD3DXCONSTANTTABLE table)
395{
396 // currently we only support top level parameters.
397 // Should be enough for the beginning. (TODO)
398
399 // print out constant names
400 D3DXCONSTANTTABLE_DESC tblDesc;
401 HRESULT hr = table->GetDesc(&tblDesc);
402 if (!FAILED(hr))
403 {
404 for (int i=0; i<(int)tblDesc.Constants; ++i)
405 {
406 D3DXCONSTANT_DESC d;
407 UINT n = 1;
408 D3DXHANDLE cHndl = table->GetConstant(NULL, i);
409 if (!FAILED(table->GetConstantDesc(cHndl, &d, &n)))
410 {
411 core::stringc s = " '";
412 s += d.Name;
413 s += "' Registers:[begin:";
414 s += (int)d.RegisterIndex;
415 s += ", count:";
416 s += (int)d.RegisterCount;
417 s += "]";
418 os::Printer::log(s.c_str());
419 }
420 }
421 }
422}
423
424
425} // end namespace video
426} // end namespace irr
427
428#endif // _IRR_COMPILE_WITH_DIRECT3D_9_