private void AddIndexedPositionWeight(Function vsMain, int index, ref int funcCounter) { Operand.OpMask indexMask = IndexToMask(index); FunctionInvocation curFuncInvocation; var outputMask = (int)(Operand.OpMask.X | Operand.OpMask.Y | Operand.OpMask.Z); if (paramInWorldMatrices.Type == GpuProgramParameters.GpuConstantType.Matrix_4X4) { outputMask = (int)Operand.OpMask.All; } //multiply posiiton with world matrix and put into temporary param curFuncInvocation = new FunctionInvocation(FFPRenderState.FFPFuncTransform, (int)FFPRenderState.FFPVertexShaderStage.VSTransform, funcCounter++); curFuncInvocation.PushOperand(paramInWorldMatrix, Operand.OpSemantic.In); curFuncInvocation.PushOperand(paramInIndices, Operand.OpSemantic.In, (int)indexMask, 1); curFuncInvocation.PushOperand(paramInPosition, Operand.OpSemantic.In); curFuncInvocation.PushOperand(paramTempFloat4, Operand.OpSemantic.Out, outputMask); vsMain.AddAtomInstance(curFuncInvocation); //set w value of temporary param to 1 curFuncInvocation = new FunctionInvocation(FFPRenderState.FFPFuncAssign, (int)FFPRenderState.FFPVertexShaderStage.VSTransform, funcCounter++); curFuncInvocation.PushOperand(ParameterFactory.CreateConstParamFloat(1.0f), Operand.OpSemantic.In); curFuncInvocation.PushOperand(paramTempFloat4, Operand.OpSemantic.Out, (int)Operand.OpMask.W); vsMain.AddAtomInstance(curFuncInvocation); //multiply temporary param with weight curFuncInvocation = new FunctionInvocation(FFPRenderState.FFPFuncModulate, (int)FFPRenderState.FFPVertexShaderStage.VSTransform, funcCounter++); curFuncInvocation.PushOperand(paramTempFloat4, Operand.OpSemantic.In); curFuncInvocation.PushOperand(paramInWeights, Operand.OpSemantic.In, (int)indexMask); curFuncInvocation.PushOperand(paramTempFloat4, Operand.OpSemantic.Out); vsMain.AddAtomInstance(curFuncInvocation); //check if on first iteration if (index == 0) { //set the local param as the value of the world param curFuncInvocation = new FunctionInvocation(FFPRenderState.FFPFuncAssign, (int)FFPRenderState.FFPVertexShaderStage.VSTransform, funcCounter++); curFuncInvocation.PushOperand(paramTempFloat4, Operand.OpSemantic.In); curFuncInvocation.PushOperand(paramLocalPositionWorld, Operand.OpSemantic.Out); vsMain.AddAtomInstance(curFuncInvocation); } else { //add the local param as the value of the world param curFuncInvocation = new FunctionInvocation(FFPRenderState.FFPFuncAdd, (int)FFPRenderState.FFPVertexShaderStage.VSTransform, funcCounter++); curFuncInvocation.PushOperand(paramTempFloat4, Operand.OpSemantic.In); curFuncInvocation.PushOperand(paramLocalPositionWorld, Operand.OpSemantic.In); curFuncInvocation.PushOperand(paramLocalPositionWorld, Operand.OpSemantic.Out); vsMain.AddAtomInstance(curFuncInvocation); } }
private void AddPositionCalculations(Function vsMain, ref int funcCounter) { FunctionInvocation curFuncInvocation = null; if (doBoneCalculations) { if (scalingShearingSupport) { //Construct a scaling and shearing matrix based on the blend weights for (int i = 0; i < WeightCount; i++) { //Assign the local param based on the current index of the scaling and shearing matrices curFuncInvocation = new FunctionInvocation(FFPRenderState.FFPFuncAssign, (int)FFPRenderState.FFPVertexShaderStage.VSTransform, funcCounter++); curFuncInvocation.PushOperand(this.paramInScaleShearMatrices, Operand.OpSemantic.In); curFuncInvocation.PushOperand(paramInIndices, Operand.OpSemantic.In, (int)IndexToMask(i), 1); curFuncInvocation.PushOperand(this.paramTempFloat3x4, Operand.OpSemantic.Out); vsMain.AddAtomInstance(curFuncInvocation); //Calculate the resultant scaling and shearing matrix based on the weigts given AddIndexedPositionWeight(vsMain, i, this.paramTempFloat3x4, this.paramTempFloat3x4, this.paramBlendS, ref funcCounter); } //Transform the position based on the scaling and shearing matrix curFuncInvocation = new FunctionInvocation(FFPRenderState.FFPFuncTransform, (int)FFPRenderState.FFPVertexShaderStage.VSTransform, funcCounter++); curFuncInvocation.PushOperand(this.paramBlendS, Operand.OpSemantic.In); curFuncInvocation.PushOperand(paramInPosition, Operand.OpSemantic.In, (int)(Operand.OpMask.X | Operand.OpMask.Y | Operand.OpMask.Z)); curFuncInvocation.PushOperand(this.paramLocalBlendPosition, Operand.OpSemantic.Out); vsMain.AddAtomInstance(curFuncInvocation); } else { //Assign the input position to the local blended position curFuncInvocation = new FunctionInvocation(FFPRenderState.FFPFuncAssign, (int)FFPRenderState.FFPVertexShaderStage.VSTransform, funcCounter++); curFuncInvocation.PushOperand(paramInPosition, Operand.OpSemantic.In, (int)(Operand.OpMask.X | Operand.OpMask.Y | Operand.OpMask.Z)); curFuncInvocation.PushOperand(this.paramLocalBlendPosition, Operand.OpSemantic.Out); vsMain.AddAtomInstance(curFuncInvocation); } //Set functions to calculate world position for (int i = 0; i < weightCount; i++) { curFuncInvocation = new FunctionInvocation(FFPRenderState.FFPFuncAssign, (int)FFPRenderState.FFPVertexShaderStage.VSTransform, funcCounter++); curFuncInvocation.PushOperand(paramInIndices, Operand.OpSemantic.In, (int)IndexToMask(i)); curFuncInvocation.PushOperand(this.paramIndex1, Operand.OpSemantic.Out); vsMain.AddAtomInstance(curFuncInvocation); //multiply the index by 2 curFuncInvocation = new FunctionInvocation(FFPRenderState.FFPFuncModulate, (int)FFPRenderState.FFPVertexShaderStage.VSTransform, funcCounter++); curFuncInvocation.PushOperand(ParameterFactory.CreateConstParamFloat(2.0f), Operand.OpSemantic.In); curFuncInvocation.PushOperand(this.paramIndex1, Operand.OpSemantic.In); curFuncInvocation.PushOperand(this.paramIndex1, Operand.OpSemantic.Out); vsMain.AddAtomInstance(curFuncInvocation); //Add 1 to the index and assign as the second row's index curFuncInvocation = new FunctionInvocation(FFPRenderState.FFPFuncAdd, (int)FFPRenderState.FFPVertexShaderStage.VSTransform, funcCounter++); curFuncInvocation.PushOperand(ParameterFactory.CreateConstParamFloat(1.0f), Operand.OpSemantic.In); curFuncInvocation.PushOperand(this.paramIndex1, Operand.OpSemantic.In); curFuncInvocation.PushOperand(this.paramIndex2, Operand.OpSemantic.Out); vsMain.AddAtomInstance(curFuncInvocation); //Build the dual quaternion matrix curFuncInvocation = new FunctionInvocation( DualQuaternionSkinning.SGXFuncBuildDualQuaternionMatrix, (int)FFPRenderState.FFPVertexShaderStage.VSTransform, funcCounter++); curFuncInvocation.PushOperand(paramInWorldMatrices, Operand.OpSemantic.In); curFuncInvocation.PushOperand(this.paramIndex1, Operand.OpSemantic.In, (int)Operand.OpMask.All, 1); curFuncInvocation.PushOperand(paramInWorldMatrices, Operand.OpSemantic.In); curFuncInvocation.PushOperand(this.paramIndex2, Operand.OpSemantic.In, (int)Operand.OpMask.All, 1); curFuncInvocation.PushOperand(this.paramTempFloat2x4, Operand.OpSemantic.Out); vsMain.AddAtomInstance(curFuncInvocation); if (correctAntipodalityHandling) { AdjustForCorrectAntipodality(vsMain, i, ref funcCounter, this.paramTempFloat2x4); } //Calculate the resultant dual quaternion based based on the weights given AddIndexedPositionWeight(vsMain, i, this.paramTempFloat2x4, this.paramTempFloat2x4, this.paramBlendDQ, ref funcCounter); } //Normalize the dual quaternion curFuncInvocation = new FunctionInvocation(DualQuaternionSkinning.SGXFuncNormalizeDualQuaternion, (int)FFPRenderState.FFPVertexShaderStage.VSTransform, funcCounter++); curFuncInvocation.PushOperand(this.paramBlendDQ, Operand.OpSemantic.InOut); vsMain.AddAtomInstance(curFuncInvocation); //Calculate the blend position curFuncInvocation = new FunctionInvocation(DualQuaternionSkinning.SGXFuncCalculateBlendPosition, (int)FFPRenderState.FFPVertexShaderStage.VSTransform, funcCounter++); curFuncInvocation.PushOperand(this.paramLocalBlendPosition, Operand.OpSemantic.In); curFuncInvocation.PushOperand(this.paramBlendDQ, Operand.OpSemantic.In); curFuncInvocation.PushOperand(paramTempFloat4, Operand.OpSemantic.Out); vsMain.AddAtomInstance(curFuncInvocation); //Update from object to projective space curFuncInvocation = new FunctionInvocation(FFPRenderState.FFPFuncTransform, (int)FFPRenderState.FFPVertexShaderStage.VSTransform, funcCounter++); curFuncInvocation.PushOperand(paramInViewProjMatrix, Operand.OpSemantic.In); curFuncInvocation.PushOperand(paramTempFloat4, Operand.OpSemantic.In); curFuncInvocation.PushOperand(paramOutPositionProj, Operand.OpSemantic.Out); vsMain.AddAtomInstance(curFuncInvocation); } else { //update from object to world space curFuncInvocation = new FunctionInvocation(FFPRenderState.FFPFuncTransform, (int)FFPRenderState.FFPVertexShaderStage.VSTransform, funcCounter++); curFuncInvocation.PushOperand(paramInWorldMatrices, Operand.OpSemantic.In); curFuncInvocation.PushOperand(paramInPosition, Operand.OpSemantic.In); curFuncInvocation.PushOperand(paramLocalPositionWorld, Operand.OpSemantic.Out); vsMain.AddAtomInstance(curFuncInvocation); //update from object to projective space curFuncInvocation = new FunctionInvocation(FFPRenderState.FFPFuncTransform, (int)FFPRenderState.FFPVertexShaderStage.VSTransform, funcCounter++); curFuncInvocation.PushOperand(paramInWorldViewProjMatrix, Operand.OpSemantic.In); curFuncInvocation.PushOperand(paramInPosition, Operand.OpSemantic.In); curFuncInvocation.PushOperand(paramOutPositionProj, Operand.OpSemantic.Out); vsMain.AddAtomInstance(curFuncInvocation); } }
protected override bool AddFunctionInvocations(ProgramSet programSet) { Program vsProgram = programSet.CpuVertexProgram; Program psProgram = programSet.CpuFragmentProgram; Function vsMain = vsProgram.EntryPointFunction; Function psMain = psProgram.EntryPointFunction; FunctionInvocation curFuncInvocation = null; int internalCounter; //Create vertex shader color invocations Parameter vsDiffuse, vsSpecular; internalCounter = 0; if (this.vsInputDiffuse != null) { vsDiffuse = this.vsInputDiffuse; } else { vsDiffuse = vsMain.ResolveLocalParameter(Parameter.SemanticType.Color, 0, Parameter.ContentType.ColorDiffuse, Graphics.GpuProgramParameters.GpuConstantType.Float4); curFuncInvocation = new FunctionInvocation(FFPRenderState.FFPFuncConstruct, (int)FFPRenderState.FFPVertexShaderStage.VSColor, internalCounter++); curFuncInvocation.PushOperand(ParameterFactory.CreateConstParamFloat(1.0f), Operand.OpSemantic.In); curFuncInvocation.PushOperand(ParameterFactory.CreateConstParamFloat(1.0f), Operand.OpSemantic.In); curFuncInvocation.PushOperand(ParameterFactory.CreateConstParamFloat(1.0f), Operand.OpSemantic.In); curFuncInvocation.PushOperand(ParameterFactory.CreateConstParamFloat(1.0f), Operand.OpSemantic.In); curFuncInvocation.PushOperand(vsDiffuse, Operand.OpSemantic.Out); vsMain.AddAtomInstance(curFuncInvocation); } if (this.vsOutputDiffuse != null) { curFuncInvocation = new FunctionInvocation(FFPRenderState.FFPFuncAssign, (int)FFPRenderState.FFPVertexShaderStage.VSColor, internalCounter++); curFuncInvocation.PushOperand(vsDiffuse, Operand.OpSemantic.In); curFuncInvocation.PushOperand(this.vsOutputDiffuse, Operand.OpSemantic.Out); vsMain.AddAtomInstance(curFuncInvocation); } if (this.vsInputSpecular != null) { vsSpecular = this.vsInputSpecular; } else { vsSpecular = vsMain.ResolveLocalParameter(Parameter.SemanticType.Color, 1, Parameter.ContentType.ColorSpecular, Graphics.GpuProgramParameters.GpuConstantType.Float4); curFuncInvocation = new FunctionInvocation(FFPRenderState.FFPFuncConstruct, (int)FFPRenderState.FFPVertexShaderStage.VSColor, internalCounter++); curFuncInvocation.PushOperand(ParameterFactory.CreateConstParamFloat(0.0f), Operand.OpSemantic.In); curFuncInvocation.PushOperand(ParameterFactory.CreateConstParamFloat(0.0f), Operand.OpSemantic.In); curFuncInvocation.PushOperand(ParameterFactory.CreateConstParamFloat(0.0f), Operand.OpSemantic.In); curFuncInvocation.PushOperand(ParameterFactory.CreateConstParamFloat(0.0f), Operand.OpSemantic.In); curFuncInvocation.PushOperand(vsSpecular, Operand.OpSemantic.Out); vsMain.AddAtomInstance(curFuncInvocation); } if (this.vsOutputSpecular != null) { curFuncInvocation = new FunctionInvocation(FFPRenderState.FFPFuncAssign, (int)FFPRenderState.FFPVertexShaderStage.VSColor, internalCounter++); curFuncInvocation.PushOperand(vsSpecular, Operand.OpSemantic.In); curFuncInvocation.PushOperand(this.vsOutputSpecular, Operand.OpSemantic.Out); vsMain.AddAtomInstance(curFuncInvocation); } //Create fragment shader color invocations Parameter psDiffuse, psSpecular; internalCounter = 0; //Handle diffuse color if (this.psInputDiffuse != null) { psDiffuse = this.psInputDiffuse; } else { psDiffuse = psMain.ResolveLocalParameter(Parameter.SemanticType.Color, 0, Parameter.ContentType.ColorDiffuse, Graphics.GpuProgramParameters.GpuConstantType.Float4); curFuncInvocation = new FunctionInvocation(FFPRenderState.FFPFuncConstruct, (int)FFPRenderState.FFPFragmentShaderStage.PSColorBegin, internalCounter++); curFuncInvocation.PushOperand(ParameterFactory.CreateConstParamFloat(1.0f), Operand.OpSemantic.In); curFuncInvocation.PushOperand(ParameterFactory.CreateConstParamFloat(1.0f), Operand.OpSemantic.In); curFuncInvocation.PushOperand(ParameterFactory.CreateConstParamFloat(1.0f), Operand.OpSemantic.In); curFuncInvocation.PushOperand(ParameterFactory.CreateConstParamFloat(1.0f), Operand.OpSemantic.In); curFuncInvocation.PushOperand(psDiffuse, Operand.OpSemantic.Out); psMain.AddAtomInstance(curFuncInvocation); } //Handle specular color if (this.psInputSpecular != null) { psSpecular = this.psInputSpecular; } else { psSpecular = psMain.ResolveLocalParameter(Parameter.SemanticType.Color, 1, Parameter.ContentType.ColorSpecular, Graphics.GpuProgramParameters.GpuConstantType.Float4); curFuncInvocation = new FunctionInvocation(FFPRenderState.FFPFuncConstruct, (int)FFPRenderState.FFPFragmentShaderStage.PSColorBegin, internalCounter++); curFuncInvocation.PushOperand(ParameterFactory.CreateConstParamFloat(0.0f), Operand.OpSemantic.In); curFuncInvocation.PushOperand(ParameterFactory.CreateConstParamFloat(0.0f), Operand.OpSemantic.In); curFuncInvocation.PushOperand(ParameterFactory.CreateConstParamFloat(0.0f), Operand.OpSemantic.In); curFuncInvocation.PushOperand(ParameterFactory.CreateConstParamFloat(0.0f), Operand.OpSemantic.In); curFuncInvocation.PushOperand(psSpecular, Operand.OpSemantic.Out); psMain.AddAtomInstance(curFuncInvocation); } //Assign diffuse color if (this.psOutputDiffuse != null) { curFuncInvocation = new FunctionInvocation(FFPRenderState.FFPFuncAssign, (int)FFPRenderState.FFPFragmentShaderStage.PSColorBegin, internalCounter++); curFuncInvocation.PushOperand(psDiffuse, Operand.OpSemantic.In); curFuncInvocation.PushOperand(this.psOutputDiffuse, Operand.OpSemantic.Out); psMain.AddAtomInstance(curFuncInvocation); } //Assign specular color if (this.psOutputSpecular != null) { curFuncInvocation = new FunctionInvocation(FFPRenderState.FFPFuncAssign, (int)FFPRenderState.FFPFragmentShaderStage.PSColorBegin, internalCounter++); curFuncInvocation.PushOperand(psSpecular, Operand.OpSemantic.In); curFuncInvocation.PushOperand(this.psOutputSpecular, Operand.OpSemantic.Out); psMain.AddAtomInstance(curFuncInvocation); } //Add specular to out color internalCounter = 0; if (this.psOutputDiffuse != null && psSpecular != null) { curFuncInvocation = new FunctionInvocation(FFPRenderState.FFPFuncAdd, (int)FFPRenderState.FFPFragmentShaderStage.PSColorEnd, internalCounter++); curFuncInvocation.PushOperand(this.psOutputDiffuse, Operand.OpSemantic.In, (Operand.OpMask.X | Operand.OpMask.Y | Operand.OpMask.Z)); curFuncInvocation.PushOperand(psSpecular, Operand.OpSemantic.In, (Operand.OpMask.X | Operand.OpMask.Y | Operand.OpMask.Z)); curFuncInvocation.PushOperand(this.psOutputDiffuse, Operand.OpSemantic.Out, (Operand.OpMask.X | Operand.OpMask.Y | Operand.OpMask.Z)); psMain.AddAtomInstance(curFuncInvocation); } return(true); }