Utility class for handling texture layer blending parameters.
Ejemplo n.º 1
0
		/// <summary>
		///		Renders the static level geometry tagged in <see cref="Plugin_BSPSceneManager.BspSceneManager.WalkTree"/>.
		/// </summary>
		protected void RenderStaticGeometry()
		{
			// Check should we be rendering
			if ( !SpecialCaseRenderQueueList.IsRenderQueueToBeProcessed( worldGeometryRenderQueueId ) )
			{
				return;
			}
			if ( this.level == null )
			{
				LogManager.Instance.Write( "BSPSceneManager [Warning]: Skip RenderStaticGeometry, no level was set!" );
				return;
			}
			// no world transform required
			targetRenderSystem.WorldMatrix = Matrix4.Identity;

			// Set view / proj
			targetRenderSystem.ViewMatrix = cameraInProgress.ViewMatrix;
			targetRenderSystem.ProjectionMatrix = cameraInProgress.ProjectionMatrix;

			ColorEx bspAmbient = ColorEx.White;

			if ( this.level.BspOptions.ambientEnabled )
			{
				bspAmbient = new ColorEx( ambientColor.r*this.level.BspOptions.ambientRatio,
				                          ambientColor.g*this.level.BspOptions.ambientRatio,
				                          ambientColor.b*this.level.BspOptions.ambientRatio );
			}

			var ambientBlend = new LayerBlendModeEx();
			ambientBlend.blendType = LayerBlendType.Color;
			ambientBlend.operation = LayerBlendOperationEx.Modulate;
			ambientBlend.source1 = LayerBlendSource.Texture;
			ambientBlend.source2 = LayerBlendSource.Manual;
			ambientBlend.colorArg2 = bspAmbient;

			// For each material in turn, cache rendering data & render
			IEnumerator mapEnu = this.matFaceGroupMap.Keys.GetEnumerator();

			bool passIsSet = false;

			while ( mapEnu.MoveNext() )
			{
				// Get Material
				var thisMaterial = (Material)mapEnu.Current;
				List<BspStaticFaceGroup> faceGrp = this.matFaceGroupMap[ thisMaterial ];

				// if one face group is a quake shader then the material is a quake shader
				bool isQuakeShader = faceGrp[ 0 ].isQuakeShader;

				// Empty existing cache
				this.renderOp.indexData.indexCount = 0;

				// lock index buffer ready to receive data
#if !AXIOM_SAFE_ONLY
				unsafe
#endif
				{
					var pIdx = this.renderOp.indexData.indexBuffer.Lock( BufferLocking.Discard );
					var sizeOfElement = this.renderOp.indexData.indexBuffer.Type == IndexType.Size32
					                    	? sizeof ( uint )
					                    	: sizeof ( ushort );

					for ( int i = 0; i < faceGrp.Count; i++ )
					{
						// Cache each
						int numElems = CacheGeometry( pIdx, faceGrp[ i ] );
						this.renderOp.indexData.indexCount += numElems;
						pIdx += numElems*sizeOfElement;
					}

					// Unlock the buffer
					this.renderOp.indexData.indexBuffer.Unlock();
				}

				// Skip if no faces to process (we're not doing flare types yet)
				if ( this.renderOp.indexData.indexCount == 0 )
				{
					continue;
				}

				if ( isQuakeShader )
				{
					for ( int i = 0; i < thisMaterial.GetTechnique( 0 ).PassCount; i++ )
					{
						SetPass( thisMaterial.GetTechnique( 0 ).GetPass( i ) );
						targetRenderSystem.Render( this.renderOp );
					}
					passIsSet = false;
				}
				else if ( !passIsSet )
				{
					int i;
					for ( i = 0; i < thisMaterial.GetTechnique( 0 ).PassCount; i++ )
					{
						SetPass( thisMaterial.GetTechnique( 0 ).GetPass( i ) );

						// for ambient lighting
						if ( i == 0 && this.level.BspOptions.ambientEnabled )
						{
							targetRenderSystem.SetTextureBlendMode( 0, ambientBlend );
						}

						targetRenderSystem.Render( this.renderOp );
					}

					// if it's only 1 pass then there's no need to set it again
					passIsSet = ( i > 1 ) ? false : true;
				}
				else
				{
					Pass pass = thisMaterial.GetTechnique( 0 ).GetPass( 0 );
					// Get the plain geometry texture
					if ( pass.TextureUnitStatesCount > 0 )
					{
						TextureUnitState geometryTex = pass.GetTextureUnitState( 0 );
						targetRenderSystem.SetTexture( 0, true, geometryTex.TextureName );
					}

					if ( pass.TextureUnitStatesCount > 1 )
					{
						// Get the lightmap
						TextureUnitState lightmapTex = pass.GetTextureUnitState( 1 );
						targetRenderSystem.SetTexture( 1, true, lightmapTex.TextureName );
					}

					targetRenderSystem.Render( this.renderOp );
				}
			}

			//if(showNodeAABs)
			//	targetRenderSystem.Render(aaBGeometry);
		}
Ejemplo n.º 2
0
		public override void SetTextureBlendMode( int unit, LayerBlendModeEx bm )
		{
			//Ogre: not supported
		}
Ejemplo n.º 3
0
        public override void SetTextureBlendMode( int stage, LayerBlendModeEx bm )
        {
            TextureStage tss;
            ColorEx manualD3D;
            // choose type of blend.
            switch ( bm.blendType )
            {
                case LayerBlendType.Color:
                    tss = TextureStage.ColorOperation;
                    break;
                case LayerBlendType.Alpha:
                    tss = TextureStage.AlphaOperation;
                    break;
                default:
                    throw new AxiomException("Invalid blend type");
            }

            // set manual factor if required by operation
            if (bm.operation == LayerBlendOperationEx.BlendManual)
            {
                SetRenderState( RenderState.TextureFactor, new Color4( bm.blendFactor, 0.0f, 0.0f, 0.0f ) );
            }

            // set operation  
            SetTextureStageState( stage, tss, D3DHelper.ConvertEnum(bm.operation, _deviceManager.ActiveDevice.D3D9DeviceCaps) );

            // choose source 1
            switch ( bm.blendType )
            {
                case LayerBlendType.Color:
                    tss = TextureStage.ColorArg1;
                    manualD3D = bm.colorArg1;
                    manualBlendColors[ stage, 0 ] = manualD3D;
                    break;
                case LayerBlendType.Alpha:
                    tss = TextureStage.AlphaArg1;
                    manualD3D = manualBlendColors[ stage, 0 ];
                    manualD3D.a = bm.alphaArg1;
                    break;
                default:
                    throw new AxiomException("Invalid blend type");
            }

            // Set manual factor if required
            if (bm.source1 == LayerBlendSource.Manual)
            {
                if (currentCapabilities.HasCapability(Graphics.Capabilities.PerStageConstant))
                {
                    // Per-stage state
                    SetTextureStageState(stage, TextureStage.Constant, manualD3D.ToARGB());
                }
                else
                {
                    // Global state
                    SetRenderState( RenderState.TextureFactor, manualD3D.ToARGB() );
                }
            }
            // set source 1
            SetTextureStageState(stage, tss, D3DHelper.ConvertEnum(bm.source1, currentCapabilities.HasCapability(Graphics.Capabilities.PerStageConstant)));

            // choose source 2
            switch ( bm.blendType )
            {
                case LayerBlendType.Color:
                    tss = TextureStage.ColorArg2;
                    manualD3D = bm.colorArg2;
                    manualBlendColors[stage, 1] = manualD3D;
                    break;
                case LayerBlendType.Alpha:
                    tss = TextureStage.AlphaArg2;
                    manualD3D = manualBlendColors[ stage, 1 ];
                    manualD3D.a = bm.alphaArg2;
                    break;
            }
            // Set manual factor if required
            if (bm.source2 == LayerBlendSource.Manual)
            {
                if (currentCapabilities.HasCapability(Graphics.Capabilities.PerStageConstant))
                {
                    // Per-stage state
                    SetTextureStageState(stage, TextureStage.Constant, manualD3D.ToARGB());
                }
                else
                {
                    SetRenderState( RenderState.TextureFactor, manualD3D.ToARGB() );
                }
            }

            // Now set source 2
            SetTextureStageState( stage, tss,D3DHelper.ConvertEnum(bm.source2, currentCapabilities.HasCapability(Graphics.Capabilities.PerStageConstant)) );
            
            // Set interpolation factor if lerping
            if ( bm.operation != LayerBlendOperationEx.BlendDiffuseColor ||
                 ( _deviceManager.ActiveDevice.D3D9DeviceCaps.TextureOperationCaps & TextureOperationCaps.Lerp ) == 0 )
                return;
            
            // choose source 0 (lerp factor)
            switch ( bm.blendType )
            {
                case LayerBlendType.Color:
                    tss = TextureStage.ColorArg0;
                    break;
                case LayerBlendType.Alpha:
                    tss = TextureStage.AlphaArg0;
                    break;
            }
            SetTextureStageState(stage, tss, TextureArgument.Diffuse);
        }
 /// <summary>
 ///		Sets the texture blend modes from a TextureLayer record.
 ///		Meant for use internally only - apps should use the Material
 ///		and TextureLayer classes.
 /// </summary>
 /// <param name="stage">Texture unit.</param>
 /// <param name="blendMode">Details of the blending modes.</param>
 public abstract void SetTextureBlendMode(int stage, LayerBlendModeEx blendMode);
