protected virtual void AddPSSampleTexelInvocation( TextureUnitParams textureUnitParams, Function psMain, Parameter texel, int groupOrder, ref int internalCounter ) { FunctionInvocation curFuncInvocation = null; if ( textureUnitParams.TexCoordCalcMethod == TexCoordCalcMethod.ProjectiveTexture ) { curFuncInvocation = new FunctionInvocation( FFPRenderState.FFPFuncSamplerTextureProj, groupOrder, internalCounter++ ); } else { curFuncInvocation = new FunctionInvocation( FFPRenderState.FFPFuncSampleTexture, groupOrder, internalCounter++ ); } curFuncInvocation.PushOperand( textureUnitParams.TextureSampler, Operand.OpSemantic.In ); curFuncInvocation.PushOperand( textureUnitParams.PSInputTexCoord, Operand.OpSemantic.In ); curFuncInvocation.PushOperand( texel, Operand.OpSemantic.Out ); psMain.AddAtomInstance( curFuncInvocation ); }
private bool AddPSFunctionInvocations( TextureUnitParams textureUnitParams, Function psMain, ref int internalCounter ) { LayerBlendModeEx colorBlend = textureUnitParams.TextureUnitState.ColorBlendMode; LayerBlendModeEx alphaBlend = textureUnitParams.TextureUnitState.AlphaBlendMode; Parameter source1; Parameter source2; var groupOrder = (int)FFPRenderState.FFPFragmentShaderStage.PSTexturing; //Add texture sampling code Parameter texel = psMain.ResolveLocalParameter( Parameter.SemanticType.Unknown, 0, "texel_" + textureUnitParams.TextureSamplerIndex.ToString(), GpuProgramParameters.GpuConstantType.Float4 ); AddPSSampleTexelInvocation( textureUnitParams, psMain, texel, groupOrder, ref internalCounter ); //Build color argument for source1 source1 = psMain.ResolveLocalParameter( Parameter.SemanticType.Unknown, 0, "source1", GpuProgramParameters.GpuConstantType.Float4 ); AddPSArgumentInvocations( psMain, source1, texel, textureUnitParams.TextureSamplerIndex, colorBlend.source1, colorBlend.colorArg1, colorBlend.alphaArg1, false, groupOrder, ref internalCounter ); //build color argument for source2 source2 = psMain.ResolveLocalParameter( Parameter.SemanticType.Unknown, 0, "source2", GpuProgramParameters.GpuConstantType.Float4 ); AddPSArgumentInvocations( psMain, source2, texel, textureUnitParams.TextureSamplerIndex, colorBlend.source2, colorBlend.colorArg2, colorBlend.alphaArg2, false, groupOrder, ref internalCounter ); bool needDifferentAlphaBlend = false; if ( alphaBlend.operation != colorBlend.operation || alphaBlend.source1 != colorBlend.source1 || alphaBlend.source2 != colorBlend.source2 || colorBlend.source1 == LayerBlendSource.Manual || colorBlend.source2 == LayerBlendSource.Manual || alphaBlend.source1 == LayerBlendSource.Manual || alphaBlend.source2 == LayerBlendSource.Manual ) { needDifferentAlphaBlend = true; } //Build colors blend AddPSBlendInvocations( psMain, source1, source2, texel, textureUnitParams.TextureSamplerIndex, colorBlend, groupOrder, ref internalCounter, needDifferentAlphaBlend ? (int)( Operand.OpMask.X | Operand.OpMask.Y | Operand.OpMask.Z ) : (int)( Operand.OpMask.All ) ); //Case we need different alpha channel code if ( needDifferentAlphaBlend ) { //build alpha argument for source1 AddPSArgumentInvocations( psMain, source1, texel, textureUnitParams.TextureSamplerIndex, alphaBlend.source1, alphaBlend.colorArg1, alphaBlend.alphaArg1, true, groupOrder, ref internalCounter ); //Build alpha argument for source2 AddPSArgumentInvocations( psMain, source2, texel, textureUnitParams.TextureSamplerIndex, alphaBlend.source2, alphaBlend.colorArg2, alphaBlend.alphaArg2, true, groupOrder, ref internalCounter ); //Build alpha blend AddPSBlendInvocations( psMain, source1, source2, texel, textureUnitParams.TextureSamplerIndex, alphaBlend, groupOrder, ref internalCounter, (int)Operand.OpMask.W ); } return true; }
private bool ResolveUniformParams( TextureUnitParams textureUnitParams, ProgramSet programSet ) { Program vsProgram = programSet.CpuVertexProgram; Program psProgram = programSet.CpuFragmentProgram; //Resolve texture sampler parameter. textureUnitParams.TextureSampler = psProgram.ResolveParameter( textureUnitParams.TextureSamplerType, textureUnitParams.TextureSamplerIndex, GpuProgramParameters.GpuParamVariability. Global, "gTextureSampler" ); if ( textureUnitParams.TextureSampler == null ) { return false; } //Resolve texture matrix parameter if ( NeedsTextureMatrix( textureUnitParams.TextureUnitState ) ) { textureUnitParams.TextureMatrix = vsProgram.ResolveAutoParameterInt( GpuProgramParameters.AutoConstantType.TextureMatrix, textureUnitParams.TextureSamplerIndex ); if ( textureUnitParams.TextureMatrix == null ) { return false; } } switch ( textureUnitParams.TexCoordCalcMethod ) { case TexCoordCalcMethod.None: break; case TexCoordCalcMethod.EnvironmentMap: case TexCoordCalcMethod.EnvironmentMapNormal: case TexCoordCalcMethod.EnvironmentMapPlanar: this.worldITMatrix = vsProgram.ResolveAutoParameterInt( GpuProgramParameters.AutoConstantType.InverseTransposeWorldMatrix, 0 ); if ( this.worldITMatrix == null ) { return false; } this.viewMatrix = vsProgram.ResolveAutoParameterInt( GpuProgramParameters.AutoConstantType.ViewMatrix, 0 ); if ( this.viewMatrix == null ) { return false; } break; case TexCoordCalcMethod.EnvironmentMapReflection: this.worldMatrix = vsProgram.ResolveAutoParameterInt( GpuProgramParameters.AutoConstantType.WorldMatrix, 0 ); if ( this.worldMatrix == null ) { return false; } this.worldITMatrix = vsProgram.ResolveAutoParameterInt( GpuProgramParameters.AutoConstantType.InverseTransposeWorldMatrix, 0 ); if ( this.worldITMatrix == null ) { return false; } this.viewMatrix = vsProgram.ResolveAutoParameterInt( GpuProgramParameters.AutoConstantType.ViewMatrix, 0 ); if ( this.viewMatrix == null ) { return false; } break; case TexCoordCalcMethod.ProjectiveTexture: this.worldMatrix = vsProgram.ResolveAutoParameterInt( GpuProgramParameters.AutoConstantType.WorldMatrix, 0 ); if ( this.worldMatrix == null ) { return false; } textureUnitParams.TextureViewProjImageMatrix = vsProgram.ResolveParameter( GpuProgramParameters.GpuConstantType.Matrix_4X4, -1, GpuProgramParameters.GpuParamVariability.Lights, "gTexViewProjImageMatrix" ); if ( textureUnitParams.TextureViewProjImageMatrix == null ) { return false; } var effects = new List<TextureEffect>(); for ( int i = 0; i < textureUnitParams.TextureUnitState.NumEffects; i++ ) { var curEffect = textureUnitParams.TextureUnitState.GetEffect( i ); effects.Add( curEffect ); } foreach ( var effi in effects ) { if ( effi.type == TextureEffectType.ProjectiveTexture ) { textureUnitParams.TextureProjector = effi.frustum; break; } } if ( textureUnitParams.TextureProjector == null ) { return false; } break; } return true; }
private bool AddVSFunctionInvocations( TextureUnitParams textureUnitParams, Function vsMain ) { FunctionInvocation texCoordCalcFunc = null; switch ( textureUnitParams.TexCoordCalcMethod ) { case TexCoordCalcMethod.None: if ( textureUnitParams.TextureMatrix == null ) { texCoordCalcFunc = new FunctionInvocation( FFPRenderState.FFPFuncAssign, (int)FFPRenderState.FFPVertexShaderStage.VSTexturing, textureUnitParams.TextureSamplerIndex ); texCoordCalcFunc.PushOperand( textureUnitParams.VSInputTexCoord, Operand.OpSemantic.In ); texCoordCalcFunc.PushOperand( textureUnitParams.VSOutputTexCoord, Operand.OpSemantic.Out ); } else { texCoordCalcFunc = new FunctionInvocation( FFPRenderState.FFPFuncTransformTexCoord, (int)FFPRenderState.FFPVertexShaderStage.VSTexturing, textureUnitParams.TextureSamplerIndex ); texCoordCalcFunc.PushOperand( textureUnitParams.TextureMatrix, Operand.OpSemantic.In ); texCoordCalcFunc.PushOperand( textureUnitParams.VSInputTexCoord, Operand.OpSemantic.In ); texCoordCalcFunc.PushOperand( textureUnitParams.VSOutputTexCoord, Operand.OpSemantic.Out ); } break; case TexCoordCalcMethod.EnvironmentMap: case TexCoordCalcMethod.EnvironmentMapPlanar: if ( textureUnitParams.TextureMatrix == null ) { texCoordCalcFunc = new FunctionInvocation( FFPRenderState.FFPFunGenerateTexcoordEnvSphere, (int)FFPRenderState.FFPVertexShaderStage.VSTexturing, textureUnitParams.TextureSamplerIndex ); texCoordCalcFunc.PushOperand( this.worldITMatrix, Operand.OpSemantic.In ); texCoordCalcFunc.PushOperand( this.viewMatrix, Operand.OpSemantic.In ); texCoordCalcFunc.PushOperand( this.vsInputNormal, Operand.OpSemantic.In ); texCoordCalcFunc.PushOperand( textureUnitParams.VSOutputTexCoord, Operand.OpSemantic.Out ); } else { texCoordCalcFunc = new FunctionInvocation( FFPRenderState.FFPFunGenerateTexcoordEnvSphere, (int)FFPRenderState.FFPVertexShaderStage.VSTexturing, textureUnitParams.TextureSamplerIndex ); texCoordCalcFunc.PushOperand( this.worldITMatrix, Operand.OpSemantic.In ); texCoordCalcFunc.PushOperand( this.viewMatrix, Operand.OpSemantic.In ); texCoordCalcFunc.PushOperand( textureUnitParams.TextureMatrix, Operand.OpSemantic.In ); texCoordCalcFunc.PushOperand( this.vsInputNormal, Operand.OpSemantic.In ); texCoordCalcFunc.PushOperand( textureUnitParams.VSOutputTexCoord, Operand.OpSemantic.Out ); } break; case TexCoordCalcMethod.EnvironmentMapReflection: if ( textureUnitParams.TextureMatrix == null ) { texCoordCalcFunc = new FunctionInvocation( FFPRenderState.FFPFuncGenerateTexCoordEnvReflect, (int)FFPRenderState.FFPVertexShaderStage.VSTexturing, textureUnitParams.TextureSamplerIndex ); texCoordCalcFunc.PushOperand( this.worldMatrix, Operand.OpSemantic.In ); texCoordCalcFunc.PushOperand( this.worldITMatrix, Operand.OpSemantic.In ); texCoordCalcFunc.PushOperand( this.viewMatrix, Operand.OpSemantic.In ); texCoordCalcFunc.PushOperand( this.vsInputNormal, Operand.OpSemantic.In ); texCoordCalcFunc.PushOperand( this.vsInputPos, Operand.OpSemantic.In ); texCoordCalcFunc.PushOperand( textureUnitParams.VSOutputTexCoord, Operand.OpSemantic.Out ); } else { texCoordCalcFunc = new FunctionInvocation( FFPRenderState.FFPFuncGenerateTexCoordEnvReflect, (int)FFPRenderState.FFPVertexShaderStage.VSTexturing, textureUnitParams.TextureSamplerIndex ); texCoordCalcFunc.PushOperand( this.worldMatrix, Operand.OpSemantic.In ); texCoordCalcFunc.PushOperand( this.worldITMatrix, Operand.OpSemantic.In ); texCoordCalcFunc.PushOperand( this.viewMatrix, Operand.OpSemantic.In ); texCoordCalcFunc.PushOperand( textureUnitParams.TextureMatrix, Operand.OpSemantic.In ); texCoordCalcFunc.PushOperand( this.vsInputNormal, Operand.OpSemantic.In ); texCoordCalcFunc.PushOperand( this.vsInputPos, Operand.OpSemantic.In ); texCoordCalcFunc.PushOperand( textureUnitParams.VSOutputTexCoord, Operand.OpSemantic.Out ); } break; case TexCoordCalcMethod.EnvironmentMapNormal: if ( textureUnitParams.TextureMatrix == null ) { texCoordCalcFunc = new FunctionInvocation( FFPRenderState.FFPFuncGenerateTexcoordEnvNormal, (int)FFPRenderState.FFPVertexShaderStage.VSTexturing, textureUnitParams.TextureSamplerIndex ); texCoordCalcFunc.PushOperand( this.worldITMatrix, Operand.OpSemantic.In ); texCoordCalcFunc.PushOperand( this.viewMatrix, Operand.OpSemantic.In ); texCoordCalcFunc.PushOperand( this.vsInputPos, Operand.OpSemantic.In ); texCoordCalcFunc.PushOperand( textureUnitParams.VSOutputTexCoord, Operand.OpSemantic.Out ); } else { texCoordCalcFunc = new FunctionInvocation( FFPRenderState.FFPFuncGenerateTexcoordEnvNormal, (int)FFPRenderState.FFPVertexShaderStage.VSTexturing, textureUnitParams.TextureSamplerIndex ); texCoordCalcFunc.PushOperand( this.worldITMatrix, Operand.OpSemantic.In ); texCoordCalcFunc.PushOperand( this.viewMatrix, Operand.OpSemantic.In ); texCoordCalcFunc.PushOperand( textureUnitParams.TextureMatrix, Operand.OpSemantic.In ); texCoordCalcFunc.PushOperand( this.vsInputNormal, Operand.OpSemantic.In ); texCoordCalcFunc.PushOperand( textureUnitParams.VSOutputTexCoord, Operand.OpSemantic.Out ); } break; case TexCoordCalcMethod.ProjectiveTexture: texCoordCalcFunc = new FunctionInvocation( FFPRenderState.FFPFuncGenerateTexCoordProjection, (int)FFPRenderState.FFPVertexShaderStage.VSTexturing, textureUnitParams.TextureSamplerIndex ); texCoordCalcFunc.PushOperand( this.worldMatrix, Operand.OpSemantic.In ); texCoordCalcFunc.PushOperand( textureUnitParams.TextureViewProjImageMatrix, Operand.OpSemantic.In ); texCoordCalcFunc.PushOperand( this.vsInputPos, Operand.OpSemantic.In ); texCoordCalcFunc.PushOperand( textureUnitParams.VSOutputTexCoord, Operand.OpSemantic.Out ); break; } if ( texCoordCalcFunc != null ) { vsMain.AddAtomInstance( texCoordCalcFunc ); } return true; }
private bool ResolveFunctionsParams( TextureUnitParams curParams, ProgramSet programSet ) { Program vsProgram = programSet.CpuVertexProgram; Program psProgram = programSet.CpuFragmentProgram; Function vsMain = vsProgram.EntryPointFunction; Function psMain = psProgram.EntryPointFunction; Parameter.ContentType texCoordContent = Parameter.ContentType.Unknown; switch ( curParams.TexCoordCalcMethod ) { case TexCoordCalcMethod.None: //Resolve explicit vs input texture coordinates if ( curParams.TextureMatrix == null ) { switch ( curParams.TextureUnitState.TextureCoordSet ) { case 0: texCoordContent = Parameter.ContentType.TextureCoordinate0; break; case 1: texCoordContent = Parameter.ContentType.TextureCoordinate1; break; case 2: texCoordContent = Parameter.ContentType.TextureCoordinate2; break; case 3: texCoordContent = Parameter.ContentType.TextureCoordinate3; break; case 4: texCoordContent = Parameter.ContentType.TextureCoordinate4; break; case 5: texCoordContent = Parameter.ContentType.TextureCoordinate5; break; case 6: texCoordContent = Parameter.ContentType.TextureCoordinate6; break; case 7: texCoordContent = Parameter.ContentType.TextureCoordinate7; break; } } Parameter.ContentType texCoordToUse = Parameter.ContentType.TextureCoordinate0; switch ( curParams.TextureUnitState.TextureCoordSet ) { case 0: texCoordToUse = Parameter.ContentType.TextureCoordinate0; break; case 1: texCoordToUse = Parameter.ContentType.TextureCoordinate1; break; case 2: texCoordToUse = Parameter.ContentType.TextureCoordinate2; break; case 3: texCoordToUse = Parameter.ContentType.TextureCoordinate3; break; case 4: texCoordToUse = Parameter.ContentType.TextureCoordinate4; break; case 5: texCoordToUse = Parameter.ContentType.TextureCoordinate5; break; case 6: texCoordToUse = Parameter.ContentType.TextureCoordinate6; break; case 7: texCoordToUse = Parameter.ContentType.TextureCoordinate7; break; } curParams.VSInputTexCoord = vsMain.ResolveInputParameter( Parameter.SemanticType.TextureCoordinates, curParams.TextureUnitState.TextureCoordSet, texCoordToUse, curParams.VSInTextureCoordinateType ); if ( curParams.VSInputTexCoord == null ) { return false; } break; case TexCoordCalcMethod.EnvironmentMap: case TexCoordCalcMethod.EnvironmentMapNormal: case TexCoordCalcMethod.EnvironmentMapPlanar: //Resolve vertex normal this.vsInputNormal = vsMain.ResolveInputParameter( Parameter.SemanticType.Normal, 0, Parameter.ContentType.NormalObjectSpace, GpuProgramParameters.GpuConstantType.Float3 ); if ( this.vsInputNormal == null ) { return false; } break; case TexCoordCalcMethod.EnvironmentMapReflection: //Resolve vertex normal this.vsInputNormal = vsMain.ResolveInputParameter( Parameter.SemanticType.Normal, 0, Parameter.ContentType.NormalObjectSpace, GpuProgramParameters.GpuConstantType.Float3 ); if ( this.vsInputNormal == null ) { return false; } //Resovle vertex position this.vsInputPos = vsMain.ResolveInputParameter( Parameter.SemanticType.Position, 0, Parameter.ContentType.PositionObjectSpace, GpuProgramParameters.GpuConstantType.Float4 ); if ( this.vsInputPos == null ) { return false; } break; case TexCoordCalcMethod.ProjectiveTexture: //Resolve vertex position this.vsInputPos = vsMain.ResolveInputParameter( Parameter.SemanticType.Position, 0, Parameter.ContentType.PositionObjectSpace, GpuProgramParameters.GpuConstantType.Float4 ); if ( this.vsInputPos == null ) { return false; } break; } //Resolve vs output texture coordinates curParams.PSInputTexCoord = psMain.ResolveInputParameter( Parameter.SemanticType.TextureCoordinates, curParams.VSOutputTexCoord.Index, curParams.VSOutputTexCoord.Content, curParams.VSOutTextureCoordinateType ); if ( curParams.PSInputTexCoord == null ) { return false; } var inputParams = psMain.InputParameters; var localParams = psMain.LocalParameters; this.psDiffuse = Function.GetParameterByContent( inputParams, Parameter.ContentType.ColorDiffuse, GpuProgramParameters.GpuConstantType.Float4 ); if ( this.psDiffuse == null ) { this.psDiffuse = Function.GetParameterByContent( localParams, Parameter.ContentType.ColorDiffuse, GpuProgramParameters.GpuConstantType.Float4 ); if ( this.psDiffuse == null ) { return false; } } this.psSpecular = Function.GetParameterByContent( inputParams, Parameter.ContentType.ColorSpecular, GpuProgramParameters.GpuConstantType.Float4 ); if ( this.psSpecular == null ) { this.psSpecular = Function.GetParameterByContent( localParams, Parameter.ContentType.ColorSpecular, GpuProgramParameters.GpuConstantType.Float4 ); if ( this.psSpecular == null ) { return false; } } this.psOutDiffuse = psMain.ResolveOutputParameter( Parameter.SemanticType.Color, 0, Parameter.ContentType.ColorDiffuse, GpuProgramParameters.GpuConstantType.Float4 ); if ( this.psOutDiffuse == null ) { return false; } return true; }