1 // Copyright (C) 2012 Patryk Nadrowski
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_CG_
7
8 #include "CCgMaterialRenderer.h"
9
10 namespace irr
11 {
12 namespace video
13 {
14
CCgUniform(const CGparameter & parameter,bool global)15 CCgUniform::CCgUniform(const CGparameter& parameter, bool global) : Parameter(parameter), Type(CG_UNKNOWN_TYPE)
16 {
17 Name = cgGetParameterName(Parameter);
18
19 if(global)
20 Space = CG_GLOBAL;
21 else
22 Space = CG_PROGRAM;
23 }
24
getName() const25 const core::stringc& CCgUniform::getName() const
26 {
27 return Name;
28 }
29
getParameter() const30 const CGparameter& CCgUniform::getParameter() const
31 {
32 return Parameter;
33 }
34
getSpace() const35 CGenum CCgUniform::getSpace() const
36 {
37 return Space;
38 }
39
getType() const40 CGtype CCgUniform::getType() const
41 {
42 return Type;
43 }
44
CCgUniform1f(const CGparameter & parameter,bool global)45 CCgUniform1f::CCgUniform1f(const CGparameter& parameter, bool global) : CCgUniform(parameter, global)
46 {
47 Type = CG_FLOAT;
48 }
49
update(const void * data,const SMaterial & material) const50 void CCgUniform1f::update(const void* data, const SMaterial& material) const
51 {
52 f32* Data = (f32*)data;
53 cgSetParameter1f(Parameter, *Data);
54 }
55
CCgUniform2f(const CGparameter & parameter,bool global)56 CCgUniform2f::CCgUniform2f(const CGparameter& parameter, bool global) : CCgUniform(parameter, global)
57 {
58 Type = CG_FLOAT2;
59 }
60
update(const void * data,const SMaterial & material) const61 void CCgUniform2f::update(const void* data, const SMaterial& material) const
62 {
63 f32* Data = (f32*)data;
64 cgSetParameter2f(Parameter, *Data, *(Data+1));
65 }
66
CCgUniform3f(const CGparameter & parameter,bool global)67 CCgUniform3f::CCgUniform3f(const CGparameter& parameter, bool global) : CCgUniform(parameter, global)
68 {
69 Type = CG_FLOAT3;
70 }
71
update(const void * data,const SMaterial & material) const72 void CCgUniform3f::update(const void* data, const SMaterial& material) const
73 {
74 f32* Data = (f32*)data;
75 cgSetParameter3f(Parameter, *Data, *(Data+1), *(Data+2));
76 }
77
CCgUniform4f(const CGparameter & parameter,bool global)78 CCgUniform4f::CCgUniform4f(const CGparameter& parameter, bool global) : CCgUniform(parameter, global)
79 {
80 Type = CG_FLOAT4;
81 }
82
update(const void * data,const SMaterial & material) const83 void CCgUniform4f::update(const void* data, const SMaterial& material) const
84 {
85 f32* Data = (f32*)data;
86 cgSetParameter4f(Parameter, *Data, *(Data+1), *(Data+2), *(Data+3));
87 }
88
CCgUniform1i(const CGparameter & parameter,bool global)89 CCgUniform1i::CCgUniform1i(const CGparameter& parameter, bool global) : CCgUniform(parameter, global)
90 {
91 Type = CG_INT;
92 }
93
update(const void * data,const SMaterial & material) const94 void CCgUniform1i::update(const void* data, const SMaterial& material) const
95 {
96 s32* Data = (s32*)data;
97 cgSetParameter1i(Parameter, *Data);
98 }
99
CCgUniform2i(const CGparameter & parameter,bool global)100 CCgUniform2i::CCgUniform2i(const CGparameter& parameter, bool global) : CCgUniform(parameter, global)
101 {
102 Type = CG_INT2;
103 }
104
update(const void * data,const SMaterial & material) const105 void CCgUniform2i::update(const void* data, const SMaterial& material) const
106 {
107 s32* Data = (s32*)data;
108 cgSetParameter2i(Parameter, *Data, *(Data+1));
109 }
110
CCgUniform3i(const CGparameter & parameter,bool global)111 CCgUniform3i::CCgUniform3i(const CGparameter& parameter, bool global) : CCgUniform(parameter, global)
112 {
113 Type = CG_INT3;
114 }
115
update(const void * data,const SMaterial & material) const116 void CCgUniform3i::update(const void* data, const SMaterial& material) const
117 {
118 s32* Data = (s32*)data;
119 cgSetParameter3i(Parameter, *Data, *(Data+1), *(Data+2));
120 }
121
CCgUniform4i(const CGparameter & parameter,bool global)122 CCgUniform4i::CCgUniform4i(const CGparameter& parameter, bool global) : CCgUniform(parameter, global)
123 {
124 Type = CG_INT4;
125 }
126
update(const void * data,const SMaterial & material) const127 void CCgUniform4i::update(const void* data, const SMaterial& material) const
128 {
129 s32* Data = (s32*)data;
130 cgSetParameter4i(Parameter, *Data, *(Data+1), *(Data+2), *(Data+3));
131 }
132
CCgUniform4x4f(const CGparameter & parameter,bool global)133 CCgUniform4x4f::CCgUniform4x4f(const CGparameter& parameter, bool global) : CCgUniform(parameter, global)
134 {
135 Type = CG_FLOAT4x4;
136 }
137
update(const void * data,const SMaterial & material) const138 void CCgUniform4x4f::update(const void* data, const SMaterial& material) const
139 {
140 f32* Data = (f32*)data;
141 cgSetMatrixParameterfr(Parameter, Data);
142 }
143
CCgUniformSampler2D(const CGparameter & parameter,bool global)144 CCgUniformSampler2D::CCgUniformSampler2D(const CGparameter& parameter, bool global) : CCgUniform(parameter, global)
145 {
146 Type = CG_SAMPLER2D;
147 }
148
update(const void * data,const SMaterial & material) const149 void CCgUniformSampler2D::update(const void* data, const SMaterial& material) const
150 {
151 }
152
CCgMaterialRenderer(IShaderConstantSetCallBack * callback,IMaterialRenderer * baseMaterial,s32 userData)153 CCgMaterialRenderer::CCgMaterialRenderer(IShaderConstantSetCallBack* callback, IMaterialRenderer* baseMaterial, s32 userData) :
154 CallBack(callback), BaseMaterial(baseMaterial), UserData(userData),
155 VertexProgram(0), FragmentProgram(0), GeometryProgram(0), VertexProfile(CG_PROFILE_UNKNOWN), FragmentProfile(CG_PROFILE_UNKNOWN), GeometryProfile(CG_PROFILE_UNKNOWN),
156 Material(IdentityMaterial), Error(CG_NO_ERROR)
157 {
158 #ifdef _DEBUG
159 setDebugName("CCgMaterialRenderer");
160 #endif
161
162 if(BaseMaterial)
163 BaseMaterial->grab();
164
165 if(CallBack)
166 CallBack->grab();
167 }
168
~CCgMaterialRenderer()169 CCgMaterialRenderer::~CCgMaterialRenderer()
170 {
171 if(CallBack)
172 CallBack->drop();
173
174 if(BaseMaterial)
175 BaseMaterial->drop();
176
177 for(unsigned int i = 0; i < UniformInfo.size(); ++i)
178 delete UniformInfo[i];
179
180 UniformInfo.clear();
181 }
182
isTransparent() const183 bool CCgMaterialRenderer::isTransparent() const
184 {
185 return BaseMaterial ? BaseMaterial->isTransparent() : false;
186 }
187
setVertexShaderConstant(const f32 * data,s32 startRegister,s32 constantAmount)188 void CCgMaterialRenderer::setVertexShaderConstant(const f32* data, s32 startRegister, s32 constantAmount)
189 {
190 os::Printer::log("Cannot set constant, please use high level shader call instead.", ELL_WARNING);
191 }
192
setVertexShaderConstant(const c8 * name,const f32 * floats,int count)193 bool CCgMaterialRenderer::setVertexShaderConstant(const c8* name, const f32* floats, int count)
194 {
195 return setPixelShaderConstant(name, floats, count);
196 }
197
setVertexShaderConstant(const c8 * name,const bool * bools,int count)198 bool CCgMaterialRenderer::setVertexShaderConstant(const c8* name, const bool* bools, int count)
199 {
200 return setPixelShaderConstant(name, bools, count);
201 }
202
setVertexShaderConstant(const c8 * name,const s32 * ints,int count)203 bool CCgMaterialRenderer::setVertexShaderConstant(const c8* name, const s32* ints, int count)
204 {
205 return setPixelShaderConstant(name, ints, count);
206 }
207
setPixelShaderConstant(const f32 * data,s32 startRegister,s32 constantAmount)208 void CCgMaterialRenderer::setPixelShaderConstant(const f32* data, s32 startRegister, s32 constantAmount)
209 {
210 os::Printer::log("Cannot set constant, please use high level shader call instead.", ELL_WARNING);
211 }
212
setPixelShaderConstant(const c8 * name,const f32 * floats,int count)213 bool CCgMaterialRenderer::setPixelShaderConstant(const c8* name, const f32* floats, int count)
214 {
215 bool Status = false;
216
217 for(unsigned int i = 0; i < UniformInfo.size(); ++i)
218 {
219 if(UniformInfo[i]->getName() == name)
220 {
221 UniformInfo[i]->update(floats, Material);
222
223 Status = true;
224 }
225 }
226
227 return Status;
228 }
229
setPixelShaderConstant(const c8 * name,const s32 * ints,int count)230 bool CCgMaterialRenderer::setPixelShaderConstant(const c8* name, const s32* ints, int count)
231 {
232 bool Status = false;
233
234 for(unsigned int i = 0; i < UniformInfo.size(); ++i)
235 {
236 if(UniformInfo[i]->getName() == name)
237 {
238 UniformInfo[i]->update(ints, Material);
239
240 Status = true;
241 }
242 }
243
244 return Status;
245 }
246
setPixelShaderConstant(const c8 * name,const bool * bools,int count)247 bool CCgMaterialRenderer::setPixelShaderConstant(const c8* name, const bool* bools, int count)
248 {
249 bool Status = false;
250
251 for(unsigned int i = 0; i < UniformInfo.size(); ++i)
252 {
253 if(UniformInfo[i]->getName() == name)
254 {
255 UniformInfo[i]->update(bools, Material);
256
257 Status = true;
258 }
259 }
260
261 return Status;
262 }
263
getUniformList()264 void CCgMaterialRenderer::getUniformList()
265 {
266 for(unsigned int i = 0; i < UniformInfo.size(); ++i)
267 delete UniformInfo[i];
268
269 UniformInfo.clear();
270
271 for(unsigned int i = 0; i < 2; ++i)
272 {
273 CGenum Space = CG_GLOBAL;
274 bool IsGlobal = 1;
275
276 if(i == 1)
277 {
278 Space = CG_PROGRAM;
279 IsGlobal = 0;
280 }
281
282 for(unsigned int j = 0; j < 3; ++j)
283 {
284 CGprogram* Program = 0;
285
286 switch(j)
287 {
288 case 0:
289 Program = &VertexProgram;
290 break;
291 case 1:
292 Program = &FragmentProgram;
293 break;
294 case 2:
295 Program = &GeometryProgram;
296 break;
297 }
298
299 if(*Program)
300 {
301 CGparameter Parameter = cgGetFirstParameter(*Program, Space);
302
303 while(Parameter)
304 {
305 if(cgGetParameterVariability(Parameter) == CG_UNIFORM && cgGetParameterDirection(Parameter) == CG_IN)
306 {
307 CCgUniform* Uniform = 0;
308
309 CGtype Type = cgGetParameterType(Parameter);
310
311 switch(Type)
312 {
313 case CG_FLOAT:
314 case CG_FLOAT1:
315 Uniform = new CCgUniform1f(Parameter, IsGlobal);
316 break;
317 case CG_FLOAT2:
318 Uniform = new CCgUniform2f(Parameter, IsGlobal);
319 break;
320 case CG_FLOAT3:
321 Uniform = new CCgUniform3f(Parameter, IsGlobal);
322 break;
323 case CG_FLOAT4:
324 Uniform = new CCgUniform4f(Parameter, IsGlobal);
325 break;
326 case CG_INT:
327 case CG_INT1:
328 Uniform = new CCgUniform1i(Parameter, IsGlobal);
329 break;
330 case CG_INT2:
331 Uniform = new CCgUniform2i(Parameter, IsGlobal);
332 break;
333 case CG_INT3:
334 Uniform = new CCgUniform3i(Parameter, IsGlobal);
335 break;
336 case CG_INT4:
337 Uniform = new CCgUniform4i(Parameter, IsGlobal);
338 break;
339 case CG_FLOAT4x4:
340 Uniform = new CCgUniform4x4f(Parameter, IsGlobal);
341 break;
342 case CG_SAMPLER2D:
343 Uniform = new CCgUniformSampler2D(Parameter, IsGlobal);
344 break;
345 }
346
347 if(Uniform)
348 UniformInfo.push_back(Uniform);
349 }
350
351 Parameter = cgGetNextParameter(Parameter);
352 }
353 }
354 }
355 }
356 }
357
358 }
359 }
360
361 #endif
362