Ejemplo n.º 5
0
		///// <summary>
		///// 
		///// </summary>
		///// <param name="unit"></param>
		///// <param name="bias"></param>
		//public void SetTextureMipmapBias(int unit, float bias)
		//{
		//    if (_rsCapabilities.HasCapability(Capabilities.MipmapLODBias))
		//    {
		//        if (ActivateGLTextureUnit(unit))
		//        {
		//            OpenGL.TexEnv(All.Texturef
		//        }
		//    }
		//}
		/// <summary>
		/// 
		/// </summary>
		/// <param name="stage"></param>
		/// <param name="blendMode"></param>
		public override void SetTextureBlendMode( int stage, LayerBlendModeEx bm )
		{
			if ( stage >= _fixedFunctionTextureUnits )
			{
				//cant do this
				return;
			}
			// Check to see if blending is supported
			if ( !_rsCapabilities.HasCapability( Capabilities.TextureBlending ) )
				return;

			All src1op, src2op, cmd;
			float[] cv1 = new float[ 4 ];
			float[] cv2 = new float[ 4 ];

			if ( bm.blendType == LayerBlendType.Color )
			{
				cv1[ 0 ] = bm.colorArg1.r;
				cv1[ 1 ] = bm.colorArg1.g;
				cv1[ 2 ] = bm.colorArg1.b;
				cv1[ 3 ] = bm.colorArg1.a;
				manualBlendColors[ stage, 0 ] = bm.colorArg1;

				cv2[ 0 ] = bm.colorArg2.r;
				cv2[ 1 ] = bm.colorArg2.g;
				cv2[ 2 ] = bm.colorArg2.b;
				cv2[ 3 ] = bm.colorArg2.a;
				manualBlendColors[ stage, 1 ] = bm.colorArg2;
			}
			if ( bm.blendType == LayerBlendType.Alpha )
			{
				cv1[ 0 ] = manualBlendColors[ stage, 0 ].r;
				cv1[ 1 ] = manualBlendColors[ stage, 0 ].g;
				cv1[ 2 ] = manualBlendColors[ stage, 0 ].b;
				cv1[ 3 ] = bm.alphaArg1;

				cv2[ 0 ] = manualBlendColors[ stage, 1 ].r;
				cv2[ 1 ] = manualBlendColors[ stage, 1 ].g;
				cv2[ 2 ] = manualBlendColors[ stage, 1 ].b;
				cv2[ 3 ] = bm.alphaArg2;
			}
			switch ( bm.source1 )
			{
				case LayerBlendSource.Current:
					src1op = All.Previous;
					break;
				case LayerBlendSource.Texture:
					src1op = All.Texture;
					break;
				case LayerBlendSource.Manual:
					src1op = All.Constant;
					break;
				case LayerBlendSource.Diffuse:
					src1op = All.PrimaryColor;
					break;
				case LayerBlendSource.Specular:
					src1op = All.PrimaryColor;
					break;
				default:
					src1op = 0;
					break;
			}

			switch ( bm.source2 )
			{
				case LayerBlendSource.Current:
					src2op = All.Previous;
					break;
				case LayerBlendSource.Texture:
					src2op = All.Texture;
					break;
				case LayerBlendSource.Manual:
					src2op = All.Constant;
					break;
				case LayerBlendSource.Diffuse:
					src2op = All.PrimaryColor;
					break;
				case LayerBlendSource.Specular:
					src2op = All.PrimaryColor;
					break;
				default:
					src2op = 0;
					break;
			}

			switch ( bm.operation )
			{
				case LayerBlendOperationEx.Source1:
					cmd = All.Replace;
					break;
				case LayerBlendOperationEx.Source2:
					cmd = All.Replace;
					break;
				case LayerBlendOperationEx.Modulate:
				case LayerBlendOperationEx.ModulateX2:
				case LayerBlendOperationEx.ModulateX4:
					cmd = All.Modulate;
					break;
				case LayerBlendOperationEx.Add:
					cmd = All.Add;
					break;
				case LayerBlendOperationEx.AddSigned:
					cmd = All.AddSigned;
					break;
				case LayerBlendOperationEx.AddSmooth:
					cmd = All.Interpolate;
					break;
				case LayerBlendOperationEx.Subtract:
					cmd = All.Subtract;
					break;
				case LayerBlendOperationEx.BlendDiffuseAlpha:
				case LayerBlendOperationEx.BlendCurrentAlpha:
				case LayerBlendOperationEx.BlendManual:
				case LayerBlendOperationEx.BlendTextureAlpha:
				case LayerBlendOperationEx.BlendDiffuseColor:
					cmd = All.Interpolate;
					break;
				case LayerBlendOperationEx.DotProduct:
					bool cap = _rsCapabilities.HasCapability( Capabilities.Dot3 );
					cmd = cap ? All.Dot3Rgb : All.Modulate;
					break;
				default:
					cmd = 0;
					break;
			}

			if ( !ActivateGLTextureUnit( 0 ) )
				return;

			OpenGL.TexEnv( All.TextureEnv, All.TextureEnvMode, (int)All.Combine );
			GLESConfig.GlCheckError( this );

			if ( bm.blendType == LayerBlendType.Color )
			{
				OpenGL.TexEnv( All.TextureEnv, All.CombineRgb, (int)cmd );
				GLESConfig.GlCheckError( this );
				OpenGL.TexEnv( All.TextureEnv, All.Src0Rgb, (int)src1op );
				GLESConfig.GlCheckError( this );
				OpenGL.TexEnv( All.TextureEnv, All.Src1Rgb, (int)src2op );
				GLESConfig.GlCheckError( this );
				OpenGL.TexEnv( All.TextureEnv, All.Src2Rgb, (int)All.Constant );
				GLESConfig.GlCheckError( this );
			}
			else
			{
				OpenGL.TexEnv( All.TextureEnv, All.CombineAlpha, (int)cmd );
				GLESConfig.GlCheckError( this );
				OpenGL.TexEnv( All.TextureEnv, All.Src0Alpha, (int)src1op );
				GLESConfig.GlCheckError( this );
				OpenGL.TexEnv( All.TextureEnv, All.Src1Alpha, (int)src2op );
				GLESConfig.GlCheckError( this );
				OpenGL.TexEnv( All.TextureEnv, All.Src2Alpha, (int)All.Constant );
				GLESConfig.GlCheckError( this );
			}
			float[] blendValue = new float[] { 0, 0, 0, bm.blendFactor };
			switch ( bm.operation )
			{
				case LayerBlendOperationEx.BlendDiffuseColor:
				case LayerBlendOperationEx.BlendDiffuseAlpha:
					OpenGL.TexEnv( All.TextureEnv, All.Src2Rgb, (int)All.PrimaryColor );
					GLESConfig.GlCheckError( this );
					OpenGL.TexEnv( All.TextureEnv, All.Src2Alpha, (int)All.PrimaryColor );
					GLESConfig.GlCheckError( this );
					break;
				case LayerBlendOperationEx.BlendTextureAlpha:
					OpenGL.TexEnv( All.TextureEnv, All.Src2Rgb, (int)All.Texture );
					GLESConfig.GlCheckError( this );
					OpenGL.TexEnv( All.TextureEnv, All.Src2Alpha, (int)All.Texture );
					GLESConfig.GlCheckError( this );
					break;
				case LayerBlendOperationEx.BlendCurrentAlpha:
					OpenGL.TexEnv( All.TextureEnv, All.Src2Rgb, (int)All.Previous );
					GLESConfig.GlCheckError( this );
					OpenGL.TexEnv( All.TextureEnv, All.Src2Alpha, (int)All.Previous );
					GLESConfig.GlCheckError( this );
					break;
				case LayerBlendOperationEx.BlendManual:
					OpenGL.TexEnv( All.TextureEnv, All.TextureEnvColor, blendValue );
					GLESConfig.GlCheckError( this );
					break;
				case LayerBlendOperationEx.ModulateX2:
					OpenGL.TexEnv( All.TextureEnv, bm.blendType == LayerBlendType.Color ?
						All.RgbScale : All.AlphaScale, 2 );
					GLESConfig.GlCheckError( this );
					break;
				case LayerBlendOperationEx.ModulateX4:
					OpenGL.TexEnv( All.TextureEnv, bm.blendType == LayerBlendType.Color ?
						All.RgbScale : All.AlphaScale, 4 );
					GLESConfig.GlCheckError( this );
					break;
				default:
					break;
			}

			if ( bm.blendType == LayerBlendType.Color )
			{
				OpenGL.TexEnv( All.TextureEnv, All.Operand0Rgb, (int)All.SrcColor );
				GLESConfig.GlCheckError( this );
				OpenGL.TexEnv( All.TextureEnv, All.Operand1Rgb, (int)All.SrcColor );
				if ( bm.operation == LayerBlendOperationEx.BlendDiffuseColor )
				{
					OpenGL.TexEnv( All.TextureEnv, All.Operand2Rgb, (int)All.SrcColor );
					GLESConfig.GlCheckError( this );
				}
				else
				{
					OpenGL.TexEnv( All.TextureEnv, All.Operand2Rgb, (int)All.SrcAlpha );
					GLESConfig.GlCheckError( this );
				}
			}

			OpenGL.TexEnv( All.TextureEnv, All.Operand0Alpha, (int)All.SrcAlpha );
			GLESConfig.GlCheckError( this );
			OpenGL.TexEnv( All.TextureEnv, All.Operand1Alpha, (int)All.SrcAlpha );
			GLESConfig.GlCheckError( this );
			OpenGL.TexEnv( All.TextureEnv, All.Operand2Alpha, (int)All.SrcAlpha );
			GLESConfig.GlCheckError( this );
			if ( bm.source1 == LayerBlendSource.Manual )
				OpenGL.TexEnv( All.TextureEnv, All.TextureEnvColor, cv1 );
			if ( bm.source2 == LayerBlendSource.Manual )
				OpenGL.TexEnv( All.TextureEnv, All.TextureEnvColor, cv2 );

			GLESConfig.GlCheckError( this );

			ActivateGLTextureUnit( 0 );
		}
        public override void SetTextureBlendMode(int stage, LayerBlendModeEx blendMode)
        {
            D3D.TextureOperation d3dTexOp = D3DHelper.ConvertEnum(blendMode.operation, d3dCaps);

            // TODO: Verify byte ordering
            if(blendMode.operation == LayerBlendOperationEx.BlendManual)
                SetTextureFactor((int)(new ColorEx(blendMode.blendFactor, 0, 0, 0)).ToARGB());

            if( blendMode.blendType == LayerBlendType.Color ) {

                // Make call to set operation
                if (cache.colorOperation[stage] != d3dTexOp) {
                    cache.colorOperation[stage] = d3dTexOp;
                    device.TextureState[stage].ColorOperation = d3dTexOp;
                }
            }
            else if( blendMode.blendType == LayerBlendType.Alpha ) {
                // Make call to set operation
                if (cache.alphaOperation[stage] != d3dTexOp) {
                    cache.alphaOperation[stage] = d3dTexOp;
                    device.TextureState[stage].AlphaOperation = d3dTexOp;
                }
            }

            // Now set up sources
            System.Drawing.Color factor = System.Drawing.Color.FromArgb(cache.textureFactor);

            // First do source1

            ColorEx manualD3D = ColorEx.FromColor(factor);
            if (blendMode.blendType == LayerBlendType.Color)
                manualD3D = new ColorEx(manualD3D.a, blendMode.colorArg1.r, blendMode.colorArg1.g, blendMode.colorArg1.b);
            else if (blendMode.blendType == LayerBlendType.Alpha)
                manualD3D = new ColorEx(blendMode.alphaArg1, manualD3D.r, manualD3D.g, manualD3D.b);

            LayerBlendSource blendSource = blendMode.source1;
            D3D.TextureArgument d3dTexArg = D3DHelper.ConvertEnum(blendSource);

            // set the texture blend factor if this is manual blending
            if(blendSource == LayerBlendSource.Manual)
                SetTextureFactor((int)manualD3D.ToARGB());

            if( blendMode.blendType == LayerBlendType.Color) {
                if (cache.colorArgument1[stage] != d3dTexArg) {
                    cache.colorArgument1[stage] = d3dTexArg;
                    device.TextureState[stage].ColorArgument1 = d3dTexArg;
                }
            }
            else if (blendMode.blendType == LayerBlendType.Alpha) {
                if (cache.alphaArgument1[stage] != d3dTexArg) {
                    cache.alphaArgument1[stage] = d3dTexArg;
                    device.TextureState[stage].AlphaArgument1 = d3dTexArg;
                }
            }

            // Now do source2

            if( blendMode.blendType == LayerBlendType.Color)
                manualD3D = new ColorEx(manualD3D.a, blendMode.colorArg2.r, blendMode.colorArg2.g, blendMode.colorArg2.b);
            else if( blendMode.blendType == LayerBlendType.Alpha)
                manualD3D = new ColorEx(blendMode.alphaArg2, manualD3D.r, manualD3D.g, manualD3D.b);

            blendSource = blendMode.source2;
            d3dTexArg = D3DHelper.ConvertEnum(blendSource);

            if(blendSource == LayerBlendSource.Manual)
                SetTextureFactor((int)manualD3D.ToARGB());

            if( blendMode.blendType == LayerBlendType.Color) {
                if (cache.colorArgument2[stage] != d3dTexArg) {
                    cache.colorArgument2[stage] = d3dTexArg;
                    device.TextureState[stage].ColorArgument2 = d3dTexArg;
                }
            }
            else if (blendMode.blendType == LayerBlendType.Alpha) {
                if (cache.alphaArgument2[stage] != d3dTexArg) {
                    cache.alphaArgument2[stage] = d3dTexArg;
                    device.TextureState[stage].AlphaArgument2 = d3dTexArg;
                }
            }
        }
