updated slimdx to custom build and made 2D rendering using direct3d

This commit is contained in:
codeimp 2007-10-19 14:27:46 +00:00
parent d51d0c83cf
commit c954b15cb6
22 changed files with 3981 additions and 1486 deletions

Binary file not shown.

File diff suppressed because it is too large Load diff

View file

@ -155,15 +155,17 @@
</Compile>
<Compile Include="Rendering\D3DGraphics.cs" />
<Compile Include="Data\ImageData.cs" />
<Compile Include="Rendering\IResource.cs" />
<Compile Include="Rendering\FlatVertex.cs" />
<Compile Include="Rendering\ID3DResource.cs" />
<Compile Include="Rendering\PixelColor.cs" />
<Compile Include="Rendering\Plotter.cs" />
<Compile Include="Rendering\PTVertex.cs" />
<Compile Include="Rendering\Renderer.cs" />
<Compile Include="Rendering\Renderer2D.cs" />
<Compile Include="Rendering\Renderer3D.cs" />
</ItemGroup>
<ItemGroup>
<Reference Include="SlimDX, Version=1.0.2813.30005, Culture=neutral, PublicKeyToken=b1b0c32fd1ffe4f9, processorArchitecture=x86" />
<Reference Include="SlimDX, Version=1.0.2847.35002, Culture=neutral, processorArchitecture=x86" />
<Reference Include="System" />
<Reference Include="System.Drawing" />
<Reference Include="System.Windows.Forms" />
@ -197,9 +199,9 @@
</ItemGroup>
<ItemGroup>
<Content Include="Resources\Builder.ico" />
<None Include="Resources\Zoom.png" />
<None Include="Resources\Properties.png" />
<None Include="Resources\NewMap2.png" />
<None Include="Resources\Zoom.png" />
<None Include="Resources\SaveMap.png" />
<None Include="Resources\OpenMap.png" />
<None Include="Resources\NewMap.png" />

View file

@ -121,6 +121,7 @@ namespace CodeImp.DoomBuilder.Editing
public virtual void MouseUp(MouseEventArgs e) { }
public virtual void Cancel() { }
public virtual void RedrawDisplay() { }
public virtual void RefreshDisplay() { }
#endregion
}

View file

