예제 #1
0
		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 );
		}
예제 #2
0
		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;
		}
예제 #3
0
		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;
		}
예제 #4
0
		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;
		}
예제 #5
0
		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;
		}