Ejemplo n.º 7
0
		public override void SetTextureBlendMode( int stage, LayerBlendModeEx bm )
		{
            if (stage >= _fixedFunctionTextureUnits)
            {
                // Can't do this
                return;
            }

            // Check to see if blending is supported
            if (!currentCapabilities.HasCapability(Graphics.Capabilities.Blending))
			{
				return;
			}


            int src1op, src2op, cmd;
		    var cv1 = _tempColorVals;
		    var cv2 = _tempLightVals;

		    if (bm.blendType == LayerBlendType.Color)
		    {
			    cv1[0] = bm.colorArg1.r;
			    cv1[1] = bm.colorArg1.g;
			    cv1[2] = bm.colorArg1.b;
			    cv1[3] = bm.colorArg1.a;
                manualBlendColors[stage, 0] = bm.colorArg1;


			    cv2[0] = bm.colorArg2.r;
			    cv2[1] = bm.colorArg2.g;
			    cv2[2] = bm.colorArg2.b;
			    cv2[3] = bm.colorArg2.a;
                manualBlendColors[stage, 1] = bm.colorArg2;
		    }

            switch (bm.source1)
            {
                case LayerBlendSource.Current:
                    src1op = Gl.GL_PREVIOUS;
                    break;
                case LayerBlendSource.Texture:
                    src1op = Gl.GL_TEXTURE;
                    break;
                case LayerBlendSource.Manual:
                    src1op = Gl.GL_CONSTANT;
                    break;
                case LayerBlendSource.Diffuse:
                    src1op = Gl.GL_PRIMARY_COLOR;
                    break;
                // XXX
                case LayerBlendSource.Specular:
                    src1op = Gl.GL_PRIMARY_COLOR;
                    break;
                default:
                    src1op = 0;
                    break;
            }

            switch (bm.source2)
            {
                case LayerBlendSource.Current:
                    src2op = Gl.GL_PREVIOUS;
                    break;
                case LayerBlendSource.Texture:
                    src2op = Gl.GL_TEXTURE;
                    break;
                case LayerBlendSource.Manual:
                    src2op = Gl.GL_CONSTANT;
                    break;
                case LayerBlendSource.Diffuse:
                    src2op = Gl.GL_PRIMARY_COLOR;
                    break;
                // XXX
                case LayerBlendSource.Specular:
                    src2op = Gl.GL_PRIMARY_COLOR;
                    break;
                default:
                    src2op = 0;
                    break;
            }

            switch (bm.operation)
            {
                case LayerBlendOperationEx.Source1:
                    cmd = Gl.GL_REPLACE;
                    break;
                case LayerBlendOperationEx.Source2:
                    cmd = Gl.GL_REPLACE;
                    break;
                case LayerBlendOperationEx.Modulate:
                    cmd = Gl.GL_MODULATE;
                    break;
                case LayerBlendOperationEx.ModulateX2:
                    cmd = Gl.GL_MODULATE;
                    break;
                case LayerBlendOperationEx.ModulateX4:
                    cmd = Gl.GL_MODULATE;
                    break;
                case LayerBlendOperationEx.Add:
                    cmd = Gl.GL_ADD;
                    break;
                case LayerBlendOperationEx.AddSigned:
                    cmd = Gl.GL_ADD_SIGNED;
                    break;
                case LayerBlendOperationEx.AddSmooth:
                    cmd = Gl.GL_INTERPOLATE;
                    break;
                case LayerBlendOperationEx.Subtract:
                    cmd = Gl.GL_SUBTRACT;
                    break;
                case LayerBlendOperationEx.BlendDiffuseColor:
                    cmd = Gl.GL_INTERPOLATE;
                    break;
                case LayerBlendOperationEx.BlendDiffuseAlpha:
                    cmd = Gl.GL_INTERPOLATE;
                    break;
                case LayerBlendOperationEx.BlendTextureAlpha:
                    cmd = Gl.GL_INTERPOLATE;
                    break;
                case LayerBlendOperationEx.BlendCurrentAlpha:
                    cmd = Gl.GL_INTERPOLATE;
                    break;
                case LayerBlendOperationEx.BlendManual:
                    cmd = Gl.GL_INTERPOLATE;
                    break;
                case LayerBlendOperationEx.DotProduct:
                    cmd = currentCapabilities.HasCapability(Graphics.Capabilities.Dot3)
                        ? Gl.GL_DOT3_RGB : Gl.GL_MODULATE;
                    break;
                default:
                    cmd = 0;
                    break;
            }

            if (!ActivateGLTextureUnit(stage))
                return;
            Gl.glTexEnvi(Gl.GL_TEXTURE_ENV, Gl.GL_TEXTURE_ENV_MODE, Gl.GL_COMBINE);

            if (bm.blendType == LayerBlendType.Color)
            {
                Gl.glTexEnvi(Gl.GL_TEXTURE_ENV, Gl.GL_COMBINE_RGB, cmd);
                Gl.glTexEnvi(Gl.GL_TEXTURE_ENV, Gl.GL_SOURCE0_RGB, src1op);
                Gl.glTexEnvi(Gl.GL_TEXTURE_ENV, Gl.GL_SOURCE1_RGB, src2op);
                Gl.glTexEnvi(Gl.GL_TEXTURE_ENV, Gl.GL_SOURCE2_RGB, Gl.GL_CONSTANT);
            }
            else
            {
                Gl.glTexEnvi(Gl.GL_TEXTURE_ENV, Gl.GL_COMBINE_ALPHA, cmd);
                Gl.glTexEnvi(Gl.GL_TEXTURE_ENV, Gl.GL_SOURCE0_ALPHA, src1op);
                Gl.glTexEnvi(Gl.GL_TEXTURE_ENV, Gl.GL_SOURCE1_ALPHA, src2op);
                Gl.glTexEnvi(Gl.GL_TEXTURE_ENV, Gl.GL_SOURCE2_ALPHA, Gl.GL_CONSTANT);
            }

            switch (bm.operation)
            {
                case LayerBlendOperationEx.BlendDiffuseColor:
                    Gl.glTexEnvi(Gl.GL_TEXTURE_ENV, Gl.GL_SOURCE2_RGB, Gl.GL_PRIMARY_COLOR);
                    Gl.glTexEnvi(Gl.GL_TEXTURE_ENV, Gl.GL_SOURCE2_ALPHA, Gl.GL_PRIMARY_COLOR);
                    break;
                case LayerBlendOperationEx.BlendDiffuseAlpha:
                    Gl.glTexEnvi(Gl.GL_TEXTURE_ENV, Gl.GL_SOURCE2_RGB, Gl.GL_PRIMARY_COLOR);
                    Gl.glTexEnvi(Gl.GL_TEXTURE_ENV, Gl.GL_SOURCE2_ALPHA, Gl.GL_PRIMARY_COLOR);
                    break;
                case LayerBlendOperationEx.BlendTextureAlpha:
                    Gl.glTexEnvi(Gl.GL_TEXTURE_ENV, Gl.GL_SOURCE2_RGB, Gl.GL_TEXTURE);
                    Gl.glTexEnvi(Gl.GL_TEXTURE_ENV, Gl.GL_SOURCE2_ALPHA, Gl.GL_TEXTURE);
                    break;
                case LayerBlendOperationEx.BlendCurrentAlpha:
                    Gl.glTexEnvi(Gl.GL_TEXTURE_ENV, Gl.GL_SOURCE2_RGB, Gl.GL_PREVIOUS);
                    Gl.glTexEnvi(Gl.GL_TEXTURE_ENV, Gl.GL_SOURCE2_ALPHA, Gl.GL_PREVIOUS);
                    break;
                case LayerBlendOperationEx.BlendManual:
                    var blendValue = _tempProgramFloats;
		            blendValue[ 0 ] = 0.0f;
		            blendValue[ 1 ] = 0.0f;
		            blendValue[ 2 ] = 0.0f;
		            blendValue[ 3 ] = bm.blendFactor;
                    Gl.glTexEnvfv(Gl.GL_TEXTURE_ENV, Gl.GL_TEXTURE_ENV_COLOR, blendValue);
                    break;
                default:
                    break;
            }

            switch (bm.operation)
            {
                case LayerBlendOperationEx.ModulateX2:
                    Gl.glTexEnvi( Gl.GL_TEXTURE_ENV, bm.blendType == LayerBlendType.Color
                                                         ? Gl.GL_RGB_SCALE
                                                         : Gl.GL_ALPHA_SCALE, 2 );
                    break;
                case LayerBlendOperationEx.ModulateX4:
                    Gl.glTexEnvi( Gl.GL_TEXTURE_ENV, bm.blendType == LayerBlendType.Color
                                                         ? Gl.GL_RGB_SCALE
                                                         : Gl.GL_ALPHA_SCALE, 4 );
                    break;
                default:
                    Gl.glTexEnvi( Gl.GL_TEXTURE_ENV, bm.blendType == LayerBlendType.Color
                                                         ? Gl.GL_RGB_SCALE
                                                         : Gl.GL_ALPHA_SCALE, 1 );
                    break;
            }

            if (bm.blendType == LayerBlendType.Color)
            {
                Gl.glTexEnvi(Gl.GL_TEXTURE_ENV, Gl.GL_OPERAND0_RGB, Gl.GL_SRC_COLOR);
                Gl.glTexEnvi(Gl.GL_TEXTURE_ENV, Gl.GL_OPERAND1_RGB, Gl.GL_SRC_COLOR);
                if (bm.operation == LayerBlendOperationEx.BlendDiffuseColor)
                {
                    Gl.glTexEnvi(Gl.GL_TEXTURE_ENV, Gl.GL_OPERAND2_RGB, Gl.GL_SRC_COLOR);
                }
                else
                {
                    Gl.glTexEnvi(Gl.GL_TEXTURE_ENV, Gl.GL_OPERAND2_RGB, Gl.GL_SRC_ALPHA);
                }
            }

            Gl.glTexEnvi(Gl.GL_TEXTURE_ENV, Gl.GL_OPERAND0_ALPHA, Gl.GL_SRC_ALPHA);
            Gl.glTexEnvi(Gl.GL_TEXTURE_ENV, Gl.GL_OPERAND1_ALPHA, Gl.GL_SRC_ALPHA);
            Gl.glTexEnvi(Gl.GL_TEXTURE_ENV, Gl.GL_OPERAND2_ALPHA, Gl.GL_SRC_ALPHA);
            if (bm.source1 == LayerBlendSource.Manual)
                Gl.glTexEnvfv(Gl.GL_TEXTURE_ENV, Gl.GL_TEXTURE_ENV_COLOR, cv1);
            if (bm.source2 == LayerBlendSource.Manual)
                Gl.glTexEnvfv(Gl.GL_TEXTURE_ENV, Gl.GL_TEXTURE_ENV_COLOR, cv2);

            ActivateGLTextureUnit(0);
		}
        /// <summary>
        /// 
        /// </summary>
        /// <param name="stage"></param>
        /// <param name="blendMode"></param>
        public override void SetTextureBlendMode(int stage, LayerBlendModeEx blendMode)
        {
            if(!caps.CheckCap(Capabilities.TextureBlending)) {
                return;
            }

            LayerBlendOperationEx lastOp;

            if(blendMode.blendType == LayerBlendType.Alpha) {
                lastOp = lastAlphaOp[stage];
            }
            else {
                lastOp = lastColorOp[stage];
            }

            // ignore the new blend mode only if the last one for the current texture stage
            // is the same, and if no special texture coord calcs are required
            if( lastOp == blendMode.operation &&
                lastTexCalMethods[stage] == TexCoordCalcMethod.None)  {
                //return;
            }

            // remember last setting
            if(blendMode.blendType == LayerBlendType.Alpha) {
                lastAlphaOp[stage] = blendMode.operation;
            }
            else {
                lastColorOp[stage] = blendMode.operation;
            }

            int src1op, src2op, cmd;

            src1op = src2op = cmd = 0;

            switch(blendMode.source1) {
                case LayerBlendSource.Current:
                    src1op = Gl.GL_PREVIOUS;
                    break;

                case LayerBlendSource.Texture:
                    src1op = Gl.GL_TEXTURE;
                    break;

                case LayerBlendSource.Manual:
                    src1op = Gl.GL_CONSTANT;
                    break;

                case LayerBlendSource.Diffuse:
                    src1op = Gl.GL_PRIMARY_COLOR;
                    break;

                    // no diffuse or specular equivalent right now
                default:
                    src1op = 0;
                    break;
            }

            switch(blendMode.source2) {
                case LayerBlendSource.Current:
                    src2op = Gl.GL_PREVIOUS;
                    break;

                case LayerBlendSource.Texture:
                    src2op = Gl.GL_TEXTURE;
                    break;

                case LayerBlendSource.Manual:
                    src2op = Gl.GL_CONSTANT;
                    break;

                case LayerBlendSource.Diffuse:
                    src2op = Gl.GL_PRIMARY_COLOR;
                    break;

                    // no diffuse or specular equivalent right now
                default:
                    src2op = 0;
                    break;
            }

            switch (blendMode.operation) {
                case LayerBlendOperationEx.Source1:
                    cmd = Gl.GL_REPLACE;
                    break;

                case LayerBlendOperationEx.Source2:
                    cmd = Gl.GL_REPLACE;
                    break;

                case LayerBlendOperationEx.Modulate:
                    cmd = Gl.GL_MODULATE;
                    break;

                case LayerBlendOperationEx.ModulateX2:
                    cmd = Gl.GL_MODULATE;
                    break;

                case LayerBlendOperationEx.ModulateX4:
                    cmd = Gl.GL_MODULATE;
                    break;

                case LayerBlendOperationEx.Add:
                    cmd = Gl.GL_ADD;
                    break;

                case LayerBlendOperationEx.AddSigned:
                    cmd = Gl.GL_ADD_SIGNED;
                    break;

                case LayerBlendOperationEx.Subtract:
                    cmd = Gl.GL_SUBTRACT;
                    break;

                case LayerBlendOperationEx.BlendDiffuseAlpha:
                    cmd = Gl.GL_INTERPOLATE;
                    break;

                case LayerBlendOperationEx.BlendTextureAlpha:
                    cmd = Gl.GL_INTERPOLATE;
                    break;

                case LayerBlendOperationEx.BlendCurrentAlpha:
                    cmd = Gl.GL_INTERPOLATE;
                    break;

                case LayerBlendOperationEx.BlendManual:
                    cmd = Gl.GL_INTERPOLATE;
                    break;

                case LayerBlendOperationEx.DotProduct:
                    // Check for Dot3 support
                    cmd = caps.CheckCap(Capabilities.Dot3) ? Gl.GL_DOT3_RGB : Gl.GL_MODULATE;
                    break;

                default:
                    cmd = 0;
                    break;
            } // end switch

            Gl.glActiveTextureARB(Gl.GL_TEXTURE0 + stage);
            Gl.glTexEnvi(Gl.GL_TEXTURE_ENV, Gl.GL_TEXTURE_ENV_MODE, Gl.GL_COMBINE);

            if (blendMode.blendType == LayerBlendType.Color) {
                Gl.glTexEnvi(Gl.GL_TEXTURE_ENV, Gl.GL_COMBINE_RGB, cmd);
                Gl.glTexEnvi(Gl.GL_TEXTURE_ENV, Gl.GL_SOURCE0_RGB, src1op);
                Gl.glTexEnvi(Gl.GL_TEXTURE_ENV, Gl.GL_SOURCE1_RGB, src2op);
                Gl.glTexEnvi(Gl.GL_TEXTURE_ENV, Gl.GL_SOURCE2_RGB, Gl.GL_CONSTANT);
            }
            else {
                Gl.glTexEnvi(Gl.GL_TEXTURE_ENV, Gl.GL_COMBINE_ALPHA, cmd);
                Gl.glTexEnvi(Gl.GL_TEXTURE_ENV, Gl.GL_SOURCE0_ALPHA, src1op);
                Gl.glTexEnvi(Gl.GL_TEXTURE_ENV, Gl.GL_SOURCE1_ALPHA, src2op);
                Gl.glTexEnvi(Gl.GL_TEXTURE_ENV, Gl.GL_SOURCE2_ALPHA, Gl.GL_CONSTANT);
            }

            // handle blend types first
            switch (blendMode.operation) {
                case LayerBlendOperationEx.BlendDiffuseAlpha:
                    Gl.glTexEnvi(Gl.GL_TEXTURE_ENV, Gl.GL_SOURCE2_RGB, Gl.GL_PRIMARY_COLOR);
                    Gl.glTexEnvi(Gl.GL_TEXTURE_ENV, Gl.GL_SOURCE2_ALPHA, Gl.GL_PRIMARY_COLOR);
                    break;

                case LayerBlendOperationEx.BlendTextureAlpha:
                    Gl.glTexEnvi(Gl.GL_TEXTURE_ENV, Gl.GL_SOURCE2_RGB, Gl.GL_TEXTURE);
                    Gl.glTexEnvi(Gl.GL_TEXTURE_ENV, Gl.GL_SOURCE2_ALPHA, Gl.GL_TEXTURE);
                    break;

                case LayerBlendOperationEx.BlendCurrentAlpha:
                    Gl.glTexEnvi(Gl.GL_TEXTURE_ENV, Gl.GL_SOURCE2_RGB, Gl.GL_PREVIOUS);
                    Gl.glTexEnvi(Gl.GL_TEXTURE_ENV, Gl.GL_SOURCE2_ALPHA, Gl.GL_PREVIOUS);
                    break;

                case LayerBlendOperationEx.BlendManual:
                    tempColorVals[0] = 0; tempColorVals[1] = 0;
                    tempColorVals[2] = 0; tempColorVals[3] = blendMode.blendFactor;
                    Gl.glTexEnvfv(Gl.GL_TEXTURE_ENV, Gl.GL_TEXTURE_ENV_COLOR, tempColorVals);
                    break;

                default:
                    break;
            }

            // set alpha scale to 1 by default unless specifically requested to be higher
            // otherwise, textures that get switch from ModulateX2 or ModulateX4 down to Source1
            // for example, the alpha scale would still be high and overbrighten the texture
            switch (blendMode.operation) {
                case LayerBlendOperationEx.ModulateX2:
                    Gl.glTexEnvi(Gl.GL_TEXTURE_ENV, blendMode.blendType == LayerBlendType.Color ?
                        Gl.GL_RGB_SCALE : Gl.GL_ALPHA_SCALE, 2);
                    break;

                case LayerBlendOperationEx.ModulateX4:
                    Gl.glTexEnvi(Gl.GL_TEXTURE_ENV, blendMode.blendType == LayerBlendType.Color ?
                        Gl.GL_RGB_SCALE : Gl.GL_ALPHA_SCALE, 4);
                    break;

                default:
                    Gl.glTexEnvi(Gl.GL_TEXTURE_ENV, blendMode.blendType == LayerBlendType.Color ?
                        Gl.GL_RGB_SCALE : Gl.GL_ALPHA_SCALE, 1);
                    break;
            }

            Gl.glTexEnvi(Gl.GL_TEXTURE_ENV, Gl.GL_OPERAND0_RGB, Gl.GL_SRC_COLOR);
            Gl.glTexEnvi(Gl.GL_TEXTURE_ENV, Gl.GL_OPERAND1_RGB, Gl.GL_SRC_COLOR);
            Gl.glTexEnvi(Gl.GL_TEXTURE_ENV, Gl.GL_OPERAND2_RGB, Gl.GL_SRC_ALPHA);
            Gl.glTexEnvi(Gl.GL_TEXTURE_ENV, Gl.GL_OPERAND0_ALPHA, Gl.GL_SRC_ALPHA);
            Gl.glTexEnvi(Gl.GL_TEXTURE_ENV, Gl.GL_OPERAND1_ALPHA, Gl.GL_SRC_ALPHA);
            Gl.glTexEnvi(Gl.GL_TEXTURE_ENV, Gl.GL_OPERAND2_ALPHA, Gl.GL_SRC_ALPHA);

            // check source1 and set colors values appropriately
            if (blendMode.source1 == LayerBlendSource.Manual) {
                if(blendMode.blendType == LayerBlendType.Color) {
                    // color value 1
                    blendMode.colorArg1.ToArrayRGBA(tempColorVals);
                }
                else {
                    // alpha value 1
                    tempColorVals[0] = 0.0f; tempColorVals[1] = 0.0f; tempColorVals[2] = 0.0f; tempColorVals[3] = blendMode.alphaArg1;
                }

                Gl.glTexEnvfv(Gl.GL_TEXTURE_ENV, Gl.GL_TEXTURE_ENV_COLOR, tempColorVals);
            }

            // check source2 and set colors values appropriately
            if (blendMode.source2 == LayerBlendSource.Manual) {
                if(blendMode.blendType == LayerBlendType.Color) {
                    // color value 2
                    blendMode.colorArg2.ToArrayRGBA(tempColorVals);
                }
                else {
                    // alpha value 2
                    tempColorVals[0] = 0.0f; tempColorVals[1] = 0.0f; tempColorVals[2] = 0.0f; tempColorVals[3] = blendMode.alphaArg2;
                }

                Gl.glTexEnvfv(Gl.GL_TEXTURE_ENV, Gl.GL_TEXTURE_ENV_COLOR, tempColorVals);
            }

            Gl.glActiveTextureARB(Gl.GL_TEXTURE0);
        }
