aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src/others/irrlicht-1.8.1/source/Irrlicht/CD3D8ShaderMaterialRenderer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/others/irrlicht-1.8.1/source/Irrlicht/CD3D8ShaderMaterialRenderer.cpp')
-rw-r--r--src/others/irrlicht-1.8.1/source/Irrlicht/CD3D8ShaderMaterialRenderer.cpp332
1 files changed, 332 insertions, 0 deletions
diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CD3D8ShaderMaterialRenderer.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CD3D8ShaderMaterialRenderer.cpp
new file mode 100644
index 0000000..f46d583
--- /dev/null
+++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CD3D8ShaderMaterialRenderer.cpp
@@ -0,0 +1,332 @@
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 "CD3D8ShaderMaterialRenderer.h"
6
7#include "IrrCompileConfig.h"
8#ifdef _IRR_COMPILE_WITH_DIRECT3D_8_
9#include <d3d8.h>
10#include <d3dx8core.h>
11#pragma comment (lib, "d3dx8.lib")
12
13#include "IShaderConstantSetCallBack.h"
14#include "IMaterialRendererServices.h"
15#include "IVideoDriver.h"
16#include "os.h"
17
18#ifndef _IRR_D3D_NO_SHADER_DEBUGGING
19#include <stdio.h>
20#endif
21
22namespace irr
23{
24namespace video
25{
26
27//! Public constructor
28CD3D8ShaderMaterialRenderer::CD3D8ShaderMaterialRenderer(IDirect3DDevice8* d3ddev, video::IVideoDriver* driver,
29 s32& outMaterialTypeNr, const c8* vertexShaderProgram, const c8* pixelShaderProgram,
30 IShaderConstantSetCallBack* callback, IMaterialRenderer* baseMaterial, s32 userData)
31: pID3DDevice(d3ddev), Driver(driver), CallBack(callback), BaseMaterial(baseMaterial),
32 VertexShader(0), OldVertexShader(0), PixelShader(0), UserData(userData)
33{
34
35 #ifdef _DEBUG
36 setDebugName("CD3D8ShaderMaterialRenderer");
37 #endif
38
39 if (BaseMaterial)
40 BaseMaterial->grab();
41
42 if (CallBack)
43 CallBack->grab();
44
45 init(outMaterialTypeNr, vertexShaderProgram, pixelShaderProgram, EVT_STANDARD);
46}
47
48//! constructor only for use by derived classes who want to
49//! create a fall back material for example.
50CD3D8ShaderMaterialRenderer::CD3D8ShaderMaterialRenderer(IDirect3DDevice8* d3ddev,
51 video::IVideoDriver* driver,
52 IShaderConstantSetCallBack* callback,
53 IMaterialRenderer* baseMaterial,
54 s32 userData)
55: pID3DDevice(d3ddev), Driver(driver), BaseMaterial(baseMaterial), CallBack(callback),
56 VertexShader(0), PixelShader(0), UserData(userData)
57{
58 if (BaseMaterial)
59 BaseMaterial->grab();
60
61 if (CallBack)
62 CallBack->grab();
63}
64
65
66
67//! Destructor
68CD3D8ShaderMaterialRenderer::~CD3D8ShaderMaterialRenderer()
69{
70 if (CallBack)
71 CallBack->drop();
72
73 if (VertexShader)
74 pID3DDevice->DeleteVertexShader(VertexShader);
75
76 if (PixelShader)
77 pID3DDevice->DeletePixelShader(PixelShader);
78
79 if (BaseMaterial)
80 BaseMaterial->drop ();
81}
82
83
84void CD3D8ShaderMaterialRenderer::init(s32& outMaterialTypeNr, const c8* vertexShaderProgram,
85 const c8* pixelShaderProgram, E_VERTEX_TYPE type)
86{
87 outMaterialTypeNr = -1;
88
89 // create vertex shader
90 if (!createVertexShader(vertexShaderProgram, type))
91 return;
92
93 // create pixel shader
94 if (!createPixelShader(pixelShaderProgram))
95 return;
96
97 // register myself as new material
98 outMaterialTypeNr = Driver->addMaterialRenderer(this);
99}
100
101
102bool CD3D8ShaderMaterialRenderer::OnRender(IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype)
103{
104 // call callback to set shader constants
105 if (CallBack && (VertexShader || PixelShader))
106 CallBack->OnSetConstants(service, UserData);
107
108 return true;
109}
110
111
112void CD3D8ShaderMaterialRenderer::OnSetMaterial(const video::SMaterial& material, const video::SMaterial& lastMaterial,
113 bool resetAllRenderstates, video::IMaterialRendererServices* services)
114{
115 if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates)
116 {
117 if (VertexShader)
118 {
119 // We do not need to save and reset the old vertex shader, because
120 // in D3D8, this is mixed up with the fvf, and this is set by the driver
121 // every time.
122 //pID3DDevice->GetVertexShader(&OldVertexShader);
123
124 // set new vertex shader
125 if (FAILED(pID3DDevice->SetVertexShader(VertexShader)))
126 os::Printer::log("Could not set vertex shader.", ELL_ERROR);
127 }
128
129 // set new pixel shader
130 if (PixelShader)
131 {
132 if (FAILED(pID3DDevice->SetPixelShader(PixelShader)))
133 os::Printer::log("Could not set pixel shader.", ELL_ERROR);
134 }
135
136 if (BaseMaterial)
137 BaseMaterial->OnSetMaterial(material, material, true, services);
138 }
139
140 //let callback know used material
141 if (CallBack)
142 CallBack->OnSetMaterial(material);
143
144 services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
145}
146
147void CD3D8ShaderMaterialRenderer::OnUnsetMaterial()
148{
149 // We do not need to save and reset the old vertex shader, because
150 // in D3D8, this is mixed up with the fvf, and this is set by the driver
151 // every time.
152 // if (VertexShader)
153 // pID3DDevice->SetVertexShader(OldVertexShader);
154
155 if (PixelShader)
156 pID3DDevice->SetPixelShader(0);
157
158 if (BaseMaterial)
159 BaseMaterial->OnUnsetMaterial();
160}
161
162
163//! Returns if the material is transparent. The scene managment needs to know this
164//! for being able to sort the materials by opaque and transparent.
165bool CD3D8ShaderMaterialRenderer::isTransparent() const
166{
167 return BaseMaterial ? BaseMaterial->isTransparent() : false;
168}
169
170bool CD3D8ShaderMaterialRenderer::createPixelShader(const c8* pxsh)
171{
172 if (!pxsh)
173 return true;
174
175#if defined( _IRR_XBOX_PLATFORM_)
176 return false;
177#else
178 // compile shader
179
180 LPD3DXBUFFER code = 0;
181 LPD3DXBUFFER errors = 0;
182
183 #ifdef _IRR_D3D_NO_SHADER_DEBUGGING
184
185 // compile shader without debug info
186 D3DXAssembleShader(pxsh, (UINT)strlen(pxsh), 0, 0, &code, &errors);
187
188 #else
189
190 // compile shader and emitt some debug informations to
191 // make it possible to debug the shader in visual studio
192
193 static int irr_dbg_file_nr = 0;
194 ++irr_dbg_file_nr;
195 char tmp[32];
196 sprintf(tmp, "irr_d3d8_dbg_shader_%d.psh", irr_dbg_file_nr);
197
198 FILE* f = fopen(tmp, "wb");
199 fwrite(pxsh, strlen(pxsh), 1, f);
200 fflush(f);
201 fclose(f);
202
203 D3DXAssembleShaderFromFile(tmp, D3DXASM_DEBUG, 0, &code, &errors);
204 #endif
205 if (errors)
206 {
207 // print out compilation errors.
208 os::Printer::log("Pixel shader compilation failed:", ELL_ERROR);
209 os::Printer::log((c8*)errors->GetBufferPointer(), ELL_ERROR);
210
211 if (code)
212 code->Release();
213
214 errors->Release();
215 return false;
216 }
217
218 if (FAILED(pID3DDevice->CreatePixelShader((DWORD*)code->GetBufferPointer(), &PixelShader)))
219 {
220 os::Printer::log("Could not create pixel shader.", ELL_ERROR);
221 code->Release();
222 return false;
223 }
224
225 code->Release();
226 return true;
227#endif
228
229}
230
231
232
233bool CD3D8ShaderMaterialRenderer::createVertexShader(const char* vtxsh, E_VERTEX_TYPE type)
234{
235 if (!vtxsh)
236 return true;
237
238 // compile shader
239#if defined( _IRR_XBOX_PLATFORM_)
240 return false;
241#else
242
243 LPD3DXBUFFER code = 0;
244 LPD3DXBUFFER errors = 0;
245
246 #ifdef _IRR_D3D_NO_SHADER_DEBUGGING
247
248 // compile shader without debug info
249 D3DXAssembleShader(vtxsh, (UINT)strlen(vtxsh), 0, 0, &code, &errors);
250
251 #else
252
253 // compile shader and emitt some debug informations to
254 // make it possible to debug the shader in visual studio
255 static int irr_dbg_file_nr = 0;
256 ++irr_dbg_file_nr;
257 char tmp[32];
258 sprintf(tmp, "irr_d3d8_dbg_shader_%d.vsh", irr_dbg_file_nr);
259
260 FILE* f = fopen(tmp, "wb");
261 fwrite(vtxsh, strlen(vtxsh), 1, f);
262 fflush(f);
263 fclose(f);
264
265 D3DXAssembleShaderFromFile(tmp, D3DXASM_DEBUG, 0, &code, &errors);
266
267 #endif
268
269
270 if (errors)
271 {
272 // print out compilation errors.
273 os::Printer::log("Vertex shader compilation failed:", ELL_ERROR);
274 os::Printer::log((c8*)errors->GetBufferPointer(), ELL_ERROR);
275
276 if (code)
277 code->Release();
278
279 errors->Release();
280 return false;
281 }
282
283 DWORD* decl = 0;
284
285 DWORD dwStdDecl[] =
286 {
287 D3DVSD_STREAM(0),
288 D3DVSD_REG(0, D3DVSDT_FLOAT3), // position 0
289 D3DVSD_REG(1, D3DVSDT_FLOAT3), // normal 1
290 D3DVSD_REG(2, D3DVSDT_D3DCOLOR ),// color 2
291 D3DVSD_REG(3, D3DVSDT_FLOAT2 ), // tex1 3
292 D3DVSD_REG(4, D3DVSDT_FLOAT2 ), // tex2 4
293 D3DVSD_END()
294 };
295
296 DWORD dwTngtDecl[] =
297 {
298 D3DVSD_STREAM(0),
299 D3DVSD_REG(0 , D3DVSDT_FLOAT3), // position 0
300 D3DVSD_REG(1 , D3DVSDT_FLOAT3), // normal 1
301 D3DVSD_REG(2 , D3DVSDT_D3DCOLOR ),// color 2
302 D3DVSD_REG(3 , D3DVSDT_FLOAT2 ), // tex1 3
303 D3DVSD_REG(4, D3DVSDT_FLOAT3 ), // tangent 4
304 D3DVSD_REG(5, D3DVSDT_FLOAT3 ), // binormal 5
305 D3DVSD_END()
306 };
307
308 if (type == EVT_TANGENTS)
309 decl = dwTngtDecl;
310 else
311 decl = dwStdDecl;
312
313 if (FAILED(pID3DDevice->CreateVertexShader(decl,
314 (DWORD*)code->GetBufferPointer(), &VertexShader, 0)))
315 {
316 os::Printer::log("Could not create vertex shader.", ELL_ERROR);
317 code->Release();
318 return false;
319 }
320
321 code->Release();
322 return true;
323#endif
324}
325
326
327
328} // end namespace video
329} // end namespace irr
330
331#endif // _IRR_COMPILE_WITH_DIRECT3D_8_
332