//----------------------------------------------------------------------- void DualQuaternionSkinning::addIndexedPositionWeight(Function* vsMain, int index, ParameterPtr& pWorldMatrix, ParameterPtr& pPositionTempParameter, ParameterPtr& pPositionRelatedOutputParam, int& funcCounter) { Operand::OpMask indexMask = indexToMask(index); FunctionInvocation* curFuncInvocation; //multiply position with world matrix and put into temporary param curFuncInvocation = OGRE_NEW FunctionInvocation(SGX_FUNC_BLEND_WEIGHT, FFP_VS_TRANSFORM, funcCounter++); curFuncInvocation->pushOperand(mParamInWeights, Operand::OPS_IN, indexMask); curFuncInvocation->pushOperand(pWorldMatrix, Operand::OPS_IN); curFuncInvocation->pushOperand(pPositionTempParameter, Operand::OPS_OUT); vsMain->addAtomInstance(curFuncInvocation); //check if on first iteration if (index == 0) { //set the local param as the value of the world param curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, FFP_VS_TRANSFORM, funcCounter++); curFuncInvocation->pushOperand(pPositionTempParameter, Operand::OPS_IN); curFuncInvocation->pushOperand(pPositionRelatedOutputParam, Operand::OPS_OUT); vsMain->addAtomInstance(curFuncInvocation); } else { //add the local param as the value of the world param curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ADD, FFP_VS_TRANSFORM, funcCounter++); curFuncInvocation->pushOperand(pPositionTempParameter, Operand::OPS_IN); curFuncInvocation->pushOperand(pPositionRelatedOutputParam, Operand::OPS_IN); curFuncInvocation->pushOperand(pPositionRelatedOutputParam, Operand::OPS_OUT); vsMain->addAtomInstance(curFuncInvocation); } }
//----------------------------------------------------------------------- void HardwareSkinning::addNormalRelatedCalculations(Function* vsMain, ParameterPtr& pNormalRelatedParam, ParameterPtr& pNormalWorldRelatedParam, int& funcCounter) { FunctionInvocation* curFuncInvocation; if (mDoBoneCalculations == true) { //set functions to calculate world normal for(int i = 0 ; i < getWeightCount() ; ++i) { addIndexedNormalRelatedWeight(vsMain, pNormalRelatedParam, pNormalWorldRelatedParam, i, funcCounter); } //update back the original position relative to the object curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_TRANSFORM, FFP_VS_TRANSFORM, funcCounter++); curFuncInvocation->pushOperand(mParamInInvWorldMatrix, Operand::OPS_IN); curFuncInvocation->pushOperand(pNormalWorldRelatedParam, Operand::OPS_IN); curFuncInvocation->pushOperand(pNormalRelatedParam, Operand::OPS_OUT); vsMain->addAtomInstance(curFuncInvocation); } else { //update from object to world space curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_TRANSFORM, FFP_VS_TRANSFORM, funcCounter++); curFuncInvocation->pushOperand(mParamInWorldMatrix, Operand::OPS_IN); curFuncInvocation->pushOperand(pNormalRelatedParam, Operand::OPS_IN); curFuncInvocation->pushOperand(pNormalWorldRelatedParam, Operand::OPS_OUT); vsMain->addAtomInstance(curFuncInvocation); } }
//----------------------------------------------------------------------- bool TriplanarTexturing::addFunctionInvocations(ProgramSet* programSet) { Program* psProgram = programSet->getCpuFragmentProgram(); Function* psMain = psProgram->getEntryPointFunction(); Program* vsProgram = programSet->getCpuVertexProgram(); Function* vsMain = vsProgram->getEntryPointFunction(); int internalCounter = 0; FunctionInvocation *curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, FFP_VS_TEXTURING, internalCounter++); curFuncInvocation->pushOperand(mVSInNormal, Operand::OPS_IN); curFuncInvocation->pushOperand(mVSOutNormal, Operand::OPS_OUT); vsMain->addAtomInstance(curFuncInvocation); curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, FFP_VS_TEXTURING, internalCounter++); curFuncInvocation->pushOperand(mVSInPosition, Operand::OPS_IN); curFuncInvocation->pushOperand(mVSOutPosition, Operand::OPS_OUT); vsMain->addAtomInstance(curFuncInvocation); curFuncInvocation = OGRE_NEW FunctionInvocation(SGX_FUNC_TRIPLANAR_TEXTURING, FFP_PS_TEXTURING, internalCounter++); curFuncInvocation->pushOperand(mPSInDiffuse, Operand::OPS_IN); curFuncInvocation->pushOperand(mPSInNormal, Operand::OPS_IN); curFuncInvocation->pushOperand(mPSInPosition, Operand::OPS_IN); curFuncInvocation->pushOperand(mSamplerFromX, Operand::OPS_IN); curFuncInvocation->pushOperand(mSamplerFromY, Operand::OPS_IN); curFuncInvocation->pushOperand(mSamplerFromZ, Operand::OPS_IN); curFuncInvocation->pushOperand(mPSTPParams, Operand::OPS_IN); curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_OUT); psMain->addAtomInstance(curFuncInvocation); return true; }
//----------------------------------------------------------------------- bool ShaderExInstancedViewports::addVSInvocations( Function* vsMain, const int groupOrder ) { FunctionInvocation* funcInvocation = NULL; int internalCounter = 0; funcInvocation = OGRE_NEW FunctionInvocation(SGX_FUNC_INSTANCED_VIEWPORTS_TRANSFORM, groupOrder, internalCounter++); funcInvocation->pushOperand(mVSInPosition, Operand::OPS_IN); funcInvocation->pushOperand(mWorldViewMatrix, Operand::OPS_IN); funcInvocation->pushOperand(mProjectionMatrix, Operand::OPS_IN); funcInvocation->pushOperand(mVSInViewportOffsetMatrixR0, Operand::OPS_IN); funcInvocation->pushOperand(mVSInViewportOffsetMatrixR1, Operand::OPS_IN); funcInvocation->pushOperand(mVSInViewportOffsetMatrixR2, Operand::OPS_IN); funcInvocation->pushOperand(mVSInViewportOffsetMatrixR3, Operand::OPS_IN); funcInvocation->pushOperand(mVSInMonitorsCount, Operand::OPS_IN); funcInvocation->pushOperand(mVSInMonitorIndex, Operand::OPS_IN); funcInvocation->pushOperand(mVSOriginalOutPositionProjectiveSpace, Operand::OPS_OUT); vsMain->addAtomInstance(funcInvocation); // Output position in projective space. funcInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, groupOrder, internalCounter++); funcInvocation->pushOperand(mVSOriginalOutPositionProjectiveSpace, Operand::OPS_IN); funcInvocation->pushOperand(mVSOutPositionProjectiveSpace, Operand::OPS_OUT); vsMain->addAtomInstance(funcInvocation); // Output monitor index. funcInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, groupOrder, internalCounter++); funcInvocation->pushOperand(mVSInMonitorIndex, Operand::OPS_IN); funcInvocation->pushOperand(mVSOutMonitorIndex, Operand::OPS_OUT); vsMain->addAtomInstance(funcInvocation); return true; }
//----------------------------------------------------------------------- bool IntegratedPSSM3::addVSInvocation(Function* vsMain, const int groupOrder, int& internalCounter) { FunctionInvocation* curFuncInvocation; // Output the vertex depth in camera space. curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, groupOrder, internalCounter++); curFuncInvocation->pushOperand(mVSOutPos, Operand::OPS_IN, Operand::OPM_Z); curFuncInvocation->pushOperand(mVSOutDepth, Operand::OPS_OUT); vsMain->addAtomInstance(curFuncInvocation); // Compute world space position. ShadowTextureParamsIterator it = mShadowTextureParamsList.begin(); while(it != mShadowTextureParamsList.end()) { curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_TRANSFORM, groupOrder, internalCounter++); curFuncInvocation->pushOperand(it->mWorldViewProjMatrix, Operand::OPS_IN); curFuncInvocation->pushOperand(mVSInPos, Operand::OPS_IN); curFuncInvocation->pushOperand(it->mVSOutLightPosition, Operand::OPS_OUT); vsMain->addAtomInstance(curFuncInvocation); ++it; } return true; }
//----------------------------------------------------------------------------- void ProgramProcessor::generateLocalSplitParameters(Function* func, GpuProgramType progType, MergeParameterList& mergedParams, ShaderParameterList& splitParams, LocalParameterMap& localParamsMap) { // No split params created. if (splitParams.size() == 0) return; // Create the local parameters + map from source to local. for (unsigned int i=0; i < splitParams.size(); ++i) { ParameterPtr srcParameter = splitParams[i]; ParameterPtr localParameter = func->resolveLocalParameter(srcParameter->getSemantic(), srcParameter->getIndex(), "lsplit_" + srcParameter->getName(), srcParameter->getType()); localParamsMap[srcParameter.get()] = localParameter; } int invocationCounter = 0; // Establish link between the local parameter to the merged parameter. for (unsigned int i=0; i < mergedParams.size(); ++i) { MergeParameter& curMergeParameter = mergedParams[i]; for (unsigned int p=0; p < curMergeParameter.getSourceParameterCount(); ++p) { ParameterPtr srcMergedParameter = curMergeParameter.getSourceParameter(p); LocalParameterMap::iterator itFind = localParamsMap.find(srcMergedParameter.get()); // Case the source parameter is split parameter. if (itFind != localParamsMap.end()) { // Case it is the vertex shader -> assign the local parameter to the output merged parameter. if (progType == GPT_VERTEX_PROGRAM) { FunctionInvocation* curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, FFP_VS_POST_PROCESS, invocationCounter++); curFuncInvocation->pushOperand(itFind->second, Operand::OPS_IN, curMergeParameter.getSourceParameterMask(p)); curFuncInvocation->pushOperand(curMergeParameter.getDestinationParameter(Operand::OPS_OUT, i), Operand::OPS_OUT, curMergeParameter.getDestinationParameterMask(p)); func->addAtomInstance(curFuncInvocation); } else if (progType == GPT_FRAGMENT_PROGRAM) { FunctionInvocation* curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, FFP_PS_PRE_PROCESS, invocationCounter++); curFuncInvocation->pushOperand(curMergeParameter.getDestinationParameter(Operand::OPS_IN, i), Operand::OPS_IN, curMergeParameter.getDestinationParameterMask(p)); curFuncInvocation->pushOperand(itFind->second, Operand::OPS_OUT, curMergeParameter.getSourceParameterMask(p)); func->addAtomInstance(curFuncInvocation); } } } } }
//----------------------------------------------------------------------- bool FFPLighting::addGlobalIlluminationInvocation(Function* vsMain, const int groupOrder, int& internalCounter) { FunctionInvocation* curFuncInvocation = NULL; if ((mTrackVertexColourType & TVC_AMBIENT) == 0 && (mTrackVertexColourType & TVC_EMISSIVE) == 0) { curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, groupOrder, internalCounter++); curFuncInvocation->pushOperand(mDerivedSceneColour, Operand::OPS_IN); curFuncInvocation->pushOperand(mVSOutDiffuse, Operand::OPS_OUT); vsMain->addAtomInstance(curFuncInvocation); } else { if (mTrackVertexColourType & TVC_AMBIENT) { curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_MODULATE, groupOrder, internalCounter++); curFuncInvocation->pushOperand(mLightAmbientColour, Operand::OPS_IN); curFuncInvocation->pushOperand(mVSDiffuse, Operand::OPS_IN); curFuncInvocation->pushOperand(mVSOutDiffuse, Operand::OPS_OUT); vsMain->addAtomInstance(curFuncInvocation); } else { curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, groupOrder, internalCounter++); curFuncInvocation->pushOperand(mDerivedAmbientLightColour, Operand::OPS_IN, (Operand::OPM_X | Operand::OPM_Y | Operand::OPM_Z)); curFuncInvocation->pushOperand(mVSOutDiffuse, Operand::OPS_OUT, (Operand::OPM_X | Operand::OPM_Y | Operand::OPM_Z)); vsMain->addAtomInstance(curFuncInvocation); } if (mTrackVertexColourType & TVC_EMISSIVE) { curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ADD, groupOrder, internalCounter++); curFuncInvocation->pushOperand(mVSDiffuse, Operand::OPS_IN); curFuncInvocation->pushOperand(mVSOutDiffuse, Operand::OPS_IN); curFuncInvocation->pushOperand(mVSOutDiffuse, Operand::OPS_OUT); vsMain->addAtomInstance(curFuncInvocation); } else { curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ADD, groupOrder, internalCounter++); curFuncInvocation->pushOperand(mSurfaceEmissiveColour, Operand::OPS_IN); curFuncInvocation->pushOperand(mVSOutDiffuse, Operand::OPS_IN); curFuncInvocation->pushOperand(mVSOutDiffuse, Operand::OPS_OUT); vsMain->addAtomInstance(curFuncInvocation); } } return true; }
//----------------------------------------------------------------------- void FFPTexturing::addPSSampleTexelInvocation(TextureUnitParams* textureUnitParams, Function* psMain, const ParameterPtr& texel, int groupOrder, int& internalCounter) { FunctionInvocation* curFuncInvocation = NULL; if (textureUnitParams->mTexCoordCalcMethod == TEXCALC_PROJECTIVE_TEXTURE) curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_SAMPLE_TEXTURE_PROJ, groupOrder, internalCounter++); else curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_SAMPLE_TEXTURE, groupOrder, internalCounter++); curFuncInvocation->pushOperand(textureUnitParams->mTextureSampler, Operand::OPS_IN); curFuncInvocation->pushOperand(textureUnitParams->mPSInputTexCoord, Operand::OPS_IN); curFuncInvocation->pushOperand(texel, Operand::OPS_OUT); psMain->addAtomInstance(curFuncInvocation); }
//----------------------------------------------------------------------- bool IntegratedPSSM3::addPSInvocation(Program* psProgram, const int groupOrder, int& internalCounter) { Function* psMain = psProgram->getEntryPointFunction(); FunctionInvocation* curFuncInvocation; ShadowTextureParams& splitParams0 = mShadowTextureParamsList[0]; ShadowTextureParams& splitParams1 = mShadowTextureParamsList[1]; ShadowTextureParams& splitParams2 = mShadowTextureParamsList[2]; // Compute shadow factor. curFuncInvocation = OGRE_NEW FunctionInvocation(SGX_FUNC_COMPUTE_SHADOW_COLOUR3, groupOrder, internalCounter++); curFuncInvocation->pushOperand(mPSInDepth, Operand::OPS_IN); curFuncInvocation->pushOperand(mPSSplitPoints, Operand::OPS_IN); curFuncInvocation->pushOperand(splitParams0.mPSInLightPosition, Operand::OPS_IN); curFuncInvocation->pushOperand(splitParams1.mPSInLightPosition, Operand::OPS_IN); curFuncInvocation->pushOperand(splitParams2.mPSInLightPosition, Operand::OPS_IN); curFuncInvocation->pushOperand(splitParams0.mTextureSampler, Operand::OPS_IN); curFuncInvocation->pushOperand(splitParams1.mTextureSampler, Operand::OPS_IN); curFuncInvocation->pushOperand(splitParams2.mTextureSampler, Operand::OPS_IN); curFuncInvocation->pushOperand(splitParams0.mInvTextureSize, Operand::OPS_IN); curFuncInvocation->pushOperand(splitParams1.mInvTextureSize, Operand::OPS_IN); curFuncInvocation->pushOperand(splitParams2.mInvTextureSize, Operand::OPS_IN); curFuncInvocation->pushOperand(mPSLocalShadowFactor, Operand::OPS_OUT); psMain->addAtomInstance(curFuncInvocation); // Apply shadow factor on diffuse colour. curFuncInvocation = OGRE_NEW FunctionInvocation(SGX_FUNC_APPLYSHADOWFACTOR_DIFFUSE, groupOrder, internalCounter++); curFuncInvocation->pushOperand(mPSDerivedSceneColour, Operand::OPS_IN); curFuncInvocation->pushOperand(mPSDiffuse, Operand::OPS_IN); curFuncInvocation->pushOperand(mPSLocalShadowFactor, Operand::OPS_IN); curFuncInvocation->pushOperand(mPSDiffuse, Operand::OPS_OUT); psMain->addAtomInstance(curFuncInvocation); // Apply shadow factor on specular colour. curFuncInvocation = OGRE_NEW FunctionInvocation(SGX_FUNC_MODULATE_SCALAR, groupOrder, internalCounter++); curFuncInvocation->pushOperand(mPSLocalShadowFactor, Operand::OPS_IN); curFuncInvocation->pushOperand(mPSSpecualr, Operand::OPS_IN); curFuncInvocation->pushOperand(mPSSpecualr, Operand::OPS_OUT); psMain->addAtomInstance(curFuncInvocation); // Assign the local diffuse to output diffuse. curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, groupOrder, internalCounter++); curFuncInvocation->pushOperand(mPSDiffuse, Operand::OPS_IN); curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_OUT); psMain->addAtomInstance(curFuncInvocation); return true; }
//----------------------------------------------------------------------- bool FFPTransform::createCpuSubPrograms(ProgramSet* programSet) { //! [param_resolve] Program* vsProgram = programSet->getCpuVertexProgram(); Function* vsEntry = vsProgram->getEntryPointFunction(); // Resolve World View Projection Matrix. UniformParameterPtr wvpMatrix = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX, 0); // Resolve input position parameter. ParameterPtr positionIn = vsEntry->resolveInputParameter(Parameter::SPS_POSITION, 0, Parameter::SPC_POSITION_OBJECT_SPACE, GCT_FLOAT4); // Resolve output position parameter. ParameterPtr positionOut = vsEntry->resolveOutputParameter(Parameter::SPS_POSITION, 0, Parameter::SPC_POSITION_PROJECTIVE_SPACE, GCT_FLOAT4); if (!wvpMatrix || !positionIn || !positionOut) { OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, "Not all parameters could be constructed for the sub-render state.", "FFPTransform::createCpuSubPrograms" ); } //! [param_resolve] // Add dependency. vsProgram->addDependency(FFP_LIB_TRANSFORM); FunctionInvocation* transformFunc = OGRE_NEW FunctionInvocation(FFP_FUNC_TRANSFORM, FFP_VS_TRANSFORM, 0); transformFunc->pushOperand(wvpMatrix, Operand::OPS_IN); transformFunc->pushOperand(positionIn, Operand::OPS_IN); transformFunc->pushOperand(positionOut, Operand::OPS_OUT); vsEntry->addAtomInstance(transformFunc); return true; }
//----------------------------------------------------------------------- void HardwareSkinning::addIndexedPositionWeight(Function* vsMain, int index, int& funcCounter) { Operand::OpMask indexMask = indexToMask(index); FunctionInvocation* curFuncInvocation; //multiply position with world matrix and put into temporary param curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_TRANSFORM, FFP_VS_TRANSFORM, funcCounter++); curFuncInvocation->pushOperand(mParamInWorldMatrices, Operand::OPS_IN); curFuncInvocation->pushOperand(mParamInIndices, Operand::OPS_IN, indexMask, 1); curFuncInvocation->pushOperand(mParamInPosition, Operand::OPS_IN); curFuncInvocation->pushOperand(mParamTempFloat4, Operand::OPS_OUT, Operand::OPM_X | Operand::OPM_Y | Operand::OPM_Z); vsMain->addAtomInstance(curFuncInvocation); //set w value of temporary param to 1 curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, FFP_VS_TRANSFORM, funcCounter++); curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(1.0f), Operand::OPS_IN); curFuncInvocation->pushOperand(mParamTempFloat4, Operand::OPS_OUT, Operand::OPM_W); vsMain->addAtomInstance(curFuncInvocation); //multiply temporary param with weight curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_MODULATE, FFP_VS_TRANSFORM, funcCounter++); curFuncInvocation->pushOperand(mParamTempFloat4, Operand::OPS_IN); curFuncInvocation->pushOperand(mParamInWeights, Operand::OPS_IN, indexMask); curFuncInvocation->pushOperand(mParamTempFloat4, Operand::OPS_OUT); vsMain->addAtomInstance(curFuncInvocation); //check if on first iteration if (index == 0) { //set the local param as the value of the world param curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, FFP_VS_TRANSFORM, funcCounter++); curFuncInvocation->pushOperand(mParamTempFloat4, Operand::OPS_IN); curFuncInvocation->pushOperand(mParamLocalPositionWorld, Operand::OPS_OUT); vsMain->addAtomInstance(curFuncInvocation); } else { //add the local param as the value of the world param curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ADD, FFP_VS_TRANSFORM, funcCounter++); curFuncInvocation->pushOperand(mParamLocalPositionWorld, Operand::OPS_IN); curFuncInvocation->pushOperand(mParamLocalPositionWorld, Operand::OPS_OUT); curFuncInvocation->pushOperand(mParamTempFloat4, Operand::OPS_IN); vsMain->addAtomInstance(curFuncInvocation); } }
//----------------------------------------------------------------------- void HardwareSkinning::addIndexedNormalRelatedWeight(Function* vsMain, ParameterPtr& pNormalParam, ParameterPtr& pNormalWorldRelatedParam, int index, int& funcCounter) { FunctionInvocation* curFuncInvocation; Operand::OpMask indexMask = indexToMask(index); //multiply position with world matrix and put into temporary param curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_TRANSFORM, FFP_VS_TRANSFORM, funcCounter++); curFuncInvocation->pushOperand(mParamInWorldMatrices, Operand::OPS_IN, Operand::OPM_ALL); curFuncInvocation->pushOperand(mParamInIndices, Operand::OPS_IN, indexMask, 1); curFuncInvocation->pushOperand(pNormalParam, Operand::OPS_IN); curFuncInvocation->pushOperand(mParamTempFloat3, Operand::OPS_OUT, Operand::OPM_X | Operand::OPM_Y | Operand::OPM_Z); vsMain->addAtomInstance(curFuncInvocation); //multiply temporary param with weight curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_MODULATE, FFP_VS_TRANSFORM, funcCounter++); curFuncInvocation->pushOperand(mParamTempFloat3, Operand::OPS_IN); curFuncInvocation->pushOperand(mParamInWeights, Operand::OPS_IN, indexMask); curFuncInvocation->pushOperand(mParamTempFloat3, Operand::OPS_OUT); vsMain->addAtomInstance(curFuncInvocation); //check if on first iteration if (index == 0) { //set the local param as the value of the world normal curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, FFP_VS_TRANSFORM, funcCounter++); curFuncInvocation->pushOperand(mParamTempFloat3, Operand::OPS_IN); curFuncInvocation->pushOperand(pNormalWorldRelatedParam, Operand::OPS_OUT); vsMain->addAtomInstance(curFuncInvocation); } else { //add the local param as the value of the world normal curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ADD, FFP_VS_TRANSFORM, funcCounter++); curFuncInvocation->pushOperand(pNormalWorldRelatedParam, Operand::OPS_IN); curFuncInvocation->pushOperand(pNormalWorldRelatedParam, Operand::OPS_OUT); curFuncInvocation->pushOperand(mParamTempFloat3, Operand::OPS_IN); vsMain->addAtomInstance(curFuncInvocation); } }
//----------------------------------------------------------------------- void HardwareSkinning::addPositionCalculations(Function* vsMain, int& funcCounter) { FunctionInvocation* curFuncInvocation = NULL; if (mDoBoneCalculations == true) { //set functions to calculate world position for(int i = 0 ; i < getWeightCount() ; ++i) { addIndexedPositionWeight(vsMain, i, funcCounter); } //update back the original position relative to the object curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_TRANSFORM, FFP_VS_TRANSFORM, funcCounter++); curFuncInvocation->pushOperand(mParamInInvWorldMatrix, Operand::OPS_IN); curFuncInvocation->pushOperand(mParamLocalPositionWorld, Operand::OPS_IN); curFuncInvocation->pushOperand(mParamInPosition, Operand::OPS_OUT); vsMain->addAtomInstance(curFuncInvocation); //update the projective position thereby filling the transform stage role curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_TRANSFORM, FFP_VS_TRANSFORM, funcCounter++); curFuncInvocation->pushOperand(mParamInViewProjMatrix, Operand::OPS_IN); curFuncInvocation->pushOperand(mParamLocalPositionWorld, Operand::OPS_IN); curFuncInvocation->pushOperand(mParamOutPositionProj, Operand::OPS_OUT); vsMain->addAtomInstance(curFuncInvocation); } else { //update from object to world space curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_TRANSFORM, FFP_VS_TRANSFORM, funcCounter++); curFuncInvocation->pushOperand(mParamInWorldMatrix, Operand::OPS_IN); curFuncInvocation->pushOperand(mParamInPosition, Operand::OPS_IN); curFuncInvocation->pushOperand(mParamLocalPositionWorld, Operand::OPS_OUT); vsMain->addAtomInstance(curFuncInvocation); //update from object to projective space curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_TRANSFORM, FFP_VS_TRANSFORM, funcCounter++); curFuncInvocation->pushOperand(mParamInWorldViewProjMatrix, Operand::OPS_IN); curFuncInvocation->pushOperand(mParamInPosition, Operand::OPS_IN); curFuncInvocation->pushOperand(mParamOutPositionProj, Operand::OPS_OUT); vsMain->addAtomInstance(curFuncInvocation); } }
//----------------------------------------------------------------------- void LayeredBlending::addPSBlendInvocations(Function* psMain, ParameterPtr arg1, ParameterPtr arg2, ParameterPtr texel, int samplerIndex, const LayerBlendModeEx& blendMode, const int groupOrder, int& internalCounter, int targetChannels) { // // Add the modifier invocation // addPSModifierInvocation(psMain, samplerIndex, arg1, arg2, groupOrder, internalCounter, targetChannels); // // Add the blending function invocations // BlendMode mode = getBlendMode(samplerIndex); if ((LB_FFPBlend == mode) || (LB_Invalid == mode)) { FFPTexturing::addPSBlendInvocations(psMain, arg1, arg2, texel, samplerIndex, blendMode, groupOrder, internalCounter, targetChannels); } else { //find the function name for the blend mode String funcName; for(int i = 0 ; i < (int)LayeredBlending::LB_MaxBlendModes ; ++i) { if (_blendModes[i].type == mode) { funcName = _blendModes[i].funcName; break; } } //add the function of the blend mode if (funcName.empty() == false) { FunctionInvocation* curFuncInvocation = OGRE_NEW FunctionInvocation(funcName, groupOrder, internalCounter++); curFuncInvocation->pushOperand(arg1, Operand::OPS_IN, targetChannels); curFuncInvocation->pushOperand(arg2, Operand::OPS_IN, targetChannels); curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_OUT, targetChannels); psMain->addAtomInstance(curFuncInvocation); } } }
//----------------------------------------------------------------------- bool ShaderExInstancedViewports::addPSInvocations( Function* psMain, const int groupOrder ) { FunctionInvocation* funcInvocation = NULL; int internalCounter = 0; funcInvocation = OGRE_NEW FunctionInvocation(SGX_FUNC_INSTANCED_VIEWPORTS_DISCARD_OUT_OF_BOUNDS, groupOrder, internalCounter++); funcInvocation->pushOperand(mPSInMonitorsCount, Operand::OPS_IN); funcInvocation->pushOperand(mPSInMonitorIndex, Operand::OPS_IN); funcInvocation->pushOperand(mPSInPositionProjectiveSpace, Operand::OPS_IN); psMain->addAtomInstance(funcInvocation); return true; }
//----------------------------------------------------------------------- bool ShaderExReflectionMap::addVSInvocations( Function* vsMain, const int groupOrder ) { FunctionInvocation* funcInvoaction = NULL; int internalCounter = 0; // Output mask texture coordinates. funcInvoaction = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, groupOrder, internalCounter++); funcInvoaction->pushOperand(mVSInMaskTexcoord, Operand::OPS_IN); funcInvoaction->pushOperand(mVSOutMaskTexcoord, Operand::OPS_OUT); vsMain->addAtomInstace(funcInvoaction); // Output reflection texture coordinates. if (mReflectionMapType == TEX_TYPE_2D) { funcInvoaction = OGRE_NEW FunctionInvocation(FFP_FUNC_GENERATE_TEXCOORD_ENV_SPHERE, groupOrder, internalCounter++); funcInvoaction->pushOperand(mWorldITMatrix, Operand::OPS_IN); funcInvoaction->pushOperand(mViewMatrix, Operand::OPS_IN); funcInvoaction->pushOperand(mVSInputNormal, Operand::OPS_IN); funcInvoaction->pushOperand(mVSOutReflectionTexcoord, Operand::OPS_OUT); vsMain->addAtomInstace(funcInvoaction); } else { funcInvoaction = OGRE_NEW FunctionInvocation(FFP_FUNC_GENERATE_TEXCOORD_ENV_REFLECT, groupOrder, internalCounter++); funcInvoaction->pushOperand(mWorldMatrix, Operand::OPS_IN); funcInvoaction->pushOperand(mWorldITMatrix, Operand::OPS_IN); funcInvoaction->pushOperand(mViewMatrix, Operand::OPS_IN); funcInvoaction->pushOperand(mVSInputNormal, Operand::OPS_IN); funcInvoaction->pushOperand(mVSInputPos, Operand::OPS_IN); funcInvoaction->pushOperand(mVSOutReflectionTexcoord, Operand::OPS_OUT); vsMain->addAtomInstace(funcInvoaction); } return true; }
//----------------------------------------------------------------------- void LayeredBlending::addPSModifierInvocation(Function* psMain, int samplerIndex, ParameterPtr arg1, ParameterPtr arg2, const int groupOrder, int& internalCounter, int targetChannels) { SourceModifier modType; int customNum; if (getSourceModifier(samplerIndex, modType, customNum) == true) { ParameterPtr modifiedParam; String funcName; switch (modType) { case SM_Source1Modulate: funcName = "SGX_src_mod_modulate"; modifiedParam = arg1; break; case SM_Source2Modulate: funcName = "SGX_src_mod_modulate"; modifiedParam = arg2; break; case SM_Source1InvModulate: funcName = "SGX_src_mod_inv_modulate"; modifiedParam = arg1; break; case SM_Source2InvModulate: funcName = "SGX_src_mod_inv_modulate"; modifiedParam = arg2; break; default: break; } //add the function of the blend mode if (funcName.empty() == false) { ParameterPtr& controlParam = mTextureBlends[samplerIndex].modControlParam; FunctionInvocation* curFuncInvocation = OGRE_NEW FunctionInvocation(funcName, groupOrder, internalCounter++); curFuncInvocation->pushOperand(modifiedParam, Operand::OPS_IN, targetChannels); curFuncInvocation->pushOperand(controlParam, Operand::OPS_IN, targetChannels); curFuncInvocation->pushOperand(modifiedParam, Operand::OPS_OUT, targetChannels); psMain->addAtomInstance(curFuncInvocation); } } }
//----------------------------------------------------------------------- void DualQuaternionSkinning::adjustForCorrectAntipodality(Function* vsMain, int index, int& funcCounter, const ParameterPtr& pTempWorldMatrix) { FunctionInvocation* curFuncInvocation; //Antipodality doesn't need to be adjusted for dq0 on itself (used as the basis of antipodality calculations) if(index > 0) { curFuncInvocation = OGRE_NEW FunctionInvocation(SGX_FUNC_ANTIPODALITY_ADJUSTMENT, FFP_VS_TRANSFORM, funcCounter++); //This is the base dual quaternion dq0, which the antipodality calculations are based on curFuncInvocation->pushOperand(mParamInitialDQ, Operand::OPS_IN); curFuncInvocation->pushOperand(mParamTempFloat2x4, Operand::OPS_IN); curFuncInvocation->pushOperand(pTempWorldMatrix, Operand::OPS_OUT); vsMain->addAtomInstance(curFuncInvocation); } else if(index == 0) { //Set the first dual quaternion as the initial dq curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, FFP_VS_TRANSFORM, funcCounter++); curFuncInvocation->pushOperand(mParamTempFloat2x4, Operand::OPS_IN); curFuncInvocation->pushOperand(mParamInitialDQ, Operand::OPS_OUT); vsMain->addAtomInstance(curFuncInvocation); } }
//----------------------------------------------------------------------- void DualQuaternionSkinning::addNormalRelatedCalculations(Function* vsMain, ParameterPtr& pNormalRelatedParam, ParameterPtr& pNormalWorldRelatedParam, int& funcCounter) { FunctionInvocation* curFuncInvocation; if (mDoBoneCalculations == true) { if(mScalingShearingSupport) { //Calculate the adjoint transpose of the blended scaling and shearing matrix curFuncInvocation = OGRE_NEW FunctionInvocation(SGX_FUNC_ADJOINT_TRANSPOSE_MATRIX, FFP_VS_TRANSFORM, funcCounter++); curFuncInvocation->pushOperand(mParamBlendS, Operand::OPS_IN); curFuncInvocation->pushOperand(mParamTempFloat3x3, Operand::OPS_OUT); vsMain->addAtomInstance(curFuncInvocation); //Transform the normal by the adjoint transpose of the blended scaling and shearing matrix curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_TRANSFORM, FFP_VS_TRANSFORM, funcCounter++); curFuncInvocation->pushOperand(mParamTempFloat3x3, Operand::OPS_IN); curFuncInvocation->pushOperand(pNormalRelatedParam, Operand::OPS_IN); curFuncInvocation->pushOperand(pNormalRelatedParam, Operand::OPS_OUT); vsMain->addAtomInstance(curFuncInvocation); //Need to normalize again after transforming the normal curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_NORMALIZE, FFP_VS_TRANSFORM, funcCounter++); curFuncInvocation->pushOperand(pNormalRelatedParam, Operand::OPS_INOUT); vsMain->addAtomInstance(curFuncInvocation); } //Transform the normal according to the dual quaternion curFuncInvocation = OGRE_NEW FunctionInvocation(SGX_FUNC_CALCULATE_BLEND_NORMAL, FFP_VS_TRANSFORM, funcCounter++); curFuncInvocation->pushOperand(pNormalRelatedParam, Operand::OPS_IN); curFuncInvocation->pushOperand(mParamBlendDQ, Operand::OPS_IN); curFuncInvocation->pushOperand(pNormalWorldRelatedParam, Operand::OPS_OUT); vsMain->addAtomInstance(curFuncInvocation); //update back the original position relative to the object curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_TRANSFORM, FFP_VS_TRANSFORM, funcCounter++); curFuncInvocation->pushOperand(mParamInInvWorldMatrix, Operand::OPS_IN); curFuncInvocation->pushOperand(pNormalWorldRelatedParam, Operand::OPS_IN); curFuncInvocation->pushOperand(pNormalRelatedParam, Operand::OPS_OUT); vsMain->addAtomInstance(curFuncInvocation); } else { //update from object to world space curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_TRANSFORM, FFP_VS_TRANSFORM, funcCounter++); curFuncInvocation->pushOperand(mParamInWorldMatrix, Operand::OPS_IN); curFuncInvocation->pushOperand(pNormalRelatedParam, Operand::OPS_IN); curFuncInvocation->pushOperand(pNormalWorldRelatedParam, Operand::OPS_OUT); vsMain->addAtomInstance(curFuncInvocation); } }
bool FFPAlphaTest::addFunctionInvocations( ProgramSet* programSet ) { Program* psProgram = programSet->getCpuFragmentProgram(); Function* psMain = psProgram->getEntryPointFunction(); FunctionInvocation *curFuncInvocation; //Fragment shader invocations curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ALPHA_TEST, FFP_PS_ALPHA_TEST, 0); curFuncInvocation->pushOperand(mPSAlphaFunc, Operand::OPS_IN); curFuncInvocation->pushOperand(mPSAlphaRef, Operand::OPS_IN); curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_IN); psMain->addAtomInstance(curFuncInvocation); return true; }
//----------------------------------------------------------------------- bool ShaderExReflectionMap::addPSInvocations( Function* psMain, const int groupOrder ) { FunctionInvocation* funcInvoaction = NULL; int internalCounter = 0; funcInvoaction = OGRE_NEW FunctionInvocation(SGX_FUNC_APPLY_REFLECTION_MAP, groupOrder, internalCounter++); funcInvoaction->pushOperand(mMaskMapSampler, Operand::OPS_IN); funcInvoaction->pushOperand(mPSInMaskTexcoord, Operand::OPS_IN); funcInvoaction->pushOperand(mReflectionMapSampler, Operand::OPS_IN); funcInvoaction->pushOperand(mPSInReflectionTexcoord, Operand::OPS_IN); funcInvoaction->pushOperand(mPSOutDiffuse, Operand::OPS_IN,(Operand::OPM_X | Operand::OPM_Y | Operand::OPM_Z)); funcInvoaction->pushOperand(mReflectionPower, Operand::OPS_IN); funcInvoaction->pushOperand(mPSOutDiffuse, Operand::OPS_OUT,(Operand::OPM_X | Operand::OPM_Y | Operand::OPM_Z)); psMain->addAtomInstace(funcInvoaction); return true; }
//----------------------------------------------------------------------- bool FFPTransform::createCpuSubPrograms(ProgramSet* programSet) { Program* vsProgram = programSet->getCpuVertexProgram(); // Resolve World View Projection Matrix. UniformParameterPtr wvpMatrix = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX, 0); if (wvpMatrix.get() == NULL) return false; Function* vsEntry = vsProgram->getEntryPointFunction(); assert(vsEntry != NULL); // Resolve input position parameter. ParameterPtr positionIn = vsEntry->resolveInputParameter(Parameter::SPS_POSITION, 0, Parameter::SPC_POSITION_OBJECT_SPACE, GCT_FLOAT4); if (positionIn.get() == NULL) return false; // Resolve output position parameter. ParameterPtr positionOut = vsEntry->resolveOutputParameter(Parameter::SPS_POSITION, 0, Parameter::SPC_POSITION_PROJECTIVE_SPACE, GCT_FLOAT4); if (positionOut.get() == NULL) return false; // Add dependency. vsProgram->addDependency(FFP_LIB_TRANSFORM); FunctionInvocation* transformFunc = OGRE_NEW FunctionInvocation(FFP_FUNC_TRANSFORM, FFP_VS_TRANSFORM, 0); transformFunc->pushOperand(wvpMatrix, Operand::OPS_IN); transformFunc->pushOperand(positionIn, Operand::OPS_IN); transformFunc->pushOperand(positionOut, Operand::OPS_OUT); vsEntry->addAtomInstace(transformFunc); return true; }
//----------------------------------------------------------------------- bool FFPFog::addFunctionInvocations(ProgramSet* programSet) { if (mFogMode == FOG_NONE) return true; Program* vsProgram = programSet->getCpuVertexProgram(); Program* psProgram = programSet->getCpuFragmentProgram(); Function* vsMain = vsProgram->getEntryPointFunction(); Function* psMain = psProgram->getEntryPointFunction(); FunctionInvocation* curFuncInvocation = NULL; int internalCounter; // Per pixel fog. if (mCalcMode == CM_PER_PIXEL) { internalCounter = 0; curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_PIXELFOG_DEPTH, FFP_VS_FOG, internalCounter++); curFuncInvocation->pushOperand(mWorldViewProjMatrix, Operand::OPS_IN); curFuncInvocation->pushOperand(mVSInPos, Operand::OPS_IN); curFuncInvocation->pushOperand(mVSOutDepth, Operand::OPS_OUT); vsMain->addAtomInstace(curFuncInvocation); internalCounter = 0; switch (mFogMode) { case FOG_LINEAR: curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_PIXELFOG_LINEAR, FFP_PS_FOG, internalCounter++); break; case FOG_EXP: curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_PIXELFOG_EXP, FFP_PS_FOG, internalCounter++); break; case FOG_EXP2: curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_PIXELFOG_EXP2, FFP_PS_FOG, internalCounter++); break; case FOG_NONE: default: break; } curFuncInvocation->pushOperand(mPSInDepth, Operand::OPS_IN); curFuncInvocation->pushOperand(mFogParams, Operand::OPS_IN); curFuncInvocation->pushOperand(mFogColour, Operand::OPS_IN); curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_IN); curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_OUT); psMain->addAtomInstace(curFuncInvocation); } // Per vertex fog. else { internalCounter = 0; switch (mFogMode) { case FOG_LINEAR: curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_VERTEXFOG_LINEAR, FFP_VS_FOG, internalCounter++); break; case FOG_EXP: curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_VERTEXFOG_EXP, FFP_VS_FOG, internalCounter++); break; case FOG_EXP2: curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_VERTEXFOG_EXP2, FFP_VS_FOG, internalCounter++); break; case FOG_NONE: default: break; } curFuncInvocation->pushOperand(mWorldViewProjMatrix, Operand::OPS_IN); curFuncInvocation->pushOperand(mVSInPos, Operand::OPS_IN); curFuncInvocation->pushOperand(mFogParams, Operand::OPS_IN); curFuncInvocation->pushOperand(mVSOutFogFactor, Operand::OPS_OUT); vsMain->addAtomInstace(curFuncInvocation); internalCounter = 0; curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_LERP, FFP_PS_FOG, internalCounter++); curFuncInvocation->pushOperand(mFogColour, Operand::OPS_IN); curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_IN); curFuncInvocation->pushOperand(mPSInFogFactor, Operand::OPS_IN); curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_OUT); psMain->addAtomInstace(curFuncInvocation); } return true; }
//----------------------------------------------------------------------- bool FFPLighting::addIlluminationInvocation(LightParams* curLightParams, Function* vsMain, const int groupOrder, int& internalCounter) { FunctionInvocation* curFuncInvocation = NULL; // Merge diffuse colour with vertex colour if need to. if (mTrackVertexColourType & TVC_DIFFUSE) { curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_MODULATE, groupOrder, internalCounter++); curFuncInvocation->pushOperand(mVSDiffuse, Operand::OPS_IN, (Operand::OPM_X | Operand::OPM_Y | Operand::OPM_Z)); curFuncInvocation->pushOperand(curLightParams->mDiffuseColour, Operand::OPS_IN, (Operand::OPM_X | Operand::OPM_Y | Operand::OPM_Z)); curFuncInvocation->pushOperand(curLightParams->mDiffuseColour, Operand::OPS_OUT, (Operand::OPM_X | Operand::OPM_Y | Operand::OPM_Z)); vsMain->addAtomInstance(curFuncInvocation); } // Merge specular colour with vertex colour if need to. if (mSpecularEnable && mTrackVertexColourType & TVC_SPECULAR) { curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_MODULATE, groupOrder, internalCounter++); curFuncInvocation->pushOperand(mVSDiffuse, Operand::OPS_IN, (Operand::OPM_X | Operand::OPM_Y | Operand::OPM_Z)); curFuncInvocation->pushOperand(curLightParams->mSpecularColour, Operand::OPS_IN, (Operand::OPM_X | Operand::OPM_Y | Operand::OPM_Z)); curFuncInvocation->pushOperand(curLightParams->mSpecularColour, Operand::OPS_OUT, (Operand::OPM_X | Operand::OPM_Y | Operand::OPM_Z)); vsMain->addAtomInstance(curFuncInvocation); } switch (curLightParams->mType) { case Light::LT_DIRECTIONAL: if (mSpecularEnable) { curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_LIGHT_DIRECTIONAL_DIFFUSESPECULAR, groupOrder, internalCounter++); curFuncInvocation->pushOperand(mWorldViewMatrix, Operand::OPS_IN); curFuncInvocation->pushOperand(mVSInPosition, Operand::OPS_IN); curFuncInvocation->pushOperand(mWorldViewITMatrix, Operand::OPS_IN); curFuncInvocation->pushOperand(mVSInNormal, Operand::OPS_IN); curFuncInvocation->pushOperand(curLightParams->mDirection, Operand::OPS_IN, (Operand::OPM_X | Operand::OPM_Y | Operand::OPM_Z)); curFuncInvocation->pushOperand(curLightParams->mDiffuseColour, Operand::OPS_IN, (Operand::OPM_X | Operand::OPM_Y | Operand::OPM_Z)); curFuncInvocation->pushOperand(curLightParams->mSpecularColour, Operand::OPS_IN, (Operand::OPM_X | Operand::OPM_Y | Operand::OPM_Z)); curFuncInvocation->pushOperand(mSurfaceShininess, Operand::OPS_IN); curFuncInvocation->pushOperand(mVSOutDiffuse, Operand::OPS_IN, (Operand::OPM_X | Operand::OPM_Y | Operand::OPM_Z)); curFuncInvocation->pushOperand(mVSOutSpecular, Operand::OPS_IN, (Operand::OPM_X | Operand::OPM_Y | Operand::OPM_Z)); curFuncInvocation->pushOperand(mVSOutDiffuse, Operand::OPS_OUT, (Operand::OPM_X | Operand::OPM_Y | Operand::OPM_Z)); curFuncInvocation->pushOperand(mVSOutSpecular, Operand::OPS_OUT, (Operand::OPM_X | Operand::OPM_Y | Operand::OPM_Z)); vsMain->addAtomInstance(curFuncInvocation); } else { curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_LIGHT_DIRECTIONAL_DIFFUSE, groupOrder, internalCounter++); curFuncInvocation->pushOperand(mWorldViewITMatrix, Operand::OPS_IN); curFuncInvocation->pushOperand(mVSInNormal, Operand::OPS_IN); curFuncInvocation->pushOperand(curLightParams->mDirection, Operand::OPS_IN, (Operand::OPM_X | Operand::OPM_Y | Operand::OPM_Z)); curFuncInvocation->pushOperand(curLightParams->mDiffuseColour, Operand::OPS_IN, (Operand::OPM_X | Operand::OPM_Y | Operand::OPM_Z)); curFuncInvocation->pushOperand(mVSOutDiffuse, Operand::OPS_IN, (Operand::OPM_X | Operand::OPM_Y | Operand::OPM_Z)); curFuncInvocation->pushOperand(mVSOutDiffuse, Operand::OPS_OUT, (Operand::OPM_X | Operand::OPM_Y | Operand::OPM_Z)); vsMain->addAtomInstance(curFuncInvocation); } break; case Light::LT_POINT: if (mSpecularEnable) { curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_LIGHT_POINT_DIFFUSESPECULAR, groupOrder, internalCounter++); curFuncInvocation->pushOperand(mWorldViewMatrix, Operand::OPS_IN); curFuncInvocation->pushOperand(mVSInPosition, Operand::OPS_IN); curFuncInvocation->pushOperand(mWorldViewITMatrix, Operand::OPS_IN); curFuncInvocation->pushOperand(mVSInNormal, Operand::OPS_IN); curFuncInvocation->pushOperand(curLightParams->mPosition, Operand::OPS_IN, (Operand::OPM_X | Operand::OPM_Y | Operand::OPM_Z)); curFuncInvocation->pushOperand(curLightParams->mAttenuatParams, Operand::OPS_IN); curFuncInvocation->pushOperand(curLightParams->mDiffuseColour, Operand::OPS_IN, (Operand::OPM_X | Operand::OPM_Y | Operand::OPM_Z)); curFuncInvocation->pushOperand(curLightParams->mSpecularColour, Operand::OPS_IN, (Operand::OPM_X | Operand::OPM_Y | Operand::OPM_Z)); curFuncInvocation->pushOperand(mSurfaceShininess, Operand::OPS_IN); curFuncInvocation->pushOperand(mVSOutDiffuse, Operand::OPS_IN, (Operand::OPM_X | Operand::OPM_Y | Operand::OPM_Z)); curFuncInvocation->pushOperand(mVSOutSpecular, Operand::OPS_IN, (Operand::OPM_X | Operand::OPM_Y | Operand::OPM_Z)); curFuncInvocation->pushOperand(mVSOutDiffuse, Operand::OPS_OUT, (Operand::OPM_X | Operand::OPM_Y | Operand::OPM_Z)); curFuncInvocation->pushOperand(mVSOutSpecular, Operand::OPS_OUT, (Operand::OPM_X | Operand::OPM_Y | Operand::OPM_Z)); vsMain->addAtomInstance(curFuncInvocation); } else { curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_LIGHT_POINT_DIFFUSE, groupOrder, internalCounter++); curFuncInvocation->pushOperand(mWorldViewMatrix, Operand::OPS_IN); curFuncInvocation->pushOperand(mVSInPosition, Operand::OPS_IN); curFuncInvocation->pushOperand(mWorldViewITMatrix, Operand::OPS_IN); curFuncInvocation->pushOperand(mVSInNormal, Operand::OPS_IN); curFuncInvocation->pushOperand(curLightParams->mPosition, Operand::OPS_IN, (Operand::OPM_X | Operand::OPM_Y | Operand::OPM_Z)); curFuncInvocation->pushOperand(curLightParams->mAttenuatParams, Operand::OPS_IN); curFuncInvocation->pushOperand(curLightParams->mDiffuseColour, Operand::OPS_IN, (Operand::OPM_X | Operand::OPM_Y | Operand::OPM_Z)); curFuncInvocation->pushOperand(mVSOutDiffuse, Operand::OPS_IN, (Operand::OPM_X | Operand::OPM_Y | Operand::OPM_Z)); curFuncInvocation->pushOperand(mVSOutDiffuse, Operand::OPS_OUT, (Operand::OPM_X | Operand::OPM_Y | Operand::OPM_Z)); vsMain->addAtomInstance(curFuncInvocation); } break; case Light::LT_SPOTLIGHT: if (mSpecularEnable) { curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_LIGHT_SPOT_DIFFUSESPECULAR, groupOrder, internalCounter++); curFuncInvocation->pushOperand(mWorldViewMatrix, Operand::OPS_IN); curFuncInvocation->pushOperand(mVSInPosition, Operand::OPS_IN); curFuncInvocation->pushOperand(mWorldViewITMatrix, Operand::OPS_IN); curFuncInvocation->pushOperand(mVSInNormal, Operand::OPS_IN); curFuncInvocation->pushOperand(curLightParams->mPosition, Operand::OPS_IN, (Operand::OPM_X | Operand::OPM_Y | Operand::OPM_Z)); curFuncInvocation->pushOperand(curLightParams->mDirection, Operand::OPS_IN, (Operand::OPM_X | Operand::OPM_Y | Operand::OPM_Z)); curFuncInvocation->pushOperand(curLightParams->mAttenuatParams, Operand::OPS_IN); curFuncInvocation->pushOperand(curLightParams->mSpotParams, Operand::OPS_IN); curFuncInvocation->pushOperand(curLightParams->mDiffuseColour, Operand::OPS_IN, (Operand::OPM_X | Operand::OPM_Y | Operand::OPM_Z)); curFuncInvocation->pushOperand(curLightParams->mSpecularColour, Operand::OPS_IN, (Operand::OPM_X | Operand::OPM_Y | Operand::OPM_Z)); curFuncInvocation->pushOperand(mSurfaceShininess, Operand::OPS_IN); curFuncInvocation->pushOperand(mVSOutDiffuse, Operand::OPS_IN, (Operand::OPM_X | Operand::OPM_Y | Operand::OPM_Z)); curFuncInvocation->pushOperand(mVSOutSpecular, Operand::OPS_IN, (Operand::OPM_X | Operand::OPM_Y | Operand::OPM_Z)); curFuncInvocation->pushOperand(mVSOutDiffuse, Operand::OPS_OUT, (Operand::OPM_X | Operand::OPM_Y | Operand::OPM_Z)); curFuncInvocation->pushOperand(mVSOutSpecular, Operand::OPS_OUT, (Operand::OPM_X | Operand::OPM_Y | Operand::OPM_Z)); vsMain->addAtomInstance(curFuncInvocation); } else { curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_LIGHT_SPOT_DIFFUSE, groupOrder, internalCounter++); curFuncInvocation->pushOperand(mWorldViewMatrix, Operand::OPS_IN); curFuncInvocation->pushOperand(mVSInPosition, Operand::OPS_IN); curFuncInvocation->pushOperand(mWorldViewITMatrix, Operand::OPS_IN); curFuncInvocation->pushOperand(mVSInNormal, Operand::OPS_IN); curFuncInvocation->pushOperand(curLightParams->mPosition, Operand::OPS_IN, (Operand::OPM_X | Operand::OPM_Y | Operand::OPM_Z)); curFuncInvocation->pushOperand(curLightParams->mDirection, Operand::OPS_IN, (Operand::OPM_X | Operand::OPM_Y | Operand::OPM_Z)); curFuncInvocation->pushOperand(curLightParams->mAttenuatParams, Operand::OPS_IN); curFuncInvocation->pushOperand(curLightParams->mSpotParams, Operand::OPS_IN); curFuncInvocation->pushOperand(curLightParams->mDiffuseColour, Operand::OPS_IN, (Operand::OPM_X | Operand::OPM_Y | Operand::OPM_Z)); curFuncInvocation->pushOperand(mVSOutDiffuse, Operand::OPS_IN, (Operand::OPM_X | Operand::OPM_Y | Operand::OPM_Z)); curFuncInvocation->pushOperand(mVSOutDiffuse, Operand::OPS_OUT, (Operand::OPM_X | Operand::OPM_Y | Operand::OPM_Z)); vsMain->addAtomInstance(curFuncInvocation); } break; } return true; }
//----------------------------------------------------------------------- bool FFPColour::addFunctionInvocations(ProgramSet* programSet) { Program* vsProgram = programSet->getCpuVertexProgram(); Program* psProgram = programSet->getCpuFragmentProgram(); Function* vsMain = vsProgram->getEntryPointFunction(); Function* psMain = psProgram->getEntryPointFunction(); FunctionInvocation* curFuncInvocation = NULL; int internalCounter; // Create vertex shader colour invocations. ParameterPtr vsDiffuse; ParameterPtr vsSpecular; internalCounter = 0; if (mVSInputDiffuse.get() != NULL) { vsDiffuse = mVSInputDiffuse; } else { vsDiffuse = vsMain->resolveLocalParameter(Parameter::SPS_COLOR, 0, Parameter::SPC_COLOR_DIFFUSE, GCT_FLOAT4); curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_CONSTRUCT, FFP_VS_COLOUR, internalCounter++); curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(1.0), Operand::OPS_IN); curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(1.0), Operand::OPS_IN); curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(1.0), Operand::OPS_IN); curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(1.0), Operand::OPS_IN); curFuncInvocation->pushOperand(vsDiffuse, Operand::OPS_OUT); vsMain->addAtomInstace(curFuncInvocation); } if (mVSOutputDiffuse.get() != NULL) { curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, FFP_VS_COLOUR, internalCounter++); curFuncInvocation->pushOperand(vsDiffuse, Operand::OPS_IN); curFuncInvocation->pushOperand(mVSOutputDiffuse, Operand::OPS_OUT); vsMain->addAtomInstace(curFuncInvocation); } if (mVSInputSpecular.get() != NULL) { vsSpecular = mVSInputSpecular; } else { vsSpecular = vsMain->resolveLocalParameter(Parameter::SPS_COLOR, 1, Parameter::SPC_COLOR_SPECULAR, GCT_FLOAT4); curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_CONSTRUCT, FFP_VS_COLOUR, internalCounter++); curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(0.0), Operand::OPS_IN); curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(0.0), Operand::OPS_IN); curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(0.0), Operand::OPS_IN); curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(0.0), Operand::OPS_IN); curFuncInvocation->pushOperand(vsSpecular, Operand::OPS_OUT); vsMain->addAtomInstace(curFuncInvocation); } if (mVSOutputSpecular.get() != NULL) { curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, FFP_VS_COLOUR, internalCounter++); curFuncInvocation->pushOperand(vsSpecular, Operand::OPS_IN); curFuncInvocation->pushOperand(mVSOutputSpecular, Operand::OPS_OUT); vsMain->addAtomInstace(curFuncInvocation); } // Create fragment shader colour invocations. ParameterPtr psDiffuse; ParameterPtr psSpecular; internalCounter = 0; // Handle diffuse colour. if (mPSInputDiffuse.get() != NULL) { psDiffuse = mPSInputDiffuse; } else { psDiffuse = psMain->resolveLocalParameter(Parameter::SPS_COLOR, 0, Parameter::SPC_COLOR_DIFFUSE, GCT_FLOAT4); curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_CONSTRUCT, FFP_PS_COLOUR_BEGIN, internalCounter++); curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(1.0), Operand::OPS_IN); curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(1.0), Operand::OPS_IN); curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(1.0), Operand::OPS_IN); curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(1.0), Operand::OPS_IN); curFuncInvocation->pushOperand(psDiffuse, Operand::OPS_OUT); psMain->addAtomInstace(curFuncInvocation); } // Handle specular colour. if (mPSInputSpecular.get() != NULL) { psSpecular = mPSInputSpecular; } else { psSpecular = psMain->resolveLocalParameter(Parameter::SPS_COLOR, 1, Parameter::SPC_COLOR_SPECULAR, GCT_FLOAT4); curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_CONSTRUCT, FFP_PS_COLOUR_BEGIN, internalCounter++); curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(0.0), Operand::OPS_IN); curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(0.0), Operand::OPS_IN); curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(0.0), Operand::OPS_IN); curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(0.0), Operand::OPS_IN); curFuncInvocation->pushOperand(psSpecular, Operand::OPS_OUT); psMain->addAtomInstace(curFuncInvocation); } // Assign diffuse colour. if (mPSOutputDiffuse.get() != NULL) { curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, FFP_PS_COLOUR_BEGIN, internalCounter++); curFuncInvocation->pushOperand(psDiffuse, Operand::OPS_IN); curFuncInvocation->pushOperand(mPSOutputDiffuse, Operand::OPS_OUT); psMain->addAtomInstace(curFuncInvocation); } // Assign specular colour. if (mPSOutputSpecular.get() != NULL) { curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, FFP_PS_COLOUR_BEGIN, internalCounter++); curFuncInvocation->pushOperand(psSpecular, Operand::OPS_IN); curFuncInvocation->pushOperand(mPSOutputSpecular, Operand::OPS_OUT); psMain->addAtomInstace(curFuncInvocation); } // Add specular to out colour. internalCounter = 0; if (mPSOutputDiffuse.get() != NULL && psSpecular.get() != NULL) { curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ADD, FFP_PS_COLOUR_END, internalCounter++); curFuncInvocation->pushOperand(mPSOutputDiffuse, Operand::OPS_IN,(Operand::OPM_X | Operand::OPM_Y | Operand::OPM_Z)); curFuncInvocation->pushOperand(psSpecular, Operand::OPS_IN,(Operand::OPM_X | Operand::OPM_Y | Operand::OPM_Z)); curFuncInvocation->pushOperand(mPSOutputDiffuse, Operand::OPS_OUT,(Operand::OPM_X | Operand::OPM_Y | Operand::OPM_Z)); psMain->addAtomInstace(curFuncInvocation); } return true; }
//----------------------------------------------------------------------- void FFPTexturing::addPSBlendInvocations(Function* psMain, ParameterPtr arg1, ParameterPtr arg2, ParameterPtr texel, int samplerIndex, const LayerBlendModeEx& blendMode, const int groupOrder, int& internalCounter, int targetChannels) { FunctionInvocation* curFuncInvocation = NULL; switch(blendMode.operation) { case LBX_SOURCE1: curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, groupOrder, internalCounter++); curFuncInvocation->pushOperand(arg1, Operand::OPS_IN, targetChannels); curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_OUT, targetChannels); psMain->addAtomInstace(curFuncInvocation); break; case LBX_SOURCE2: curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, groupOrder, internalCounter++); curFuncInvocation->pushOperand(arg2, Operand::OPS_IN, targetChannels); curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_OUT, targetChannels); psMain->addAtomInstace(curFuncInvocation); break; case LBX_MODULATE: curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_MODULATE, groupOrder, internalCounter++); curFuncInvocation->pushOperand(arg1, Operand::OPS_IN, targetChannels); curFuncInvocation->pushOperand(arg2, Operand::OPS_IN, targetChannels); curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_OUT, targetChannels); psMain->addAtomInstace(curFuncInvocation); break; case LBX_MODULATE_X2: curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_MODULATEX2, groupOrder, internalCounter++); curFuncInvocation->pushOperand(arg1, Operand::OPS_IN, targetChannels); curFuncInvocation->pushOperand(arg2, Operand::OPS_IN, targetChannels); curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_OUT, targetChannels); psMain->addAtomInstace(curFuncInvocation); break; case LBX_MODULATE_X4: curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_MODULATEX4, groupOrder, internalCounter++); curFuncInvocation->pushOperand(arg1, Operand::OPS_IN, targetChannels); curFuncInvocation->pushOperand(arg2, Operand::OPS_IN, targetChannels); curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_OUT, targetChannels); psMain->addAtomInstace(curFuncInvocation); break; case LBX_ADD: curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ADD, groupOrder, internalCounter++); curFuncInvocation->pushOperand(arg1, Operand::OPS_IN, targetChannels); curFuncInvocation->pushOperand(arg2, Operand::OPS_IN, targetChannels); curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_OUT, targetChannels); psMain->addAtomInstace(curFuncInvocation); break; case LBX_ADD_SIGNED: curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ADDSIGNED, groupOrder, internalCounter++); curFuncInvocation->pushOperand(arg1, Operand::OPS_IN, targetChannels); curFuncInvocation->pushOperand(arg2, Operand::OPS_IN, targetChannels); curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_OUT, targetChannels); psMain->addAtomInstace(curFuncInvocation); break; case LBX_ADD_SMOOTH: curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ADDSMOOTH, groupOrder, internalCounter++); curFuncInvocation->pushOperand(arg1, Operand::OPS_IN, targetChannels); curFuncInvocation->pushOperand(arg2, Operand::OPS_IN, targetChannels); curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_OUT, targetChannels); psMain->addAtomInstace(curFuncInvocation); break; case LBX_SUBTRACT: curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_SUBTRACT, groupOrder, internalCounter++); curFuncInvocation->pushOperand(arg1, Operand::OPS_IN, targetChannels); curFuncInvocation->pushOperand(arg2, Operand::OPS_IN, targetChannels); curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_OUT, targetChannels); psMain->addAtomInstace(curFuncInvocation); break; case LBX_BLEND_DIFFUSE_ALPHA: curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_SUBTRACT, groupOrder, internalCounter++); curFuncInvocation->pushOperand(arg2, Operand::OPS_IN, targetChannels); curFuncInvocation->pushOperand(arg1, Operand::OPS_IN, targetChannels); curFuncInvocation->pushOperand(mPSDiffuse, Operand::OPS_IN, Operand::OPM_W); curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_OUT, targetChannels); psMain->addAtomInstace(curFuncInvocation); break; case LBX_BLEND_TEXTURE_ALPHA: curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_LERP, groupOrder, internalCounter++); curFuncInvocation->pushOperand(arg2, Operand::OPS_IN, targetChannels); curFuncInvocation->pushOperand(arg1, Operand::OPS_IN, targetChannels); curFuncInvocation->pushOperand(texel, Operand::OPS_IN, Operand::OPM_W); curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_OUT, targetChannels); psMain->addAtomInstace(curFuncInvocation); break; case LBX_BLEND_CURRENT_ALPHA: curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_LERP, groupOrder, internalCounter++); curFuncInvocation->pushOperand(arg2, Operand::OPS_IN, targetChannels); curFuncInvocation->pushOperand(arg1, Operand::OPS_OUT, targetChannels); if (samplerIndex == 0) curFuncInvocation->pushOperand(mPSDiffuse, Operand::OPS_IN, Operand::OPM_W); else curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_IN, Operand::OPM_W); curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_OUT, targetChannels); psMain->addAtomInstace(curFuncInvocation); break; case LBX_BLEND_MANUAL: curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_LERP, groupOrder, internalCounter++); curFuncInvocation->pushOperand(arg2, Operand::OPS_IN, targetChannels); curFuncInvocation->pushOperand(arg1, Operand::OPS_IN, targetChannels); curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(blendMode.factor), Operand::OPS_IN); curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_OUT, targetChannels); psMain->addAtomInstace(curFuncInvocation); break; case LBX_DOTPRODUCT: curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_DOTPRODUCT, groupOrder, internalCounter++); curFuncInvocation->pushOperand(arg2, Operand::OPS_IN, targetChannels); curFuncInvocation->pushOperand(arg1, Operand::OPS_IN, targetChannels); curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_OUT, targetChannels); psMain->addAtomInstace(curFuncInvocation); break; case LBX_BLEND_DIFFUSE_COLOUR: curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_LERP, groupOrder, internalCounter++); curFuncInvocation->pushOperand(arg2, Operand::OPS_IN, targetChannels); curFuncInvocation->pushOperand(arg1, Operand::OPS_IN, targetChannels); curFuncInvocation->pushOperand(mPSDiffuse, Operand::OPS_IN); curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_OUT, targetChannels); psMain->addAtomInstace(curFuncInvocation); break; } }
//----------------------------------------------------------------------- void FFPTexturing::addPSArgumentInvocations(Function* psMain, ParameterPtr arg, ParameterPtr texel, int samplerIndex, LayerBlendSource blendSrc, const ColourValue& colourValue, Real alphaValue, bool isAlphaArgument, const int groupOrder, int& internalCounter) { FunctionInvocation* curFuncInvocation = NULL; switch(blendSrc) { case LBS_CURRENT: curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, groupOrder, internalCounter++); if (samplerIndex == 0) curFuncInvocation->pushOperand(mPSDiffuse, Operand::OPS_IN); else curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_IN); curFuncInvocation->pushOperand(arg, Operand::OPS_OUT); psMain->addAtomInstace(curFuncInvocation); break; case LBS_TEXTURE: curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, groupOrder, internalCounter++); curFuncInvocation->pushOperand(texel, Operand::OPS_IN); curFuncInvocation->pushOperand(arg, Operand::OPS_OUT); psMain->addAtomInstace(curFuncInvocation); break; case LBS_DIFFUSE: curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, groupOrder, internalCounter++); curFuncInvocation->pushOperand(mPSDiffuse, Operand::OPS_IN); curFuncInvocation->pushOperand(arg, Operand::OPS_OUT); psMain->addAtomInstace(curFuncInvocation); break; case LBS_SPECULAR: curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, groupOrder, internalCounter++); curFuncInvocation->pushOperand(mPSSpecular, Operand::OPS_IN); curFuncInvocation->pushOperand(arg, Operand::OPS_OUT); psMain->addAtomInstace(curFuncInvocation); break; case LBS_MANUAL: curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_CONSTRUCT, groupOrder, internalCounter++); if (isAlphaArgument) { curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(alphaValue), Operand::OPS_IN); } else { curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(colourValue.r), Operand::OPS_IN); curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(colourValue.g), Operand::OPS_IN); curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(colourValue.b), Operand::OPS_IN); curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(colourValue.a), Operand::OPS_IN); } curFuncInvocation->pushOperand(arg, Operand::OPS_IN); psMain->addAtomInstace(curFuncInvocation); break; } }
//----------------------------------------------------------------------- bool FFPTexturing::addPSFunctionInvocations(TextureUnitParams* textureUnitParams, Function* psMain, int& internalCounter) { const LayerBlendModeEx& colourBlend = textureUnitParams->mTextureUnitState->getColourBlendMode(); const LayerBlendModeEx& alphaBlend = textureUnitParams->mTextureUnitState->getAlphaBlendMode(); ParameterPtr source1; ParameterPtr source2; int groupOrder = FFP_PS_TEXTURING; // Add texture sampling code. ParameterPtr texel = psMain->resolveLocalParameter(Parameter::SPS_UNKNOWN, 0, "texel", GCT_FLOAT4); FunctionInvocation* curFuncInvocation = NULL; if (textureUnitParams->mTexCoordCalcMethod == TEXCALC_PROJECTIVE_TEXTURE) curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_SAMPLE_TEXTURE_PROJ, groupOrder, internalCounter++); else curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_SAMPLE_TEXTURE, groupOrder, internalCounter++); curFuncInvocation->pushOperand(textureUnitParams->mTextureSampler, Operand::OPS_IN); curFuncInvocation->pushOperand(textureUnitParams->mPSInputTexCoord, Operand::OPS_IN); curFuncInvocation->pushOperand(texel, Operand::OPS_OUT); psMain->addAtomInstace(curFuncInvocation); // Build colour argument for source1. source1 = psMain->resolveLocalParameter(Parameter::SPS_UNKNOWN, 0, "source1", GCT_FLOAT4); addPSArgumentInvocations(psMain, source1, texel, textureUnitParams->mTextureSamplerIndex, colourBlend.source1, colourBlend.colourArg1, colourBlend.alphaArg1, false, groupOrder, internalCounter); // Build colour argument for source2. source2 = psMain->resolveLocalParameter(Parameter::SPS_UNKNOWN, 0, "source2", GCT_FLOAT4); addPSArgumentInvocations(psMain, source2, texel, textureUnitParams->mTextureSamplerIndex, colourBlend.source2, colourBlend.colourArg2, colourBlend.alphaArg2, false, groupOrder, internalCounter); bool needDifferentAlphaBlend = false; if (alphaBlend.operation != colourBlend.operation || alphaBlend.source1 != colourBlend.source1 || alphaBlend.source2 != colourBlend.source2 || colourBlend.source1 == LBS_MANUAL || colourBlend.source2 == LBS_MANUAL || alphaBlend.source1 == LBS_MANUAL || alphaBlend.source2 == LBS_MANUAL) needDifferentAlphaBlend = true; // Build colours blend addPSBlendInvocations(psMain, source1, source2, texel, textureUnitParams->mTextureSamplerIndex, colourBlend, groupOrder, internalCounter, needDifferentAlphaBlend ? (Operand::OPM_X | Operand::OPM_Y | Operand::OPM_Z ) : Operand::OPM_ALL); // Case we need different alpha channel code. if (needDifferentAlphaBlend) { // Build alpha argument for source1. addPSArgumentInvocations(psMain, source1, texel, textureUnitParams->mTextureSamplerIndex, alphaBlend.source1, alphaBlend.colourArg1, alphaBlend.alphaArg1, true, groupOrder, internalCounter); // Build alpha argument for source2. addPSArgumentInvocations(psMain, source2, texel, textureUnitParams->mTextureSamplerIndex, alphaBlend.source2, alphaBlend.colourArg2, alphaBlend.alphaArg2, true, groupOrder, internalCounter); // Build alpha blend addPSBlendInvocations(psMain, source1, source2, texel, textureUnitParams->mTextureSamplerIndex, alphaBlend, groupOrder, internalCounter, Operand::OPM_W); } return true; }
//----------------------------------------------------------------------- bool FFPTexturing::addVSFunctionInvocations(TextureUnitParams* textureUnitParams, Function* vsMain) { FunctionInvocation* texCoordCalcFunc = NULL; switch (textureUnitParams->mTexCoordCalcMethod) { case TEXCALC_NONE: if (textureUnitParams->mTextureMatrix.get() == NULL) { texCoordCalcFunc = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, FFP_VS_TEXTURING, textureUnitParams->mTextureSamplerIndex); texCoordCalcFunc->pushOperand(textureUnitParams->mVSInputTexCoord, Operand::OPS_IN); texCoordCalcFunc->pushOperand(textureUnitParams->mVSOutputTexCoord, Operand::OPS_OUT); } else { texCoordCalcFunc = OGRE_NEW FunctionInvocation(FFP_FUNC_TRANSFORM_TEXCOORD, FFP_VS_TEXTURING, textureUnitParams->mTextureSamplerIndex); texCoordCalcFunc->pushOperand(textureUnitParams->mTextureMatrix, Operand::OPS_IN); texCoordCalcFunc->pushOperand(textureUnitParams->mVSInputTexCoord, Operand::OPS_IN); texCoordCalcFunc->pushOperand(textureUnitParams->mVSOutputTexCoord, Operand::OPS_OUT); } break; case TEXCALC_ENVIRONMENT_MAP: case TEXCALC_ENVIRONMENT_MAP_PLANAR: if (textureUnitParams->mTextureMatrix.get() == NULL) { texCoordCalcFunc = OGRE_NEW FunctionInvocation(FFP_FUNC_GENERATE_TEXCOORD_ENV_SPHERE, FFP_VS_TEXTURING, textureUnitParams->mTextureSamplerIndex); texCoordCalcFunc->pushOperand(mWorldITMatrix, Operand::OPS_IN); texCoordCalcFunc->pushOperand(mViewMatrix, Operand::OPS_IN); texCoordCalcFunc->pushOperand(mVSInputNormal, Operand::OPS_IN); texCoordCalcFunc->pushOperand(textureUnitParams->mVSOutputTexCoord, Operand::OPS_OUT); } else { texCoordCalcFunc = OGRE_NEW FunctionInvocation(FFP_FUNC_GENERATE_TEXCOORD_ENV_SPHERE, FFP_VS_TEXTURING, textureUnitParams->mTextureSamplerIndex); texCoordCalcFunc->pushOperand(mWorldITMatrix, Operand::OPS_IN); texCoordCalcFunc->pushOperand(mViewMatrix, Operand::OPS_IN); texCoordCalcFunc->pushOperand(textureUnitParams->mTextureMatrix, Operand::OPS_IN); texCoordCalcFunc->pushOperand(mVSInputNormal, Operand::OPS_IN); texCoordCalcFunc->pushOperand(textureUnitParams->mVSOutputTexCoord, Operand::OPS_OUT); } break; case TEXCALC_ENVIRONMENT_MAP_REFLECTION: if (textureUnitParams->mTextureMatrix.get() == NULL) { texCoordCalcFunc = OGRE_NEW FunctionInvocation(FFP_FUNC_GENERATE_TEXCOORD_ENV_REFLECT, FFP_VS_TEXTURING, textureUnitParams->mTextureSamplerIndex); texCoordCalcFunc->pushOperand(mWorldMatrix, Operand::OPS_IN); texCoordCalcFunc->pushOperand(mWorldITMatrix, Operand::OPS_IN); texCoordCalcFunc->pushOperand(mViewMatrix, Operand::OPS_IN); texCoordCalcFunc->pushOperand(mVSInputNormal, Operand::OPS_IN); texCoordCalcFunc->pushOperand(mVSInputPos, Operand::OPS_IN); texCoordCalcFunc->pushOperand(textureUnitParams->mVSOutputTexCoord, Operand::OPS_OUT); } else { texCoordCalcFunc = OGRE_NEW FunctionInvocation(FFP_FUNC_GENERATE_TEXCOORD_ENV_REFLECT, FFP_VS_TEXTURING, textureUnitParams->mTextureSamplerIndex); texCoordCalcFunc->pushOperand(mWorldMatrix, Operand::OPS_IN); texCoordCalcFunc->pushOperand(mWorldITMatrix, Operand::OPS_IN); texCoordCalcFunc->pushOperand(mViewMatrix, Operand::OPS_IN); texCoordCalcFunc->pushOperand(textureUnitParams->mTextureMatrix, Operand::OPS_IN); texCoordCalcFunc->pushOperand(mVSInputNormal, Operand::OPS_IN); texCoordCalcFunc->pushOperand(mVSInputPos, Operand::OPS_IN); texCoordCalcFunc->pushOperand(textureUnitParams->mVSOutputTexCoord, Operand::OPS_OUT); } break; case TEXCALC_ENVIRONMENT_MAP_NORMAL: if (textureUnitParams->mTextureMatrix.get() == NULL) { texCoordCalcFunc = OGRE_NEW FunctionInvocation(FFP_FUNC_GENERATE_TEXCOORD_ENV_NORMAL, FFP_VS_TEXTURING, textureUnitParams->mTextureSamplerIndex); texCoordCalcFunc->pushOperand(mWorldITMatrix, Operand::OPS_IN); texCoordCalcFunc->pushOperand(mViewMatrix, Operand::OPS_IN); texCoordCalcFunc->pushOperand(mVSInputNormal, Operand::OPS_IN); texCoordCalcFunc->pushOperand(textureUnitParams->mVSOutputTexCoord, Operand::OPS_OUT); } else { texCoordCalcFunc = OGRE_NEW FunctionInvocation(FFP_FUNC_GENERATE_TEXCOORD_ENV_NORMAL, FFP_VS_TEXTURING, textureUnitParams->mTextureSamplerIndex); texCoordCalcFunc->pushOperand(mWorldITMatrix, Operand::OPS_IN); texCoordCalcFunc->pushOperand(mViewMatrix, Operand::OPS_IN); texCoordCalcFunc->pushOperand(textureUnitParams->mTextureMatrix, Operand::OPS_IN); texCoordCalcFunc->pushOperand(mVSInputNormal, Operand::OPS_IN); texCoordCalcFunc->pushOperand(textureUnitParams->mVSOutputTexCoord, Operand::OPS_OUT); } break; break; case TEXCALC_PROJECTIVE_TEXTURE: texCoordCalcFunc = OGRE_NEW FunctionInvocation(FFP_FUNC_GENERATE_TEXCOORD_PROJECTION, FFP_VS_TEXTURING, textureUnitParams->mTextureSamplerIndex); texCoordCalcFunc->pushOperand(mWorldMatrix, Operand::OPS_IN); texCoordCalcFunc->pushOperand(textureUnitParams->mTextureViewProjImageMatrix, Operand::OPS_IN); texCoordCalcFunc->pushOperand(mVSInputPos, Operand::OPS_IN); texCoordCalcFunc->pushOperand(textureUnitParams->mVSOutputTexCoord, Operand::OPS_OUT); break; } if (texCoordCalcFunc != NULL) vsMain->addAtomInstace(texCoordCalcFunc); return true; }
//----------------------------------------------------------------------- void DualQuaternionSkinning::addPositionCalculations(Function* vsMain, int& funcCounter) { FunctionInvocation* curFuncInvocation = NULL; if (mDoBoneCalculations == true) { if(mScalingShearingSupport) { //Construct a scaling and shearing matrix based on the blend weights for(int i = 0 ; i < getWeightCount() ; ++i) { //Assign the local param based on the current index of the scaling and shearing matrices curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, FFP_VS_TRANSFORM, funcCounter++); curFuncInvocation->pushOperand(mParamInScaleShearMatrices, Operand::OPS_IN); curFuncInvocation->pushOperand(mParamInIndices, Operand::OPS_IN, indexToMask(i), 1); curFuncInvocation->pushOperand(mParamTempFloat3x4, Operand::OPS_OUT); vsMain->addAtomInstance(curFuncInvocation); //Calculate the resultant scaling and shearing matrix based on the weights given addIndexedPositionWeight(vsMain, i, mParamTempFloat3x4, mParamTempFloat3x4, mParamBlendS, funcCounter); } //Transform the position based by the scaling and shearing matrix curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_TRANSFORM, FFP_VS_TRANSFORM, funcCounter++); curFuncInvocation->pushOperand(mParamBlendS, Operand::OPS_IN); curFuncInvocation->pushOperand(mParamInPosition, Operand::OPS_IN, Operand::OPM_XYZ); curFuncInvocation->pushOperand(mParamLocalBlendPosition, Operand::OPS_OUT); vsMain->addAtomInstance(curFuncInvocation); } else { //Assign the input position to the local blended position curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, FFP_VS_TRANSFORM, funcCounter++); curFuncInvocation->pushOperand(mParamInPosition, Operand::OPS_IN, Operand::OPM_XYZ); curFuncInvocation->pushOperand(mParamLocalBlendPosition, Operand::OPS_OUT); vsMain->addAtomInstance(curFuncInvocation); } //Set functions to calculate world position for(int i = 0 ; i < getWeightCount() ; ++i) { //Set the index of the matrix curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, FFP_VS_TRANSFORM, funcCounter++); curFuncInvocation->pushOperand(mParamInIndices, Operand::OPS_IN, indexToMask(i)); curFuncInvocation->pushOperand(mParamIndex1, Operand::OPS_OUT); vsMain->addAtomInstance(curFuncInvocation); //Multiply the index by 2 curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_MODULATE, FFP_VS_TRANSFORM, funcCounter++); curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(2.0f), Operand::OPS_IN); curFuncInvocation->pushOperand(mParamIndex1, Operand::OPS_IN); curFuncInvocation->pushOperand(mParamIndex1, Operand::OPS_OUT); vsMain->addAtomInstance(curFuncInvocation); //Add 1 to the index and assign as the second row's index curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ADD, FFP_VS_TRANSFORM, funcCounter++); curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(1.0f), Operand::OPS_IN); curFuncInvocation->pushOperand(mParamIndex1, Operand::OPS_IN); curFuncInvocation->pushOperand(mParamIndex2, Operand::OPS_OUT); vsMain->addAtomInstance(curFuncInvocation); //Build the dual quaternion matrix curFuncInvocation = OGRE_NEW FunctionInvocation(SGX_FUNC_BUILD_DUAL_QUATERNION_MATRIX, FFP_VS_TRANSFORM, funcCounter++); curFuncInvocation->pushOperand(mParamInWorldMatrices, Operand::OPS_IN); curFuncInvocation->pushOperand(mParamIndex1, Operand::OPS_IN, Operand::OPM_ALL, 1); curFuncInvocation->pushOperand(mParamInWorldMatrices, Operand::OPS_IN); curFuncInvocation->pushOperand(mParamIndex2, Operand::OPS_IN, Operand::OPM_ALL, 1); curFuncInvocation->pushOperand(mParamTempFloat2x4, Operand::OPS_OUT); vsMain->addAtomInstance(curFuncInvocation); //Adjust the podalities of the dual quaternions if(mCorrectAntipodalityHandling) { adjustForCorrectAntipodality(vsMain, i, funcCounter, mParamTempFloat2x4); } //Calculate the resultant dual quaternion based on the weights given addIndexedPositionWeight(vsMain, i, mParamTempFloat2x4, mParamTempFloat2x4, mParamBlendDQ, funcCounter); } //Normalize the dual quaternion curFuncInvocation = OGRE_NEW FunctionInvocation(SGX_FUNC_NORMALIZE_DUAL_QUATERNION, FFP_VS_TRANSFORM, funcCounter++); curFuncInvocation->pushOperand(mParamBlendDQ, Operand::OPS_INOUT); vsMain->addAtomInstance(curFuncInvocation); //Calculate the blend position curFuncInvocation = OGRE_NEW FunctionInvocation(SGX_FUNC_CALCULATE_BLEND_POSITION, FFP_VS_TRANSFORM, funcCounter++); curFuncInvocation->pushOperand(mParamLocalBlendPosition, Operand::OPS_IN); curFuncInvocation->pushOperand(mParamBlendDQ, Operand::OPS_IN); curFuncInvocation->pushOperand(mParamTempFloat4, Operand::OPS_OUT); vsMain->addAtomInstance(curFuncInvocation); //Update from object to projective space curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_TRANSFORM, FFP_VS_TRANSFORM, funcCounter++); curFuncInvocation->pushOperand(mParamInViewProjMatrix, Operand::OPS_IN); curFuncInvocation->pushOperand(mParamTempFloat4, Operand::OPS_IN); curFuncInvocation->pushOperand(mParamOutPositionProj, Operand::OPS_OUT); vsMain->addAtomInstance(curFuncInvocation); } else { //update from object to world space curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_TRANSFORM, FFP_VS_TRANSFORM, funcCounter++); curFuncInvocation->pushOperand(mParamInWorldMatrix, Operand::OPS_IN); curFuncInvocation->pushOperand(mParamInPosition, Operand::OPS_IN); curFuncInvocation->pushOperand(mParamLocalPositionWorld, Operand::OPS_OUT); vsMain->addAtomInstance(curFuncInvocation); //update from object to projective space curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_TRANSFORM, FFP_VS_TRANSFORM, funcCounter++); curFuncInvocation->pushOperand(mParamInWorldViewProjMatrix, Operand::OPS_IN); curFuncInvocation->pushOperand(mParamInPosition, Operand::OPS_IN); curFuncInvocation->pushOperand(mParamOutPositionProj, Operand::OPS_OUT); vsMain->addAtomInstance(curFuncInvocation); } }