Ejemplo n.º 9
0
		protected virtual void AddPSBlendInvocations( Function psMain, Parameter arg1, Parameter arg2, Parameter texel,
		                                              int samplerIndex, LayerBlendModeEx blendMode,
		                                              int groupOrder, ref int internalCounter, int targetChannels )
		{
			FunctionInvocation curFuncInvocation = null;

			switch ( blendMode.operation )
			{
				case LayerBlendOperationEx.Add:
					curFuncInvocation = new FunctionInvocation( FFPRenderState.FFPFuncAdd, groupOrder, internalCounter++ );
					curFuncInvocation.PushOperand( arg1, Operand.OpSemantic.In, targetChannels );
					curFuncInvocation.PushOperand( arg2, Operand.OpSemantic.In, targetChannels );
					curFuncInvocation.PushOperand( this.psOutDiffuse, Operand.OpSemantic.Out, targetChannels );
					psMain.AddAtomInstance( curFuncInvocation );
					break;
				case LayerBlendOperationEx.AddSigned:
					curFuncInvocation = new FunctionInvocation( FFPRenderState.FFPFuncAddSigned, groupOrder,
					                                            internalCounter++ );
					curFuncInvocation.PushOperand( arg1, Operand.OpSemantic.In, targetChannels );
					curFuncInvocation.PushOperand( arg2, Operand.OpSemantic.In, targetChannels );
					curFuncInvocation.PushOperand( this.psOutDiffuse, Operand.OpSemantic.Out, targetChannels );
					psMain.AddAtomInstance( curFuncInvocation );
					break;
				case LayerBlendOperationEx.AddSmooth:
					curFuncInvocation = new FunctionInvocation( FFPRenderState.FFPFuncAddSmooth, groupOrder,
					                                            internalCounter++ );
					curFuncInvocation.PushOperand( arg1, Operand.OpSemantic.In, targetChannels );
					curFuncInvocation.PushOperand( arg2, Operand.OpSemantic.In, targetChannels );
					curFuncInvocation.PushOperand( this.psOutDiffuse, Operand.OpSemantic.Out, targetChannels );
					psMain.AddAtomInstance( curFuncInvocation );
					break;
				case LayerBlendOperationEx.BlendCurrentAlpha:
					curFuncInvocation = new FunctionInvocation( FFPRenderState.FFPFuncLerp, groupOrder,
					                                            internalCounter++ );
					curFuncInvocation.PushOperand( arg2, Operand.OpSemantic.In, targetChannels );
					curFuncInvocation.PushOperand( arg1, Operand.OpSemantic.In, targetChannels );

					if ( samplerIndex == 0 )
					{
						curFuncInvocation.PushOperand( this.psDiffuse, Operand.OpSemantic.In, Operand.OpMask.W );
					}
					else
					{
						curFuncInvocation.PushOperand( this.psOutDiffuse, Operand.OpSemantic.In, Operand.OpMask.W );
					}
					curFuncInvocation.PushOperand( this.psOutDiffuse, Operand.OpSemantic.Out, targetChannels );
					psMain.AddAtomInstance( curFuncInvocation );
					break;
				case LayerBlendOperationEx.BlendDiffuseAlpha:
					curFuncInvocation = new FunctionInvocation( FFPRenderState.FFPFuncSubtract, groupOrder,
					                                            internalCounter++ );
					curFuncInvocation.PushOperand( arg1, Operand.OpSemantic.In, targetChannels );
					curFuncInvocation.PushOperand( arg2, Operand.OpSemantic.In, targetChannels );
					curFuncInvocation.PushOperand( this.psDiffuse, Operand.OpSemantic.In, Operand.OpMask.W );
					curFuncInvocation.PushOperand( this.psOutDiffuse, Operand.OpSemantic.Out, targetChannels );
					psMain.AddAtomInstance( curFuncInvocation );
					break;
				case LayerBlendOperationEx.BlendDiffuseColor:
					curFuncInvocation = new FunctionInvocation( FFPRenderState.FFPFuncLerp, groupOrder,
					                                            internalCounter++ );
					curFuncInvocation.PushOperand( arg2, Operand.OpSemantic.In, targetChannels );
					curFuncInvocation.PushOperand( arg1, Operand.OpSemantic.In, targetChannels );
					curFuncInvocation.PushOperand( this.psDiffuse, Operand.OpSemantic.In );
					curFuncInvocation.PushOperand( this.psOutDiffuse, Operand.OpSemantic.Out, targetChannels );
					psMain.AddAtomInstance( curFuncInvocation );
					break;
				case LayerBlendOperationEx.BlendManual:
					curFuncInvocation = new FunctionInvocation( FFPRenderState.FFPFuncLerp, groupOrder, internalCounter );
					curFuncInvocation.PushOperand( arg2, Operand.OpSemantic.In, targetChannels );
					curFuncInvocation.PushOperand( arg1, Operand.OpSemantic.In, targetChannels );
					curFuncInvocation.PushOperand( ParameterFactory.CreateConstParamFloat( blendMode.blendFactor ),
					                               Operand.OpSemantic.In );
					curFuncInvocation.PushOperand( this.psOutDiffuse, Operand.OpSemantic.Out, targetChannels );
					psMain.AddAtomInstance( curFuncInvocation );
					break;
				case LayerBlendOperationEx.BlendTextureAlpha:
					curFuncInvocation = new FunctionInvocation( FFPRenderState.FFPFuncLerp, groupOrder,
					                                            internalCounter++ );
					curFuncInvocation.PushOperand( arg1, Operand.OpSemantic.In, targetChannels );
					curFuncInvocation.PushOperand( arg2, Operand.OpSemantic.In, targetChannels );
					curFuncInvocation.PushOperand( texel, Operand.OpSemantic.In, Operand.OpMask.W );
					curFuncInvocation.PushOperand( this.psOutDiffuse, Operand.OpSemantic.Out, targetChannels );
					psMain.AddAtomInstance( curFuncInvocation );
					break;
				case LayerBlendOperationEx.DotProduct:
					curFuncInvocation = new FunctionInvocation( FFPRenderState.FFPFuncDotProduct, groupOrder,
					                                            internalCounter++ );
					curFuncInvocation.PushOperand( arg2, Operand.OpSemantic.In, targetChannels );
					curFuncInvocation.PushOperand( arg1, Operand.OpSemantic.In, targetChannels );
					curFuncInvocation.PushOperand( this.psOutDiffuse, Operand.OpSemantic.Out, targetChannels );
					psMain.AddAtomInstance( curFuncInvocation );
					break;
				case LayerBlendOperationEx.Modulate:
					curFuncInvocation = new FunctionInvocation( FFPRenderState.FFPFuncModulate, groupOrder,
					                                            internalCounter++ );
					curFuncInvocation.PushOperand( arg1, Operand.OpSemantic.In, targetChannels );
					curFuncInvocation.PushOperand( arg2, Operand.OpSemantic.In, targetChannels );
					curFuncInvocation.PushOperand( this.psOutDiffuse, Operand.OpSemantic.Out, targetChannels );
					psMain.AddAtomInstance( curFuncInvocation );
					break;
				case LayerBlendOperationEx.ModulateX2:
					curFuncInvocation = new FunctionInvocation( FFPRenderState.FFPFuncModulateX2, groupOrder,
					                                            internalCounter );
					curFuncInvocation.PushOperand( arg1, Operand.OpSemantic.In, targetChannels );
					curFuncInvocation.PushOperand( arg2, Operand.OpSemantic.In, targetChannels );
					curFuncInvocation.PushOperand( this.psOutDiffuse, Operand.OpSemantic.Out, targetChannels );
					psMain.AddAtomInstance( curFuncInvocation );
					break;
				case LayerBlendOperationEx.ModulateX4:
					curFuncInvocation = new FunctionInvocation( FFPRenderState.FFPFuncModulateX4, groupOrder,
					                                            internalCounter );
					curFuncInvocation.PushOperand( arg1, Operand.OpSemantic.In, targetChannels );
					curFuncInvocation.PushOperand( arg2, Operand.OpSemantic.In, targetChannels );
					curFuncInvocation.PushOperand( this.psOutDiffuse, Operand.OpSemantic.Out, targetChannels );
					psMain.AddAtomInstance( curFuncInvocation );
					break;
				case LayerBlendOperationEx.Source1:
					curFuncInvocation = new FunctionInvocation( FFPRenderState.FFPFuncAssign, groupOrder,
					                                            internalCounter++ );
					curFuncInvocation.PushOperand( arg1, Operand.OpSemantic.In, targetChannels );
					curFuncInvocation.PushOperand( this.psOutDiffuse, Operand.OpSemantic.Out, targetChannels );
					psMain.AddAtomInstance( curFuncInvocation );
					break;
				case LayerBlendOperationEx.Source2:
					curFuncInvocation = new FunctionInvocation( FFPRenderState.FFPFuncAssign, groupOrder,
					                                            internalCounter++ );
					curFuncInvocation.PushOperand( arg2, Operand.OpSemantic.In, targetChannels );
					curFuncInvocation.PushOperand( this.psOutDiffuse, Operand.OpSemantic.Out, targetChannels );
					psMain.AddAtomInstance( curFuncInvocation );
					break;
				case LayerBlendOperationEx.Subtract:
					curFuncInvocation = new FunctionInvocation( FFPRenderState.FFPFuncSubtract, groupOrder,
					                                            internalCounter++ );
					curFuncInvocation.PushOperand( arg1, Operand.OpSemantic.In, targetChannels );
					curFuncInvocation.PushOperand( arg2, Operand.OpSemantic.In, targetChannels );
					curFuncInvocation.PushOperand( this.psOutDiffuse, Operand.OpSemantic.Out, targetChannels );
					psMain.AddAtomInstance( curFuncInvocation );
					break;
			}
		}
