shadow casting
This commit is contained in:
@@ -6,7 +6,9 @@ using System.Data;
|
||||
using System.Diagnostics;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Drawing2D;
|
||||
using System.Drawing.Text;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
@@ -16,8 +18,10 @@ namespace SpriteStacker
|
||||
{
|
||||
public partial class Form1 : Form
|
||||
{
|
||||
public static PrivateFontCollection pfc = new PrivateFontCollection();
|
||||
public static Thread MainThread;
|
||||
public static bool running = true;
|
||||
public static bool ValidLocation = true;
|
||||
Model model = new Model(Camera.CanvasWidth, Camera.CanvasHeight);
|
||||
public double LastFT = 0;
|
||||
public bool mouseLeftDown = false;
|
||||
@@ -50,9 +54,18 @@ namespace SpriteStacker
|
||||
Color.Beige,
|
||||
Color.Azure
|
||||
});
|
||||
private void initFont()
|
||||
{
|
||||
int fontLength = Resources.Monocraft.Length;
|
||||
byte[] fontdata = Resources.Monocraft;
|
||||
System.IntPtr data = Marshal.AllocCoTaskMem(fontLength);
|
||||
Marshal.Copy(fontdata, 0, data, fontLength);
|
||||
pfc.AddMemoryFont(data, fontLength);
|
||||
}
|
||||
public Form1()
|
||||
{
|
||||
InitializeComponent();
|
||||
initFont();
|
||||
ResizeDisplay();
|
||||
MainThread = new Thread(mainThread);
|
||||
MainThread.SetApartmentState(ApartmentState.STA);
|
||||
@@ -70,9 +83,15 @@ namespace SpriteStacker
|
||||
public void mainThread()
|
||||
{
|
||||
LastFT = Process.GetCurrentProcess().TotalProcessorTime.TotalMilliseconds;
|
||||
double SecondCounter = Process.GetCurrentProcess().TotalProcessorTime.TotalMilliseconds;
|
||||
while (running)
|
||||
{
|
||||
Display.Refresh();
|
||||
if (Process.GetCurrentProcess().TotalProcessorTime.TotalMilliseconds - SecondCounter > 1000)
|
||||
{
|
||||
SecondCounter = Process.GetCurrentProcess().TotalProcessorTime.TotalMilliseconds;
|
||||
//model.DrawLayersToImages();
|
||||
}
|
||||
if (Process.GetCurrentProcess().TotalProcessorTime.TotalMilliseconds - LastFT > 16)
|
||||
{
|
||||
LastFT = Process.GetCurrentProcess().TotalProcessorTime.TotalMilliseconds;
|
||||
@@ -80,12 +99,12 @@ namespace SpriteStacker
|
||||
if(Rotate)Camera.Rotation++;
|
||||
if (mouseLeftDown)
|
||||
{
|
||||
if(!palette.Bounds.Contains(MousePosition)) DrawBrush(new Voxel(Camera.SelectedColor));
|
||||
if(ValidLocation) DrawBrush(new Voxel(Camera.SelectedColor));
|
||||
|
||||
}
|
||||
if (mouseRightDown)
|
||||
{
|
||||
if (!palette.Bounds.Contains(MousePosition)) DrawBrush(new Voxel(Color.Transparent));
|
||||
if (ValidLocation) DrawBrush(new Voxel(Color.Transparent));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -93,10 +112,19 @@ namespace SpriteStacker
|
||||
private void PaintDisplay(object sender, PaintEventArgs e)
|
||||
{
|
||||
e.Graphics.PixelOffsetMode = PixelOffsetMode.Half;
|
||||
model.DrawSpriteStack(e.Graphics);
|
||||
switch (Config.renderMode)
|
||||
{
|
||||
case RenderMode.Editing:
|
||||
model.DrawSpriteStack(e.Graphics);
|
||||
break;
|
||||
case RenderMode.Rendering:
|
||||
model.RenderModel(e.Graphics,Config.RenderResolution);
|
||||
break;
|
||||
|
||||
}
|
||||
palette.Draw(e.Graphics);
|
||||
e.Graphics.ResetTransform();
|
||||
|
||||
e.Graphics.DrawString(String.Format("Selected Brush: {0}\nLayer: {1}/{2}\nBrush Size: {3}\nBrush Intensity: {4}\nRender Type: {5}\nRender Resolution: {6}", Camera.type, Camera.SelectedLayer + 1, model.LayerImages.Count, Camera.BrushSize, Camera.SprayIntensity,Config.renderMode,Config.renderMode == RenderMode.Editing ? "N/A": Config.RenderResolution.ToString()), new Font(pfc.Families[0], Config.FontSize), Brushes.DarkSlateBlue, new Point(0, palette.Bounds.Bottom));
|
||||
}
|
||||
|
||||
private void ResizeDisplay()
|
||||
@@ -130,10 +158,12 @@ namespace SpriteStacker
|
||||
private void Reset()
|
||||
{
|
||||
model = new Model(Camera.CanvasWidth, Camera.CanvasHeight);
|
||||
Camera.SelectedLayer = 0;
|
||||
}
|
||||
private void KeyDownEvent(object sender, KeyEventArgs e)
|
||||
{
|
||||
BrushType[] types = new BrushType[] { BrushType.Square, BrushType.Circle,BrushType.Spray };
|
||||
RenderMode[] RenderModes = new RenderMode[] {RenderMode.Editing, RenderMode.Rendering };
|
||||
if (e.KeyCode == Keys.W) Camera.BrushY = Math.Min(Camera.BrushY + 1,model.Length);
|
||||
if (e.KeyCode == Keys.S) Camera.BrushY = Math.Max(Camera.BrushY -1, 0);
|
||||
if (e.KeyCode == Keys.A) Camera.BrushX = Math.Min(Camera.BrushX + 1, model.Width);
|
||||
@@ -146,8 +176,16 @@ namespace SpriteStacker
|
||||
if (e.KeyCode == Keys.H) Camera.ViewAngle -= 0.25f;
|
||||
if (e.KeyCode == Keys.D1) Config.BackgroundTile += 2;
|
||||
if (e.KeyCode == Keys.D2) Config.BackgroundTile -= 2;
|
||||
if (e.KeyCode == Keys.D3) Config.RenderResolution += 1;
|
||||
if (e.KeyCode == Keys.D4) Config.RenderResolution -= 1;
|
||||
if (e.KeyCode == Keys.R) Rotate = !Rotate;
|
||||
if (e.KeyCode == Keys.ShiftKey) Camera.EditMode = !Camera.EditMode;
|
||||
if (e.KeyCode == Keys.ControlKey)
|
||||
{
|
||||
Config.RenderIndex++;
|
||||
if (Config.RenderIndex >= RenderModes.Length) Config.RenderIndex = 0;
|
||||
Config.renderMode = RenderModes[Config.RenderIndex];
|
||||
}
|
||||
if (e.KeyCode == Keys.Up) model.SetCurrentLayer(Camera.SelectedLayer + 1);
|
||||
if (e.KeyCode == Keys.Down) model.SetCurrentLayer(Math.Max(Camera.SelectedLayer - 1,0));
|
||||
if (e.KeyCode == Keys.Delete) Reset();
|
||||
@@ -181,8 +219,12 @@ namespace SpriteStacker
|
||||
{
|
||||
for (int j = 0; j < Camera.BrushSize; j++)
|
||||
{
|
||||
int locx = Math.Min(Math.Max((Camera.BrushX + i - Camera.BrushSize / 2), 0), model.Width - 1);
|
||||
int locy = Math.Min(Math.Max((Camera.BrushY + j - Camera.BrushSize / 2), 0), model.Length - 1);
|
||||
int locx = (Camera.BrushX + i - Camera.BrushSize / 2);
|
||||
int locy = (Camera.BrushY + j - Camera.BrushSize / 2);
|
||||
if (locx < -4 || locx > model.Width + 4 || locy < -4 || locy > model.Length + 4) ValidLocation = false;
|
||||
else ValidLocation = true;
|
||||
locx = Math.Min(Math.Max(locx, 0), model.Width - 1);
|
||||
locy = Math.Min(Math.Max(locy, 0), model.Length - 1);
|
||||
bool paintPixel = false;
|
||||
if (Camera.type == BrushType.Square) paintPixel = true;
|
||||
if (Camera.type == BrushType.Circle && Camera.isWithinCircle(i, j, (int)Math.Floor(Camera.BrushSize / 2.0), (int)(Camera.BrushSize / 2.0), (int)(Camera.BrushSize / 2.0)))
|
||||
@@ -196,7 +238,7 @@ namespace SpriteStacker
|
||||
if(paintPixel) model.SetData(Math.Min(locx, model.Width - 1), Math.Min(locy, model.Length - 1), Camera.SelectedLayer, voxel);
|
||||
}
|
||||
}
|
||||
model.DrawLayersToImages();
|
||||
model.DrawSelectedLayerToImage();
|
||||
}
|
||||
|
||||
private void MouseMoveEvent(object sender, MouseEventArgs e)
|
||||
@@ -228,10 +270,14 @@ namespace SpriteStacker
|
||||
if (e.Button == MouseButtons.Left)
|
||||
{
|
||||
mouseLeftDown = false;
|
||||
model.DrawLayersToImages();
|
||||
|
||||
}
|
||||
if (e.Button == MouseButtons.Right)
|
||||
{
|
||||
mouseRightDown = false;
|
||||
model.DrawLayersToImages();
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.Linq;
|
||||
using System.Runtime.Versioning;
|
||||
using System.Text;
|
||||
@@ -10,10 +11,20 @@ using System.Windows.Forms;
|
||||
|
||||
namespace SpriteStacker
|
||||
{
|
||||
public enum RenderMode
|
||||
{
|
||||
Editing,
|
||||
Rendering
|
||||
}
|
||||
public static class Config
|
||||
{
|
||||
public static Color BasePlateColour = Color.FromArgb(255, 255, 255, 255);
|
||||
public static int BackgroundTile = 2;
|
||||
public static List<Font> customFonts = new List<Font>();
|
||||
public static int FontSize = 16;
|
||||
public static int RenderIndex = 0;
|
||||
public static RenderMode renderMode = RenderMode.Editing;
|
||||
public static int RenderResolution = 1;
|
||||
}
|
||||
public class ColourPalette
|
||||
{
|
||||
@@ -167,10 +178,12 @@ namespace SpriteStacker
|
||||
public int Width;
|
||||
public int Length;
|
||||
public List<Rectangle> Bounds = new List<Rectangle>();
|
||||
public Bitmap RenderedModel;
|
||||
public Model(int Width, int Length)
|
||||
{
|
||||
this.Width = Width;
|
||||
this.Length = Length;
|
||||
RenderedModel = new Bitmap(Width * 2, Length * 2);
|
||||
AddLayer();
|
||||
}
|
||||
public void SetCurrentLayer(int Layer)
|
||||
@@ -220,6 +233,61 @@ namespace SpriteStacker
|
||||
LayerImages.Add(new Bitmap(Width, Length));
|
||||
ModelData.Add(new Voxel[Width,Length]);
|
||||
Bounds.Add(new Rectangle(new Point(-(int)(Width * Camera.scale) / 2, -(int)(Length * Camera.scale) / 2), new Size((int)(Width * Camera.scale), (int)(Length * Camera.scale))));
|
||||
Bitmap Render = new Bitmap(Width * 2, (Length + (int)(ModelData.Count * Camera.ViewAngle)) * 2);
|
||||
}
|
||||
public void RenderModel(Graphics R, int RenderResolution)
|
||||
{
|
||||
RenderResolution = Math.Max(RenderResolution, 1);
|
||||
Bitmap Render = new Bitmap((Width * 2 * RenderResolution), (Length + (int)(ModelData.Count * Camera.ViewAngle)) * 2 * RenderResolution);
|
||||
Graphics G = Graphics.FromImage(Render);
|
||||
G.ResetTransform();
|
||||
G.TranslateTransform(Render.Width/2, Render.Height/2);
|
||||
G.RotateTransform(Camera.Rotation);
|
||||
float AngleScale = Camera.ViewAngle * RenderResolution;
|
||||
G.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.None;
|
||||
G.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;
|
||||
G.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.Half;
|
||||
float[][] colorMatrixElements = {
|
||||
new float[] {0.0f, 0, 0, 0, 0},//R
|
||||
new float[] {0, 0.0f, 0, 0, 0},//G
|
||||
new float[] {0, 0, 0.0f, 0, 0},//B
|
||||
new float[] {0, 0, 0, 0.8f, 0},
|
||||
new float[] {0.0f, 0.0f, 0.0f, 0f, 1}};
|
||||
|
||||
ColorMatrix colorMatrix = new ColorMatrix(colorMatrixElements);
|
||||
ImageAttributes imageAttributes = new ImageAttributes();
|
||||
imageAttributes.SetColorMatrix(
|
||||
colorMatrix,
|
||||
ColorMatrixFlag.Default,
|
||||
ColorAdjustType.Bitmap);
|
||||
for (int i = 0; i < ModelData.Count; i++)
|
||||
{
|
||||
G.ResetTransform();
|
||||
G.TranslateTransform(Render.Width / 2 - ((i * RenderResolution / 1.25f) * (float)Math.Cos(Camera.Rotation * Math.PI / 180.0)), Render.Height / 2 - (((i / 1.25f) * (float)Math.Sin(Camera.Rotation * Math.PI / 180.0)) * AngleScale));
|
||||
G.RotateTransform(Camera.Rotation);
|
||||
G.DrawImage(LayerImages[i], new Rectangle(-(LayerImages[i].Width / 2) * RenderResolution, -(LayerImages[i].Height / 2) * RenderResolution, LayerImages[i].Width * RenderResolution, LayerImages[i].Height * RenderResolution)
|
||||
, 0, 0, LayerImages[i].Width, LayerImages[i].Height, GraphicsUnit.Pixel, imageAttributes);
|
||||
}
|
||||
for (int i = 0; i < ModelData.Count; i++)
|
||||
{
|
||||
G.ResetTransform();
|
||||
G.TranslateTransform(Render.Width / 2, Render.Height / 2 - (i * AngleScale));
|
||||
G.RotateTransform(Camera.Rotation);
|
||||
G.DrawImage(LayerImages[i], new Rectangle(-(LayerImages[i].Width / 2) * RenderResolution, -(LayerImages[i].Height / 2) * RenderResolution, LayerImages[i].Width * RenderResolution, LayerImages[i].Height * RenderResolution));
|
||||
}
|
||||
int X = Camera.LocX + Camera.Width / 2;
|
||||
int Y = Camera.Height / 2 + Camera.LocY;
|
||||
R.ResetTransform();
|
||||
R.TranslateTransform(X, Y);
|
||||
R.RotateTransform(Camera.Rotation);
|
||||
R.FillRectangle(new SolidBrush(Config.BasePlateColour), Bounds[0]);
|
||||
int difference = Render.Height - Render.Width;
|
||||
R.ResetTransform();
|
||||
R.TranslateTransform(X, Y);
|
||||
R.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;
|
||||
R.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.Half;
|
||||
R.DrawImage(Render,( -Render.Width / 2)/ RenderResolution * Camera.scale, (-(Render.Width + difference) / 2)/ RenderResolution * Camera.scale, Render.Width/ RenderResolution * Camera.scale, Render.Height/ RenderResolution * Camera.scale);
|
||||
RenderedModel = Render;
|
||||
}
|
||||
public void DrawSpriteStack(Graphics G)
|
||||
{
|
||||
@@ -254,7 +322,7 @@ namespace SpriteStacker
|
||||
{
|
||||
G.ResetTransform();
|
||||
G.TranslateTransform(X, Y);
|
||||
TextureBrush TileBrush = new TextureBrush(Resources.Background);
|
||||
TextureBrush TileBrush = new TextureBrush(Resources.OpaqueBackground);
|
||||
TileBrush.ScaleTransform((1 / 32.0f) * Camera.scale * (Config.BackgroundTile / 2), (1 / 32.0f) * Camera.scale * (Config.BackgroundTile / 2));
|
||||
G.FillRectangle(TileBrush, Bounds[Camera.SelectedLayer]);
|
||||
G.DrawImage(LayerImages[Camera.SelectedLayer], Bounds[Camera.SelectedLayer]);
|
||||
@@ -263,6 +331,21 @@ namespace SpriteStacker
|
||||
|
||||
}
|
||||
}
|
||||
public void DrawSelectedLayerToImage()
|
||||
{
|
||||
Bitmap newImage = new Bitmap(Width, Length);
|
||||
for (int x = 0; x < ModelData[Camera.SelectedLayer].GetLength(0); x++)
|
||||
{
|
||||
for (int y = 0; y < ModelData[Camera.SelectedLayer].GetLength(1); y++)
|
||||
{
|
||||
if (ModelData[Camera.SelectedLayer][x, y] != null)
|
||||
{
|
||||
newImage.SetPixel(x, y, ModelData[Camera.SelectedLayer][x, y].GetColor());
|
||||
}
|
||||
}
|
||||
}
|
||||
LayerImages[Camera.SelectedLayer] = newImage;
|
||||
}
|
||||
public void DrawLayersToImages()
|
||||
{
|
||||
for (int i = 0; i < ModelData.Count; i++)
|
||||
|
||||
20
SpriteStacker/Properties/Resources.Designer.cs
generated
20
SpriteStacker/Properties/Resources.Designer.cs
generated
@@ -329,5 +329,25 @@ namespace SpriteStacker.Properties {
|
||||
return ((System.Drawing.Bitmap)(obj));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Byte[].
|
||||
/// </summary>
|
||||
internal static byte[] Monocraft {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("Monocraft", resourceCulture);
|
||||
return ((byte[])(obj));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Drawing.Bitmap.
|
||||
/// </summary>
|
||||
internal static System.Drawing.Bitmap OpaqueBackground {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("OpaqueBackground", resourceCulture);
|
||||
return ((System.Drawing.Bitmap)(obj));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -121,6 +121,12 @@
|
||||
<data name="Background" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\Background.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="Monocraft" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\Monocraft.ttf;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="OpaqueBackground" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\OpaqueBackground.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="_1" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\1.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 243 B After Width: | Height: | Size: 245 B |
BIN
SpriteStacker/Resources/Monocraft.ttf
Normal file
BIN
SpriteStacker/Resources/Monocraft.ttf
Normal file
Binary file not shown.
BIN
SpriteStacker/Resources/OpaqueBackground.png
Normal file
BIN
SpriteStacker/Resources/OpaqueBackground.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 241 B |
@@ -77,6 +77,7 @@
|
||||
<DependentUpon>Settings.settings</DependentUpon>
|
||||
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||
</Compile>
|
||||
<None Include="Resources\Monocraft.ttf" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="App.config" />
|
||||
@@ -159,6 +160,9 @@
|
||||
<ItemGroup>
|
||||
<None Include="Resources\16.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="Resources\OpaqueBackground.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="Resources\Background.png" />
|
||||
</ItemGroup>
|
||||
|
||||
Reference in New Issue
Block a user