//-----------------------------------------------------------------------
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;
}
示例#8
0
//-----------------------------------------------------------------------
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;
}
示例#10
0
//-----------------------------------------------------------------------
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;
}
示例#16
0
//-----------------------------------------------------------------------
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);
	}
}
示例#20
0
		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;
		}
示例#21
0
//-----------------------------------------------------------------------
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;
}
示例#22
0
//-----------------------------------------------------------------------
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;
}
示例#25
0
//-----------------------------------------------------------------------
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);
	}
}