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-2013 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 #include "OgreShaderFFPTexturing.h"
28 #ifdef RTSHADER_SYSTEM_BUILD_CORE_SHADERS
29 #include "OgreShaderFFPRenderState.h"
30 #include "OgreShaderProgram.h"
31 #include "OgreShaderParameter.h"
32 #include "OgreShaderProgramSet.h"
33 #include "OgreTextureUnitState.h"
34 #include "OgreFrustum.h"
35 #include "OgrePass.h"
36
37 namespace Ogre {
38 namespace RTShader {
39
40 /************************************************************************/
41 /* */
42 /************************************************************************/
43 String FFPTexturing::Type = "FFP_Texturing";
44 #define _INT_VALUE(f) (*(int*)(&(f)))
45
46 const String c_ParamTexelEx("texel_");
47
48 //-----------------------------------------------------------------------
FFPTexturing()49 FFPTexturing::FFPTexturing()
50 {
51 }
52
53 //-----------------------------------------------------------------------
getType() const54 const String& FFPTexturing::getType() const
55 {
56 return Type;
57 }
58
59 //-----------------------------------------------------------------------
getExecutionOrder() const60 int FFPTexturing::getExecutionOrder() const
61 {
62 return FFP_TEXTURING;
63 }
64
65 //-----------------------------------------------------------------------
resolveParameters(ProgramSet * programSet)66 bool FFPTexturing::resolveParameters(ProgramSet* programSet)
67 {
68 for (unsigned int i=0; i < mTextureUnitParamsList.size(); ++i)
69 {
70 TextureUnitParams* curParams = &mTextureUnitParamsList[i];
71
72 if (false == resolveUniformParams(curParams, programSet))
73 return false;
74
75
76 if (false == resolveFunctionsParams(curParams, programSet))
77 return false;
78 }
79
80
81 return true;
82 }
83
84 //-----------------------------------------------------------------------
resolveUniformParams(TextureUnitParams * textureUnitParams,ProgramSet * programSet)85 bool FFPTexturing::resolveUniformParams(TextureUnitParams* textureUnitParams, ProgramSet* programSet)
86 {
87 Program* vsProgram = programSet->getCpuVertexProgram();
88 Program* psProgram = programSet->getCpuFragmentProgram();
89 bool hasError = false;
90
91 // Resolve texture sampler parameter.
92 textureUnitParams->mTextureSampler = psProgram->resolveParameter(textureUnitParams->mTextureSamplerType, textureUnitParams->mTextureSamplerIndex, (uint16)GPV_GLOBAL, "gTextureSampler");
93 hasError |= !(textureUnitParams->mTextureSampler.get());
94
95 // Resolve texture matrix parameter.
96 if (needsTextureMatrix(textureUnitParams->mTextureUnitState))
97 {
98 textureUnitParams->mTextureMatrix = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_TEXTURE_MATRIX, textureUnitParams->mTextureSamplerIndex);
99 hasError |= !(textureUnitParams->mTextureMatrix.get());
100 }
101
102 switch (textureUnitParams->mTexCoordCalcMethod)
103 {
104 case TEXCALC_NONE:
105 break;
106
107 // Resolve World + View matrices.
108 case TEXCALC_ENVIRONMENT_MAP:
109 case TEXCALC_ENVIRONMENT_MAP_PLANAR:
110 case TEXCALC_ENVIRONMENT_MAP_NORMAL:
111 //TODO: change the following 'mWorldITMatrix' member to 'mWorldViewITMatrix'
112 mWorldITMatrix = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_INVERSE_TRANSPOSE_WORLDVIEW_MATRIX, 0);
113 mViewMatrix = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_VIEW_MATRIX, 0);
114 mWorldMatrix = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_WORLD_MATRIX, 0);
115
116 hasError |= !(mWorldITMatrix.get()) || !(mViewMatrix.get()) || !(mWorldITMatrix.get());
117 break;
118
119 case TEXCALC_ENVIRONMENT_MAP_REFLECTION:
120 mWorldMatrix = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_WORLD_MATRIX, 0);
121 mWorldITMatrix = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_INVERSE_TRANSPOSE_WORLD_MATRIX, 0);
122 mViewMatrix = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_VIEW_MATRIX, 0);
123
124 hasError |= !(mWorldMatrix.get()) || !(mWorldITMatrix.get()) || !(mViewMatrix.get());
125 break;
126
127 case TEXCALC_PROJECTIVE_TEXTURE:
128
129 mWorldMatrix = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_WORLD_MATRIX, 0);
130 textureUnitParams->mTextureViewProjImageMatrix = vsProgram->resolveParameter(GCT_MATRIX_4X4, -1, (uint16)GPV_LIGHTS, "gTexViewProjImageMatrix");
131
132 hasError |= !(mWorldMatrix.get()) || !(textureUnitParams->mTextureViewProjImageMatrix.get());
133
134 const TextureUnitState::EffectMap& effectMap = textureUnitParams->mTextureUnitState->getEffects();
135 TextureUnitState::EffectMap::const_iterator effi;
136
137 for (effi = effectMap.begin(); effi != effectMap.end(); ++effi)
138 {
139 if (effi->second.type == TextureUnitState::ET_PROJECTIVE_TEXTURE)
140 {
141 textureUnitParams->mTextureProjector = effi->second.frustum;
142 break;
143 }
144 }
145
146 hasError |= !(textureUnitParams->mTextureProjector);
147 break;
148 }
149
150
151 if (hasError)
152 {
153 OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR,
154 "Not all parameters could be constructed for the sub-render state.",
155 "FFPTexturing::resolveUniformParams" );
156 }
157 return true;
158 }
159
160
161
162 //-----------------------------------------------------------------------
resolveFunctionsParams(TextureUnitParams * textureUnitParams,ProgramSet * programSet)163 bool FFPTexturing::resolveFunctionsParams(TextureUnitParams* textureUnitParams, ProgramSet* programSet)
164 {
165 Program* vsProgram = programSet->getCpuVertexProgram();
166 Program* psProgram = programSet->getCpuFragmentProgram();
167 Function* vsMain = vsProgram->getEntryPointFunction();
168 Function* psMain = psProgram->getEntryPointFunction();
169 Parameter::Content texCoordContent = Parameter::SPC_UNKNOWN;
170 bool hasError = false;
171
172 switch (textureUnitParams->mTexCoordCalcMethod)
173 {
174 case TEXCALC_NONE:
175 // Resolve explicit vs input texture coordinates.
176
177 if (textureUnitParams->mTextureMatrix.get() == NULL)
178 texCoordContent = Parameter::Content(Parameter::SPC_TEXTURE_COORDINATE0 + textureUnitParams->mTextureUnitState->getTextureCoordSet());
179
180 textureUnitParams->mVSInputTexCoord = vsMain->resolveInputParameter(Parameter::SPS_TEXTURE_COORDINATES,
181 textureUnitParams->mTextureUnitState->getTextureCoordSet(),
182 Parameter::Content(Parameter::SPC_TEXTURE_COORDINATE0 + textureUnitParams->mTextureUnitState->getTextureCoordSet()),
183 textureUnitParams->mVSInTextureCoordinateType);
184 hasError |= !(textureUnitParams->mVSInputTexCoord.get());
185 break;
186
187 case TEXCALC_ENVIRONMENT_MAP:
188 case TEXCALC_ENVIRONMENT_MAP_PLANAR:
189 case TEXCALC_ENVIRONMENT_MAP_NORMAL:
190 // Resolve vertex normal.
191 mVSInputPos = vsMain->resolveInputParameter(Parameter::SPS_POSITION, 0, Parameter::SPC_POSITION_OBJECT_SPACE, GCT_FLOAT4);
192 mVSInputNormal = vsMain->resolveInputParameter(Parameter::SPS_NORMAL, 0, Parameter::SPC_NORMAL_OBJECT_SPACE, GCT_FLOAT3);
193 hasError |= !(mVSInputNormal.get()) || !(mVSInputPos.get());
194 break;
195
196 case TEXCALC_ENVIRONMENT_MAP_REFLECTION:
197
198 // Resolve vertex normal.
199 mVSInputNormal = vsMain->resolveInputParameter(Parameter::SPS_NORMAL, 0, Parameter::SPC_NORMAL_OBJECT_SPACE, GCT_FLOAT3);
200 // Resolve vertex position.
201 mVSInputPos = vsMain->resolveInputParameter(Parameter::SPS_POSITION, 0, Parameter::SPC_POSITION_OBJECT_SPACE, GCT_FLOAT4);
202
203 hasError |= !(mVSInputNormal.get()) || !(mVSInputPos.get());
204 break;
205
206 case TEXCALC_PROJECTIVE_TEXTURE:
207 // Resolve vertex position.
208 mVSInputPos = vsMain->resolveInputParameter(Parameter::SPS_POSITION, 0, Parameter::SPC_POSITION_OBJECT_SPACE, GCT_FLOAT4);
209 hasError |= !(mVSInputPos.get());
210 break;
211 }
212
213 // Resolve vs output texture coordinates.
214 textureUnitParams->mVSOutputTexCoord = vsMain->resolveOutputParameter(Parameter::SPS_TEXTURE_COORDINATES,
215 -1,
216 texCoordContent,
217 textureUnitParams->mVSOutTextureCoordinateType);
218
219 // Resolve ps input texture coordinates.
220 textureUnitParams->mPSInputTexCoord = psMain->resolveInputParameter(Parameter::SPS_TEXTURE_COORDINATES,
221 textureUnitParams->mVSOutputTexCoord->getIndex(),
222 textureUnitParams->mVSOutputTexCoord->getContent(),
223 textureUnitParams->mVSOutTextureCoordinateType);
224
225 const ShaderParameterList& inputParams = psMain->getInputParameters();
226 const ShaderParameterList& localParams = psMain->getLocalParameters();
227
228 mPSDiffuse = psMain->getParameterByContent(inputParams, Parameter::SPC_COLOR_DIFFUSE, GCT_FLOAT4);
229 if (mPSDiffuse.get() == NULL)
230 {
231 mPSDiffuse = psMain->getParameterByContent(localParams, Parameter::SPC_COLOR_DIFFUSE, GCT_FLOAT4);
232 }
233
234 mPSSpecular = psMain->getParameterByContent(inputParams, Parameter::SPC_COLOR_SPECULAR, GCT_FLOAT4);
235 if (mPSSpecular.get() == NULL)
236 {
237 mPSSpecular = psMain->getParameterByContent(localParams, Parameter::SPC_COLOR_SPECULAR, GCT_FLOAT4);
238 }
239
240 mPSOutDiffuse = psMain->resolveOutputParameter(Parameter::SPS_COLOR, 0, Parameter::SPC_COLOR_DIFFUSE, GCT_FLOAT4);
241
242 hasError |= !(textureUnitParams->mVSOutputTexCoord.get()) || !(textureUnitParams->mPSInputTexCoord.get()) ||
243 !(mPSDiffuse.get()) || !(mPSSpecular.get()) || !(mPSOutDiffuse.get());
244
245 if (hasError)
246 {
247 OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR,
248 "Not all parameters could be constructed for the sub-render state.",
249 "FFPTexturing::resolveFunctionsParams" );
250 }
251 return true;
252 }
253
254 //-----------------------------------------------------------------------
resolveDependencies(ProgramSet * programSet)255 bool FFPTexturing::resolveDependencies(ProgramSet* programSet)
256 {
257 Program* vsProgram = programSet->getCpuVertexProgram();
258 Program* psProgram = programSet->getCpuFragmentProgram();
259
260 vsProgram->addDependency(FFP_LIB_COMMON);
261 vsProgram->addDependency(FFP_LIB_TEXTURING);
262 psProgram->addDependency(FFP_LIB_COMMON);
263 psProgram->addDependency(FFP_LIB_TEXTURING);
264
265 return true;
266 }
267
268 //-----------------------------------------------------------------------
addFunctionInvocations(ProgramSet * programSet)269 bool FFPTexturing::addFunctionInvocations(ProgramSet* programSet)
270 {
271 Program* vsProgram = programSet->getCpuVertexProgram();
272 Program* psProgram = programSet->getCpuFragmentProgram();
273 Function* vsMain = vsProgram->getEntryPointFunction();
274 Function* psMain = psProgram->getEntryPointFunction();
275 int internalCounter = 0;
276
277 for (unsigned int i=0; i < mTextureUnitParamsList.size(); ++i)
278 {
279 TextureUnitParams* curParams = &mTextureUnitParamsList[i];
280
281 if (false == addVSFunctionInvocations(curParams, vsMain))
282 return false;
283
284 if (false == addPSFunctionInvocations(curParams, psMain, internalCounter))
285 return false;
286 }
287
288 return true;
289 }
290
291 //-----------------------------------------------------------------------
addVSFunctionInvocations(TextureUnitParams * textureUnitParams,Function * vsMain)292 bool FFPTexturing::addVSFunctionInvocations(TextureUnitParams* textureUnitParams, Function* vsMain)
293 {
294 FunctionInvocation* texCoordCalcFunc = NULL;
295
296
297 switch (textureUnitParams->mTexCoordCalcMethod)
298 {
299 case TEXCALC_NONE:
300 if (textureUnitParams->mTextureMatrix.get() == NULL)
301 {
302 texCoordCalcFunc = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, FFP_VS_TEXTURING, textureUnitParams->mTextureSamplerIndex);
303
304 texCoordCalcFunc->pushOperand(textureUnitParams->mVSInputTexCoord, Operand::OPS_IN);
305 texCoordCalcFunc->pushOperand(textureUnitParams->mVSOutputTexCoord, Operand::OPS_OUT);
306 }
307 else
308 {
309 texCoordCalcFunc = OGRE_NEW FunctionInvocation(FFP_FUNC_TRANSFORM_TEXCOORD, FFP_VS_TEXTURING, textureUnitParams->mTextureSamplerIndex);
310
311 texCoordCalcFunc->pushOperand(textureUnitParams->mTextureMatrix, Operand::OPS_IN);
312 texCoordCalcFunc->pushOperand(textureUnitParams->mVSInputTexCoord, Operand::OPS_IN);
313 texCoordCalcFunc->pushOperand(textureUnitParams->mVSOutputTexCoord, Operand::OPS_OUT);
314 }
315 break;
316
317 case TEXCALC_ENVIRONMENT_MAP:
318 case TEXCALC_ENVIRONMENT_MAP_PLANAR:
319 if (textureUnitParams->mTextureMatrix.get() == NULL)
320 {
321 texCoordCalcFunc = OGRE_NEW FunctionInvocation(FFP_FUNC_GENERATE_TEXCOORD_ENV_SPHERE, FFP_VS_TEXTURING, textureUnitParams->mTextureSamplerIndex);
322
323 //TODO: Add field member mWorldViewITMatrix
324 texCoordCalcFunc->pushOperand(mWorldMatrix, Operand::OPS_IN);
325 texCoordCalcFunc->pushOperand(mViewMatrix, Operand::OPS_IN);
326 texCoordCalcFunc->pushOperand(mWorldITMatrix, Operand::OPS_IN);
327 texCoordCalcFunc->pushOperand(mVSInputPos, Operand::OPS_IN);
328 texCoordCalcFunc->pushOperand(mVSInputNormal, Operand::OPS_IN);
329 texCoordCalcFunc->pushOperand(textureUnitParams->mVSOutputTexCoord, Operand::OPS_OUT);
330 }
331 else
332 {
333 texCoordCalcFunc = OGRE_NEW FunctionInvocation(FFP_FUNC_GENERATE_TEXCOORD_ENV_SPHERE, FFP_VS_TEXTURING, textureUnitParams->mTextureSamplerIndex);
334
335 texCoordCalcFunc->pushOperand(mWorldMatrix, Operand::OPS_IN);
336 texCoordCalcFunc->pushOperand(mViewMatrix, Operand::OPS_IN);
337 texCoordCalcFunc->pushOperand(mWorldITMatrix, Operand::OPS_IN);
338 texCoordCalcFunc->pushOperand(mVSInputPos, Operand::OPS_IN);
339 texCoordCalcFunc->pushOperand(mVSInputNormal, Operand::OPS_IN);
340 texCoordCalcFunc->pushOperand(textureUnitParams->mTextureMatrix, Operand::OPS_IN);
341 texCoordCalcFunc->pushOperand(textureUnitParams->mVSOutputTexCoord, Operand::OPS_OUT);
342 }
343 break;
344
345
346 case TEXCALC_ENVIRONMENT_MAP_REFLECTION:
347 if (textureUnitParams->mTextureMatrix.get() == NULL)
348 {
349 texCoordCalcFunc = OGRE_NEW FunctionInvocation(FFP_FUNC_GENERATE_TEXCOORD_ENV_REFLECT, FFP_VS_TEXTURING, textureUnitParams->mTextureSamplerIndex);
350
351 texCoordCalcFunc->pushOperand(mWorldMatrix, Operand::OPS_IN);
352 texCoordCalcFunc->pushOperand(mWorldITMatrix, Operand::OPS_IN);
353 texCoordCalcFunc->pushOperand(mViewMatrix, Operand::OPS_IN);
354 texCoordCalcFunc->pushOperand(mVSInputNormal, Operand::OPS_IN);
355 texCoordCalcFunc->pushOperand(mVSInputPos, Operand::OPS_IN);
356 texCoordCalcFunc->pushOperand(textureUnitParams->mVSOutputTexCoord, Operand::OPS_OUT);
357 }
358 else
359 {
360 texCoordCalcFunc = OGRE_NEW FunctionInvocation(FFP_FUNC_GENERATE_TEXCOORD_ENV_REFLECT, FFP_VS_TEXTURING, textureUnitParams->mTextureSamplerIndex);
361
362 texCoordCalcFunc->pushOperand(mWorldMatrix, Operand::OPS_IN);
363 texCoordCalcFunc->pushOperand(mWorldITMatrix, Operand::OPS_IN);
364 texCoordCalcFunc->pushOperand(mViewMatrix, Operand::OPS_IN);
365 texCoordCalcFunc->pushOperand(textureUnitParams->mTextureMatrix, Operand::OPS_IN);
366 texCoordCalcFunc->pushOperand(mVSInputNormal, Operand::OPS_IN);
367 texCoordCalcFunc->pushOperand(mVSInputPos, Operand::OPS_IN);
368 texCoordCalcFunc->pushOperand(textureUnitParams->mVSOutputTexCoord, Operand::OPS_OUT);
369 }
370 break;
371
372 case TEXCALC_ENVIRONMENT_MAP_NORMAL:
373 if (textureUnitParams->mTextureMatrix.get() == NULL)
374 {
375 texCoordCalcFunc = OGRE_NEW FunctionInvocation(FFP_FUNC_GENERATE_TEXCOORD_ENV_NORMAL, FFP_VS_TEXTURING, textureUnitParams->mTextureSamplerIndex);
376
377 texCoordCalcFunc->pushOperand(mWorldITMatrix, Operand::OPS_IN);
378 texCoordCalcFunc->pushOperand(mViewMatrix, Operand::OPS_IN);
379 texCoordCalcFunc->pushOperand(mVSInputNormal, Operand::OPS_IN);
380 texCoordCalcFunc->pushOperand(textureUnitParams->mVSOutputTexCoord, Operand::OPS_OUT);
381 }
382 else
383 {
384 texCoordCalcFunc = OGRE_NEW FunctionInvocation(FFP_FUNC_GENERATE_TEXCOORD_ENV_NORMAL, FFP_VS_TEXTURING, textureUnitParams->mTextureSamplerIndex);
385
386 texCoordCalcFunc->pushOperand(mWorldITMatrix, Operand::OPS_IN);
387 texCoordCalcFunc->pushOperand(mViewMatrix, Operand::OPS_IN);
388 texCoordCalcFunc->pushOperand(textureUnitParams->mTextureMatrix, Operand::OPS_IN);
389 texCoordCalcFunc->pushOperand(mVSInputNormal, Operand::OPS_IN);
390 texCoordCalcFunc->pushOperand(textureUnitParams->mVSOutputTexCoord, Operand::OPS_OUT);
391 }
392 break;
393
394 case TEXCALC_PROJECTIVE_TEXTURE:
395
396 texCoordCalcFunc = OGRE_NEW FunctionInvocation(FFP_FUNC_GENERATE_TEXCOORD_PROJECTION, FFP_VS_TEXTURING, textureUnitParams->mTextureSamplerIndex);
397
398 texCoordCalcFunc->pushOperand(mWorldMatrix, Operand::OPS_IN);
399 texCoordCalcFunc->pushOperand(textureUnitParams->mTextureViewProjImageMatrix, Operand::OPS_IN);
400 texCoordCalcFunc->pushOperand(mVSInputPos, Operand::OPS_IN);
401 texCoordCalcFunc->pushOperand(textureUnitParams->mVSOutputTexCoord, Operand::OPS_OUT);
402
403 break;
404 }
405
406 if (texCoordCalcFunc != NULL)
407 vsMain->addAtomInstance(texCoordCalcFunc);
408
409 return true;
410 }
411 //-----------------------------------------------------------------------
addPSFunctionInvocations(TextureUnitParams * textureUnitParams,Function * psMain,int & internalCounter)412 bool FFPTexturing::addPSFunctionInvocations(TextureUnitParams* textureUnitParams, Function* psMain, int& internalCounter)
413 {
414 const LayerBlendModeEx& colourBlend = textureUnitParams->mTextureUnitState->getColourBlendMode();
415 const LayerBlendModeEx& alphaBlend = textureUnitParams->mTextureUnitState->getAlphaBlendMode();
416 ParameterPtr source1;
417 ParameterPtr source2;
418 int groupOrder = FFP_PS_TEXTURING;
419
420
421 // Add texture sampling code.
422 ParameterPtr texel = psMain->resolveLocalParameter(Parameter::SPS_UNKNOWN, 0, c_ParamTexelEx + StringConverter::toString(textureUnitParams->mTextureSamplerIndex), GCT_FLOAT4);
423 addPSSampleTexelInvocation(textureUnitParams, psMain, texel, FFP_PS_SAMPLING, internalCounter);
424
425 // Build colour argument for source1.
426 source1 = psMain->resolveLocalParameter(Parameter::SPS_UNKNOWN, 0, "source1", GCT_FLOAT4);
427
428 addPSArgumentInvocations(psMain, source1, texel,
429 textureUnitParams->mTextureSamplerIndex,
430 colourBlend.source1, colourBlend.colourArg1,
431 colourBlend.alphaArg1, false, groupOrder, internalCounter);
432
433 // Build colour argument for source2.
434 source2 = psMain->resolveLocalParameter(Parameter::SPS_UNKNOWN, 0, "source2", GCT_FLOAT4);
435
436 addPSArgumentInvocations(psMain, source2, texel,
437 textureUnitParams->mTextureSamplerIndex,
438 colourBlend.source2, colourBlend.colourArg2,
439 colourBlend.alphaArg2, false, groupOrder, internalCounter);
440
441 bool needDifferentAlphaBlend = false;
442 if (alphaBlend.operation != colourBlend.operation ||
443 alphaBlend.source1 != colourBlend.source1 ||
444 alphaBlend.source2 != colourBlend.source2 ||
445 colourBlend.source1 == LBS_MANUAL ||
446 colourBlend.source2 == LBS_MANUAL ||
447 alphaBlend.source1 == LBS_MANUAL ||
448 alphaBlend.source2 == LBS_MANUAL)
449 needDifferentAlphaBlend = true;
450
451 // Build colours blend
452 addPSBlendInvocations(psMain, source1, source2, texel,
453 textureUnitParams->mTextureSamplerIndex,
454 colourBlend, groupOrder, internalCounter,
455 needDifferentAlphaBlend ? Operand::OPM_XYZ : Operand::OPM_ALL);
456
457 // Case we need different alpha channel code.
458 if (needDifferentAlphaBlend)
459 {
460 // Build alpha argument for source1.
461 addPSArgumentInvocations(psMain, source1, texel,
462 textureUnitParams->mTextureSamplerIndex,
463 alphaBlend.source1, alphaBlend.colourArg1,
464 alphaBlend.alphaArg1, true, groupOrder, internalCounter);
465
466 // Build alpha argument for source2.
467 addPSArgumentInvocations(psMain, source2, texel,
468 textureUnitParams->mTextureSamplerIndex,
469 alphaBlend.source2, alphaBlend.colourArg2,
470 alphaBlend.alphaArg2, true, groupOrder, internalCounter);
471
472 // Build alpha blend
473 addPSBlendInvocations(psMain, source1, source2, texel,
474 textureUnitParams->mTextureSamplerIndex,
475 alphaBlend, groupOrder, internalCounter,
476 Operand::OPM_W);
477 }
478
479
480
481 return true;
482 }
483
484 //-----------------------------------------------------------------------
addPSSampleTexelInvocation(TextureUnitParams * textureUnitParams,Function * psMain,const ParameterPtr & texel,int groupOrder,int & internalCounter)485 void FFPTexturing::addPSSampleTexelInvocation(TextureUnitParams* textureUnitParams, Function* psMain,
486 const ParameterPtr& texel, int groupOrder, int& internalCounter)
487 {
488 FunctionInvocation* curFuncInvocation = NULL;
489
490 if (textureUnitParams->mTexCoordCalcMethod == TEXCALC_PROJECTIVE_TEXTURE)
491 curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_SAMPLE_TEXTURE_PROJ, groupOrder, internalCounter++);
492 else
493 curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_SAMPLE_TEXTURE, groupOrder, internalCounter++);
494
495 curFuncInvocation->pushOperand(textureUnitParams->mTextureSampler, Operand::OPS_IN);
496 curFuncInvocation->pushOperand(textureUnitParams->mPSInputTexCoord, Operand::OPS_IN);
497 curFuncInvocation->pushOperand(texel, Operand::OPS_OUT);
498 psMain->addAtomInstance(curFuncInvocation);
499 }
500
501
502 //-----------------------------------------------------------------------
addPSArgumentInvocations(Function * psMain,ParameterPtr arg,ParameterPtr texel,int samplerIndex,LayerBlendSource blendSrc,const ColourValue & colourValue,Real alphaValue,bool isAlphaArgument,const int groupOrder,int & internalCounter)503 void FFPTexturing::addPSArgumentInvocations(Function* psMain,
504 ParameterPtr arg,
505 ParameterPtr texel,
506 int samplerIndex,
507 LayerBlendSource blendSrc,
508 const ColourValue& colourValue,
509 Real alphaValue,
510 bool isAlphaArgument,
511 const int groupOrder,
512 int& internalCounter)
513 {
514 FunctionInvocation* curFuncInvocation = NULL;
515
516 switch(blendSrc)
517 {
518 case LBS_CURRENT:
519 curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, groupOrder, internalCounter++);
520 if (samplerIndex == 0)
521 curFuncInvocation->pushOperand(mPSDiffuse, Operand::OPS_IN);
522 else
523 curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_IN);
524 curFuncInvocation->pushOperand(arg, Operand::OPS_OUT);
525 psMain->addAtomInstance(curFuncInvocation);
526 break;
527 case LBS_TEXTURE:
528 curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, groupOrder, internalCounter++);
529 curFuncInvocation->pushOperand(texel, Operand::OPS_IN);
530 curFuncInvocation->pushOperand(arg, Operand::OPS_OUT);
531 psMain->addAtomInstance(curFuncInvocation);
532 break;
533 case LBS_DIFFUSE:
534 curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, groupOrder, internalCounter++);
535 curFuncInvocation->pushOperand(mPSDiffuse, Operand::OPS_IN);
536 curFuncInvocation->pushOperand(arg, Operand::OPS_OUT);
537 psMain->addAtomInstance(curFuncInvocation);
538 break;
539 case LBS_SPECULAR:
540 curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, groupOrder, internalCounter++);
541 curFuncInvocation->pushOperand(mPSSpecular, Operand::OPS_IN);
542 curFuncInvocation->pushOperand(arg, Operand::OPS_OUT);
543 psMain->addAtomInstance(curFuncInvocation);
544 break;
545
546 case LBS_MANUAL:
547 curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_CONSTRUCT, groupOrder, internalCounter++);
548
549 if (isAlphaArgument)
550 {
551 curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(alphaValue), Operand::OPS_IN);
552 }
553 else
554 {
555 curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(colourValue.r), Operand::OPS_IN);
556 curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(colourValue.g), Operand::OPS_IN);
557 curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(colourValue.b), Operand::OPS_IN);
558 curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(colourValue.a), Operand::OPS_IN);
559 }
560
561 curFuncInvocation->pushOperand(arg, Operand::OPS_OUT);
562 psMain->addAtomInstance(curFuncInvocation);
563 break;
564 }
565 }
566
567 //-----------------------------------------------------------------------
addPSBlendInvocations(Function * psMain,ParameterPtr arg1,ParameterPtr arg2,ParameterPtr texel,int samplerIndex,const LayerBlendModeEx & blendMode,const int groupOrder,int & internalCounter,int targetChannels)568 void FFPTexturing::addPSBlendInvocations(Function* psMain,
569 ParameterPtr arg1,
570 ParameterPtr arg2,
571 ParameterPtr texel,
572 int samplerIndex,
573 const LayerBlendModeEx& blendMode,
574 const int groupOrder,
575 int& internalCounter,
576 int targetChannels)
577 {
578 FunctionInvocation* curFuncInvocation = NULL;
579
580 switch(blendMode.operation)
581 {
582 case LBX_SOURCE1:
583 curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, groupOrder, internalCounter++);
584 curFuncInvocation->pushOperand(arg1, Operand::OPS_IN, targetChannels);
585 curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_OUT, targetChannels);
586 psMain->addAtomInstance(curFuncInvocation);
587 break;
588 case LBX_SOURCE2:
589 curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, groupOrder, internalCounter++);
590 curFuncInvocation->pushOperand(arg2, Operand::OPS_IN, targetChannels);
591 curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_OUT, targetChannels);
592 psMain->addAtomInstance(curFuncInvocation);
593 break;
594 case LBX_MODULATE:
595 curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_MODULATE, groupOrder, internalCounter++);
596 curFuncInvocation->pushOperand(arg1, Operand::OPS_IN, targetChannels);
597 curFuncInvocation->pushOperand(arg2, Operand::OPS_IN, targetChannels);
598 curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_OUT, targetChannels);
599 psMain->addAtomInstance(curFuncInvocation);
600 break;
601 case LBX_MODULATE_X2:
602 curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_MODULATEX2, groupOrder, internalCounter++);
603 curFuncInvocation->pushOperand(arg1, Operand::OPS_IN, targetChannels);
604 curFuncInvocation->pushOperand(arg2, Operand::OPS_IN, targetChannels);
605 curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_OUT, targetChannels);
606 psMain->addAtomInstance(curFuncInvocation);
607 break;
608 case LBX_MODULATE_X4:
609 curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_MODULATEX4, groupOrder, internalCounter++);
610 curFuncInvocation->pushOperand(arg1, Operand::OPS_IN, targetChannels);
611 curFuncInvocation->pushOperand(arg2, Operand::OPS_IN, targetChannels);
612 curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_OUT, targetChannels);
613 psMain->addAtomInstance(curFuncInvocation);
614 break;
615 case LBX_ADD:
616 curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ADD, groupOrder, internalCounter++);
617 curFuncInvocation->pushOperand(arg1, Operand::OPS_IN, targetChannels);
618 curFuncInvocation->pushOperand(arg2, Operand::OPS_IN, targetChannels);
619 curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_OUT, targetChannels);
620 psMain->addAtomInstance(curFuncInvocation);
621 break;
622 case LBX_ADD_SIGNED:
623 curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ADDSIGNED, groupOrder, internalCounter++);
624 curFuncInvocation->pushOperand(arg1, Operand::OPS_IN, targetChannels);
625 curFuncInvocation->pushOperand(arg2, Operand::OPS_IN, targetChannels);
626 curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_OUT, targetChannels);
627 psMain->addAtomInstance(curFuncInvocation);
628 break;
629 case LBX_ADD_SMOOTH:
630 curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ADDSMOOTH, groupOrder, internalCounter++);
631 curFuncInvocation->pushOperand(arg1, Operand::OPS_IN, targetChannels);
632 curFuncInvocation->pushOperand(arg2, Operand::OPS_IN, targetChannels);
633 curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_OUT, targetChannels);
634 psMain->addAtomInstance(curFuncInvocation);
635 break;
636 case LBX_SUBTRACT:
637 curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_SUBTRACT, groupOrder, internalCounter++);
638 curFuncInvocation->pushOperand(arg1, Operand::OPS_IN, targetChannels);
639 curFuncInvocation->pushOperand(arg2, Operand::OPS_IN, targetChannels);
640 curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_OUT, targetChannels);
641 psMain->addAtomInstance(curFuncInvocation);
642 break;
643 case LBX_BLEND_DIFFUSE_ALPHA:
644 curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_SUBTRACT, groupOrder, internalCounter++);
645 curFuncInvocation->pushOperand(arg2, Operand::OPS_IN, targetChannels);
646 curFuncInvocation->pushOperand(arg1, Operand::OPS_IN, targetChannels);
647 curFuncInvocation->pushOperand(mPSDiffuse, Operand::OPS_IN, Operand::OPM_W);
648 curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_OUT, targetChannels);
649 psMain->addAtomInstance(curFuncInvocation);
650 break;
651 case LBX_BLEND_TEXTURE_ALPHA:
652 curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_LERP, groupOrder, internalCounter++);
653 curFuncInvocation->pushOperand(arg2, Operand::OPS_IN, targetChannels);
654 curFuncInvocation->pushOperand(arg1, Operand::OPS_IN, targetChannels);
655 curFuncInvocation->pushOperand(texel, Operand::OPS_IN, Operand::OPM_W);
656 curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_OUT, targetChannels);
657 psMain->addAtomInstance(curFuncInvocation);
658 break;
659 case LBX_BLEND_CURRENT_ALPHA:
660 curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_LERP, groupOrder, internalCounter++);
661 curFuncInvocation->pushOperand(arg2, Operand::OPS_IN, targetChannels);
662 curFuncInvocation->pushOperand(arg1, Operand::OPS_IN, targetChannels);
663
664 if (samplerIndex == 0)
665 curFuncInvocation->pushOperand(mPSDiffuse, Operand::OPS_IN, Operand::OPM_W);
666 else
667 curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_IN, Operand::OPM_W);
668 curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_OUT, targetChannels);
669 psMain->addAtomInstance(curFuncInvocation);
670 break;
671 case LBX_BLEND_MANUAL:
672 curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_LERP, groupOrder, internalCounter++);
673 curFuncInvocation->pushOperand(arg2, Operand::OPS_IN, targetChannels);
674 curFuncInvocation->pushOperand(arg1, Operand::OPS_IN, targetChannels);
675 curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(blendMode.factor), Operand::OPS_IN);
676 curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_OUT, targetChannels);
677 psMain->addAtomInstance(curFuncInvocation);
678 break;
679 case LBX_DOTPRODUCT:
680 curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_DOTPRODUCT, groupOrder, internalCounter++);
681 curFuncInvocation->pushOperand(arg2, Operand::OPS_IN, targetChannels);
682 curFuncInvocation->pushOperand(arg1, Operand::OPS_IN, targetChannels);
683 curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_OUT, targetChannels);
684 psMain->addAtomInstance(curFuncInvocation);
685 break;
686 case LBX_BLEND_DIFFUSE_COLOUR:
687 curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_LERP, groupOrder, internalCounter++);
688 curFuncInvocation->pushOperand(arg2, Operand::OPS_IN, targetChannels);
689 curFuncInvocation->pushOperand(arg1, Operand::OPS_IN, targetChannels);
690 curFuncInvocation->pushOperand(mPSDiffuse, Operand::OPS_IN);
691 curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_OUT, targetChannels);
692 psMain->addAtomInstance(curFuncInvocation);
693 break;
694 }
695 }
696
697 //-----------------------------------------------------------------------
getTexCalcMethod(TextureUnitState * textureUnitState)698 TexCoordCalcMethod FFPTexturing::getTexCalcMethod(TextureUnitState* textureUnitState)
699 {
700 TexCoordCalcMethod texCoordCalcMethod = TEXCALC_NONE;
701 const TextureUnitState::EffectMap& effectMap = textureUnitState->getEffects();
702 TextureUnitState::EffectMap::const_iterator effi;
703
704 for (effi = effectMap.begin(); effi != effectMap.end(); ++effi)
705 {
706 switch (effi->second.type)
707 {
708 case TextureUnitState::ET_ENVIRONMENT_MAP:
709 if (effi->second.subtype == TextureUnitState::ENV_CURVED)
710 {
711 texCoordCalcMethod = TEXCALC_ENVIRONMENT_MAP;
712 }
713 else if (effi->second.subtype == TextureUnitState::ENV_PLANAR)
714 {
715 texCoordCalcMethod = TEXCALC_ENVIRONMENT_MAP_PLANAR;
716 }
717 else if (effi->second.subtype == TextureUnitState::ENV_REFLECTION)
718 {
719 texCoordCalcMethod = TEXCALC_ENVIRONMENT_MAP_REFLECTION;
720 }
721 else if (effi->second.subtype == TextureUnitState::ENV_NORMAL)
722 {
723 texCoordCalcMethod = TEXCALC_ENVIRONMENT_MAP_NORMAL;
724 }
725 break;
726 case TextureUnitState::ET_UVSCROLL:
727 case TextureUnitState::ET_USCROLL:
728 case TextureUnitState::ET_VSCROLL:
729 case TextureUnitState::ET_ROTATE:
730 case TextureUnitState::ET_TRANSFORM:
731 break;
732 case TextureUnitState::ET_PROJECTIVE_TEXTURE:
733 texCoordCalcMethod = TEXCALC_PROJECTIVE_TEXTURE;
734 break;
735 }
736 }
737
738 return texCoordCalcMethod;
739 }
740
741 //-----------------------------------------------------------------------
needsTextureMatrix(TextureUnitState * textureUnitState)742 bool FFPTexturing::needsTextureMatrix(TextureUnitState* textureUnitState)
743 {
744 const TextureUnitState::EffectMap& effectMap = textureUnitState->getEffects();
745 TextureUnitState::EffectMap::const_iterator effi;
746
747 for (effi = effectMap.begin(); effi != effectMap.end(); ++effi)
748 {
749 switch (effi->second.type)
750 {
751
752 case TextureUnitState::ET_UVSCROLL:
753 case TextureUnitState::ET_USCROLL:
754 case TextureUnitState::ET_VSCROLL:
755 case TextureUnitState::ET_ROTATE:
756 case TextureUnitState::ET_TRANSFORM:
757 case TextureUnitState::ET_ENVIRONMENT_MAP:
758 case TextureUnitState::ET_PROJECTIVE_TEXTURE:
759 return true;
760 }
761 }
762
763 const Ogre::Matrix4 matTexture = textureUnitState->getTextureTransform();
764
765 // Resolve texture matrix parameter.
766 if (matTexture != Matrix4::IDENTITY)
767 return true;
768
769 return false;
770 }
771
772
773 //-----------------------------------------------------------------------
copyFrom(const SubRenderState & rhs)774 void FFPTexturing::copyFrom(const SubRenderState& rhs)
775 {
776 const FFPTexturing& rhsTexture = static_cast<const FFPTexturing&>(rhs);
777
778 setTextureUnitCount(rhsTexture.getTextureUnitCount());
779
780 for (unsigned int i=0; i < rhsTexture.getTextureUnitCount(); ++i)
781 {
782 setTextureUnit(i, rhsTexture.mTextureUnitParamsList[i].mTextureUnitState);
783 }
784 }
785
786 //-----------------------------------------------------------------------
preAddToRenderState(const RenderState * renderState,Pass * srcPass,Pass * dstPass)787 bool FFPTexturing::preAddToRenderState(const RenderState* renderState, Pass* srcPass, Pass* dstPass)
788 {
789 //count the number of texture units we need to process
790 size_t validTexUnits = 0;
791 for (unsigned short i=0; i < srcPass->getNumTextureUnitStates(); ++i)
792 {
793 if (isProcessingNeeded(srcPass->getTextureUnitState(i)))
794 {
795 ++validTexUnits;
796 }
797 }
798
799 setTextureUnitCount(validTexUnits);
800
801 // Build texture stage sub states.
802 for (unsigned short i=0; i < srcPass->getNumTextureUnitStates(); ++i)
803 {
804 TextureUnitState* texUnitState = srcPass->getTextureUnitState(i);
805
806 if (isProcessingNeeded(texUnitState))
807 {
808 setTextureUnit(i, texUnitState);
809 }
810 }
811
812 return true;
813 }
814
815 //-----------------------------------------------------------------------
updateGpuProgramsParams(Renderable * rend,Pass * pass,const AutoParamDataSource * source,const LightList * pLightList)816 void FFPTexturing::updateGpuProgramsParams(Renderable* rend, Pass* pass, const AutoParamDataSource* source,
817 const LightList* pLightList)
818 {
819 for (unsigned int i=0; i < mTextureUnitParamsList.size(); ++i)
820 {
821 TextureUnitParams* curParams = &mTextureUnitParamsList[i];
822
823 if (curParams->mTextureProjector != NULL && curParams->mTextureViewProjImageMatrix.get() != NULL)
824 {
825 Matrix4 matTexViewProjImage;
826
827 matTexViewProjImage =
828 Matrix4::CLIPSPACE2DTOIMAGESPACE *
829 curParams->mTextureProjector->getProjectionMatrixWithRSDepth() *
830 curParams->mTextureProjector->getViewMatrix();
831
832 curParams->mTextureViewProjImageMatrix->setGpuParameter(matTexViewProjImage);
833 }
834 }
835 }
836
837 //-----------------------------------------------------------------------
setTextureUnitCount(size_t count)838 void FFPTexturing::setTextureUnitCount(size_t count)
839 {
840 mTextureUnitParamsList.resize(count);
841
842 for (unsigned int i=0; i < count; ++i)
843 {
844 TextureUnitParams& curParams = mTextureUnitParamsList[i];
845
846 curParams.mTextureUnitState = NULL;
847 curParams.mTextureProjector = NULL;
848 curParams.mTextureSamplerIndex = 0;
849 curParams.mTextureSamplerType = GCT_SAMPLER2D;
850 curParams.mVSInTextureCoordinateType = GCT_FLOAT2;
851 curParams.mVSOutTextureCoordinateType = GCT_FLOAT2;
852 }
853 }
854
855 //-----------------------------------------------------------------------
setTextureUnit(unsigned short index,TextureUnitState * textureUnitState)856 void FFPTexturing::setTextureUnit(unsigned short index, TextureUnitState* textureUnitState)
857 {
858 if (index >= mTextureUnitParamsList.size())
859 {
860 OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
861 "FFPTexturing unit index out of bounds !!!",
862 "FFPTexturing::setTextureUnit");
863 }
864
865 if (textureUnitState->getBindingType() == TextureUnitState::BT_VERTEX)
866 {
867 OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
868 "FFP Texture unit does not support vertex texture fetch !!!",
869 "FFPTexturing::setTextureUnit");
870 }
871
872
873 TextureUnitParams& curParams = mTextureUnitParamsList[index];
874
875
876 curParams.mTextureSamplerIndex = index;
877 curParams.mTextureUnitState = textureUnitState;
878
879 switch (curParams.mTextureUnitState->getTextureType())
880 {
881 case TEX_TYPE_1D:
882 curParams.mTextureSamplerType = GCT_SAMPLER1D;
883 curParams.mVSInTextureCoordinateType = GCT_FLOAT1;
884 break;
885 case TEX_TYPE_2D:
886 curParams.mTextureSamplerType = GCT_SAMPLER2D;
887 curParams.mVSInTextureCoordinateType = GCT_FLOAT2;
888 break;
889 case TEX_TYPE_2D_RECT:
890 curParams.mTextureSamplerType = GCT_SAMPLERRECT;
891 curParams.mVSInTextureCoordinateType = GCT_FLOAT2;
892 break;
893 case TEX_TYPE_2D_ARRAY:
894 curParams.mTextureSamplerType = GCT_SAMPLER2DARRAY;
895 curParams.mVSInTextureCoordinateType = GCT_FLOAT3;
896 break;
897 case TEX_TYPE_3D:
898 curParams.mTextureSamplerType = GCT_SAMPLER3D;
899 curParams.mVSInTextureCoordinateType = GCT_FLOAT3;
900 break;
901 case TEX_TYPE_CUBE_MAP:
902 curParams.mTextureSamplerType = GCT_SAMPLERCUBE;
903 curParams.mVSInTextureCoordinateType = GCT_FLOAT3;
904 break;
905 }
906
907 curParams.mVSOutTextureCoordinateType = curParams.mVSInTextureCoordinateType;
908 curParams.mTexCoordCalcMethod = getTexCalcMethod(curParams.mTextureUnitState);
909
910 if (curParams.mTexCoordCalcMethod == TEXCALC_PROJECTIVE_TEXTURE)
911 curParams.mVSOutTextureCoordinateType = GCT_FLOAT3;
912 }
913
914 //-----------------------------------------------------------------------
isProcessingNeeded(TextureUnitState * texUnitState)915 bool FFPTexturing::isProcessingNeeded(TextureUnitState* texUnitState)
916 {
917 return texUnitState->getBindingType() == TextureUnitState::BT_FRAGMENT;
918 }
919
920
921 //-----------------------------------------------------------------------
getType() const922 const String& FFPTexturingFactory::getType() const
923 {
924 return FFPTexturing::Type;
925 }
926
927 //-----------------------------------------------------------------------
createInstance(ScriptCompiler * compiler,PropertyAbstractNode * prop,Pass * pass,SGScriptTranslator * translator)928 SubRenderState* FFPTexturingFactory::createInstance(ScriptCompiler* compiler,
929 PropertyAbstractNode* prop, Pass* pass, SGScriptTranslator* translator)
930 {
931 if (prop->name == "texturing_stage")
932 {
933 if(prop->values.size() == 1)
934 {
935 String modelType;
936
937 if(false == SGScriptTranslator::getString(prop->values.front(), &modelType))
938 {
939 compiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line);
940 return NULL;
941 }
942
943 if (modelType == "ffp")
944 {
945 return createOrRetrieveInstance(translator);
946 }
947 }
948 }
949
950 return NULL;
951 }
952
953 //-----------------------------------------------------------------------
writeInstance(MaterialSerializer * ser,SubRenderState * subRenderState,Pass * srcPass,Pass * dstPass)954 void FFPTexturingFactory::writeInstance(MaterialSerializer* ser, SubRenderState* subRenderState,
955 Pass* srcPass, Pass* dstPass)
956 {
957 ser->writeAttribute(4, "texturing_stage");
958 ser->writeValue("ffp");
959 }
960
961 //-----------------------------------------------------------------------
createInstanceImpl()962 SubRenderState* FFPTexturingFactory::createInstanceImpl()
963 {
964 return OGRE_NEW FFPTexturing;
965 }
966
967
968 }
969 }
970
971 #endif
972