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