Skip to content

Commit

Permalink
Fixed float precision problems with large zoom.
Browse files Browse the repository at this point in the history
It was causing some performance problems.
  • Loading branch information
bombomby committed May 12, 2017
1 parent 4640fd3 commit 42754dc
Show file tree
Hide file tree
Showing 9 changed files with 255 additions and 64 deletions.
1 change: 1 addition & 0 deletions Brofiler/Brofiler.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@
<Compile Include="Data\SourceView.cs" />
<Compile Include="Data\Synchronization.cs" />
<Compile Include="Data\Utils.cs" />
<Compile Include="DirectX\ComplexDynamicMesh.cs" />
<Compile Include="DirectX\DirectXCanvas.xaml.cs">
<DependentUpon>DirectXCanvas.xaml</DependentUpon>
</Compile>
Expand Down
68 changes: 68 additions & 0 deletions Brofiler/DirectX/ComplexDynamicMesh.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
using System;
using System.Collections.Generic;
using SharpDX.Direct3D11;
using System.Windows.Media;
using System.Windows;

namespace Profiler.DirectX
{
public class ComplexDynamicMesh
{
List<DynamicMesh> DIPs = new List<DynamicMesh>();

public ComplexDynamicMesh(DirectXCanvas canvas, int chunkCount)
{
double scaleX = 1.0 / chunkCount;

for (int i = 0; i < chunkCount; ++i)
{
DynamicMesh mesh = canvas.CreateMesh();
mesh.LocalTransform = new Matrix(scaleX, 0.0, 0.0, 1.0, -i/chunkCount, 0.0);
DIPs.Add(mesh);
}
}

private DynamicMesh SelectMesh(Point p)
{
int index = Math.Min(DIPs.Count - 1, Math.Max((int)(p.X * DIPs.Count), 0));
return DIPs[index];
}

public void AddRect(Rect rect, System.Windows.Media.Color color)
{
SelectMesh(rect.Location).AddRect(rect, color);
}

public void AddRect(System.Windows.Point[] rect, System.Windows.Media.Color color)
{
SelectMesh(rect[0]).AddRect(rect, color);
}

public void AddRect(Rect rect, System.Windows.Media.Color[] colors)
{
SelectMesh(rect.Location).AddRect(rect, colors);
}

public void AddTri(System.Windows.Point a, System.Windows.Point b, System.Windows.Point c, System.Windows.Media.Color color)
{
SelectMesh(a).AddTri(a, b, c, color);
}

public void AddLine(System.Windows.Point start, System.Windows.Point finish, System.Windows.Media.Color color)
{
SelectMesh(start).AddLine(start, finish, color);
}

public List<Mesh> Freeze(SharpDX.Direct3D11.Device device)
{
List<Mesh> result = new List<Mesh>(DIPs.Count);
DIPs.ForEach(dip =>
{
Mesh mesh = dip.Freeze(device);
if (mesh != null)
result.Add(mesh);
});
return result;
}
}
}
47 changes: 36 additions & 11 deletions Brofiler/DirectX/DirectXCanvas.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -246,10 +246,30 @@ public void Update()
RenderCanvas.Refresh();
}

public struct Stats
{
public int DIPs { get; set; }
public int Tris { get; set; }
public void Reset()
{
DIPs = 0;
Tris = 0;
}
public void Add(int triCount)
{
Tris += triCount;
DIPs += 1;
}
}

public Stats Statistics = new Stats();

private void RenderCanvas_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
{
var context = RenderDevice.ImmediateContext;

Statistics.Reset();

context.ClearRenderTargetView(RTView, ConvertColor(Background));

if (OnDraw != null)
Expand All @@ -261,9 +281,6 @@ private void RenderCanvas_Paint(object sender, System.Windows.Forms.PaintEventAr
}
}

//DelayedDrawList.ForEach(mesh => Draw(mesh));
//DelayedDrawList.Clear();

SwapChain.Present(0, PresentFlags.None);
}

Expand All @@ -272,7 +289,20 @@ public void Draw(Mesh mesh)
if (mesh != null && mesh.Fragment != null && mesh.VertexBuffer != null && mesh.IndexBuffer != null)
{
WP.View = mesh.Projection == Mesh.ProjectionType.Unit ? UnitView : PixelView;
WP.World = mesh.World;

System.Windows.Media.Matrix world = System.Windows.Media.Matrix.Multiply(mesh.LocalTransform, mesh.WorldTransform);
WP.World = Utils.Convert(world);

SharpDX.Matrix vw = SharpDX.Matrix.Multiply(WP.World, WP.View);
Vector4 posA = Vector2.Transform(new Vector2((float)mesh.AABB.Left, (float)mesh.AABB.Bottom), vw);
Vector4 posB = Vector2.Transform(new Vector2((float)mesh.AABB.Right, (float)mesh.AABB.Top), vw);

float minX = Math.Min(posA.X, posB.X);
float maxX = Math.Max(posA.X, posB.X);

if (maxX < -1f || minX > 1f)
return;


PrimitiveTopology topology = mesh.Geometry == Mesh.GeometryType.Polygons ? PrimitiveTopology.TriangleList : PrimitiveTopology.LineList;
int indexCount = (mesh.Geometry == Mesh.GeometryType.Polygons ? 3 : 2) * mesh.PrimitiveCount;
Expand All @@ -281,16 +311,11 @@ public void Draw(Mesh mesh)
Setup(mesh.Fragment, mesh.VertexBufferBinding, mesh.IndexBuffer, topology);
RenderDevice.ImmediateContext.DrawIndexed(indexCount, 0, 0);
SetAlphaBlend(false);

Statistics.Add(mesh.PrimitiveCount);
}
}

