Browse Source

Added .NET Core sample project.

improved_timing
Ian Burgmyer 7 years ago
parent
commit
2edb35a78c
  1. 13
      DotSDL.sln
  2. 8
      DotSDL/DotSDL.csproj
  3. 18
      Samples/Sample.BasicPixelsCore/Line.cs
  4. 205
      Samples/Sample.BasicPixelsCore/Plotting.cs
  5. 8
      Samples/Sample.BasicPixelsCore/Program.cs
  6. 16
      Samples/Sample.BasicPixelsCore/Sample.BasicPixelsCore.csproj
  7. 115
      Samples/Sample.BasicPixelsCore/Window.cs

13
DotSDL.sln

@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26228.9
VisualStudioVersion = 15.0.26430.6
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{53C506CE-9D99-4306-A304-D4B09924A883}"
ProjectSection(SolutionItems) = preProject
@ -14,6 +14,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Samples", "Samples", "{70DA
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sample.BasicPixels", "Samples\Sample.BasicPixels\Sample.BasicPixels.csproj", "{C1CCAC4E-6914-4BC1-B81F-BDFB68B476F6}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sample.BasicPixelsCore", "Samples\Sample.BasicPixelsCore\Sample.BasicPixelsCore.csproj", "{51055215-1F3D-436F-B88C-02A5C58C6989}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
@ -38,11 +40,20 @@ Global
{C1CCAC4E-6914-4BC1-B81F-BDFB68B476F6}.Release|x64.Build.0 = Release|x64
{C1CCAC4E-6914-4BC1-B81F-BDFB68B476F6}.Release|x86.ActiveCfg = Release|x86
{C1CCAC4E-6914-4BC1-B81F-BDFB68B476F6}.Release|x86.Build.0 = Release|x86
{51055215-1F3D-436F-B88C-02A5C58C6989}.Debug|x64.ActiveCfg = Debug|x64
{51055215-1F3D-436F-B88C-02A5C58C6989}.Debug|x64.Build.0 = Debug|x64
{51055215-1F3D-436F-B88C-02A5C58C6989}.Debug|x86.ActiveCfg = Debug|x86
{51055215-1F3D-436F-B88C-02A5C58C6989}.Debug|x86.Build.0 = Debug|x86
{51055215-1F3D-436F-B88C-02A5C58C6989}.Release|x64.ActiveCfg = Release|x64
{51055215-1F3D-436F-B88C-02A5C58C6989}.Release|x64.Build.0 = Release|x64
{51055215-1F3D-436F-B88C-02A5C58C6989}.Release|x86.ActiveCfg = Release|x86
{51055215-1F3D-436F-B88C-02A5C58C6989}.Release|x86.Build.0 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{C1CCAC4E-6914-4BC1-B81F-BDFB68B476F6} = {70DA3135-B76E-421D-B9CF-E49CD6440B0A}
{51055215-1F3D-436F-B88C-02A5C58C6989} = {70DA3135-B76E-421D-B9CF-E49CD6440B0A}
EndGlobalSection
EndGlobal

8
DotSDL/DotSDL.csproj

@ -12,4 +12,12 @@
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x86'">
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
</PropertyGroup>
</Project>

18
Samples/Sample.BasicPixelsCore/Line.cs

@ -0,0 +1,18 @@
using DotSDL.Graphics;
namespace Sample.BasicPixelsCore {
/// <summary>
/// Defines a line.
/// </summary>
public struct Line {
/// <summary>
/// The starting point of the <see cref="Line"/>.
/// </summary>
public Point Start;
/// <summary>
/// The ending point of the <see cref="Line"/>.
/// </summary>
public Point End;
}
}

205
Samples/Sample.BasicPixelsCore/Plotting.cs

@ -0,0 +1,205 @@
using DotSDL.Graphics;
using System;
namespace Sample.BasicPixelsCore {
internal static class Plotting {
/// <summary>
/// An internal function that gets the point on a specific section of a Beziér curve.
/// </summary>
/// <param name="points">A list of control points.</param>
/// <param name="t">The section of the curve to return a point for.</param>
/// <returns>The requested point on the curve.</returns>
private static Point BezierGetPoint(Point[] points, double t) {
while(true) {
if(points.Length == 1)
return points[0];
var newPoints = new Point[points.Length - 1];
for(var i = 0; i < points.Length - 1; i++) {
newPoints[i] = new Point {
X = (int)Math.Round((1 - t) * points[i].X + t * points[i + 1].X),
Y = (int)Math.Round((1 - t) * points[i].Y + t * points[i + 1].Y)
};
}
points = newPoints;
}
}
/// <summary>
/// Draws a Beziér curve onto a <see cref="Canvas"/>.
/// </summary>
/// <param name="canvas">The <see cref="Canvas"/> to plot pixels on.</param>
/// <param name="color">The color of the Beziér curve.(r</param>
/// <param name="segments">The number of segments in the drawn curve.</param>
/// <param name="points">A collection of points for the Beziér curve. If fewer than two points are specified, an exception will be thrown.</param>
public static void DrawBezier(ref Canvas canvas, Color color, int segments, params Point[] points) {
if(points.Length < 2) throw new ArgumentException("Too few points specified.", nameof(points));
if(points.Length == 2) // Just draw a line.
DrawLine(ref canvas, color, new Line { Start = points[0], End = points[1] });
var d = 1.0 / segments;
var newPoints = new Point[segments + 1];
var i = 0;
for(var t = 0.0; i < segments; t += d, i++)
newPoints[i] = BezierGetPoint(points, t);
// Always make sure that the end point is represented.
newPoints[segments] = BezierGetPoint(points, 1);
DrawLines(ref canvas, color, newPoints);
}
/// <summary>
/// Draws a circle onto a <see cref="Canvas"/>.
/// </summary>
/// <param name="canvas">The <see cref="Canvas"/> to plot pixels on.</param>
/// <param name="color">The color of the circle.</param>
/// <param name="center">A <see cref="Point"/> indicating the center of the circle.</param>
/// <param name="radius">The radius of the drawn circle, in pixels.</param>
public static void DrawCircle(ref Canvas canvas, Color color, Point center, int radius) {
var x = radius;
var y = 0;
var err = 0;
while(x >= y) {
PlotMirroredPointsQuad(ref canvas, color, center, x, y);
PlotMirroredPointsQuad(ref canvas, color, center, y, x);
y += 1;
if(err <= 0) {
err += 2 * y + 1;
}
if(err > 0) {
x -= 1;
err -= 2 * x + 1;
}
}
}
/// <summary>
/// Draws an ellipse onto a <see cref="Canvas"/>.
/// </summary>
/// <param name="canvas">The <see cref="Canvas"/> to plot pixels on.</param>
/// <param name="color">The color of the ellipse.</param>
/// <param name="center">A <see cref="Point"/> indicating the center of the ellipse.</param>
/// <param name="width">The radius when measured horizontally, in pixels.</param>
/// <param name="height">The radius when measured vertically, in pixels.</param>
public static void DrawEllipse(ref Canvas canvas, Color color, Point center, int width, int height) {
var rxSq = width * width;
var rySq = height * height;
var x = 0;
var y = height;
int p;
var px = 0;
var py = 2 * rxSq * y;
PlotMirroredPointsQuad(ref canvas, color, center, x, y);
// Region 1
p = (int)(rySq - (rxSq * height) + (0.25 * rxSq));
while(px < py) {
x++;
px = px + 2 * rySq;
if(p < 0) {
p = p + rySq + px;
} else {
y--;
py = py - 2 * rxSq;
p = p + rySq + px - py;
}
PlotMirroredPointsQuad(ref canvas, color, center, x, y);
}
// Region 2
p = (int)(rySq * (x + 0.5) * (x + 0.5) + rxSq * (y - 1) * (y - 1) - rxSq * rySq);
while(y > 0) {
y--;
py = py - 2 * rxSq;
if(p > 0) {
p = p + rxSq - py;
} else {
x++;
px = px + 2 * rySq;
p = p + rxSq - py + px;
}
PlotMirroredPointsQuad(ref canvas, color, center, x, y);
}
}
/// <summary>
/// Used to reduce the number of calculations needed to plot a circle or ellipse.
/// </summary>
/// <param name="canvas">The <see cref="Canvas"/> to plot pixels on.</param>
/// <param name="color">The color of the shape.</param>
/// <param name="center">A <see cref="Point"/> representing the center of the shape.</param>
/// <param name="rX">The relative X coordinate of the pixel to color.</param>
/// <param name="rY">The relative Y coordinate of the pixel to color.</param>
private static void PlotMirroredPointsQuad(ref Canvas canvas, Color color, Point center, int rX, int rY) {
canvas.Pixels[canvas.GetIndex(center.X + rX, center.Y + rY)] = color;
canvas.Pixels[canvas.GetIndex(center.X + rX, center.Y - rY)] = color;
canvas.Pixels[canvas.GetIndex(center.X - rX, center.Y + rY)] = color;
canvas.Pixels[canvas.GetIndex(center.X - rX, center.Y - rY)] = color;
}
/// <summary>
/// Plots a line on a <see cref="Canvas"/>.
/// </summary>
/// <param name="canvas">The <see cref="Canvas"/> to plot pixels on.</param>
/// <param name="color">The color of the line.</param>
/// <param name="line">A <see cref="Line"/> object representing the shape that should be drawn.</param>
public static void DrawLine(ref Canvas canvas, Color color, Line line) {
var dx = line.End.X - line.Start.X;
var dy = line.End.Y - line.Start.Y;
if(Math.Abs(dx) > Math.Abs(dy)) {
if(line.End.X > line.Start.X) {
for(var x = line.Start.X; x < line.End.X; x++) {
var y = line.Start.Y + dy * (x - line.Start.X) / dx;
canvas.Pixels[canvas.GetIndex(x, y)] = color;
}
} else {
for(var x = line.Start.X; x > line.End.X; x--) {
var y = line.Start.Y + dy * (x - line.Start.X) / dx;
canvas.Pixels[canvas.GetIndex(x, y)] = color;
}
}
} else {
if(line.End.Y > line.Start.Y) {
for(var y = line.Start.Y; y < line.End.Y; y++) {
var x = line.Start.X + dx * (y - line.Start.Y) / dy;
canvas.Pixels[canvas.GetIndex(x, y)] = color;
}
} else {
for(var y = line.Start.Y; y > line.End.Y; y--) {
var x = line.Start.X + dx * (y - line.Start.Y) / dy;
canvas.Pixels[canvas.GetIndex(x, y)] = color;
}
}
}
}
/// <summary>
/// Plots a sequence of lines on a <see cref="Canvas"/>.
/// </summary>
/// <param name="canvas">The <see cref="Canvas"/> to plot pixels on.</param>
/// <param name="color">The color of the lines.</param>
/// <param name="lines">A set of <see cref="Line"/> objects representing the shapes that should be drawn.</param>
public static void DrawLines(ref Canvas canvas, Color color, params Line[] lines) {
foreach(var line in lines)
DrawLine(ref canvas, color, line);
}
/// <summary>
/// Plots a sequence of lines on a <see cref="Canvas"/>.
/// </summary>
/// <param name="canvas">The <see cref="Canvas"/> to plot pixels on.</param>
/// <param name="color">The color of the lines.</param>
/// <param name="points">A list of points to draw. There must be at least two points specified.</param>
public static void DrawLines(ref Canvas canvas, Color color, params Point[] points) {
if(points.Length < 2) throw new ArgumentException("Too few points specified.", nameof(points));
for(var i = 0; i < points.Length - 1; i++)
DrawLine(ref canvas, color, new Line { Start = points[i], End = points[i + 1] });
}
}
}

8
Samples/Sample.BasicPixelsCore/Program.cs

@ -0,0 +1,8 @@
namespace Sample.BasicPixelsCore {
internal class Program {
private static void Main(string[] args) {
var window = new Window(512, 256);
window.Start(100, 16); // 10fps, 62.5ups
}
}
}

16
Samples/Sample.BasicPixelsCore/Sample.BasicPixelsCore.csproj

@ -0,0 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp1.1</TargetFramework>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x86'" />
<ItemGroup>
<ProjectReference Include="..\..\DotSDL\DotSDL.csproj" />
</ItemGroup>
</Project>

115
Samples/Sample.BasicPixelsCore/Window.cs

@ -0,0 +1,115 @@
using DotSDL.Graphics;
using System;
namespace Sample.BasicPixelsCore {
internal class Window : SdlWindow {
public Window(int width, int height) : base("Basic Pixels", new Point { X = WindowPosUndefined, Y = WindowPosUndefined }, width, height) { }
private void DrawBackground(ref Color[] pixels) {
byte d = 0;
var dec = false;
for(var i = 0; i < pixels.Length; i++) {
pixels[i].A = 255;
pixels[i].R = 0;
pixels[i].G = 0;
pixels[i].B = 0;
switch(i % 12 / 3) {
case 0:
pixels[i].R = (byte)(d / 2);
break;
case 1:
pixels[i].G = (byte)(d / 2);
break;
case 2:
pixels[i].B = (byte)(d / 2);
break;
}
if(dec) {
if(d == 0)
dec = false;
else
d--;
} else {
if(d == 255)
dec = true;
else
d++;
}
}
}
protected override void OnDraw(ref Canvas canvas) {
const byte min = 128, max = 255;
const int offsetX = 96, offsetY = 80;
DrawBackground(ref canvas.Pixels);
var color = RandomColor(min, max);
// D
Plotting.DrawLines(ref canvas, color,
new Line { Start = new Point { X = offsetX, Y = offsetY + 96 }, End = new Point { X = offsetX, Y = offsetY } },
new Line { Start = new Point { X = offsetX, Y = offsetY }, End = new Point { X = offsetX + 10, Y = offsetY } },
new Line { Start = new Point { X = offsetX, Y = offsetY + 96 }, End = new Point { X = offsetX + 10, Y = offsetY + 96 } }
);
Plotting.DrawBezier(ref canvas, color, 100,
new Point { X = offsetX + 8, Y = offsetY },
new Point { X = offsetX + 48, Y = offsetY },
new Point { X = offsetX + 48, Y = offsetY + 96 },
new Point { X = offsetX + 8, Y = offsetY + 96 }
);
// o
Plotting.DrawEllipse(ref canvas, color, new Point { X = offsetX + 76, Y = offsetY + 72 }, 12, 24);
// t
Plotting.DrawLines(ref canvas, color,
new Line { Start = new Point { X = offsetX + 104 + 12, Y = offsetY + 24 }, End = new Point { X = offsetX + 104 + 12, Y = offsetY + 96 } },
new Line { Start = new Point { X = offsetX + 104, Y = offsetY + 48 }, End = new Point { X = offsetX + 104 + 24, Y = offsetY + 48 } }
);
// S
Plotting.DrawBezier(ref canvas, color, 100,
new Point { X = offsetX + 144 + 48, Y = offsetY },
new Point { X = offsetX + 144 - 24, Y = offsetY },
new Point { X = offsetX + 144, Y = offsetY + 48 },
new Point { X = offsetX + 144 + 48, Y = offsetY + 48 },
new Point { X = offsetX + 144 + 72, Y = offsetY + 96 },
new Point { X = offsetX + 144, Y = offsetY + 96 }
);
// D
Plotting.DrawLines(ref canvas, color,
new Line { Start = new Point { X = offsetX + 208, Y = offsetY + 96 }, End = new Point { X = offsetX + 208, Y = offsetY } },
new Line { Start = new Point { X = offsetX + 208, Y = offsetY }, End = new Point { X = offsetX + 208 + 10, Y = offsetY } },
new Line { Start = new Point { X = offsetX + 208, Y = offsetY + 96 }, End = new Point { X = offsetX + 208 + 10, Y = offsetY + 96 } }
);
Plotting.DrawBezier(ref canvas, color, 100,
new Point { X = offsetX + 208 + 8, Y = offsetY },
new Point { X = offsetX + 208 + 48, Y = offsetY },
new Point { X = offsetX + 208 + 48, Y = offsetY + 96 },
new Point { X = offsetX + 208 + 8, Y = offsetY + 96 }
);
// L
Plotting.DrawLines(ref canvas, color,
new Line { Start = new Point { X = offsetX + 272, Y = offsetY }, End = new Point { X = offsetX + 272, Y = offsetY + 96 } },
new Line { Start = new Point { X = offsetX + 272, Y = offsetY + 96 }, End = new Point { X = offsetX + 272 + 48, Y = offsetY + 96 } }
);
}
private Color RandomColor(byte min, byte max) {
var color = new Color();
var rng = new Random();
color.A = 255;
color.R = (byte)rng.Next(min, max);
color.G = (byte)rng.Next(min, max);
color.B = (byte)rng.Next(min, max);
return color;
}
}
}
Loading…
Cancel
Save