Ejemplo n.º 10
0
		private static void RenderSystem_Setup()
		{
			Axiom.Graphics.RenderSystem rs = Root.Instance.RenderSystem;

			var colorBlendMode = new LayerBlendModeEx();
			colorBlendMode.blendType = LayerBlendType.Color;
			colorBlendMode.source1 = LayerBlendSource.Texture;
			colorBlendMode.operation = LayerBlendOperationEx.Source1;

			var uvwAddressMode = new UVWAddressing( TextureAddressing.Clamp );

			rs.WorldMatrix = Matrix4.Identity;
			rs.ViewMatrix = Matrix4.Identity;
			rs.ProjectionMatrix = Matrix4.Identity;
			rs.SetTextureMatrix( 0, Matrix4.Identity );
			rs.SetTextureCoordSet( 0, 0 );
			rs.SetTextureCoordCalculation( 0, TexCoordCalcMethod.None );
			rs.SetTextureBlendMode( 0, colorBlendMode );
			rs.SetTextureAddressingMode( 0, uvwAddressMode );
			rs.DisableTextureUnitsFrom( 1 );
			rs.LightingEnabled = false;
			rs.SetFog( FogMode.None );
			rs.CullingMode = CullingMode.None;
			rs.SetDepthBufferParams( false, false );
			rs.SetColorBufferWriteEnabled( true, true, true, false );
			rs.ShadingType = ShadeOptions.Gouraud;
			rs.PolygonMode = PolygonMode.Solid;
			rs.UnbindGpuProgram( GpuProgramType.Fragment );
			rs.UnbindGpuProgram( GpuProgramType.Vertex );
			rs.SetSeparateSceneBlending( SceneBlendFactor.SourceAlpha, SceneBlendFactor.OneMinusSourceAlpha, SceneBlendFactor.One,
			                             SceneBlendFactor.One );
			rs.SetAlphaRejectSettings( CompareFunction.AlwaysPass, 0, true );
		}
