1 /*
2 -----------------------------------------------------------------------------
3 This source file is part of OGRE
4 (Object-oriented Graphics Rendering Engine)
5 For the latest info, see http://www.ogre3d.org/
6
7 Copyright (c) 2000-2014 Torus Knot Software Ltd
8 Permission is hereby granted, free of charge, to any person obtaining a copy
9 of this software and associated documentation files (the "Software"), to deal
10 in the Software without restriction, including without limitation the rights
11 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 copies of the Software, and to permit persons to whom the Software is
13 furnished to do so, subject to the following conditions:
14
15 The above copyright notice and this permission notice shall be included in
16 all copies or substantial portions of the Software.
17
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 THE SOFTWARE.
25 -----------------------------------------------------------------------------
26 */
27
28 #include "OgreShaderPrecompiledHeaders.h"
29
30 namespace Ogre {
31 namespace RTShader {
32
33 //-----------------------------------------------------------------------------
Program(GpuProgramType type)34 Program::Program(GpuProgramType type)
35 {
36 mType = type;
37 mEntryPointFunction = NULL;
38 mSkeletalAnimation = false;
39 mColumnMajorMatrices = true;
40 }
41
42 //-----------------------------------------------------------------------------
~Program()43 Program::~Program()
44 {
45 destroyParameters();
46
47 destroyFunctions();
48 }
49
50 //-----------------------------------------------------------------------------
destroyParameters()51 void Program::destroyParameters()
52 {
53 mParameters.clear();
54 }
55
56 //-----------------------------------------------------------------------------
destroyFunctions()57 void Program::destroyFunctions()
58 {
59 ShaderFunctionIterator it;
60
61 for (it = mFunctions.begin(); it != mFunctions.end(); ++it)
62 {
63 OGRE_DELETE *it;
64 }
65 mFunctions.clear();
66 }
67
68 //-----------------------------------------------------------------------------
getType() const69 GpuProgramType Program::getType() const
70 {
71 return mType;
72 }
73
74 //-----------------------------------------------------------------------------
addParameter(UniformParameterPtr parameter)75 void Program::addParameter(UniformParameterPtr parameter)
76 {
77 if (getParameterByName(parameter->getName()).get() != NULL)
78 {
79 OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS,
80 "Parameter <" + parameter->getName() + "> already declared in program.",
81 "Program::addParameter" );
82 }
83
84 mParameters.push_back(parameter);
85 }
86
87 //-----------------------------------------------------------------------------
removeParameter(UniformParameterPtr parameter)88 void Program::removeParameter(UniformParameterPtr parameter)
89 {
90 UniformParameterIterator it;
91
92 for (it = mParameters.begin(); it != mParameters.end(); ++it)
93 {
94 if ((*it) == parameter)
95 {
96 (*it).reset();
97 mParameters.erase(it);
98 break;
99 }
100 }
101 }
102
103 //-----------------------------------------------------------------------------
104
isArray(GpuProgramParameters::AutoConstantType autoType)105 static bool isArray(GpuProgramParameters::AutoConstantType autoType)
106 {
107 switch (autoType)
108 {
109 case GpuProgramParameters::ACT_WORLD_MATRIX_ARRAY_3x4:
110 case GpuProgramParameters::ACT_WORLD_MATRIX_ARRAY:
111 case GpuProgramParameters::ACT_WORLD_DUALQUATERNION_ARRAY_2x4:
112 case GpuProgramParameters::ACT_WORLD_SCALE_SHEAR_MATRIX_ARRAY_3x4:
113 case GpuProgramParameters::ACT_LIGHT_DIFFUSE_COLOUR_ARRAY:
114 case GpuProgramParameters::ACT_LIGHT_SPECULAR_COLOUR_ARRAY:
115 case GpuProgramParameters::ACT_LIGHT_DIFFUSE_COLOUR_POWER_SCALED_ARRAY:
116 case GpuProgramParameters::ACT_LIGHT_SPECULAR_COLOUR_POWER_SCALED_ARRAY:
117 case GpuProgramParameters::ACT_LIGHT_ATTENUATION_ARRAY:
118 case GpuProgramParameters::ACT_LIGHT_POSITION_ARRAY:
119 case GpuProgramParameters::ACT_LIGHT_POSITION_OBJECT_SPACE_ARRAY:
120 case GpuProgramParameters::ACT_LIGHT_POSITION_VIEW_SPACE_ARRAY:
121 case GpuProgramParameters::ACT_LIGHT_DIRECTION_ARRAY:
122 case GpuProgramParameters::ACT_LIGHT_DIRECTION_OBJECT_SPACE_ARRAY:
123 case GpuProgramParameters::ACT_LIGHT_DIRECTION_VIEW_SPACE_ARRAY:
124 case GpuProgramParameters::ACT_LIGHT_DISTANCE_OBJECT_SPACE_ARRAY:
125 case GpuProgramParameters::ACT_LIGHT_POWER_SCALE_ARRAY:
126 case GpuProgramParameters::ACT_SPOTLIGHT_PARAMS_ARRAY:
127 case GpuProgramParameters::ACT_DERIVED_LIGHT_DIFFUSE_COLOUR_ARRAY:
128 case GpuProgramParameters::ACT_DERIVED_LIGHT_SPECULAR_COLOUR_ARRAY:
129 case GpuProgramParameters::ACT_LIGHT_CASTS_SHADOWS_ARRAY:
130 case GpuProgramParameters::ACT_TEXTURE_VIEWPROJ_MATRIX_ARRAY:
131 case GpuProgramParameters::ACT_TEXTURE_WORLDVIEWPROJ_MATRIX_ARRAY:
132 case GpuProgramParameters::ACT_SPOTLIGHT_VIEWPROJ_MATRIX_ARRAY:
133 case GpuProgramParameters::ACT_SPOTLIGHT_WORLDVIEWPROJ_MATRIX_ARRAY:
134 case GpuProgramParameters::ACT_SHADOW_SCENE_DEPTH_RANGE_ARRAY:
135 return true;
136 default:
137 return false;
138 }
139 }
140
resolveParameter(GpuProgramParameters::AutoConstantType autoType,size_t data)141 UniformParameterPtr Program::resolveParameter(GpuProgramParameters::AutoConstantType autoType, size_t data)
142 {
143 UniformParameterPtr param;
144
145 // Check if parameter already exists.
146 param = getParameterByAutoType(autoType);
147
148 size_t size = 0;
149 if(isArray(autoType)) std::swap(size, data); // for array autotypes the extra parameter is the size
150
151 if (param && param->getAutoConstantIntData() == data)
152 {
153 return param;
154 }
155
156 // Create new parameter
157 param = UniformParameterPtr(OGRE_NEW UniformParameter(autoType, data, size));
158 addParameter(param);
159
160 return param;
161 }
162
resolveAutoParameterReal(GpuProgramParameters::AutoConstantType autoType,Real data,size_t size)163 UniformParameterPtr Program::resolveAutoParameterReal(GpuProgramParameters::AutoConstantType autoType,
164 Real data, size_t size)
165 {
166 UniformParameterPtr param;
167
168 // Check if parameter already exists.
169 param = getParameterByAutoType(autoType);
170 if (param.get() != NULL)
171 {
172 if (param->isAutoConstantRealParameter() &&
173 param->getAutoConstantRealData() == data)
174 {
175 param->setSize(std::max(size, param->getSize()));
176 return param;
177 }
178 }
179
180 // Create new parameter.
181 param = UniformParameterPtr(OGRE_NEW UniformParameter(autoType, data, size));
182 addParameter(param);
183
184 return param;
185 }
186
187 //-----------------------------------------------------------------------------
resolveAutoParameterReal(GpuProgramParameters::AutoConstantType autoType,GpuConstantType type,Real data,size_t size)188 UniformParameterPtr Program::resolveAutoParameterReal(GpuProgramParameters::AutoConstantType autoType, GpuConstantType type,
189 Real data, size_t size)
190 {
191 UniformParameterPtr param;
192
193 // Check if parameter already exists.
194 param = getParameterByAutoType(autoType);
195 if (param.get() != NULL)
196 {
197 if (param->isAutoConstantRealParameter() &&
198 param->getAutoConstantRealData() == data)
199 {
200 param->setSize(std::max(size, param->getSize()));
201 return param;
202 }
203 }
204
205 // Create new parameter.
206 param = UniformParameterPtr(OGRE_NEW UniformParameter(autoType, data, size, type));
207 addParameter(param);
208
209 return param;
210 }
211
212 //-----------------------------------------------------------------------------
resolveAutoParameterInt(GpuProgramParameters::AutoConstantType autoType,size_t data,size_t size)213 UniformParameterPtr Program::resolveAutoParameterInt(GpuProgramParameters::AutoConstantType autoType,
214 size_t data, size_t size)
215 {
216 UniformParameterPtr param;
217
218 // Check if parameter already exists.
219 param = getParameterByAutoType(autoType);
220 if (param.get() != NULL)
221 {
222 if (param->isAutoConstantIntParameter() &&
223 param->getAutoConstantIntData() == data)
224 {
225 param->setSize(std::max(size, param->getSize()));
226 return param;
227 }
228 }
229
230 // Create new parameter.
231 param = UniformParameterPtr(OGRE_NEW UniformParameter(autoType, data, size));
232 addParameter(param);
233
234 return param;
235 }
236
237 //-----------------------------------------------------------------------------
resolveAutoParameterInt(GpuProgramParameters::AutoConstantType autoType,GpuConstantType type,size_t data,size_t size)238 UniformParameterPtr Program::resolveAutoParameterInt(GpuProgramParameters::AutoConstantType autoType, GpuConstantType type,
239 size_t data, size_t size)
240 {
241 UniformParameterPtr param;
242
243 // Check if parameter already exists.
244 param = getParameterByAutoType(autoType);
245 if (param.get() != NULL)
246 {
247 if (param->isAutoConstantIntParameter() &&
248 param->getAutoConstantIntData() == data)
249 {
250 param->setSize(std::max(size, param->getSize()));
251 return param;
252 }
253 }
254
255 // Create new parameter.
256 param = UniformParameterPtr(OGRE_NEW UniformParameter(autoType, data, size, type));
257 addParameter(param);
258
259 return param;
260 }
261
262 //-----------------------------------------------------------------------------
resolveParameter(GpuConstantType type,int index,uint16 variability,const String & suggestedName,size_t size)263 UniformParameterPtr Program::resolveParameter(GpuConstantType type,
264 int index, uint16 variability,
265 const String& suggestedName,
266 size_t size)
267 {
268 UniformParameterPtr param;
269
270 if (index == -1)
271 {
272 index = 0;
273
274 // Find the next available index of the target type.
275 UniformParameterIterator it;
276
277 for (it = mParameters.begin(); it != mParameters.end(); ++it)
278 {
279 if ((*it)->getType() == type &&
280 (*it)->isAutoConstantParameter() == false)
281 {
282 index++;
283 }
284 }
285 }
286 else
287 {
288 // Check if parameter already exists.
289 param = getParameterByType(type, index);
290 if (param.get() != NULL)
291 {
292 return param;
293 }
294 }
295
296 // Create new parameter.
297 param = ParameterFactory::createUniform(type, index, variability, suggestedName, size);
298 addParameter(param);
299
300 return param;
301 }
302
303
304
305 //-----------------------------------------------------------------------------
getParameterByName(const String & name)306 UniformParameterPtr Program::getParameterByName(const String& name)
307 {
308 UniformParameterIterator it;
309
310 for (it = mParameters.begin(); it != mParameters.end(); ++it)
311 {
312 if ((*it)->getName() == name)
313 {
314 return *it;
315 }
316 }
317
318 return UniformParameterPtr();
319 }
320
321 //-----------------------------------------------------------------------------
getParameterByType(GpuConstantType type,int index)322 UniformParameterPtr Program::getParameterByType(GpuConstantType type, int index)
323 {
324 UniformParameterIterator it;
325
326 for (it = mParameters.begin(); it != mParameters.end(); ++it)
327 {
328 if ((*it)->getType() == type &&
329 (*it)->getIndex() == index)
330 {
331 return *it;
332 }
333 }
334
335 return UniformParameterPtr();
336 }
337
338 //-----------------------------------------------------------------------------
getParameterByAutoType(GpuProgramParameters::AutoConstantType autoType)339 UniformParameterPtr Program::getParameterByAutoType(GpuProgramParameters::AutoConstantType autoType)
340 {
341 UniformParameterIterator it;
342
343 for (it = mParameters.begin(); it != mParameters.end(); ++it)
344 {
345 if ((*it)->isAutoConstantParameter() && (*it)->getAutoConstantType() == autoType)
346 {
347 return *it;
348 }
349 }
350
351 return UniformParameterPtr();
352 }
353
354 //-----------------------------------------------------------------------------
createFunction(const String & name,const String & desc,const Function::FunctionType functionType)355 Function* Program::createFunction(const String& name, const String& desc, const Function::FunctionType functionType)
356 {
357 Function* shaderFunction;
358
359 shaderFunction = getFunctionByName(name);
360 if (shaderFunction != NULL)
361 {
362 OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS,
363 "Function " + name + " already declared in program.",
364 "Program::createFunction" );
365 }
366
367 shaderFunction = OGRE_NEW Function(name, desc, functionType);
368 mFunctions.push_back(shaderFunction);
369
370 return shaderFunction;
371 }
372
373 //-----------------------------------------------------------------------------
getFunctionByName(const String & name)374 Function* Program::getFunctionByName(const String& name)
375 {
376 ShaderFunctionIterator it;
377
378 for (it = mFunctions.begin(); it != mFunctions.end(); ++it)
379 {
380 if ((*it)->getName() == name)
381 {
382 return *it;
383 }
384 }
385
386 return NULL;
387 }
388
389 //-----------------------------------------------------------------------------
addDependency(const String & libFileName)390 void Program::addDependency(const String& libFileName)
391 {
392 for (unsigned int i=0; i < mDependencies.size(); ++i)
393 {
394 if (mDependencies[i] == libFileName)
395 {
396 return;
397 }
398 }
399 mDependencies.push_back(libFileName);
400 }
401
addPreprocessorDefines(const String & defines)402 void Program::addPreprocessorDefines(const String& defines)
403 {
404 mPreprocessorDefines +=
405 mPreprocessorDefines.empty() ? defines : ("," + defines);
406 }
407
408 //-----------------------------------------------------------------------------
getDependencyCount() const409 size_t Program::getDependencyCount() const
410 {
411 return mDependencies.size();
412 }
413
414 //-----------------------------------------------------------------------------
getDependency(unsigned int index) const415 const String& Program::getDependency(unsigned int index) const
416 {
417 return mDependencies[index];
418 }
419
420 }
421 }
422