- Delay plotter drawing until DrawContents is called

This commit is contained in:
Magnus Norddahl 2019-08-18 08:07:28 +02:00
parent 3142437444
commit b51270fdfa
2 changed files with 242 additions and 249 deletions

View file

@ -17,6 +17,7 @@
#region ================== Namespaces
using System;
using System.Collections.Generic;
using CodeImp.DoomBuilder.Geometry;
#endregion
@ -25,10 +26,6 @@ namespace CodeImp.DoomBuilder.Rendering
{
internal unsafe sealed class Plotter : IDisposable
{
private const int DASH_INTERVAL = 16; //mxd
private PixelColor* pixels;
public Plotter(int width, int height)
{
this.Texture = new Texture(width, height);
@ -43,30 +40,32 @@ namespace CodeImp.DoomBuilder.Rendering
public int Height { get { return Texture.Height; } }
public Texture Texture { get; set; }
public void Dispose()
{
if (Texture != null) Texture.Dispose();
}
public void Begin(RenderDevice graphics)
{
this.pixels = (PixelColor*)graphics.LockTexture(Texture).ToPointer();
}
public void DrawContents(RenderDevice graphics)
{
pixels = (PixelColor*)graphics.LockTexture(Texture).ToPointer();
if (clear)
General.ZeroMemory(new IntPtr(pixels), Width * Height * sizeof(PixelColor));
foreach (var command in commands)
{
command();
}
graphics.UnlockTexture(Texture);
}
// This clears all pixels black
public void Clear()
{
// Clear memory
General.ZeroMemory(new IntPtr(pixels), Width * Height * sizeof(PixelColor));
clear = true;
commands.Clear();
}
// This draws a pixel normally
public void DrawVertexSolid(int x, int y, int size, ref PixelColor c, ref PixelColor l, ref PixelColor d)
public void DrawVertexSolid(int x, int y, int size, PixelColor c, PixelColor l, PixelColor d)
{
commands.Add(() =>
{
int width = Width;
int height = Height;
@ -101,37 +100,13 @@ namespace CodeImp.DoomBuilder.Rendering
pixels[y2 * width + x2] = d;
pixels[y1 * width + x1] = l;
}
/*
else
{
// Filled square
for(yp = y - size; yp <= y + size; yp++)
for(xp = x - size; xp <= x + size; xp++)
DrawPixelSolid(xp, yp, c);
// Vertical edges
for(yp = y - size + 1; yp <= y + size - 1; yp++)
{
DrawPixelSolid(x - size, yp, l);
DrawPixelSolid(x + size, yp, d);
}
// Horizontal edges
for(xp = x - size + 1; xp <= x + size - 1; xp++)
{
DrawPixelSolid(xp, y - size, l);
DrawPixelSolid(xp, y + size, d);
}
// Corners
DrawPixelSolid(x + size, y + size, d);
DrawPixelSolid(x - size, y - size, l);
}
*/
});
}
// This draws a dotted grid line horizontally
public void DrawGridLineH(int y, int x1, int x2, ref PixelColor c)
public void DrawGridLineH(int y, int x1, int x2, PixelColor c)
{
commands.Add(() =>
{
int width = Width;
int height = Height;
@ -146,10 +121,13 @@ namespace CodeImp.DoomBuilder.Rendering
// Draw all pixels on this line
for (int i = x1; i < x2; i++) pixels[ywidth + ((i << 1) | offset)] = c;
}
});
}
// This draws a dotted grid line vertically
public void DrawGridLineV(int x, int y1, int y2, ref PixelColor c)
public void DrawGridLineV(int x, int y1, int y2, PixelColor c)
{
commands.Add(() =>
{
int width = Width;
int height = Height;
@ -163,12 +141,16 @@ namespace CodeImp.DoomBuilder.Rendering
// Draw all pixels on this line
for (int i = y1; i < y2; i++) pixels[((i << 1) | offset) * width + x] = c;
}
});
}
// This draws a line normally
// See: http://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm
public void DrawLineSolid(int x1, int y1, int x2, int y2, ref PixelColor c, uint mask = 0xffffffff)
public void DrawLineSolid(int x1, int y1, int x2, int y2, PixelColor c, uint mask = 0xffffffff)
{
commands.Add(() =>
{
int width = Width;
int height = Height;
@ -223,7 +205,8 @@ namespace CodeImp.DoomBuilder.Rendering
px += sdx;
// Draw pixel
if ((mask & (1 << (i & 0x7))) != 0) {
if ((mask & (1 << (i & 0x7))) != 0)
{
pixels[py * width + px] = c;
}
}
@ -242,7 +225,8 @@ namespace CodeImp.DoomBuilder.Rendering
py += sdy;
// Draw pixel
if ((mask & (1 << (i & 0x7))) != 0) {
if ((mask & (1 << (i & 0x7))) != 0)
{
pixels[py * width + px] = c;
}
}
@ -268,7 +252,8 @@ namespace CodeImp.DoomBuilder.Rendering
px += sdx;
// Draw pixel
if ((mask & (1 << (i & 0x7))) != 0) {
if ((mask & (1 << (i & 0x7))) != 0)
{
if ((px >= 0) && (px < width) && (py >= 0) && (py < height))
pixels[py * width + px] = c;
}
@ -288,24 +273,25 @@ namespace CodeImp.DoomBuilder.Rendering
py += sdy;
// Draw pixel
if ((mask & (1 << (i & 0x7))) != 0) {
if ((mask & (1 << (i & 0x7))) != 0)
{
if ((px >= 0) && (px < width) && (py >= 0) && (py < height))
pixels[py * width + px] = c;
}
}
}
}
});
}
//mxd
public void DrawLine3DFloor(Vector2D start, Vector2D end, ref PixelColor c, PixelColor c2)
public void DrawLine3DFloor(Vector2D start, Vector2D end, PixelColor c, PixelColor c2)
{
Vector2D delta = end - start;
float length = delta.GetLength();
if(length < DASH_INTERVAL * 2)
{
DrawLineSolid((int)start.x, (int)start.y, (int)end.x, (int)end.y, ref c2);
DrawLineSolid((int)start.x, (int)start.y, (int)end.x, (int)end.y, c2);
}
else
{
@ -315,10 +301,21 @@ namespace CodeImp.DoomBuilder.Rendering
Vector2D p1 = CurveTools.GetPointOnLine(start, end, d1);
Vector2D p2 = CurveTools.GetPointOnLine(start, end, d2);
DrawLineSolid((int)start.x, (int)start.y, (int)p1.x, (int)p1.y, ref c2);
DrawLineSolid((int)p1.x, (int)p1.y, (int)p2.x, (int)p2.y, ref c);
DrawLineSolid((int)p2.x, (int)p2.y, (int)end.x, (int)end.y, ref c2);
DrawLineSolid((int)start.x, (int)start.y, (int)p1.x, (int)p1.y, c2);
DrawLineSolid((int)p1.x, (int)p1.y, (int)p2.x, (int)p2.y, c);
DrawLineSolid((int)p2.x, (int)p2.y, (int)end.x, (int)end.y, c2);
}
}
public void Dispose()
{
if (Texture != null) Texture.Dispose();
}
PixelColor* pixels;
bool clear = true;
List<Action> commands = new List<Action>();
const int DASH_INTERVAL = 16;
}
}

