- created dynamic presentation pipeline

- added sectors brightness editing mode
This commit is contained in:
codeimp 2008-05-18 07:31:33 +00:00
parent 5c90215666
commit 1d58484dd3
27 changed files with 852 additions and 145 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 362 B

View file

@ -343,6 +343,7 @@
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<Compile Include="Rendering\Color2DShader.cs" />
<Compile Include="Rendering\Presentation.cs" />
<Compile Include="Rendering\Texture2DShader.cs" />
<Compile Include="Rendering\Display2DShader.cs" />
<Compile Include="Rendering\ColorCollection.cs" />

View file

@ -33,6 +33,7 @@
<Reference Include="System.Windows.Forms" />
</ItemGroup>
<ItemGroup>
<Compile Include="ClassicModes\BrightnessMode.cs" />
<Compile Include="ClassicModes\CurveLinedefsMode.cs" />
<Compile Include="ClassicModes\DragLinedefsMode.cs" />
<Compile Include="ClassicModes\DragSectorsMode.cs" />
@ -115,6 +116,9 @@
<Name>Builder</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Resources\BrightnessMode.png" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.

View file

@ -0,0 +1,507 @@
#region ================== Copyright (c) 2007 Pascal vd Heiden
/*
* Copyright (c) 2007 Pascal vd Heiden, www.codeimp.com
* This program is released under GNU General Public License
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#endregion
#region ================== Namespaces
using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Reflection;
using CodeImp.DoomBuilder.Interface;
using CodeImp.DoomBuilder.IO;
using CodeImp.DoomBuilder.Map;
using CodeImp.DoomBuilder.Rendering;
using CodeImp.DoomBuilder.Geometry;
using CodeImp.DoomBuilder.Editing;
using System.Drawing;
using CodeImp.DoomBuilder.Controls;
#endregion
namespace CodeImp.DoomBuilder.BuilderModes
{
[EditMode(SwitchAction = "brightnessmode",
ButtonDesc = "Brightness Mode",
ButtonImage = "BrightnessMode.png",
ButtonOrder = int.MinValue + 3)]
public class BrightnessMode : ClassicMode
{
#region ================== Constants
#endregion
#region ================== Variables
// Highlighted item
private Sector highlighted;
// Interface
private bool editpressed;
// The methods GetSelected* and MarkSelected* on the MapSet do not
// retain the order in which items were selected.
// This list keeps in order while sectors are selected/deselected.
private List<Sector> orderedselection;
#endregion
#region ================== Properties
#endregion
#region ================== Constructor / Disposer
// Constructor
public BrightnessMode()
{
// Make ordered selection list
orderedselection = new List<Sector>();
// Fill the list with selected sectors (these are not in order, but we have no other choice)
ICollection<Sector> selectedsectors = General.Map.Map.GetSelectedSectors(true);
foreach(Sector s in selectedsectors) orderedselection.Add(s);
}
// Disposer
public override void Dispose()
{
// Not already disposed?
if(!isdisposed)
{
// Clean up
orderedselection = null;
// Dispose base
base.Dispose();
}
}
#endregion
#region ================== Methods
// When undo is used
[EndAction("undo", BaseAction = true)]
public void Undo()
{
// Clear ordered selection
orderedselection.Clear();
}
// When redo is used
[EndAction("redo", BaseAction = true)]
public void Redo()
{
// Clear ordered selection
orderedselection.Clear();
}
// This selectes or deselects a sector
protected void SelectSector(Sector s, bool selectstate)
{
bool selectionchanged = false;
// Select the sector?
if(selectstate && !s.Selected)
{
orderedselection.Add(s);
s.Selected = true;
selectionchanged = true;
}
// Deselect the sector?
else if(!selectstate && s.Selected)
{
orderedselection.Remove(s);
s.Selected = false;
selectionchanged = true;
}
// Selection changed?
if(selectionchanged)
{
// Make update lines selection
foreach(Sidedef sd in s.Sidedefs)
{
bool front, back;
if(sd.Line.Front != null) front = sd.Line.Front.Sector.Selected; else front = false;
if(sd.Line.Back != null) back = sd.Line.Back.Sector.Selected; else back = false;
sd.Line.Selected = front | back;
}
}
}
// Cancel mode
public override void OnCancel()
{
base.OnCancel();
// Return to this mode
General.Map.ChangeMode(new SectorsMode());
}
// Mode engages
public override void OnEngage()
{
base.OnEngage();
// Make customized presentation
CustomPresentation p = new CustomPresentation();
p.AddLayer(new PresentLayer(RendererLayer.Background, BlendingMode.Mask));
p.AddLayer(new PresentLayer(RendererLayer.Grid, BlendingMode.Mask));
p.AddLayer(new PresentLayer(RendererLayer.Overlay, BlendingMode.Alpha, 1f, true));
p.AddLayer(new PresentLayer(RendererLayer.Geometry, BlendingMode.Alpha, 1f, true));
renderer.SetPresentation(p);
}
// Mode disengages
public override void OnDisengage()
{
base.OnDisengage();
// Check which mode we are switching to
if(General.Map.NewMode is VerticesMode)
{
// Convert selection to vertices
// Clear selected sectors
General.Map.Map.ClearSelectedSectors();
}
else if(General.Map.NewMode is LinedefsMode)
{
// Convert selection to linedefs
// Clear selected sectors
General.Map.Map.ClearSelectedSectors();
}
// Hide highlight info
General.Interface.HideInfo();
}
// This redraws the display
public override void OnRedrawDisplay()
{
// Render lines and vertices
if(renderer.StartPlotter(true))
{
renderer.PlotLinedefSet(General.Map.Map.Linedefs);
renderer.PlotVerticesSet(General.Map.Map.Vertices);
if((highlighted != null) && !highlighted.IsDisposed)
renderer.PlotSector(highlighted, General.Colors.Highlight);
renderer.Finish();
}
// Render things
if(renderer.StartThings(true))
{
renderer.Finish();
}
// Render selection
if(renderer.StartOverlay(true))
{
foreach(Sector s in General.Map.Map.Sectors)
{
PixelColor b = new PixelColor(255, (byte)s.Brightness, (byte)s.Brightness, (byte)s.Brightness);
int bint = b.ToInt();
FlatVertex[] verts = new FlatVertex[s.Triangles.Count];
int index = 0;
foreach(Vector2D v in s.Triangles)
{
Vector2D tv = v.GetTransformed(renderer.TranslateX, renderer.TranslateY, renderer.Scale, -renderer.Scale);
verts[index].x = tv.x;
verts[index].y = tv.y;
verts[index].z = 0f;
verts[index].w = 1f;
verts[index].c = bint;
index++;
}
renderer.RenderGeometry(verts, null);
}
if(selecting) RenderMultiSelection();
renderer.Finish();
}
renderer.Present();
}
// This highlights a new item
protected void Highlight(Sector s)
{
// Update display
if(renderer.StartPlotter(false))
{
// Undraw previous highlight
if((highlighted != null) && !highlighted.IsDisposed)
renderer.PlotSector(highlighted);
/*
// Undraw highlighted things
if(highlighted != null)
foreach(Thing t in highlighted.Things)
renderer.RenderThing(t, renderer.DetermineThingColor(t));
*/
// Set new highlight
highlighted = s;
// Render highlighted item
if((highlighted != null) && !highlighted.IsDisposed)
renderer.PlotSector(highlighted, General.Colors.Highlight);
/*
// Render highlighted things
if(highlighted != null)
foreach(Thing t in highlighted.Things)
renderer.RenderThing(t, General.Colors.Highlight);
*/
// Done
renderer.Finish();
renderer.Present();
}
// Show highlight info
if((highlighted != null) && !highlighted.IsDisposed)
General.Interface.ShowSectorInfo(highlighted);
else
General.Interface.HideInfo();
}
// Selection
protected override void OnSelect()
{
// Item highlighted?
if((highlighted != null) && !highlighted.IsDisposed)
{
// Flip selection
SelectSector(highlighted, !highlighted.Selected);
// Update display
if(renderer.StartPlotter(false))
{
// Redraw highlight to show selection
renderer.PlotSector(highlighted);
renderer.Finish();
renderer.Present();
}
}
else
{
// Start making a selection
StartMultiSelection();
}
base.OnSelect();
}
// End selection
protected override void OnEndSelect()
{
// Not stopping from multiselection?
if(!selecting)
{
// Item highlighted?
if((highlighted != null) && !highlighted.IsDisposed)
{
// Update display
if(renderer.StartPlotter(false))
{
// Render highlighted item
renderer.PlotSector(highlighted, General.Colors.Highlight);
renderer.Finish();
renderer.Present();
}
}
}
base.OnEndSelect();
}
// Start editing
protected override void OnEdit()
{
// Item highlighted?
if((highlighted != null) && !highlighted.IsDisposed)
{
// Edit pressed in this mode
editpressed = true;
// Highlighted item not selected?
if(!highlighted.Selected)
{
// Make this the only selection
General.Map.Map.ClearSelectedSectors();
General.Map.Map.ClearSelectedLinedefs();
SelectSector(highlighted, true);
General.Interface.RedrawDisplay();
}
// Update display
if(renderer.StartPlotter(false))
{
// Redraw highlight to show selection
renderer.PlotSector(highlighted);
renderer.Finish();
renderer.Present();
}
}
base.OnEdit();
}
// Done editing
protected override void OnEndEdit()
{
// Edit pressed in this mode?
if(editpressed)
{
}
editpressed = false;
base.OnEndEdit();
}
// Mouse moves
public override void OnMouseMove(MouseEventArgs e)
{
base.OnMouseMove(e);
// Not holding any buttons?
if(e.Button == MouseButtons.None)
{
// Find the nearest linedef within highlight range
Linedef l = General.Map.Map.NearestLinedef(mousemappos);
if(l != null)
{
// Check on which side of the linedef the mouse is
float side = l.SideOfLine(mousemappos);
if(side > 0)
{
// Is there a sidedef here?
if(l.Back != null)
{
// Highlight if not the same
if(l.Back.Sector != highlighted) Highlight(l.Back.Sector);
}
else
{
// Highlight nothing
if(highlighted != null) Highlight(null);
}
}
else
{
// Is there a sidedef here?
if(l.Front != null)
{
// Highlight if not the same
if(l.Front.Sector != highlighted) Highlight(l.Front.Sector);
}
else
{
// Highlight nothing
if(highlighted != null) Highlight(null);
}
}
}
else
{
// Highlight nothing
if(highlighted != null) Highlight(null);
}
}
}
// Mouse leaves
public override void OnMouseLeave(EventArgs e)
{
base.OnMouseLeave(e);
// Highlight nothing
Highlight(null);
}
// This is called wheh selection ends
protected override void OnEndMultiSelection()
{
// Go for all lines
foreach(Linedef l in General.Map.Map.Linedefs)
{
l.Selected = ((l.Start.Position.x >= selectionrect.Left) &&
(l.Start.Position.y >= selectionrect.Top) &&
(l.Start.Position.x <= selectionrect.Right) &&
(l.Start.Position.y <= selectionrect.Bottom) &&
(l.End.Position.x >= selectionrect.Left) &&
(l.End.Position.y >= selectionrect.Top) &&
(l.End.Position.x <= selectionrect.Right) &&
(l.End.Position.y <= selectionrect.Bottom));
}
// Go for all sectors
foreach(Sector s in General.Map.Map.Sectors)
{
// Go for all sidedefs
bool allselected = true;
foreach(Sidedef sd in s.Sidedefs)
{
if(!sd.Line.Selected)
{
allselected = false;
break;
}
}
// Sector completely selected?
s.Selected = allselected;
}
// Make sure all linedefs reflect selected sectors
foreach(Sector s in General.Map.Map.Sectors)
SelectSector(s, s.Selected);
base.OnEndMultiSelection();
if(renderer.StartOverlay(true)) renderer.Finish();
General.Interface.RedrawDisplay();
}
// This is called when the selection is updated
protected override void OnUpdateMultiSelection()
{
base.OnUpdateMultiSelection();
// Render selection
if(renderer.StartOverlay(true))
{
RenderMultiSelection();
renderer.Finish();
renderer.Present();
}
}
#endregion
#region ================== Actions
#endregion
}
}

