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 "OgreShaderExTriplanarTexturing.h"
28 #ifdef RTSHADER_SYSTEM_BUILD_EXT_SHADERS
29 #include "OgreShaderFFPRenderState.h"
30 #include "OgreShaderProgram.h"
31 #include "OgreShaderParameter.h"
32 #include "OgreShaderProgramSet.h"
33 
34 namespace Ogre {
35 namespace RTShader {
36 
37     String TriplanarTexturing::type = "SGX_TriplanarTexturing";
38 
39     //-----------------------------------------------------------------------
40 
resolveParameters(ProgramSet * programSet)41     bool TriplanarTexturing::resolveParameters(ProgramSet* programSet)
42     {
43         Program* vsProgram = programSet->getCpuVertexProgram();
44         Program* psProgram = programSet->getCpuFragmentProgram();
45         Function* vsMain   = vsProgram->getEntryPointFunction();
46         Function* psMain   = psProgram->getEntryPointFunction();
47 
48         // Resolve pixel shader output diffuse color.
49         mPSInDiffuse = vsMain->resolveInputParameter(Parameter::SPS_COLOR, 0, Parameter::SPC_COLOR_DIFFUSE, GCT_FLOAT4);
50 
51         // Resolve input vertex shader normal.
52         mVSInNormal = vsMain->resolveInputParameter(Parameter::SPS_NORMAL, 0, Parameter::SPC_NORMAL_OBJECT_SPACE, GCT_FLOAT3);
53 
54         // Resolve output vertex shader normal.
55         mVSOutNormal = vsMain->resolveOutputParameter(Parameter::SPS_TEXTURE_COORDINATES, -1, Parameter::SPC_NORMAL_VIEW_SPACE, GCT_FLOAT3);
56 
57 	// Resolve pixel shader output diffuse color.
58 	mPSInDiffuse = psMain->resolveInputParameter(Parameter::SPS_COLOR, 0, Parameter::SPC_COLOR_DIFFUSE, GCT_FLOAT4);
59 
60         // Resolve input pixel shader normal.
61         mPSInNormal = psMain->resolveInputParameter(Parameter::SPS_TEXTURE_COORDINATES,
62             mVSOutNormal->getIndex(),
63             mVSOutNormal->getContent(),
64             GCT_FLOAT3);
65 
66         // Resolve input vertex shader normal.
67         mVSInPosition = vsMain->resolveInputParameter(Parameter::SPS_POSITION, 0, Parameter::SPC_POSITION_OBJECT_SPACE, GCT_FLOAT4);
68 
69         mVSInPosition  = vsMain->resolveInputParameter(Parameter::SPS_POSITION, 0, Parameter::SPC_POSITION_OBJECT_SPACE, GCT_FLOAT4);
70         mVSOutPosition = vsMain->resolveOutputParameter(Parameter::SPS_TEXTURE_COORDINATES, -1, Parameter::SPC_POSITION_OBJECT_SPACE, GCT_FLOAT4);
71         mPSInPosition = psMain->resolveInputParameter(Parameter::SPS_TEXTURE_COORDINATES,
72             mVSOutPosition->getIndex(),
73             mVSOutPosition->getContent(),
74             GCT_FLOAT4);
75 
76         mSamplerFromX = psProgram->resolveParameter(GCT_SAMPLER2D, mTextureSamplerIndexFromX, (uint16)GPV_GLOBAL, "tp_sampler_from_x");
77         if (mSamplerFromX.get() == NULL)
78             return false;
79         mSamplerFromY = psProgram->resolveParameter(GCT_SAMPLER2D, mTextureSamplerIndexFromY, (uint16)GPV_GLOBAL, "tp_sampler_from_y");
80         if (mSamplerFromY.get() == NULL)
81             return false;
82         mSamplerFromZ = psProgram->resolveParameter(GCT_SAMPLER2D, mTextureSamplerIndexFromZ, (uint16)GPV_GLOBAL, "tp_sampler_from_z");
83         if (mSamplerFromZ.get() == NULL)
84             return false;
85 
86         mPSOutDiffuse = psMain->resolveOutputParameter(Parameter::SPS_COLOR, 0, Parameter::SPC_COLOR_DIFFUSE, GCT_FLOAT4);
87         if (mPSOutDiffuse.get() == NULL)
88             return false;
89 
90         mPSTPParams = psProgram->resolveParameter(GCT_FLOAT3, -1, (uint16)GPV_GLOBAL, "gTPParams");
91         if (mPSTPParams.get() == NULL)
92             return false;
93         return true;
94     }
95 
96     //-----------------------------------------------------------------------
resolveDependencies(ProgramSet * programSet)97     bool TriplanarTexturing::resolveDependencies(ProgramSet* programSet)
98     {
99         Program* psProgram = programSet->getCpuFragmentProgram();
100         Program* vsProgram = programSet->getCpuVertexProgram();
101         psProgram->addDependency("SGXLib_TriplanarTexturing");
102         vsProgram->addDependency(FFP_LIB_COMMON);
103         return true;
104     }
105 
106     //-----------------------------------------------------------------------
addFunctionInvocations(ProgramSet * programSet)107     bool TriplanarTexturing::addFunctionInvocations(ProgramSet* programSet)
108     {
109         Program* psProgram = programSet->getCpuFragmentProgram();
110         Function* psMain = psProgram->getEntryPointFunction();
111         Program* vsProgram = programSet->getCpuVertexProgram();
112         Function* vsMain = vsProgram->getEntryPointFunction();
113 
114         int internalCounter = 0;
115 
116         FunctionInvocation *curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, FFP_VS_TEXTURING, internalCounter++);
117         curFuncInvocation->pushOperand(mVSInNormal, Operand::OPS_IN);
118         curFuncInvocation->pushOperand(mVSOutNormal, Operand::OPS_OUT);
119         vsMain->addAtomInstance(curFuncInvocation);
120 
121         curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, FFP_VS_TEXTURING, internalCounter++);
122         curFuncInvocation->pushOperand(mVSInPosition, Operand::OPS_IN);
123         curFuncInvocation->pushOperand(mVSOutPosition, Operand::OPS_OUT);
124         vsMain->addAtomInstance(curFuncInvocation);
125 
126         curFuncInvocation = OGRE_NEW FunctionInvocation(SGX_FUNC_TRIPLANAR_TEXTURING, FFP_PS_TEXTURING, internalCounter++);
127         curFuncInvocation->pushOperand(mPSInDiffuse, Operand::OPS_IN);
128         curFuncInvocation->pushOperand(mPSInNormal, Operand::OPS_IN);
129         curFuncInvocation->pushOperand(mPSInPosition, Operand::OPS_IN);
130         curFuncInvocation->pushOperand(mSamplerFromX, Operand::OPS_IN);
131         curFuncInvocation->pushOperand(mSamplerFromY, Operand::OPS_IN);
132         curFuncInvocation->pushOperand(mSamplerFromZ, Operand::OPS_IN);
133         curFuncInvocation->pushOperand(mPSTPParams, Operand::OPS_IN);
134         curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_OUT);
135         psMain->addAtomInstance(curFuncInvocation);
136 
137         return true;
138     }
139 
140     //-----------------------------------------------------------------------
getType() const141     const String& TriplanarTexturing::getType() const
142     {
143         return type;
144     }
145 
146     //-----------------------------------------------------------------------
getExecutionOrder() const147     int	TriplanarTexturing::getExecutionOrder() const
148     {
149         return FFP_TEXTURING;
150     }
151 
152     //-----------------------------------------------------------------------
preAddToRenderState(const RenderState * renderState,Pass * srcPass,Pass * dstPass)153     bool TriplanarTexturing::preAddToRenderState(const RenderState* renderState, Pass* srcPass, Pass* dstPass )
154     {
155         TextureUnitState* textureUnit;
156 
157         // Create the mapping textures
158         textureUnit = dstPass->createTextureUnitState();
159         textureUnit->setTextureName(mTextureNameFromX);
160         mTextureSamplerIndexFromX = dstPass->getNumTextureUnitStates() - 1;
161 
162         textureUnit = dstPass->createTextureUnitState();
163         textureUnit->setTextureName(mTextureNameFromY);
164         mTextureSamplerIndexFromY = dstPass->getNumTextureUnitStates() - 1;
165 
166         textureUnit = dstPass->createTextureUnitState();
167         textureUnit->setTextureName(mTextureNameFromZ);
168         mTextureSamplerIndexFromZ = dstPass->getNumTextureUnitStates() - 1;
169         return true;
170     }
171 
172     //-----------------------------------------------------------------------
copyFrom(const SubRenderState & rhs)173     void TriplanarTexturing::copyFrom(const SubRenderState& rhs)
174     {
175         const TriplanarTexturing& rhsTP = static_cast<const TriplanarTexturing&>(rhs);
176 
177         mPSOutDiffuse = rhsTP.mPSOutDiffuse;
178         mPSInDiffuse = rhsTP.mPSInDiffuse;
179 
180         mVSInPosition = rhsTP.mVSInPosition;
181         mVSOutPosition = rhsTP.mVSOutPosition;
182 
183         mVSOutNormal = rhsTP.mVSOutNormal;
184         mVSInNormal = rhsTP.mVSInNormal;
185         mPSInNormal = rhsTP.mPSInNormal;
186 
187         mVSOutPosition = rhsTP.mVSOutPosition;
188         mVSInPosition = rhsTP.mVSInPosition;
189         mPSInPosition = rhsTP.mPSInPosition;
190 
191         mSamplerFromX = rhsTP.mSamplerFromX;
192         mSamplerFromY = rhsTP.mSamplerFromY;
193         mSamplerFromZ = rhsTP.mSamplerFromZ;
194 
195         mPSTPParams = rhsTP.mPSTPParams;
196         mParameters = rhsTP.mParameters;
197         mTextureNameFromX = rhsTP.mTextureNameFromX;
198         mTextureNameFromY = rhsTP.mTextureNameFromY;
199         mTextureNameFromZ = rhsTP.mTextureNameFromZ;
200     }
201 
202     //-----------------------------------------------------------------------
updateGpuProgramsParams(Renderable * rend,Pass * pass,const AutoParamDataSource * source,const LightList * pLightList)203     void TriplanarTexturing::updateGpuProgramsParams(Renderable* rend, Pass* pass, const AutoParamDataSource* source,
204                                          const LightList* pLightList)
205     {
206         mPSTPParams->setGpuParameter(mParameters);
207     }
208 
209     //-----------------------------------------------------------------------
setParameters(const Vector3 & parameters)210     void TriplanarTexturing::setParameters(const Vector3 &parameters)
211     {
212         mParameters = parameters;
213     }
214 
215     //-----------------------------------------------------------------------
setTextureNames(const String & textureNameFromX,const String & textureNameFromY,const String & textureNameFromZ)216     void TriplanarTexturing::setTextureNames(const String &textureNameFromX, const String &textureNameFromY, const String &textureNameFromZ)
217     {
218         mTextureNameFromX = textureNameFromX;
219         mTextureNameFromY = textureNameFromY;
220         mTextureNameFromZ = textureNameFromZ;
221     }
222 
223     //-----------------------------------------------------------------------
getType() const224     const String& TriplanarTexturingFactory::getType() const
225     {
226         return TriplanarTexturing::type;
227     }
228 
229     //-----------------------------------------------------------------------
createInstance(ScriptCompiler * compiler,PropertyAbstractNode * prop,Pass * pass,SGScriptTranslator * translator)230     SubRenderState*	TriplanarTexturingFactory::createInstance(ScriptCompiler* compiler,
231                                                        PropertyAbstractNode* prop, Pass* pass, SGScriptTranslator* translator)
232     {
233         if (prop->name == "triplanarTexturing")
234         {
235             if (prop->values.size() == 6)
236             {
237                 SubRenderState* subRenderState = createOrRetrieveInstance(translator);
238                 TriplanarTexturing* tpSubRenderState = static_cast<TriplanarTexturing*>(subRenderState);
239 
240 	            AbstractNodeList::const_iterator it = prop->values.begin();
241                 float parameters[3];
242                 if (false == SGScriptTranslator::getFloat(*it, parameters))
243                 {
244                     compiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line);
245                     return NULL;
246                 }
247                 it++;
248                 if (false == SGScriptTranslator::getFloat(*it, parameters + 1))
249                 {
250                     compiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line);
251                     return NULL;
252                 }
253                 it++;
254                 if (false == SGScriptTranslator::getFloat(*it, parameters + 2))
255                 {
256                     compiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line);
257                     return NULL;
258                 }
259                 Vector3 vParameters(parameters[0], parameters[1], parameters[2]);
260                 tpSubRenderState->setParameters(vParameters);
261 
262                 String textureNameFromX, textureNameFromY, textureNameFromZ;
263                 ++it;
264                 if (false == SGScriptTranslator::getString(*it, &textureNameFromX))
265                 {
266                     compiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line);
267                     return NULL;
268                 }
269                 ++it;
270                 if (false == SGScriptTranslator::getString(*it, &textureNameFromY))
271                 {
272                     compiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line);
273                     return NULL;
274                 }
275                 ++it;
276                 if (false == SGScriptTranslator::getString(*it, &textureNameFromZ))
277                 {
278                     compiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line);
279                     return NULL;
280                 }
281                 tpSubRenderState->setTextureNames(textureNameFromX, textureNameFromY, textureNameFromZ);
282 
283                 return subRenderState;
284             }
285             else
286             {
287                 compiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line);
288             }
289         }
290         return NULL;
291     }
292 
293     //-----------------------------------------------------------------------
createInstanceImpl()294     SubRenderState*	TriplanarTexturingFactory::createInstanceImpl()
295     {
296         return OGRE_NEW TriplanarTexturing;
297     }
298 
299 
300 }
301 }
302 
303 #endif
304