View file

@ -626,8 +626,6 @@ namespace CodeImp.DoomBuilder.Rendering
// Rendertargets available?
if(plotter != null)
{
plotter.Begin(graphics);
// Redraw grid when structures image was cleared
if(clear)
{
@ -779,8 +777,6 @@ namespace CodeImp.DoomBuilder.Rendering
if(lastgridsize != General.Map.Grid.GridSizeF || lastgridscale != scale ||
lastgridx != offsetx || lastgridy != offsety || drawmapcenter != lastdrawmapcenter)
{
// Create a plotter
gridplotter.Begin(graphics);
gridplotter.Clear();
if(General.Settings.RenderGrid) //mxd
@ -816,10 +812,10 @@ namespace CodeImp.DoomBuilder.Rendering
Vector2D tl = new Vector2D(General.Map.Config.LeftBoundary, General.Map.Config.TopBoundary).GetTransformed(translatex, translatey, scale, -scale);
Vector2D rb = new Vector2D(General.Map.Config.RightBoundary, General.Map.Config.BottomBoundary).GetTransformed(translatex, translatey, scale, -scale);
PixelColor g = General.Colors.Grid64;
gridplotter.DrawGridLineH((int)tl.y, (int)tl.x, (int)rb.x, ref g);
gridplotter.DrawGridLineH((int)rb.y, (int)tl.x, (int)rb.x, ref g);
gridplotter.DrawGridLineV((int)tl.x, (int)tl.y, (int)rb.y, ref g);
gridplotter.DrawGridLineV((int)rb.x, (int)tl.y, (int)rb.y, ref g);
gridplotter.DrawGridLineH((int)tl.y, (int)tl.x, (int)rb.x, g);
gridplotter.DrawGridLineH((int)rb.y, (int)tl.x, (int)rb.x, g);
gridplotter.DrawGridLineV((int)tl.x, (int)tl.y, (int)rb.y, g);
gridplotter.DrawGridLineV((int)rb.x, (int)tl.y, (int)rb.y, g);
}
//mxd. Render center of map
@ -829,8 +825,8 @@ namespace CodeImp.DoomBuilder.Rendering
int cx = (int)center.x;
int cy = (int)center.y;
PixelColor c = General.Colors.Highlight;
gridplotter.DrawLineSolid(cx, cy + MAP_CENTER_SIZE, cx, cy - MAP_CENTER_SIZE, ref c);
gridplotter.DrawLineSolid(cx - MAP_CENTER_SIZE, cy, cx + MAP_CENTER_SIZE, cy, ref c);
gridplotter.DrawLineSolid(cx, cy + MAP_CENTER_SIZE, cx, cy - MAP_CENTER_SIZE, c);
gridplotter.DrawLineSolid(cx - MAP_CENTER_SIZE, cy, cx + MAP_CENTER_SIZE, cy, c);
}
// Done
@ -911,19 +907,19 @@ namespace CodeImp.DoomBuilder.Rendering
if (xminintersect)
{
gridplotter.DrawLineSolid((int)xminplotline.v1.x, (int)xminplotline.v1.y, (int)xminplotline.v2.x, (int)xminplotline.v2.y, ref c, mask);
gridplotter.DrawLineSolid((int)xminplotline.v1.x, (int)xminplotline.v1.y, (int)xminplotline.v2.x, (int)xminplotline.v2.y, c, mask);
}
if (xmaxintersect)
{
gridplotter.DrawLineSolid((int)xmaxplotline.v1.x, (int)xmaxplotline.v1.y, (int)xmaxplotline.v2.x, (int)xmaxplotline.v2.y, ref c, mask);
gridplotter.DrawLineSolid((int)xmaxplotline.v1.x, (int)xmaxplotline.v1.y, (int)xmaxplotline.v2.x, (int)xmaxplotline.v2.y, c, mask);
}
if (yminintersect)
{
gridplotter.DrawLineSolid((int)yminplotline.v1.x, (int)yminplotline.v1.y, (int)yminplotline.v2.x, (int)yminplotline.v2.y, ref c, mask);
gridplotter.DrawLineSolid((int)yminplotline.v1.x, (int)yminplotline.v1.y, (int)yminplotline.v2.x, (int)yminplotline.v2.y, c, mask);
}
if (ymaxintersect)
{
gridplotter.DrawLineSolid((int)ymaxplotline.v1.x, (int)ymaxplotline.v1.y, (int)ymaxplotline.v2.x, (int)ymaxplotline.v2.y, ref c, mask);
gridplotter.DrawLineSolid((int)ymaxplotline.v1.x, (int)ymaxplotline.v1.y, (int)ymaxplotline.v2.x, (int)ymaxplotline.v2.y, c, mask);
}
num++;
@ -968,7 +964,7 @@ namespace CodeImp.DoomBuilder.Rendering
pos = pos.GetTransformed(translatex, translatey, scale, -scale);
// Note: I'm not using Math.Ceiling in this case, because that doesn't work right.
gridplotter.DrawGridLineH((int)pos.y, (int)Math.Round(from + 0.49999f), (int)Math.Round(to + 0.49999f), ref c);
gridplotter.DrawGridLineH((int)pos.y, (int)Math.Round(from + 0.49999f), (int)Math.Round(to + 0.49999f), c);
}
// Draw all vertical grid lines
@ -987,7 +983,7 @@ namespace CodeImp.DoomBuilder.Rendering
pos = pos.GetTransformed(translatex, translatey, scale, -scale);
// Note: I'm not using Math.Ceiling in this case, because that doesn't work right.
gridplotter.DrawGridLineV((int)pos.x, (int)Math.Round(from + 0.49999f), (int)Math.Round(to + 0.49999f), ref c);
gridplotter.DrawGridLineV((int)pos.x, (int)Math.Round(from + 0.49999f), (int)Math.Round(to + 0.49999f), c);
}
}
@ -2042,7 +2038,7 @@ namespace CodeImp.DoomBuilder.Rendering
if((v2 - v1).GetLengthSq() < linenormalsize * lengthscaler) return;
// Draw line
plotter.DrawLineSolid((int)v1.x, (int)v1.y, (int)v2.x, (int)v2.y, ref c);
plotter.DrawLineSolid((int)v1.x, (int)v1.y, (int)v2.x, (int)v2.y, c);
}
// This renders a single linedef
@ -2058,9 +2054,9 @@ namespace CodeImp.DoomBuilder.Rendering
// Draw line. mxd: added 3d-floor indication
if(l.ExtraFloorFlag && General.Settings.GZMarkExtraFloors)
plotter.DrawLine3DFloor(v1, v2, ref c, General.Colors.ThreeDFloor);
plotter.DrawLine3DFloor(v1, v2, c, General.Colors.ThreeDFloor);
else
plotter.DrawLineSolid((int)v1.x, (int)v1.y, (int)v2.x, (int)v2.y, ref c);
plotter.DrawLineSolid((int)v1.x, (int)v1.y, (int)v2.x, (int)v2.y, c);
//mxd. Should we bother?
if(lengthsq < minlinenormallength) return; //mxd
@ -2072,7 +2068,7 @@ namespace CodeImp.DoomBuilder.Rendering
// Draw normal indicator
plotter.DrawLineSolid((int)(v1.x + mx), (int)(v1.y + my),
(int)((v1.x + mx) - (my * l.LengthInv) * linenormalsize),
(int)((v1.y + my) + (mx * l.LengthInv) * linenormalsize), ref c);
(int)((v1.y + my) + (mx * l.LengthInv) * linenormalsize), c);
}
// This renders a set of linedefs
@ -2094,9 +2090,9 @@ namespace CodeImp.DoomBuilder.Rendering
// Draw line. mxd: added 3d-floor indication
if(l.ExtraFloorFlag && General.Settings.GZMarkExtraFloors)
plotter.DrawLine3DFloor(v1, v2, ref c, General.Colors.ThreeDFloor);
plotter.DrawLine3DFloor(v1, v2, c, General.Colors.ThreeDFloor);
else
plotter.DrawLineSolid((int)v1.x, (int)v1.y, (int)v2.x, (int)v2.y, ref c);
plotter.DrawLineSolid((int)v1.x, (int)v1.y, (int)v2.x, (int)v2.y, c);
//mxd. Should we bother?
if(lengthsq < minlinenormallength) continue; //mxd
@ -2108,7 +2104,7 @@ namespace CodeImp.DoomBuilder.Rendering
// Draw normal indicator
plotter.DrawLineSolid((int)(v1.x + mx), (int)(v1.y + my),
(int)((v1.x + mx) - (my * l.LengthInv) * linenormalsize),
(int)((v1.y + my) + (mx * l.LengthInv) * linenormalsize), ref c);
(int)((v1.y + my) + (mx * l.LengthInv) * linenormalsize), c);
}
}
@ -2119,7 +2115,7 @@ namespace CodeImp.DoomBuilder.Rendering
Vector2D nv = v.Position.GetTransformed(translatex, translatey, scale, -scale);
// Draw pixel here
plotter.DrawVertexSolid((int)nv.x, (int)nv.y, vertexsize, ref General.Colors.Colors[colorindex], ref General.Colors.BrightColors[colorindex], ref General.Colors.DarkColors[colorindex]);
plotter.DrawVertexSolid((int)nv.x, (int)nv.y, vertexsize, General.Colors.Colors[colorindex], General.Colors.BrightColors[colorindex], General.Colors.DarkColors[colorindex]);
}
// This renders a single vertex at specified coordinates
@ -2129,7 +2125,7 @@ namespace CodeImp.DoomBuilder.Rendering
Vector2D nv = v.GetTransformed(translatex, translatey, scale, -scale);
// Draw pixel here
plotter.DrawVertexSolid((int)nv.x, (int)nv.y, vertexsize, ref General.Colors.Colors[colorindex], ref General.Colors.BrightColors[colorindex], ref General.Colors.DarkColors[colorindex]);
plotter.DrawVertexSolid((int)nv.x, (int)nv.y, vertexsize, General.Colors.Colors[colorindex], General.Colors.BrightColors[colorindex], General.Colors.DarkColors[colorindex]);
}
// This renders a set of vertices