Ejemplo n.º 11
0
		private static void Render()
		{
			if ( sprites.Count == 0 )
			{
				return;
			}

			Axiom.Graphics.RenderSystem rs = Root.Instance.RenderSystem;

			var thisChunk = new Chunk();
			var chunks = new List<Chunk>();

			int newSize;

			newSize = sprites.Count*6;
			if ( newSize < MinimalHardwareBufferSize )
			{
				newSize = MinimalHardwareBufferSize;
			}

			// grow hardware buffer if needed
			if ( hardwareBuffer == null || hardwareBuffer.VertexCount < newSize )
			{
				if ( hardwareBuffer != null )
				{
					HardwareBuffer_Destroy();
				}

				HardwareBuffer_Create( newSize );
			}

			// write quads to the hardware buffer, and remember chunks
			unsafe
			{
				var buffer = (Vertex*)hardwareBuffer.Lock( BufferLocking.Discard ).Pin();

				LinkedListNode<Sprite> node = sprites.First;
				Sprite currSpr;

				while ( node != null )
				{
					currSpr = node.Value;
					thisChunk.Alpha = currSpr.Alpha;
					thisChunk.TexHandle = currSpr.TexHandle;

					for ( int i = 0; i < 6; i++ )
					{
						*buffer++ = new Vertex( currSpr.Pos[ i ], currSpr.UV[ i ] );
					}

					thisChunk.VertexCount += 6;

					node = node.Next;

					if ( node == null || thisChunk.TexHandle != node.Value.TexHandle || thisChunk.Alpha != node.Value.Alpha )
					{
						chunks.Add( thisChunk );
						thisChunk.VertexCount = 0;
					}
				}
			}

			hardwareBuffer.Unlock();

			// set up...
			RenderSystem_Setup();

			// do the real render!
			// do the real render!
			Texture tp = null;
			renderOp.vertexData.vertexStart = 0;
			foreach ( Chunk currChunk in chunks )
			{
				renderOp.vertexData.vertexCount = currChunk.VertexCount;
				tp = (Texture)TextureManager.Instance.GetByHandle( currChunk.TexHandle );
				rs.SetTexture( 0, true, tp.Name );
				rs.SetTextureUnitFiltering( 0, FilterOptions.Linear, FilterOptions.Linear, FilterOptions.Point );

				// set alpha
				var alphaBlendMode = new LayerBlendModeEx();
				alphaBlendMode.alphaArg1 = 0;
				alphaBlendMode.alphaArg2 = currChunk.Alpha;
				alphaBlendMode.source1 = LayerBlendSource.Texture;
				alphaBlendMode.source2 = LayerBlendSource.Manual;
				alphaBlendMode.blendType = LayerBlendType.Alpha;
				alphaBlendMode.operation = LayerBlendOperationEx.Modulate;
				alphaBlendMode.blendFactor = currChunk.Alpha;
				rs.SetTextureBlendMode( 0, alphaBlendMode );

				rs.Render( renderOp );
				renderOp.vertexData.vertexStart += currChunk.VertexCount;
			}

			if ( tp != null )
			{
				tp.Dispose();
			}

			// sprites go home!
			sprites.Clear();
		}
        /// <summary>
        ///		Renders the static level geometry tagged in <see cref="Plugin_BSPSceneManager.BspSceneManager.WalkTree"/>.
        /// </summary>
        protected void RenderStaticGeometry()
        {
            // no world transform required
            targetRenderSystem.WorldMatrix = Matrix4.Identity;

            // Set view / proj
            targetRenderSystem.ViewMatrix = camInProgress.ViewMatrix;
            targetRenderSystem.ProjectionMatrix = camInProgress.ProjectionMatrix;

            ColorEx bspAmbient = null;

            if (level.BspOptions.ambientEnabled)
            {
                bspAmbient = new ColorEx(ambientColor.r * level.BspOptions.ambientRatio,
                    ambientColor.g * level.BspOptions.ambientRatio,
                    ambientColor.b * level.BspOptions.ambientRatio);
            }

            LayerBlendModeEx ambientBlend = new LayerBlendModeEx();
            ambientBlend.blendType = LayerBlendType.Color;
            ambientBlend.operation = LayerBlendOperationEx.Modulate;
            ambientBlend.source1 = LayerBlendSource.Texture;
            ambientBlend.source2 = LayerBlendSource.Manual;
            ambientBlend.colorArg2 = bspAmbient;

            // For each material in turn, cache rendering data & render
            IEnumerator mapEnu = matFaceGroupMap.buckets.Keys.GetEnumerator();

            bool passIsSet = false;

            while(mapEnu.MoveNext())
            {
                // Get Material
                Material thisMaterial = (Material) mapEnu.Current;
                BspStaticFaceGroup[] faceGrp = (BspStaticFaceGroup[]) ((ArrayList) matFaceGroupMap.buckets[thisMaterial]).ToArray(typeof(BspStaticFaceGroup));

                // if one face group is a quake shader then the material is a quake shader
                bool isQuakeShader = faceGrp[0].isQuakeShader;

                // Empty existing cache
                renderOp.indexData.indexCount = 0;

                // lock index buffer ready to receive data
                unsafe
                {
                    uint *pIdx = (uint *) renderOp.indexData.indexBuffer.Lock(BufferLocking.Discard);

                    for(int i = 0; i < faceGrp.Length; i++)
                    {
                        // Cache each
                        int numElems = CacheGeometry((IntPtr) pIdx, faceGrp[i]);
                        renderOp.indexData.indexCount += numElems;
                        pIdx += numElems;
                    }

                    // Unlock the buffer
                    renderOp.indexData.indexBuffer.Unlock();
                }

                // Skip if no faces to process (we're not doing flare types yet)
                if(renderOp.indexData.indexCount == 0)
                    continue;

                if (isQuakeShader)
                {
                    for(int i = 0; i < thisMaterial.GetTechnique(0).NumPasses; i++)
                    {
                        SetPass(thisMaterial.GetTechnique(0).GetPass(i));
                        targetRenderSystem.Render(renderOp);
                    }
                    passIsSet = false;
                }
                else if (!passIsSet)
                {
                    int i;
                    for(i = 0; i < thisMaterial.GetTechnique(0).NumPasses; i++)
                    {
                        SetPass(thisMaterial.GetTechnique(0).GetPass(i));

                        // for ambient lighting
                        if (i == 0 && level.BspOptions.ambientEnabled)
                        {
                            targetRenderSystem.SetTextureBlendMode(0, ambientBlend);
                        }

                        targetRenderSystem.Render(renderOp);
                    }

                    // if it's only 1 pass then there's no need to set it again
                    passIsSet = (i > 1) ? false : true;
                }
                else
                {
                    Pass pass = thisMaterial.GetTechnique(0).GetPass(0);
                    // Get the plain geometry texture
                    TextureUnitState geometryTex = pass.GetTextureUnitState(0);
                    targetRenderSystem.SetTexture(0, true, geometryTex.TextureName);

                    if (pass.NumTextureUnitStages > 1)
                    {
                        // Get the lightmap
                        TextureUnitState lightmapTex = pass.GetTextureUnitState(1);
                        targetRenderSystem.SetTexture(1, true, lightmapTex.TextureName);
                    }

                    targetRenderSystem.Render(renderOp);
                }
            }

            //if(showNodeAABs)
            //	targetRenderSystem.Render(aaBGeometry);
        }