/// <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); }
public override void SetTextureBlendMode( int unit, LayerBlendModeEx bm ) { //Ogre: not supported }
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);
///// <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; } } }
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); }
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; } }
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 ); }
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); }