View file

@ -108,7 +108,8 @@ namespace CodeImp.DoomBuilder.BuilderModes
public override void OnEngage()
{
base.OnEngage();
renderer.SetPresentation(Presentation.Standard);
// Show toolbox window
BuilderPlug.Me.CurveLinedefsForm.Show((Form)General.Interface);
}
@ -206,7 +207,6 @@ namespace CodeImp.DoomBuilder.BuilderModes
// Render things
if(renderer.StartThings(true))
{
renderer.SetThingsRenderOrder(false);
renderer.RenderThingSet(General.Map.Map.Things);
renderer.Finish();
}

View file

@ -296,6 +296,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
public override void OnEngage()
{
base.OnEngage();
renderer.SetPresentation(Presentation.Standard);
}
// Disenagaging

View file

@ -155,7 +155,6 @@ namespace CodeImp.DoomBuilder.BuilderModes
// Start rendering things
if(renderer.StartThings(true))
{
renderer.SetThingsRenderOrder(false);
renderer.RenderThingSet(General.Map.Map.Things);
renderer.Finish();
}
@ -170,7 +169,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
}
renderer.Finish();
}
renderer.Present();
}

View file

@ -104,6 +104,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
public override void OnEngage()
{
base.OnEngage();
renderer.SetPresentation(Presentation.Standard);
}
// Disenagaging
@ -160,7 +161,6 @@ namespace CodeImp.DoomBuilder.BuilderModes
{
if(renderer.StartThings(true))
{
renderer.SetThingsRenderOrder(false);
renderer.RenderThingSet(General.Map.Map.Things);
renderer.Finish();
}
@ -175,7 +175,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
}
renderer.Finish();
}
renderer.Present();
}

