Beispiel #1
0
        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);
            }
        }
Beispiel #3
0
        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);
        }