//List<Mesh> DelayedDrawList = new List<Mesh>();

//public void DrawLater(Mesh mesh)
//{
// DelayedDrawList.Add(mesh);
//}

public void SetAlphaBlend(bool isOn)
{
RenderDevice.ImmediateContext.OutputMerger.SetBlendState(isOn ? AlphaBlendState : null);
Expand Down
69 changes: 51 additions & 18 deletions Brofiler/DirectX/DynamicMesh.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,10 @@ int[] GetTriIndicesList()
return Geometry == Mesh.GeometryType.Polygons ? TriIndices : TriLineIndices;
}

public void AddRect(Rect rect, System.Windows.Media.Color color)
public virtual void AddRect(Rect rect, System.Windows.Media.Color color)
{
rect = new Rect(InverseLocalTransform.Transform(rect.Location), new Size(InverseLocalTransform.M11 * rect.Size.Width, InverseLocalTransform.M22 * rect.Size.Height));

int index = Vertices.Count;
SharpDX.Color c = Utils.Convert(color);
Vertices.Add(new Mesh.Vertex() { Position = new Vector2((float)rect.Left, (float)rect.Top), Color = c });
Expand All @@ -48,12 +50,15 @@ public void AddRect(Rect rect, System.Windows.Media.Color color)
IsDirty = true;
}