View file

@ -232,7 +232,6 @@ namespace CodeImp.DoomBuilder.BuilderModes
if(renderer.StartThings(true))
{
// Render things
renderer.SetThingsRenderOrder(true);
renderer.RenderThingSet(unselectedthings);
renderer.RenderThingSet(selectedthings);
@ -271,6 +270,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
public override void OnEngage()
{
base.OnEngage();
renderer.SetPresentation(Presentation.Things);
}
// Disenagaging

View file

@ -137,7 +137,6 @@ namespace CodeImp.DoomBuilder.BuilderModes
{
if(renderer.StartThings(true))
{
renderer.SetThingsRenderOrder(false);
renderer.RenderThingSet(General.Map.Map.Things);
renderer.Finish();
}

View file

@ -127,7 +127,8 @@ namespace CodeImp.DoomBuilder.BuilderModes
public override void OnEngage()
{
base.OnEngage();
renderer.SetPresentation(Presentation.Standard);
// Set cursor
General.Interface.SetCursor(Cursors.Cross);
}
@ -569,7 +570,6 @@ namespace CodeImp.DoomBuilder.BuilderModes
// Render things
if(renderer.StartThings(true))
{
renderer.SetThingsRenderOrder(false);
renderer.RenderThingSet(General.Map.Map.Things);
renderer.Finish();
}

View file

@ -100,6 +100,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
public override void OnEngage()
{
base.OnEngage();
renderer.SetPresentation(Presentation.Standard);
}
// Mode disengages
@ -143,7 +144,6 @@ namespace CodeImp.DoomBuilder.BuilderModes
// Render things
if(renderer.StartThings(true))
{
renderer.SetThingsRenderOrder(false);
renderer.RenderThingSet(General.Map.Map.Things);
renderer.Finish();
}
@ -158,7 +158,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
renderer.Finish();
}
}
renderer.Present();
}