@ -72,8 +72,14 @@ namespace CodeImp.DoomBuilder.Editing
#region ================== Methods
// This just refreshes the display
public override void RefreshDisplay()
{
renderer.Present();
}
// This redraws the display
public override void RedrawDisplay()
public unsafe override void RedrawDisplay()
{
if(renderer.StartRendering())
{

View file

@ -803,6 +803,18 @@ namespace CodeImp.DoomBuilder
#region ================== Tools
// This returns the next power of 2
public static int NextPowerOf2(int v)
{
int p = 0;
// Continue increasing until higher than v
while(Math.Pow(2, p) < v) p++;
// Return power
return (int)Math.Pow(2, p);
}
// Convert bool to integer
public static int Bool2Int(bool v)
{

View file

@ -689,7 +689,7 @@ namespace CodeImp.DoomBuilder
// Check if this lump should be copied
if((lumprequired && copyrequired) || (lumpblindcopy && copyblindcopy) ||
(lumpnodebuild && copynodebuild) || ((lumpscript != "") && copyscript))
(lumpnodebuild && copynodebuild) || ((lumpscript.Length != 0) && copyscript))
{
// Get the lump name
srclumpname = ml.Key.ToString();

View file

@ -261,9 +261,15 @@ namespace CodeImp.DoomBuilder.Geometry
}
// Transform
public Vector2D GetTransformed(Vector2D offset, Vector2D scale)
public unsafe Vector2D GetTransformed(Vector2D* offset, Vector2D* scale)
{
return new Vector2D((x + offset.x) * scale.x, (y + offset.y) * scale.y);
return new Vector2D((x + offset->x) * scale->x, (y + offset->y) * scale->y);
}
// Transform
public unsafe Vector2D GetTransformed(float offsetx, float offsety, float scalex, float scaley)
{
return new Vector2D((x + offsetx) * scalex, (y + offsety) * scaley);
}
#endregion

View file

@ -507,6 +507,7 @@ namespace CodeImp.DoomBuilder.Interface
this.display.MouseLeave += new System.EventHandler(this.display_MouseLeave);
this.display.MouseDown += new System.Windows.Forms.MouseEventHandler(this.display_MouseDown);
this.display.MouseMove += new System.Windows.Forms.MouseEventHandler(this.display_MouseMove);
this.display.Paint += new System.Windows.Forms.PaintEventHandler(this.display_Paint);
this.display.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(this.display_MouseDoubleClick);
this.display.Resize += new System.EventHandler(this.display_Resize);
this.display.MouseClick += new System.Windows.Forms.MouseEventHandler(this.display_MouseClick);

View file

@ -335,9 +335,15 @@ namespace CodeImp.DoomBuilder.Interface
public void RedrawDisplay()
{
if((General.Map != null) && (General.Map.Mode != null)) General.Map.Mode.RedrawDisplay();
display.Invalidate();
//display.Invalidate();
}
// This event is called when a repaint is needed
private void display_Paint(object sender, PaintEventArgs e)
{
if((General.Map != null) && (General.Map.Mode != null) && !displayresized) General.Map.Mode.RefreshDisplay();
}
// Redraw requested
private void redrawtimer_Tick(object sender, EventArgs e)
{

View file

@ -87,7 +87,7 @@ namespace CodeImp.DoomBuilder.Interface
// Pass on to base
// Do we really want this?
base.OnPaint(pe);
base.RaisePaintEvent(this, pe);
}
#endregion
@ -136,10 +136,10 @@ namespace CodeImp.DoomBuilder.Interface
*/
this.SetStyle(ControlStyles.SupportsTransparentBackColor, false);
this.SetStyle(ControlStyles.ContainerControl, false);
this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
this.SetStyle(ControlStyles.OptimizedDoubleBuffer, false);
this.SetStyle(ControlStyles.UserPaint, true);
this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
this.SetStyle(ControlStyles.Opaque, false);
this.SetStyle(ControlStyles.Opaque, true);
this.UpdateStyles();
this.BackColor = Color.Black;
this.BackgroundImage = null;

View file

@ -121,9 +121,6 @@
<data name="OpenMap" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\OpenMap.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="Zoom" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\Zoom.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="Splash2small" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\Splash2small.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
@ -142,4 +139,7 @@
<data name="Properties" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\Properties.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="Zoom" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\Zoom.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
</root>

View file

@ -57,6 +57,7 @@ namespace CodeImp.DoomBuilder.Rendering
private Renderer2D renderer2d;
private Renderer3D renderer3d;
private Viewport viewport;
private List<ID3DResource> resources;
// Disposing
private bool isdisposed = false;
@ -82,6 +83,9 @@ namespace CodeImp.DoomBuilder.Rendering
// Set render target
this.rendertarget = rendertarget;
// Create resources list
resources = new List<ID3DResource>();
// Create renderers
renderer2d = new Renderer2D(this);
renderer3d = new Renderer3D(this);
@ -148,22 +152,22 @@ namespace CodeImp.DoomBuilder.Rendering
device.SetSamplerState(0, SamplerState.AddressW, TextureAddress.Wrap);
// First texture stage
device.SetTextureStageState(0, TextureStage.ColorOp, TextureOperation.SelectArg1);
device.SetTextureStageState(0, TextureStage.ColorArg1, TextureArgument.Diffuse);
device.SetTextureStageState(0, TextureStage.ColorOperation, TextureOperation.SelectArg1);
device.SetTextureStageState(0, TextureStage.ColorArg1, TextureArgument.Texture);
device.SetTextureStageState(0, TextureStage.ColorArg2, TextureArgument.TFactor);
device.SetTextureStageState(0, TextureStage.ResultArg, TextureArgument.Current);
device.SetTextureStageState(0, TextureStage.TexCoordIndex, 0);
// No more further stages
device.SetTextureStageState(1, TextureStage.ColorOp, TextureOperation.Disable);
device.SetTextureStageState(1, TextureStage.ColorOperation, TextureOperation.Disable);
// First alpha stage
device.SetTextureStageState(0, TextureStage.AlphaOp, TextureOperation.SelectArg1);
device.SetTextureStageState(0, TextureStage.AlphaArg1, TextureArgument.TFactor);
device.SetTextureStageState(0, TextureStage.AlphaOperation, TextureOperation.SelectArg1);
device.SetTextureStageState(0, TextureStage.AlphaArg1, TextureArgument.Texture);
device.SetTextureStageState(0, TextureStage.AlphaArg2, TextureArgument.TFactor);
// No more further stages
device.SetTextureStageState(1, TextureStage.AlphaOp, TextureOperation.Disable);
device.SetTextureStageState(1, TextureStage.AlphaOperation, TextureOperation.Disable);
// Setup material
Material material = new Material();
@ -229,7 +233,11 @@ namespace CodeImp.DoomBuilder.Rendering
// Add event to cancel resize event
//device.DeviceResizing += new CancelEventHandler(CancelResize);
// Reset renderers
renderer2d.Reset();
renderer3d.Reset();
// Initialize settings
SetupSettings();
@ -262,7 +270,7 @@ namespace CodeImp.DoomBuilder.Rendering
displaypp.BackBufferHeight = rendertarget.ClientSize.Height;
displaypp.EnableAutoDepthStencil = true;
displaypp.AutoDepthStencilFormat = Format.D16;
displaypp.MultiSample = MultiSampleType.None;
displaypp.Multisample = MultisampleType.None;
displaypp.PresentationInterval = PresentInterval.Immediate;
// Return result
@ -273,12 +281,27 @@ namespace CodeImp.DoomBuilder.Rendering
#region ================== Resetting
// This registers a resource
public void RegisterResource(ID3DResource res)
{
// Add resource
resources.Add(res);
}
// This unregisters a resource
public void UnregisterResource(ID3DResource res)
{
// Remove resource
resources.Remove(res);
}
// This resets the device and returns true on success
public bool Reset()
{
PresentParameters displaypp;
// TODO: Unload all Direct3D resources
// Unload all Direct3D resources
foreach(ID3DResource res in resources) res.UnloadResource();
// Make present parameters
displaypp = CreatePresentParameters(adapter);
@ -296,12 +319,9 @@ namespace CodeImp.DoomBuilder.Rendering
// Initialize settings
SetupSettings();
// Reset renderers
renderer2d.Reset();
renderer3d.Reset();
// TODO: Reload all Direct3D resources
// Reload all Direct3D resources
foreach(ID3DResource res in resources) res.ReloadResource();
// Success
return true;

View file

@ -0,0 +1,25 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Text;
using SlimDX.Direct3D9;
namespace CodeImp.DoomBuilder.Rendering
{
// FlatVertex
public struct FlatVertex
{
// Vertex format
public static readonly VertexFormat Format = VertexFormat.PositionRhw | VertexFormat.Texture1;
public static readonly int Stride = 6 * 4;
// Members
public float x;
public float y;
public float z;
public float w;
public float u;
public float v;
}
}

View file

@ -34,7 +34,7 @@ using SlimDX;
namespace CodeImp.DoomBuilder.Rendering
{
internal interface IResource : IDisposable
internal interface ID3DResource : IDisposable
{
// This is used to unload the resouce
void UnloadResource();

View file

@ -38,7 +38,7 @@ namespace CodeImp.DoomBuilder.Rendering
// Vertex format
public static readonly VertexFormat Format = VertexFormat.Position | VertexFormat.Diffuse | VertexFormat.Texture1;
public static readonly int Stride = 6 * 4;
// Members
public float x;
public float y;

View file

@ -1,10 +1,31 @@
#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.Reflection;
using System.Drawing;
#endregion
namespace CodeImp.DoomBuilder.Rendering
{
public struct PixelColor

370
Source/Rendering/Plotter.cs Normal file
View file

@ -0,0 +1,370 @@
#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 System.Drawing;
using System.ComponentModel;
using CodeImp.DoomBuilder.Map;
using SlimDX.Direct3D;
using SlimDX.Direct3D9;
using SlimDX;
using CodeImp.DoomBuilder.Geometry;
using System.Drawing.Imaging;
#endregion
namespace CodeImp.DoomBuilder.Rendering
{
internal unsafe class Plotter
{
#region ================== Constants
#endregion
#region ================== Variables
// Memory
private PixelColor* pixels;
private int width;
private int height;
private int visiblewidth;
private int visibleheight;
#endregion
#region ================== Properties
#endregion
#region ================== Constructor / Disposer
// Constructor
public Plotter(PixelColor* pixels, int width, int height, int visiblewidth, int visibleheight)
{
// Initialize
this.pixels = pixels;
this.width = width;
this.height = height;
this.visiblewidth = width;
this.visibleheight = height;
// We have no destructor
GC.SuppressFinalize(this);
}
#endregion
#region ================== Pixel Rendering
// This clears all pixels black
public void Clear()
{
// Clear memory
General.ZeroMemory(new IntPtr(pixels), width * height * sizeof(PixelColor));
}
// This draws a pixel normally
public void DrawPixelSolid(int x, int y, PixelColor c)
{
// Draw pixel when within range
if((x >= 0) && (x < visiblewidth) && (y >= 0) && (y < visibleheight))
pixels[y * width + x] = c;
}
// This draws a pixel normally
public void DrawVertexSolid(int x, int y, int size, PixelColor c)
{
int xp, yp;
// Do unchecked?
if((x - size >= 0) && (x + size < visiblewidth) && (y - size >= 0) && (y + size < visibleheight))
{
for(yp = y - size; yp <= y + size; yp++)
for(xp = x - size; xp <= x + size; xp++)
pixels[yp * width + xp] = c;
}
else
{
for(yp = y - size; yp <= y + size; yp++)
for(xp = x - size; xp <= x + size; xp++)
if((xp >= 0) && (xp < visiblewidth) && (yp >= 0) && (yp < visibleheight))
pixels[yp * width + xp] = c;
}
}
// This draws a pixel alpha blended
public void DrawPixelAlpha(int x, int y, PixelColor c)
{
float a;
// Draw only when within range
if((x >= 0) && (x < visiblewidth) && (y >= 0) && (y < visibleheight))
{
// Get the target pixel
PixelColor* p = pixels + (y * width + x);
// Not drawn on target yet?
if(*(int*)p == 0)
{
// Simply apply color to pixel
*p = c;
}
else
{
// Blend with pixel
a = (float)c.a * 0.003921568627450980392156862745098f;
if((int)p->a + (int)c.a > 255) p->a = 255; else p->a += c.a;
p->r = (byte)((float)p->r * (1f - a) + (float)c.r * a);
p->g = (byte)((float)p->g * (1f - a) + (float)c.g * a);
p->b = (byte)((float)p->b * (1f - a) + (float)c.b * a);
}
}
}
// This draws a line alpha blended
// See: http://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm
public void DrawLineAlpha(int x1, int y1, int x2, int y2, PixelColor c)
{
int i;
// Check if the line is outside the screen for sure.
// This is quickly done by checking in which area both points are. When this
// is above, below, right or left of the screen, then skip drawing the line.
if(((x1 < 0) && (x2 < 0)) ||
((x1 > visiblewidth) && (x2 > visiblewidth)) ||
((y1 < 0) && (y2 < 0)) ||
((y1 > visibleheight) && (y2 > visibleheight))) return;
// Distance of the line
int dx = x2 - x1;
int dy = y2 - y1;
// Positive (absolute) distance
int dxabs = Math.Abs(dx);
int dyabs = Math.Abs(dy);
// Half distance
int x = dyabs >> 1;
int y = dxabs >> 1;
// Direction
int sdx = Math.Sign(dx);
int sdy = Math.Sign(dy);
// Start position
int px = x1;
int py = y1;
// Draw first pixel
DrawPixelAlpha(px, py, c);
// Check if the line is more horizontal than vertical
if(dxabs >= dyabs)
{
for(i = 0; i < dxabs; i++)
{
y += dyabs;
if(y >= dxabs)
{
y -= dxabs;
py += sdy;
}
px += sdx;
// Draw pixel
DrawPixelAlpha(px, py, c);
}
}
// Else the line is more vertical than horizontal
else
{
for(i = 0; i < dyabs; i++)
{
x += dxabs;
if(x >= dyabs)
{
x -= dyabs;
px += sdx;
}
py += sdy;
// Draw pixel
DrawPixelAlpha(px, py, 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, PixelColor c)
{
int i;
// Check if the line is outside the screen for sure.
// This is quickly done by checking in which area both points are. When this
// is above, below, right or left of the screen, then skip drawing the line.
if(((x1 < 0) && (x2 < 0)) ||
((x1 > visiblewidth) && (x2 > visiblewidth)) ||
((y1 < 0) && (y2 < 0)) ||
((y1 > visibleheight) && (y2 > visibleheight))) return;
// When the line is completely inside screen,
// then do an unchecked draw, because all of its pixels are
// guaranteed to be within the memory range
if((x1 >= 0) && (x2 >= 0) && (x1 < visiblewidth) && (x2 < visiblewidth) &&
(y1 >= 0) && (y2 >= 0) && (y1 < visibleheight) && (y2 < visibleheight))
{
// Do an unchecked draw
DrawLineSolidUnchecked(x1, y1, x2, y2, c);
return;
}
// Distance of the line
int dx = x2 - x1;
int dy = y2 - y1;
// Positive (absolute) distance
int dxabs = Math.Abs(dx);
int dyabs = Math.Abs(dy);
// Half distance
int x = dyabs >> 1;
int y = dxabs >> 1;
// Direction
int sdx = Math.Sign(dx);
int sdy = Math.Sign(dy);
// Start position
int px = x1;
int py = y1;
// Draw first pixel
DrawPixelSolid(px, py, c);
// Check if the line is more horizontal than vertical
if(dxabs >= dyabs)
{
for(i = 0; i < dxabs; i++)
{
y += dyabs;
if(y >= dxabs)
{
y -= dxabs;
py += sdy;
}
px += sdx;
// Draw pixel
DrawPixelSolid(px, py, c);
}
}
// Else the line is more vertical than horizontal
else
{
for(i = 0; i < dyabs; i++)
{
x += dxabs;
if(x >= dyabs)
{
x -= dyabs;
px += sdx;
}
py += sdy;
// Draw pixel
DrawPixelSolid(px, py, c);
}
}
}
// This draws a line normally
// See: http://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm
private void DrawLineSolidUnchecked(int x1, int y1, int x2, int y2, PixelColor c)
{
int i;
// Distance of the line
int dx = x2 - x1;
int dy = y2 - y1;
// Positive (absolute) distance
int dxabs = Math.Abs(dx);
int dyabs = Math.Abs(dy);
// Half distance
int x = dyabs >> 1;
int y = dxabs >> 1;
// Direction
int sdx = Math.Sign(dx);
int sdy = Math.Sign(dy);
// Start position
int px = x1;
int py = y1;
// Draw first pixel
pixels[py * width + px] = c;
// Check if the line is more horizontal than vertical
if(dxabs >= dyabs)
{
for(i = 0; i < dxabs; i++)
{
y += dyabs;
if(y >= dxabs)
{
y -= dxabs;
py += sdy;
}
px += sdx;
// Draw pixel
pixels[py * width + px] = c;
}
}
// Else the line is more vertical than horizontal
else
{
for(i = 0; i < dyabs; i++)
{
x += dxabs;
if(x >= dyabs)
{
x -= dyabs;
px += sdx;
}
py += sdy;
// Draw pixel
pixels[py * width + px] = c;
}
}
}
#endregion
}
}

View file

@ -1,12 +1,32 @@
#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
{
internal abstract class Renderer : IDisposable
internal abstract class Renderer : IDisposable, ID3DResource
{
#region ================== Constants
@ -14,6 +34,9 @@ namespace CodeImp.DoomBuilder.Rendering
#region ================== Variables
// Graphics
protected D3DGraphics graphics;
// Disposing
protected bool isdisposed = false;
@ -29,10 +52,14 @@ namespace CodeImp.DoomBuilder.Rendering
#region ================== Constructor / Disposer
// Constructor
public Renderer()
public Renderer(D3DGraphics g)
{
// Initialize
this.graphics = g;
// Register as resource
g.RegisterResource(this);
// We have no destructor
GC.SuppressFinalize(this);
}
@ -45,6 +72,9 @@ namespace CodeImp.DoomBuilder.Rendering
{
// Clean up
// Unregister resource
graphics.UnregisterResource(this);
// Done
isdisposed = true;
}
@ -58,5 +88,9 @@ namespace CodeImp.DoomBuilder.Rendering
public virtual void Reset() { }
#endregion
// For DirectX resources
public virtual void UnloadResource() { }
public virtual void ReloadResource() { }
}
}

View file

@ -45,16 +45,12 @@ namespace CodeImp.DoomBuilder.Rendering
#region ================== Variables
// Owner
private D3DGraphics graphics;
// Rendering memory
private Bitmap image;
private BitmapData pixeldata;
private PixelColor* pixels;
private int width;
private int height;
private Texture tex;
private int width, height;
private int pwidth, pheight;
private Plotter plotter;
// View settings (world coordinates)
private float scale;
private float offsetx;
@ -73,13 +69,9 @@ namespace CodeImp.DoomBuilder.Rendering
#region ================== Constructor / Disposer
// Constructor
public Renderer2D(D3DGraphics graphics)
public Renderer2D(D3DGraphics graphics) : base(graphics)
{
// Initialize
this.graphics = graphics;
// Create image memory
CreateMemory();
// We have no destructor
GC.SuppressFinalize(this);
@ -92,9 +84,8 @@ namespace CodeImp.DoomBuilder.Rendering
if(!isdisposed)
{
// Clean up
graphics.RenderTarget.SetImageSource(null);
if(image != null) image.Dispose();
pixels = null;
if(tex != null) tex.Dispose();
tex = null;
// Done
base.Dispose();
@ -105,53 +96,134 @@ namespace CodeImp.DoomBuilder.Rendering
#region ================== Control
// This draws the image on screen
public void Present()
{
FlatVertex[] verts = new FlatVertex[4];
// Start drawing
if(graphics.StartRendering())
{
graphics.Device.VertexFormat = FlatVertex.Format;
// Left top
verts[0].x = -0.5f;
verts[0].y = -0.5f;
verts[0].w = 1f;
verts[0].u = 0f;
verts[0].v = 0f;
// Right top
verts[1].x = pwidth - 0.5f;
verts[1].y = -0.5f;
verts[1].w = 1f;
verts[1].u = 1f;
verts[1].v = 0f;
// Left bottom
verts[2].x = -0.5f;
verts[2].y = pheight - 0.5f;
verts[2].w = 1f;
verts[2].u = 0f;
verts[2].v = 1f;
// Right bottom
verts[3].x = pwidth - 0.5f;
verts[3].y = pheight - 0.5f;
verts[3].w = 1f;
verts[3].u = 1f;
verts[3].v = 1f;
// Draw
graphics.Device.SetTexture(0, tex);
graphics.Device.SetRenderState(RenderState.CullMode, Cull.None);
try { graphics.Device.DrawUserPrimitives<FlatVertex>(PrimitiveType.TriangleStrip, 0, 2, verts); }
catch(Exception) { }
// Done
graphics.FinishRendering();
}
}
// This is called before a device is reset
// (when resized or display adapter was changed)
public override void UnloadResource()
{
// Trash old texture
if(tex != null) tex.Dispose();
tex = null;
}
// This is called resets when the device is reset
// (when resized or display adapter was changed)
public override void ReloadResource()
{
// Re-create texture
CreateTexture();
}
// This resets the graphics
public override void Reset()
{
// Trash old image
graphics.RenderTarget.SetImageSource(null);
if(image != null) image.Dispose();
// Re-create image memory
CreateMemory();
UnloadResource();
ReloadResource();
}
// Allocates new image memory to render on
public void CreateMemory()
public void CreateTexture()
{
SurfaceDescription sd;
// Get new width and height
width = graphics.RenderTarget.ClientSize.Width;
height = graphics.RenderTarget.ClientSize.Height;
// Trash old image
graphics.RenderTarget.SetImageSource(null);
if(image != null) image.Dispose();
// Trash old texture
if(tex != null) tex.Dispose();
tex = null;
// Allocate memory
image = new Bitmap(width, height, PixelFormat.Format32bppArgb);
graphics.RenderTarget.SetImageSource(image);
// Create new texture
tex = new Texture(graphics.Device, width, height, 1, Usage.Dynamic, Format.A8R8G8B8, Pool.Default);
// Get the real surface size
sd = tex.GetLevelDescription(0);
pwidth = sd.Width;
pheight = sd.Height;
}
// This begins a drawing session
public unsafe bool StartRendering()
{
// Lock memory
pixeldata = image.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
pixels = (PixelColor*)pixeldata.Scan0.ToPointer();
LockedRect rect;
// Erase image
General.ZeroMemory(pixeldata.Scan0, width * height * 4);
// Ready for rendering
return true;
// Do we have a texture?
if(tex != null)
{
// Lock memory
rect = tex.LockRectangle(0, LockFlags.Discard);
// Create plotter
plotter = new Plotter((PixelColor*)rect.Data.DataPointer.ToPointer(), rect.Pitch / sizeof(PixelColor), pheight, width, height);
plotter.Clear();
// Ready for rendering
return true;
}
else
{
// Can't render!
return false;
}
}
// This ends a drawing session
public void FinishRendering()
{
// Unlock memory
image.UnlockBits(pixeldata);
tex.UnlockRectangle(0);
// Present new image
Present();
}
// This changes view position
@ -178,206 +250,9 @@ namespace CodeImp.DoomBuilder.Rendering
// This unprojects mouse coordinates into map coordinates
public Vector2D GetMapCoordinates(Vector2D mousepos)
{
Vector3 mp, res;
// FIXME!
// Get mouse position in Vector3
//mp = new Vector3(mousepos.x, mousepos.y, 1f);
// Unproject
//res = mp.Unproject(graphics.Viewport, matproj, matview, matworld);
// Return result
//return new Vector2D(res.X, res.Y);
return new Vector2D();
}
#endregion
#region ================== Pixel Rendering
// This draws a pixel normally
private void DrawPixelSolid(int x, int y, PixelColor c)
{
// Draw pixel when within range
if((x >= 0) && (x < width) && (y >= 0) && (y < height))
pixels[y * width + x] = c;
}
// This draws a pixel alpha blended
private void DrawPixelAlpha(int x, int y, PixelColor c)
{
float a;
// Draw only when within range
if((x >= 0) && (x < width) && (y >= 0) && (y < height))
{
// Get the target pixel
PixelColor* p = pixels + (y * width + x);
// Not drawn on target yet?
if(*(int*)p == 0)
{
// Simply apply color to pixel
*p = c;
}
else
{
// Blend with pixel
a = (float)c.a * 0.003921568627450980392156862745098f;
if((int)p->a + (int)c.a > 255) p->a = 255; else p->a += c.a;
p->r = (byte)((float)p->r * (1f - a) + (float)c.r * a);
p->g = (byte)((float)p->g * (1f - a) + (float)c.g * a);
p->b = (byte)((float)p->b * (1f - a) + (float)c.b * a);
}
}
}
// This draws a line alpha blended
// See: http://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm
private void DrawLineAlpha(int x1, int y1, int x2, int y2, PixelColor c)
{
int i;
// Check if the line is outside the screen for sure.
// This is quickly done by checking in which area both points are. When this
// is above, below, right or left of the screen, then skip drawing the line.
if(((x1 < 0) && (x2 < 0)) ||
((x1 > width) && (x2 > width)) ||
((y1 < 0) && (y2 < 0)) ||
((y1 > height) && (y2 > height))) return;
// Distance of the line
int dx = x2 - x1;
int dy = y2 - y1;
// Positive (absolute) distance
int dxabs = Math.Abs(dx);
int dyabs = Math.Abs(dy);
// Half distance
int x = dyabs >> 1;
int y = dxabs >> 1;
// Direction
int sdx = Math.Sign(dx);
int sdy = Math.Sign(dy);
// Start position
int px = x1;
int py = y1;
// Draw first pixel
DrawPixelAlpha(px, py, c);
// Check if the line is more horizontal than vertical
if(dxabs >= dyabs)
{
for(i = 0; i < dxabs; i++)
{
y += dyabs;
if(y >= dxabs)
{
y -= dxabs;
py += sdy;
}
px += sdx;
// Draw pixel
DrawPixelAlpha(px, py, c);
}
}
// Else the line is more vertical than horizontal
else
{
for(i = 0; i < dyabs; i++)
{
x += dxabs;
if(x >= dyabs)
{
x -= dyabs;
px += sdx;
}
py += sdy;
// Draw pixel
DrawPixelAlpha(px, py, c);
}
}
}
// This draws a line normally
// See: http://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm
private void DrawLineSolid(int x1, int y1, int x2, int y2, PixelColor c)
{
int i;
// Check if the line is outside the screen for sure.
// This is quickly done by checking in which area both points are. When this
// is above, below, right or left of the screen, then skip drawing the line.
if(((x1 < 0) && (x2 < 0)) ||
((x1 > width) && (x2 > width)) ||
((y1 < 0) && (y2 < 0)) ||
((y1 > height) && (y2 > height))) return;
// Distance of the line
int dx = x2 - x1;
int dy = y2 - y1;
// Positive (absolute) distance
int dxabs = Math.Abs(dx);
int dyabs = Math.Abs(dy);
// Half distance
int x = dyabs >> 1;
int y = dxabs >> 1;
// Direction
int sdx = Math.Sign(dx);
int sdy = Math.Sign(dy);
// Start position
int px = x1;
int py = y1;
// Draw first pixel
DrawPixelSolid(px, py, c);
// Check if the line is more horizontal than vertical
if(dxabs >= dyabs)
{
for(i = 0; i < dxabs; i++)
{
y += dyabs;
if(y >= dxabs)
{
y -= dxabs;
py += sdy;
}
px += sdx;
// Draw pixel
DrawPixelSolid(px, py, c);
}
}
// Else the line is more vertical than horizontal
else
{
for(i = 0; i < dyabs; i++)
{
x += dxabs;
if(x >= dyabs)
{
x -= dyabs;
px += sdx;
}
py += sdy;
// Draw pixel
DrawPixelSolid(px, py, c);
}
}
float ox = -offsetx + (width * 0.5f) / scale;
float oy = -offsety - (height * 0.5f) / scale;
return mousepos.GetTransformed(ox, oy, scale, -scale);
}
#endregion
@ -385,22 +260,22 @@ namespace CodeImp.DoomBuilder.Rendering
#region ================== Map Rendering
// This renders a set of Linedefs
public unsafe void RenderLinedefs(MapSet map, ICollection<Linedef> linedefs)
public void RenderLinedefs(MapSet map, ICollection<Linedef> linedefs)
{
Vector2D voffset = new Vector2D(-offsetx + (width * 0.5f) / scale, -offsety - (height * 0.5f) / scale);
Vector2D vscale = new Vector2D(scale, -scale);
PixelColor c = PixelColor.FromColor(Color.SkyBlue);
float ox = -offsetx + (width * 0.5f) / scale;
float oy = -offsety - (height * 0.5f) / scale;
PixelColor c = PixelColor.FromColor(Color.White);
Vector2D v1, v2;
// Go for all linedefs
foreach(Linedef l in linedefs)
{
// Transform vertex coordinates
v1 = l.Start.Position.GetTransformed(voffset, vscale);
v2 = l.End.Position.GetTransformed(voffset, vscale);
v1 = l.Start.Position.GetTransformed(ox, oy, scale, -scale);
v2 = l.End.Position.GetTransformed(ox, oy, scale, -scale);
// Draw line
DrawLineSolid((int)v1.x, (int)v1.y, (int)v2.x, (int)v2.y, c);
plotter.DrawLineSolid((int)v1.x, (int)v1.y, (int)v2.x, (int)v2.y, c);
}
}
@ -408,29 +283,21 @@ namespace CodeImp.DoomBuilder.Rendering
public void RenderVertices(MapSet map, ICollection<Vertex> vertices)
{
Vector2D nv;
Vector2D voffset = new Vector2D(-offsetx + (width * 0.5f) / scale, -offsety - (height * 0.5f) / scale);
Vector2D vscale = new Vector2D(scale, -scale);
PixelColor c = PixelColor.FromInt(-1);
float ox = -offsetx + (width * 0.5f) / scale;
float oy = -offsety - (height * 0.5f) / scale;
PixelColor c = PixelColor.FromColor(Color.DeepSkyBlue);
int x, y;
// Go for all vertices
foreach(Vertex v in vertices)
{
// Transform vertex coordinates
nv = v.Position.GetTransformed(voffset, vscale);
nv = v.Position.GetTransformed(ox, oy, scale, -scale);
x = (int)nv.x;
y = (int)nv.y;
// Draw pixel here
DrawPixelSolid(x, y, c);
DrawPixelSolid(x + 1, y, c);
DrawPixelSolid(x, y + 1, c);
DrawPixelSolid(x - 1, y, c);
DrawPixelSolid(x, y - 1, c);
DrawPixelSolid(x + 1, y - 1, c);
DrawPixelSolid(x + 1, y + 1, c);
DrawPixelSolid(x - 1, y - 1, c);
DrawPixelSolid(x - 1, y + 1, c);
plotter.DrawVertexSolid(x, y, 2, c);
}
}

View file

@ -40,9 +40,6 @@ namespace CodeImp.DoomBuilder.Rendering
#region ================== Variables
// Owner
private D3DGraphics graphics;
#endregion
#region ================== Properties
@ -52,10 +49,9 @@ namespace CodeImp.DoomBuilder.Rendering
#region ================== Constructor / Disposer
// Constructor
public Renderer3D(D3DGraphics graphics)
public Renderer3D(D3DGraphics graphics) : base(graphics)
{
// Initialize
this.graphics = General.Map.Graphics;
// We have no destructor
GC.SuppressFinalize(this);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 195 B

After

Width:  |  Height:  |  Size: 194 B