public void AddRect(System.Windows.Point[] rect, System.Windows.Media.Color color)
public virtual void AddRect(System.Windows.Point[] rect, System.Windows.Media.Color color)
{
int index = Vertices.Count;
SharpDX.Color c = Utils.Convert(color);
for (int i = 0; i < 4; ++i)
Vertices.Add(new Mesh.Vertex() { Position = new Vector2((float)rect[i].X, (float)rect[i].Y), Color = c });
{
System.Windows.Point p = InverseLocalTransform.Transform(rect[i]);
Vertices.Add(new Mesh.Vertex() { Position = new Vector2((float)p.X, (float)p.Y), Color = c });
}

foreach (int i in GetBoxIndicesList())
Indices.Add(index + i);
Expand All @@ -62,8 +67,10 @@ public void AddRect(System.Windows.Point[] rect, System.Windows.Media.Color colo
}


public void AddRect(Rect rect, System.Windows.Media.Color[] colors)
public virtual void AddRect(Rect rect, System.Windows.Media.Color[] colors)
{
rect = new Rect(InverseLocalTransform.Transform(rect.Location), new Size(InverseLocalTransform.M11 * rect.Size.Width, InverseLocalTransform.M22 * rect.Size.Height));

int index = Vertices.Count;
Vertices.Add(new Mesh.Vertex() { Position = new Vector2((float)rect.Left, (float)rect.Top), Color = Utils.Convert(colors[0]) });
Vertices.Add(new Mesh.Vertex() { Position = new Vector2((float)rect.Right, (float)rect.Top), Color = Utils.Convert(colors[1]) });
Expand All @@ -75,8 +82,12 @@ public void AddRect(Rect rect, System.Windows.Media.Color[] colors)
IsDirty = true;
}

public void AddTri(System.Windows.Point a, System.Windows.Point b, System.Windows.Point c, System.Windows.Media.Color color)
public virtual void AddTri(System.Windows.Point a, System.Windows.Point b, System.Windows.Point c, System.Windows.Media.Color color)
{
a = InverseLocalTransform.Transform(a);
b = InverseLocalTransform.Transform(b);
c = InverseLocalTransform.Transform(c);

int index = Vertices.Count;
SharpDX.Color vertexColor = Utils.Convert(color);
Vertices.Add(new Mesh.Vertex() { Position = new Vector2((float)a.X, (float)a.Y), Color = vertexColor });
Expand All @@ -89,6 +100,23 @@ public void AddTri(System.Windows.Point a, System.Windows.Point b, System.Window
IsDirty = true;
}

public virtual void AddLine(System.Windows.Point start, System.Windows.Point finish, System.Windows.Media.Color color)
{
start = InverseLocalTransform.Transform(start);
finish = InverseLocalTransform.Transform(finish);

Debug.Assert(Geometry == Mesh.GeometryType.Lines);

int index = Vertices.Count;
SharpDX.Color c = Utils.Convert(color);
Vertices.Add(new Mesh.Vertex() { Position = new Vector2((float)start.X, (float)start.Y), Color = c });
Vertices.Add(new Mesh.Vertex() { Position = new Vector2((float)finish.X, (float)finish.Y), Color = c });
Indices.Add(index + 0);
Indices.Add(index + 1);

IsDirty = true;
}

public void Update(Device device, bool autoclear = true)
{
if (IsDirty || (Vertices.Count == 0 && PrimitiveCount > 0))
Expand All @@ -112,29 +140,34 @@ public Mesh Freeze(Device device)
return null;

Mesh mesh = new Mesh();

System.Windows.Point minP = Utils.Convert(Vertices[0].Position);
System.Windows.Point maxP = Utils.Convert(Vertices[0].Position);

mesh.AABB = new Rect(Utils.Convert(Vertices[0].Position), new Size());
foreach (var v in Vertices)
{
System.Windows.Point p = Utils.Convert(v.Position);
minP.X = Math.Min(minP.X, p.X);
minP.Y = Math.Min(minP.Y, p.Y);
maxP.X = Math.Max(maxP.X, p.X);
maxP.Y = Math.Max(maxP.Y, p.Y);
}

mesh.AABB = new Rect(minP, maxP);

mesh.VertexBuffer = Vertices.Freeze(device);
mesh.IndexBuffer = Indices.Freeze(device);
mesh.VertexBufferBinding = new VertexBufferBinding(mesh.VertexBuffer, Marshal.SizeOf(typeof(Mesh.Vertex)), 0);
mesh.PrimitiveCount = Geometry == Mesh.GeometryType.Polygons ? Indices.Count / 3 : Indices.Count / 2;
mesh.Geometry = Geometry;
mesh.Projection = Projection;
mesh.World = World;
mesh.WorldTransform = WorldTransform;
mesh.LocalTransform = LocalTransform;
mesh.Fragment = Fragment;
return mesh;
}

public void AddLine(System.Windows.Point start, System.Windows.Point finish, System.Windows.Media.Color color)
{
Debug.Assert(Geometry == Mesh.GeometryType.Lines);

int index = Vertices.Count;
SharpDX.Color c = Utils.Convert(color);
Vertices.Add(new Mesh.Vertex() { Position = new Vector2((float)start.X, (float)start.Y), Color = c });
Vertices.Add(new Mesh.Vertex() { Position = new Vector2((float)finish.X, (float)finish.Y), Color = c });
Indices.Add(index + 0);
Indices.Add(index + 1);
}

public DynamicMesh(Device device)
{
Vertices = new DynamicBuffer<Vertex>(device, BindFlags.VertexBuffer);
Expand Down
30 changes: 28 additions & 2 deletions Brofiler/DirectX/Mesh.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,37 @@ public enum GeometryType

public SharpDX.Direct3D11.VertexBufferBinding VertexBufferBinding;

public SharpDX.Matrix World { get; set; }
public System.Windows.Media.Matrix WorldTransform { get; set; }

private System.Windows.Media.Matrix localTransform = System.Windows.Media.Matrix.Identity;
private System.Windows.Media.Matrix inverseLocalTransform = System.Windows.Media.Matrix.Identity;

public System.Windows.Rect AABB { get; set; }

public System.Windows.Media.Matrix LocalTransform
{
get
{
return localTransform;
}
set
{
localTransform = value;
inverseLocalTransform = value;
inverseLocalTransform.Invert();
}
}

public System.Windows.Media.Matrix InverseLocalTransform
{
get { return inverseLocalTransform; }
}

public Mesh()
{
World = SharpDX.Matrix.Identity;
WorldTransform = System.Windows.Media.Matrix.Identity;
LocalTransform = System.Windows.Media.Matrix.Identity;
AABB = new System.Windows.Rect();
}

public void Dispose()
Expand Down
14 changes: 14 additions & 0 deletions Brofiler/DirectX/Utils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,19 @@ public static double GetLuminance(System.Windows.Media.Color color)
{
return 0.2126 * color.ScR + 0.7152 * color.ScG + 0.0722 * color.ScB;
}

public static SharpDX.Matrix Convert(System.Windows.Media.Matrix m)
{
return new SharpDX.Matrix((float)m.M11, (float)m.M12, 0.0f, 0.0f,
(float)m.M21, (float)m.M22, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
(float)m.OffsetX, (float)m.OffsetY, 0.0f, 1.0f);
}

public static System.Windows.Point Convert(SharpDX.Vector2 pos)
{
return new System.Windows.Point(pos.X, pos.Y);
}

}
}

0 comments on commit 42754dc

Please sign in to comment.