View file

@ -161,6 +161,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
public override void OnEngage()
{
base.OnEngage();
renderer.SetPresentation(Presentation.Standard);
}
// Mode disengages
@ -204,7 +205,6 @@ namespace CodeImp.DoomBuilder.BuilderModes
// Render things
if(renderer.StartThings(true))
{
renderer.SetThingsRenderOrder(false);
renderer.RenderThingSet(General.Map.Map.Things);
renderer.Finish();
}
@ -219,7 +219,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
renderer.Finish();
}
}
renderer.Present();
}

View file

@ -100,6 +100,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
public override void OnEngage()
{
base.OnEngage();
renderer.SetPresentation(Presentation.Things);
}
// Mode disengages
@ -127,7 +128,6 @@ namespace CodeImp.DoomBuilder.BuilderModes
// Render things
if(renderer.StartThings(true))
{
renderer.SetThingsRenderOrder(true);
renderer.RenderThingSet(General.Map.Map.Things);
renderer.Finish();
}
@ -142,10 +142,10 @@ namespace CodeImp.DoomBuilder.BuilderModes
renderer.Finish();
}
}
renderer.Present();
}
// This highlights a new item
protected void Highlight(Thing t)
{

View file

@ -101,6 +101,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
public override void OnEngage()
{
base.OnEngage();
renderer.SetPresentation(Presentation.Standard);
}
// Mode disengages
@ -144,7 +145,6 @@ namespace CodeImp.DoomBuilder.BuilderModes
// Render things
if(renderer.StartThings(true))
{
renderer.SetThingsRenderOrder(false);
renderer.RenderThingSet(General.Map.Map.Things);
renderer.Finish();
}
@ -159,7 +159,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
renderer.Finish();
}
}
renderer.Present();
}

View file

