diff --git a/Source/BuilderModes/VisualModes/BaseVisualMode.cs b/Source/BuilderModes/VisualModes/BaseVisualMode.cs index 934791de..b245624a 100644 --- a/Source/BuilderModes/VisualModes/BaseVisualMode.cs +++ b/Source/BuilderModes/VisualModes/BaseVisualMode.cs @@ -49,7 +49,7 @@ namespace CodeImp.DoomBuilder.BuilderModes #region ================== Constants // Object picking - private const double PICK_INTERVAL = 100.0d; + private const double PICK_INTERVAL = 80.0d; private const float PICK_RANGE = 0.98f; // Gravity @@ -265,6 +265,9 @@ namespace CodeImp.DoomBuilder.BuilderModes { // Use fog! renderer.SetFogMode(true); + + // Set target for highlighting + renderer.SetHighlightedObject(target.picked); // Begin with geometry renderer.StartGeometry(); diff --git a/Source/Rendering/IRenderer3D.cs b/Source/Rendering/IRenderer3D.cs index f13ba1b4..9da503a5 100644 --- a/Source/Rendering/IRenderer3D.cs +++ b/Source/Rendering/IRenderer3D.cs @@ -56,6 +56,7 @@ namespace CodeImp.DoomBuilder.Rendering void FinishGeometry(); // Rendering methods + void SetHighlightedObject(IVisualPickable obj); void AddSectorGeometry(VisualGeometry g); void AddThingGeometry(VisualThing t); void RenderCrosshair(); diff --git a/Source/Rendering/Renderer3D.cs b/Source/Rendering/Renderer3D.cs index 6dda9b53..29bbe4ba 100644 --- a/Source/Rendering/Renderer3D.cs +++ b/Source/Rendering/Renderer3D.cs @@ -76,6 +76,10 @@ namespace CodeImp.DoomBuilder.Rendering // Crosshair private FlatVertex[] crosshairverts; private bool crosshairbusy; + + // Highlighting + private IVisualPickable highlighted; + private float highlightglow; // Geometry to be rendered. // Each Dictionary in the array is a render pass. @@ -376,11 +380,16 @@ namespace CodeImp.DoomBuilder.Rendering graphics.Device.SetRenderState(RenderState.RangeFogEnable, false); graphics.Device.SetRenderState(RenderState.TextureFactor, -1); graphics.Shaders.World3D.SetModulateColor(-1); + graphics.Shaders.World3D.SetHighlightColor(0); // Matrices world = Matrix.Identity; ApplyMatrices3D(); + // Highlight + double time = General.Clock.GetCurrentTime(); + highlightglow = (float)Math.Sin(time / 100.0f) * 0.3f + 0.5f; + // Determine shader pass to use if(fullbrightness) shaderpass = 1; else shaderpass = 0; @@ -427,17 +436,13 @@ namespace CodeImp.DoomBuilder.Rendering // SOLID PASS world = Matrix.Identity; ApplyMatrices3D(); - graphics.Shaders.World3D.BeginPass(shaderpass); RenderSinglePass((int)RenderPass.Solid); - graphics.Shaders.World3D.EndPass(); // MASK PASS world = Matrix.Identity; ApplyMatrices3D(); graphics.Device.SetRenderState(RenderState.AlphaTestEnable, true); - graphics.Shaders.World3D.BeginPass(shaderpass); RenderSinglePass((int)RenderPass.Mask); - graphics.Shaders.World3D.EndPass(); // ALPHA PASS world = Matrix.Identity; @@ -447,9 +452,7 @@ namespace CodeImp.DoomBuilder.Rendering graphics.Device.SetRenderState(RenderState.ZWriteEnable, false); graphics.Device.SetRenderState(RenderState.SourceBlend, Blend.SourceAlpha); graphics.Device.SetRenderState(RenderState.DestinationBlend, Blend.InverseSourceAlpha); - graphics.Shaders.World3D.BeginPass(shaderpass); RenderSinglePass((int)RenderPass.Alpha); - graphics.Shaders.World3D.EndPass(); // THINGS if(renderthingcages) RenderThingCages(); @@ -458,9 +461,7 @@ namespace CodeImp.DoomBuilder.Rendering world = Matrix.Identity; ApplyMatrices3D(); graphics.Device.SetRenderState(RenderState.DestinationBlend, Blend.One); - graphics.Shaders.World3D.BeginPass(shaderpass); RenderSinglePass((int)RenderPass.Additive); - graphics.Shaders.World3D.EndPass(); // Remove references graphics.Shaders.World3D.Texture1 = null; @@ -510,6 +511,9 @@ namespace CodeImp.DoomBuilder.Rendering { // Get geometry for this pass Dictionary> geopass = geometry[pass]; + + // Begin rendering with this shader + graphics.Shaders.World3D.BeginPass(shaderpass); // Render the geometry collected foreach(KeyValuePair> group in geopass) @@ -558,10 +562,29 @@ namespace CodeImp.DoomBuilder.Rendering } } - // Render! if(sector != null) { + // Highlight this object? + if(g == highlighted) + { + // Temporarely switch shader and use a highlight color + graphics.Shaders.World3D.EndPass(); + Color4 highlight = General.Colors.Highlight.ToColorValue(); + highlight.Alpha = highlightglow; + graphics.Shaders.World3D.SetHighlightColor(highlight.ToArgb()); + graphics.Shaders.World3D.BeginPass(shaderpass + 2); + } + + // Render! graphics.Device.DrawPrimitives(PrimitiveType.TriangleList, g.VertexOffset, g.Triangles); + + // Reset highlight settings + if(g == highlighted) + { + graphics.Shaders.World3D.EndPass(); + graphics.Shaders.World3D.SetHighlightColor(0); + graphics.Shaders.World3D.BeginPass(shaderpass); + } } } } @@ -600,6 +623,17 @@ namespace CodeImp.DoomBuilder.Rendering // Only do this sector when a vertexbuffer is created if(t.GeometryBuffer != null) { + // Highlight this object? + if(t == highlighted) + { + // Temporarely switch shader and use a highlight color + graphics.Shaders.World3D.EndPass(); + Color4 highlight = General.Colors.Highlight.ToColorValue(); + highlight.Alpha = highlightglow; + graphics.Shaders.World3D.SetHighlightColor(highlight.ToArgb()); + graphics.Shaders.World3D.BeginPass(shaderpass + 2); + } + // Create the matrix for positioning / rotation world = t.Orientation; if(t.Billboard) world = Matrix.Multiply(world, billboard); @@ -612,10 +646,21 @@ namespace CodeImp.DoomBuilder.Rendering // Render! graphics.Device.DrawPrimitives(PrimitiveType.TriangleList, 0, t.Triangles); + + // Reset highlight settings + if(t == highlighted) + { + graphics.Shaders.World3D.EndPass(); + graphics.Shaders.World3D.SetHighlightColor(0); + graphics.Shaders.World3D.BeginPass(shaderpass); + } } } } } + + // Done rendering with this shader + graphics.Shaders.World3D.EndPass(); } // This finishes rendering @@ -624,12 +669,19 @@ namespace CodeImp.DoomBuilder.Rendering // Done graphics.FinishRendering(); graphics.Present(); + highlighted = null; } #endregion #region ================== Rendering + // This sets the highlighted object for the rendering + public void SetHighlightedObject(IVisualPickable obj) + { + highlighted = obj; + } + // This collects a visual sector's geometry for rendering public void AddSectorGeometry(VisualGeometry g) { diff --git a/Source/Rendering/World3DShader.cs b/Source/Rendering/World3DShader.cs index 473ef8ef..6cd3964b 100644 --- a/Source/Rendering/World3DShader.cs +++ b/Source/Rendering/World3DShader.cs @@ -46,6 +46,7 @@ namespace CodeImp.DoomBuilder.Rendering private EffectHandle minfiltersettings; private EffectHandle magfiltersettings; private EffectHandle modulatecolor; + private EffectHandle highlightcolor; #endregion @@ -72,6 +73,7 @@ namespace CodeImp.DoomBuilder.Rendering minfiltersettings = effect.GetParameter(null, "minfiltersettings"); magfiltersettings = effect.GetParameter(null, "magfiltersettings"); modulatecolor = effect.GetParameter(null, "modulatecolor"); + highlightcolor = effect.GetParameter(null, "highlightcolor"); } // Initialize world vertex declaration @@ -100,6 +102,7 @@ namespace CodeImp.DoomBuilder.Rendering if(minfiltersettings != null) minfiltersettings.Dispose(); if(magfiltersettings != null) magfiltersettings.Dispose(); if(modulatecolor != null) modulatecolor.Dispose(); + if(highlightcolor != null) highlightcolor.Dispose(); // Done base.Dispose(); @@ -113,17 +116,17 @@ namespace CodeImp.DoomBuilder.Rendering // This sets the constant settings public void SetConstants(bool bilinear, bool useanisotropic) { - if(manager.Enabled) + if(manager.Enabled && General.Settings.QualityDisplay) { if(bilinear) { - effect.SetValue(magfiltersettings, (int)TextureFilter.Linear); + effect.SetValue(magfiltersettings, (int)TextureFilter.Linear); if(useanisotropic) effect.SetValue(minfiltersettings, (int)TextureFilter.Anisotropic); } else { - effect.SetValue(magfiltersettings, (int)TextureFilter.Point); - effect.SetValue(minfiltersettings, (int)TextureFilter.Point); + effect.SetValue(magfiltersettings, (int)TextureFilter.Point); + effect.SetValue(minfiltersettings, (int)TextureFilter.Point); } } } @@ -131,9 +134,9 @@ namespace CodeImp.DoomBuilder.Rendering // This sets the modulation color public void SetModulateColor(int modcolor) { - if(manager.Enabled) + if(manager.Enabled && General.Settings.QualityDisplay) { - effect.SetValue(modulatecolor, new Color4(modcolor)); + effect.SetValue(modulatecolor, new Color4(modcolor)); } else { @@ -142,6 +145,15 @@ namespace CodeImp.DoomBuilder.Rendering } } + // This sets the highlight color + public void SetHighlightColor(int hicolor) + { + if(manager.Enabled && General.Settings.QualityDisplay) + { + effect.SetValue(highlightcolor, new Color4(hicolor)); + } + } + // This sets up the render pipeline public override void BeginPass(int index) { diff --git a/Source/Resources/world3d.fx b/Source/Resources/world3d.fx index ccd6032e..e7e7b796 100644 --- a/Source/Resources/world3d.fx +++ b/Source/Resources/world3d.fx @@ -20,6 +20,9 @@ struct PixelData // Modulation color float4 modulatecolor; +// Highlight color +float4 highlightcolor; + // Matrix for final transformation float4x4 worldviewproj; @@ -74,6 +77,30 @@ float4 ps_fullbright(PixelData pd) : COLOR return tcolor * modulatecolor; } +// Normal pixel shader with highlight +float4 ps_main_highlight(PixelData pd) : COLOR +{ + float4 tcolor = tex2D(texturesamp, pd.uv); + + // Blend texture color, vertex color and modulation color + float4 ncolor = tcolor * pd.color * modulatecolor; + float4 hcolor = float4(highlightcolor.rgb, ncolor.a); + + return ncolor + hcolor * highlightcolor.a; +} + +// Full-bright pixel shader with highlight +float4 ps_fullbright_highlight(PixelData pd) : COLOR +{ + float4 tcolor = tex2D(texturesamp, pd.uv); + + // Blend texture color and modulation color + float4 ncolor = tcolor * modulatecolor; + float4 hcolor = float4(highlightcolor.rgb, ncolor.a); + + return ncolor + hcolor * highlightcolor.a; +} + // Technique for shader model 2.0 technique SM20 { @@ -90,4 +117,18 @@ technique SM20 VertexShader = compile vs_2_0 vs_main(); PixelShader = compile ps_2_0 ps_fullbright(); } + + // Normal with highlight + pass p2 + { + VertexShader = compile vs_2_0 vs_main(); + PixelShader = compile ps_2_0 ps_main_highlight(); + } + + // Full brightness mode with highlight + pass p3 + { + VertexShader = compile vs_2_0 vs_main(); + PixelShader = compile ps_2_0 ps_fullbright_highlight(); + } }