@ -45,6 +45,15 @@ sectorsmode
allowscroll = true;
}
brightnessmode
{
title = "Edit: Sectors Brightness Mode";
description = "Switches to sectors brightness editing mode.";
allowkeys = true;
allowmouse = true;
allowscroll = true;
}
thingsmode
{
title = "Edit: Things Mode";

Binary file not shown.

After

Width:  |  Height:  |  Size: 362 B

View file

@ -141,7 +141,6 @@ namespace CodeImp.DoomBuilder.BuilderModes.Editing
// Do not show things
if(renderer.StartThings(true))
{
renderer.SetThingsRenderOrder(false);
renderer.Finish();
}

View file

@ -142,7 +142,6 @@ namespace CodeImp.DoomBuilder.BuilderModes.Editing
// Render things
if(renderer.StartThings(true))
{
renderer.SetThingsRenderOrder(true);
renderer.RenderThingSet(General.Map.Map.Things);
if((highlighted != null) && (highlighted is Thing)) DrawHighlight(true);
renderer.Finish();

View file

@ -404,7 +404,7 @@ namespace CodeImp.DoomBuilder.Editing
#region ================== Display
// This just refreshes the display
public override void OnRefreshDisplay()
public override void OnPresentDisplay()
{
renderer2d.Present();
}

View file

@ -179,7 +179,7 @@ namespace CodeImp.DoomBuilder.Editing
// Rendering events
public virtual void OnRedrawDisplay() { }
public virtual void OnRefreshDisplay() { }
public virtual void OnPresentDisplay() { }
// Processing events
public virtual void OnProcess() { }

View file

@ -653,7 +653,7 @@ namespace CodeImp.DoomBuilder.Interface
{
if(General.Map.Mode != null)
{
if(!displayresized) General.Map.Mode.OnRefreshDisplay();
if(!displayresized) General.Map.Mode.OnPresentDisplay();
}
else
{

View file

@ -269,6 +269,9 @@ namespace CodeImp.DoomBuilder.Rendering
fonttexture.MipMapLevels = 2;
fonttexture.CreateTexture();
// Initialize presentations
Presentation.Initialize();
// Initialize settings
SetupSettings();

View file

@ -37,7 +37,7 @@ using System.Drawing.Imaging;
namespace CodeImp.DoomBuilder.Rendering
{
// FlatVertex
internal struct FlatVertex
public struct FlatVertex
{
// Vertex format
public static readonly int Stride = 7 * 4;

View file

@ -43,6 +43,8 @@ namespace CodeImp.DoomBuilder.Rendering
// Properties
float OffsetX { get; }
float OffsetY { get; }
float TranslateX { get; }
float TranslateY { get; }
float Scale { get; }
int VertexSize { get; }
@ -56,7 +58,7 @@ namespace CodeImp.DoomBuilder.Rendering
bool StartThings(bool clear);
bool StartOverlay(bool clear);
void Finish();
void SetThingsRenderOrder(bool front);
void SetPresentation(Presentation present);
void Present();
// Drawing methods
@ -74,5 +76,6 @@ namespace CodeImp.DoomBuilder.Rendering
void RenderRectangleFilled(RectangleF rect, PixelColor c, bool transformrect);
void RenderLine(Vector2D start, Vector2D end, float thickness, PixelColor c, bool transformcoords);
void RenderText(TextLabel text);
void RenderGeometry(FlatVertex[] vertices, ImageData texture);
}
}

View file

@ -0,0 +1,156 @@
#region ================== Copyright (c) 2007 Pascal vd Heiden
/*
* Copyright (c) 2007 Pascal vd Heiden, www.codeimp.com
* This program is released under GNU General Public License
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#endregion
#region ================== Namespaces
using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Text;
#endregion
namespace CodeImp.DoomBuilder.Rendering
{
/// <summary>
/// Presentation settings
/// </summary>
public class Presentation
{
// Constants for static instances
private const float THINGS_BACK_ALPHA = 0.3f;
// Static instances
private static Presentation standard;
private static Presentation things;
// Static properties
public static Presentation Standard { get { return standard; } }
public static Presentation Things { get { return things; } }
// Variables
protected internal List<PresentLayer> layers;
// Constructor
public Presentation()
{
// Initialize
layers = new List<PresentLayer>();
}
// Copy constructor
public Presentation(Presentation p)
{
layers = new List<PresentLayer>(p.layers);
}
// This creates the static instances
internal static void Initialize()
{
// Standard classic mode
standard = new Presentation();
standard.layers.Add(new PresentLayer(RendererLayer.Background, BlendingMode.Mask));
standard.layers.Add(new PresentLayer(RendererLayer.Things, BlendingMode.Alpha, THINGS_BACK_ALPHA));
standard.layers.Add(new PresentLayer(RendererLayer.Grid, BlendingMode.Mask));
standard.layers.Add(new PresentLayer(RendererLayer.Geometry, BlendingMode.Alpha, 1f, true));
standard.layers.Add(new PresentLayer(RendererLayer.Overlay, BlendingMode.Alpha, 1f, true));
// Things classic mode
things = new Presentation();
things.layers.Add(new PresentLayer(RendererLayer.Background, BlendingMode.Mask));
things.layers.Add(new PresentLayer(RendererLayer.Grid, BlendingMode.Mask));
things.layers.Add(new PresentLayer(RendererLayer.Geometry, BlendingMode.Alpha, 1f, true));
things.layers.Add(new PresentLayer(RendererLayer.Things, BlendingMode.Alpha, 1f, true));
things.layers.Add(new PresentLayer(RendererLayer.Overlay, BlendingMode.Alpha, 1f, true));
}
}
/// <summary>
/// Customizable Presentation
/// </summary>
public class CustomPresentation : Presentation
{
// Allow public adding
public void AddLayer(PresentLayer layer)
{
this.layers.Add(layer);
}
}
public struct PresentLayer
{
public RendererLayer layer;
public BlendingMode blending;
public float alpha;
public bool antialiasing;
// Constructor
public PresentLayer(RendererLayer layer, BlendingMode blending, float alpha, bool antialiasing)
{
this.layer = layer;
this.blending = blending;
this.alpha = alpha;
this.antialiasing = antialiasing;
}
// Constructor
public PresentLayer(RendererLayer layer, BlendingMode blending, float alpha)
{
this.layer = layer;
this.blending = blending;
this.alpha = alpha;
this.antialiasing = false;
}
// Constructor
public PresentLayer(RendererLayer layer, BlendingMode blending)
{
this.layer = layer;
this.blending = blending;
this.alpha = 1f;
this.antialiasing = false;
}
// Constructor
public PresentLayer(RendererLayer layer)
{
this.layer = layer;
this.blending = BlendingMode.None;
this.alpha = 1f;
this.antialiasing = false;
}
}
// The different layers
public enum RendererLayer : int
{
Background,
Grid,
Things,
Geometry,
Overlay
}
// Blending modes
public enum BlendingMode : int
{
None,
Mask,
Alpha,
Additive,
}
}

View file

@ -39,19 +39,9 @@ using CodeImp.DoomBuilder.Editing;
namespace CodeImp.DoomBuilder.Rendering
{
/* This renders a 2D presentation of the map
* This is done in several layers:
*
* 1) Background grid
*
* 2) Things
*
* 3) Plotter (geometric structures)
*
* 4) Overlay
*
* The order of layers 2 and 3 can be changed by
* calling SetThingsRenderOrder.
/* This renders a 2D presentation of the map. This is done in several
* layers which each are optimized for a different purpose. Set the
* PresentationLayer(s) to specify how to present these layers.
*/
internal unsafe sealed class Renderer2D : Renderer, IRenderer2D
@ -59,8 +49,7 @@ namespace CodeImp.DoomBuilder.Rendering
#region ================== Constants
private const byte DOUBLESIDED_LINE_ALPHA = 130;
private const float FSAA_PLOTTER_BLEND_FACTOR = 0.6f;
private const float FSAA_OVERLAY_BLEND_FACTOR = 0.6f;
private const float FSAA_FACTOR = 0.6f;
private const float THING_ARROW_SIZE = 1.5f;
private const float THING_ARROW_SHRINK = 2f;
private const float THING_CIRCLE_SIZE = 1f;
@ -131,6 +120,9 @@ namespace CodeImp.DoomBuilder.Rendering
private float lastgridscale = -1f;
private float lastgridx;
private float lastgridy;
// Presentation
private Presentation present;
#endregion
@ -193,6 +185,12 @@ namespace CodeImp.DoomBuilder.Rendering
#region ================== Presenting
// This sets the presentation to use
public void SetPresentation(Presentation present)
{
this.present = new Presentation(present);
}
// This draws the image on screen
public void Present()
{
@ -202,80 +200,106 @@ namespace CodeImp.DoomBuilder.Rendering
// Renderstates that count for this whole sequence
graphics.Device.SetRenderState(RenderState.CullMode, Cull.None);
graphics.Device.SetRenderState(RenderState.ZEnable, false);
graphics.Shaders.Display2D.Begin();
// Render a background image?
if((backimageverts != null) && (General.Map.Grid.Background.Texture != null))
{
// Set renderstates
graphics.Device.SetRenderState(RenderState.AlphaBlendEnable, false);
graphics.Device.SetRenderState(RenderState.AlphaTestEnable, true);
graphics.Device.SetRenderState(RenderState.TextureFactor, -1);
graphics.Device.SetTexture(0, General.Map.Grid.Background.Texture);
graphics.Shaders.Display2D.Texture1 = General.Map.Grid.Background.Texture;
graphics.Shaders.Display2D.SetSettings(1f / windowsize.Width, 1f / windowsize.Height, FSAA_PLOTTER_BLEND_FACTOR, 1f);
// Draw the background image
graphics.Shaders.Display2D.BeginPass(1);
graphics.Device.DrawUserPrimitives<FlatVertex>(PrimitiveType.TriangleStrip, 0, 2, backimageverts);
graphics.Shaders.Display2D.EndPass();
}
// From here on only using screen vertices
graphics.Device.SetStreamSource(0, screenverts, 0, sizeof(FlatVertex));
graphics.Shaders.Display2D.Begin();
// Render things in back?
if(!thingsfront) PresentThings(THINGS_BACK_ALPHA);
// Go for all layers
foreach(PresentLayer layer in present.layers)
{
int aapass;
// Set blending mode
switch(layer.blending)
{
case BlendingMode.None:
graphics.Device.SetRenderState(RenderState.AlphaBlendEnable, false);
graphics.Device.SetRenderState(RenderState.AlphaTestEnable, false);
graphics.Device.SetRenderState(RenderState.TextureFactor, -1);
break;
// Set renderstates
graphics.Device.SetRenderState(RenderState.AlphaBlendEnable, false);
graphics.Device.SetRenderState(RenderState.AlphaTestEnable, true);
graphics.Device.SetRenderState(RenderState.TextureFactor, -1);
graphics.Device.SetTexture(0, backtex);
graphics.Shaders.Display2D.Texture1 = backtex;
graphics.Shaders.Display2D.SetSettings(1f / backsize.Width, 1f / backsize.Height, 0f, 1f);
case BlendingMode.Mask:
graphics.Device.SetRenderState(RenderState.AlphaBlendEnable, false);
graphics.Device.SetRenderState(RenderState.AlphaTestEnable, true);
graphics.Device.SetRenderState(RenderState.TextureFactor, -1);
break;
// Draw the background grid
graphics.Shaders.Display2D.BeginPass(1);
//graphics.Device.DrawUserPrimitives<FlatVertex>(PrimitiveType.TriangleStrip, 0, 2, backverts);
graphics.Device.DrawPrimitives(PrimitiveType.TriangleStrip, 0, 2);
graphics.Shaders.Display2D.EndPass();
// Set renderstates
graphics.Device.SetRenderState(RenderState.AlphaBlendEnable, true);
graphics.Device.SetRenderState(RenderState.AlphaTestEnable, false);
graphics.Device.SetRenderState(RenderState.SourceBlend, Blend.SourceAlpha);
graphics.Device.SetRenderState(RenderState.DestinationBlend, Blend.InvSourceAlpha);
graphics.Device.SetRenderState(RenderState.TextureFactor, -1);
graphics.Device.SetTexture(0, plottertex);
graphics.Shaders.Display2D.Texture1 = plottertex;
graphics.Shaders.Display2D.SetSettings(1f / structsize.Width, 1f / structsize.Height, FSAA_PLOTTER_BLEND_FACTOR, 1f);
// Draw the lines and vertices texture
graphics.Shaders.Display2D.BeginPass(0);
//try { graphics.Device.DrawUserPrimitives<FlatVertex>(PrimitiveType.TriangleStrip, 0, 2, structverts); } catch(Exception) { }
//graphics.Device.DrawUserPrimitives<FlatVertex>(PrimitiveType.TriangleStrip, 0, 2, structverts);
graphics.Device.DrawPrimitives(PrimitiveType.TriangleStrip, 0, 2);
graphics.Shaders.Display2D.EndPass();
// Render things in front?
if(thingsfront) PresentThings(1f);
// Set renderstates
graphics.Device.SetRenderState(RenderState.AlphaBlendEnable, true);
graphics.Device.SetRenderState(RenderState.AlphaTestEnable, false);
graphics.Device.SetRenderState(RenderState.SourceBlend, Blend.SourceAlpha);
graphics.Device.SetRenderState(RenderState.DestinationBlend, Blend.InvSourceAlpha);
graphics.Device.SetRenderState(RenderState.TextureFactor, -1);
graphics.Device.SetTexture(0, overlaytex);
graphics.Shaders.Display2D.Texture1 = overlaytex;
graphics.Shaders.Display2D.SetSettings(1f / thingssize.Width, 1f / thingssize.Height, FSAA_OVERLAY_BLEND_FACTOR, 1f);
case BlendingMode.Alpha:
graphics.Device.SetRenderState(RenderState.AlphaBlendEnable, true);
graphics.Device.SetRenderState(RenderState.AlphaTestEnable, false);
graphics.Device.SetRenderState(RenderState.SourceBlend, Blend.SourceAlpha);
graphics.Device.SetRenderState(RenderState.DestinationBlend, Blend.InvSourceAlpha);
graphics.Device.SetRenderState(RenderState.TextureFactor, (new Color4(layer.alpha, 1f, 1f, 1f)).ToArgb());
break;
case BlendingMode.Additive:
graphics.Device.SetRenderState(RenderState.AlphaBlendEnable, true);
graphics.Device.SetRenderState(RenderState.AlphaTestEnable, false);
graphics.Device.SetRenderState(RenderState.SourceBlend, Blend.SourceAlpha);
graphics.Device.SetRenderState(RenderState.DestinationBlend, Blend.One);
graphics.Device.SetRenderState(RenderState.TextureFactor, (new Color4(layer.alpha, 1f, 1f, 1f)).ToArgb());
break;
}
// Check which pass to use
if(layer.antialiasing) aapass = 0; else aapass = 1;
// Render layer
switch(layer.layer)
{
// BACKGROUND
case RendererLayer.Background:
if((backimageverts == null) || (General.Map.Grid.Background.Texture == null)) break;
graphics.Device.SetTexture(0, General.Map.Grid.Background.Texture);
graphics.Shaders.Display2D.Texture1 = General.Map.Grid.Background.Texture;
graphics.Shaders.Display2D.SetSettings(1f / windowsize.Width, 1f / windowsize.Height, FSAA_FACTOR, layer.alpha);
graphics.Shaders.Display2D.BeginPass(aapass);
graphics.Device.DrawUserPrimitives<FlatVertex>(PrimitiveType.TriangleStrip, 0, 2, backimageverts);
graphics.Shaders.Display2D.EndPass();
graphics.Device.SetStreamSource(0, screenverts, 0, sizeof(FlatVertex));
break;
// GRID
case RendererLayer.Grid:
graphics.Device.SetTexture(0, backtex);
graphics.Shaders.Display2D.Texture1 = backtex;
graphics.Shaders.Display2D.SetSettings(1f / backsize.Width, 1f / backsize.Height, FSAA_FACTOR, layer.alpha);
graphics.Shaders.Display2D.BeginPass(aapass);
graphics.Device.DrawPrimitives(PrimitiveType.TriangleStrip, 0, 2);
graphics.Shaders.Display2D.EndPass();
break;
// GEOMETRY
case RendererLayer.Geometry:
graphics.Device.SetTexture(0, plottertex);
graphics.Shaders.Display2D.Texture1 = plottertex;
graphics.Shaders.Display2D.SetSettings(1f / structsize.Width, 1f / structsize.Height, FSAA_FACTOR, layer.alpha);
graphics.Shaders.Display2D.BeginPass(aapass);
graphics.Device.DrawPrimitives(PrimitiveType.TriangleStrip, 0, 2);
graphics.Shaders.Display2D.EndPass();
break;
// THINGS
case RendererLayer.Things:
graphics.Device.SetTexture(0, thingstex);
graphics.Shaders.Display2D.Texture1 = thingstex;
graphics.Shaders.Display2D.SetSettings(1f / thingssize.Width, 1f / thingssize.Height, FSAA_FACTOR, layer.alpha);
graphics.Shaders.Display2D.BeginPass(aapass);
graphics.Device.DrawPrimitives(PrimitiveType.TriangleStrip, 0, 2);
graphics.Shaders.Display2D.EndPass();
break;
// OVERLAY
case RendererLayer.Overlay:
graphics.Device.SetTexture(0, overlaytex);
graphics.Shaders.Display2D.Texture1 = overlaytex;
graphics.Shaders.Display2D.SetSettings(1f / thingssize.Width, 1f / thingssize.Height, FSAA_FACTOR, layer.alpha);
graphics.Shaders.Display2D.BeginPass(aapass);
graphics.Device.DrawPrimitives(PrimitiveType.TriangleStrip, 0, 2);
graphics.Shaders.Display2D.EndPass();
break;
}
}
// Draw the overlay texture
graphics.Shaders.Display2D.BeginPass(0);
graphics.Device.DrawPrimitives(PrimitiveType.TriangleStrip, 0, 2);
graphics.Shaders.Display2D.EndPass();
// Done
graphics.Shaders.Display2D.End();
graphics.FinishRendering();
@ -286,30 +310,6 @@ namespace CodeImp.DoomBuilder.Rendering
graphics.Shaders.Display2D.Texture1 = null;
}
}
// This presents the things
private void PresentThings(float alpha)
{
// Set renderstates
//graphics.Device.SetRenderState(RenderState.AlphaBlendEnable, false);
//graphics.Device.SetRenderState(RenderState.AlphaTestEnable, true);
//graphics.Device.SetRenderState(RenderState.AlphaFunc, Compare.GreaterEqual);
graphics.Device.SetRenderState(RenderState.AlphaBlendEnable, true);
graphics.Device.SetRenderState(RenderState.AlphaTestEnable, false);
graphics.Device.SetRenderState(RenderState.SourceBlend, Blend.SourceAlpha);
graphics.Device.SetRenderState(RenderState.DestinationBlend, Blend.InvSourceAlpha);
graphics.Device.SetRenderState(RenderState.TextureFactor, (new Color4(alpha, 1f, 1f, 1f)).ToArgb());
graphics.Device.SetTexture(0, thingstex);
graphics.Shaders.Display2D.Texture1 = thingstex;
graphics.Shaders.Display2D.SetSettings(1f / thingssize.Width, 1f / thingssize.Height, FSAA_PLOTTER_BLEND_FACTOR, alpha);
// Draw the things texture
graphics.Shaders.Display2D.BeginPass(0);
//try { graphics.Device.DrawUserPrimitives<FlatVertex>(PrimitiveType.TriangleStrip, 0, 2, thingsverts); } catch(Exception) { }
//graphics.Device.DrawUserPrimitives<FlatVertex>(PrimitiveType.TriangleStrip, 0, 2, thingsverts);
graphics.Device.DrawPrimitives(PrimitiveType.TriangleStrip, 0, 2);
graphics.Shaders.Display2D.EndPass();
}
#endregion
@ -537,17 +537,6 @@ namespace CodeImp.DoomBuilder.Rendering
#endregion
#region ================== Settings
// This sets the things in front or back
public void SetThingsRenderOrder(bool front)
{
// Set things render order
this.thingsfront = front;
}
#endregion
#region ================== Start / Finish
// This begins a drawing session
@ -1051,6 +1040,44 @@ namespace CodeImp.DoomBuilder.Rendering
#region ================== Overlay
// This renders geometry
// The geometry must be a triangle list
public void RenderGeometry(FlatVertex[] vertices, ImageData texture)
{
Texture t = null;
if(vertices.Length > 0)
{
if(texture != null)
{
// Make sure the texture is loaded
if(!texture.IsLoaded) texture.LoadImage();
if(texture.Texture == null) texture.CreateTexture();
t = texture.Texture;
}
else
{
t = whitetexture.Texture;
}
// Set renderstates for rendering
graphics.Device.SetRenderState(RenderState.CullMode, Cull.None);
graphics.Device.SetRenderState(RenderState.ZEnable, false);
graphics.Device.SetRenderState(RenderState.AlphaBlendEnable, true);
graphics.Device.SetRenderState(RenderState.AlphaTestEnable, false);
graphics.Device.SetRenderState(RenderState.TextureFactor, -1);
graphics.Shaders.Texture2D.Texture1 = t;
graphics.Device.SetTexture(0, t);
// Draw
graphics.Shaders.Texture2D.Begin();
graphics.Shaders.Texture2D.BeginPass(0);
graphics.Device.DrawUserPrimitives<FlatVertex>(PrimitiveType.TriangleList, 0, vertices.Length / 3, vertices);
graphics.Shaders.Texture2D.EndPass();
graphics.Shaders.Texture2D.End();
}
}
// This renders text
public void RenderText(TextLabel text)
{