diff --git a/Raster3D.App/Game.cs b/Raster3D.App/Game.cs new file mode 100644 index 0000000..9a8bc79 --- /dev/null +++ b/Raster3D.App/Game.cs @@ -0,0 +1,25 @@ +using Raster3D.Engine; +using Raster3D.Engine.Impl; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Raster3D.Engine.Graphics; +using Raster3D.Engine.Objects; + +namespace Raster3D.App +{ + internal class Game : CGameLoop + { + + + + + public override void exec(Engine.Engine engine) + { + Line line = new Line(new Vec2D(0, 30), new Vec2D(30,60), engine); + line._Draw(); + } + } +} diff --git a/Raster3D.App/Interfaces/IDrawable.cs b/Raster3D.App/Interfaces/IDrawable.cs new file mode 100644 index 0000000..ef37163 --- /dev/null +++ b/Raster3D.App/Interfaces/IDrawable.cs @@ -0,0 +1,14 @@ +using Microsoft.Xna.Framework; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Raster3D.App.Interfaces +{ + internal interface IDrawable + { + void draw(GameTime time); + } +} diff --git a/Raster3D.App/Interfaces/IEntity.cs b/Raster3D.App/Interfaces/IEntity.cs new file mode 100644 index 0000000..f4ccdd7 --- /dev/null +++ b/Raster3D.App/Interfaces/IEntity.cs @@ -0,0 +1,20 @@ +using Raster3D.Engine; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Raster3D.Engine.Graphics; + +namespace Raster3D.App.Interfaces +{ + internal interface IEntity + { + int id { get; set; } + Vec2D position { get; set; } + + void tick(); + void spawn(); + void free(); + } +} diff --git a/Raster3D.App/Player.cs b/Raster3D.App/Player.cs new file mode 100644 index 0000000..0e47593 --- /dev/null +++ b/Raster3D.App/Player.cs @@ -0,0 +1,32 @@ +using Raster3D.App.Interfaces; +using Raster3D.Engine; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Raster3D.Engine.Graphics; + +namespace Raster3D.App +{ + public class Player : IEntity + { + public int id { get; set; } + public Vec2D position { get; set; } + + public void tick() + { + + } + + public void spawn() + { + + } + + public void free() + { + + } + } +} diff --git a/Raster3D.App/Program.cs b/Raster3D.App/Program.cs new file mode 100644 index 0000000..0f588b5 --- /dev/null +++ b/Raster3D.App/Program.cs @@ -0,0 +1,29 @@ +using Raster3D.Engine; +using Raster3D.Engine.Impl; + + +namespace Raster3D.App +{ + public class App : IRunnable + { + public static Engine.Engine engine; + + public string WindowTitle { get; set; } = "Raster3D Testing Application"; + + public App() + { + engine = new Engine.Engine(this, new Game()); + } + + public void Run(string[] args) + { + engine.Run(); + } + + static void Main(string[] args) + { + IRunnable app = new App(); + app.Run(args); + } + } +} \ No newline at end of file diff --git a/Raster3D.App/Raster3D.App.csproj b/Raster3D.App/Raster3D.App.csproj new file mode 100644 index 0000000..0e35c1b --- /dev/null +++ b/Raster3D.App/Raster3D.App.csproj @@ -0,0 +1,14 @@ + + + + Exe + net9.0-windows + enable + enable + + + + + + + diff --git a/Raster3D.slnx b/Raster3D.slnx new file mode 100644 index 0000000..c729c7f --- /dev/null +++ b/Raster3D.slnx @@ -0,0 +1,4 @@ + + + + diff --git a/Raster3D/.config/dotnet-tools.json b/Raster3D/.config/dotnet-tools.json new file mode 100644 index 0000000..ffcc32a --- /dev/null +++ b/Raster3D/.config/dotnet-tools.json @@ -0,0 +1,36 @@ +{ + "version": 1, + "isRoot": true, + "tools": { + "dotnet-mgcb": { + "version": "3.8.5", + "commands": [ + "mgcb" + ] + }, + "dotnet-mgcb-editor": { + "version": "3.8.5", + "commands": [ + "mgcb-editor" + ] + }, + "dotnet-mgcb-editor-linux": { + "version": "3.8.5", + "commands": [ + "mgcb-editor-linux" + ] + }, + "dotnet-mgcb-editor-windows": { + "version": "3.8.5", + "commands": [ + "mgcb-editor-windows" + ] + }, + "dotnet-mgcb-editor-mac": { + "version": "3.8.5", + "commands": [ + "mgcb-editor-mac" + ] + } + } +} \ No newline at end of file diff --git a/Raster3D/.vscode/launch.json b/Raster3D/.vscode/launch.json new file mode 100644 index 0000000..1a1266f --- /dev/null +++ b/Raster3D/.vscode/launch.json @@ -0,0 +1,14 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "C#: Raster3D Debug", + "type": "dotnet", + "request": "launch", + "projectPath": "${workspaceFolder}/Raster3D.csproj" + } + ], + } \ No newline at end of file diff --git a/Raster3D/Content/Content.mgcb b/Raster3D/Content/Content.mgcb new file mode 100644 index 0000000..3c42606 --- /dev/null +++ b/Raster3D/Content/Content.mgcb @@ -0,0 +1,15 @@ + +#----------------------------- Global Properties ----------------------------# + +/outputDir:bin/$(Platform) +/intermediateDir:obj/$(Platform) +/platform:Windows +/config: +/profile:Reach +/compress:False + +#-------------------------------- References --------------------------------# + + +#---------------------------------- Content ---------------------------------# + diff --git a/Raster3D/Engine.cs b/Raster3D/Engine.cs new file mode 100644 index 0000000..fa2b66d --- /dev/null +++ b/Raster3D/Engine.cs @@ -0,0 +1,71 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using Microsoft.Xna.Framework.Input; +using Raster3D.Engine.Impl; +using Raster3D.Engine.Graphics; + +namespace Raster3D.Engine +{ + public class Engine : Game + { + private GraphicsDeviceManager _graphics; + private SpriteBatch _spriteBatch; + + public Pixel[] pixels; + public Renderer renderer = new Renderer(); + public IRunnable TargetApplication; + + public CGameLoop loop; + + + public Engine(IRunnable Application, CGameLoop EngineLoop) + { + _graphics = new GraphicsDeviceManager(this); + Content.RootDirectory = "Content"; + IsMouseVisible = true; + TargetApplication = Application; + loop = EngineLoop; + } + + + + protected override void Initialize() + { + // Allocate pixel array based on current viewport size + pixels = new Pixel[GraphicsDevice.Viewport.Width * GraphicsDevice.Viewport.Height]; + Window.Title = TargetApplication.WindowTitle; + base.Initialize(); + + } + + protected override void LoadContent() + { + _spriteBatch = new SpriteBatch(GraphicsDevice); + } + + protected override void Update(GameTime gameTime) + { + if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape)) + Exit(); + + base.Update(gameTime); + } + + protected override void Draw(GameTime gameTime) + { + + if (loop != null) + { + loop.exec(this); + } + + + GraphicsDevice.Clear(Color.Black); + _spriteBatch.Begin(); + renderer.RenderFrame(pixels, _spriteBatch, GraphicsDevice, GraphicsDevice.Viewport.Width, GraphicsDevice.Viewport.Height); + _spriteBatch.End(); + + base.Draw(gameTime); + } + } +} \ No newline at end of file diff --git a/Raster3D/Graphics/Pixel.cs b/Raster3D/Graphics/Pixel.cs new file mode 100644 index 0000000..967048d --- /dev/null +++ b/Raster3D/Graphics/Pixel.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Raster3D.Engine.Graphics +{ + public struct Pixel + { + public int X; + public int Y; + public rgb color; + + public Pixel(int _x, int _y, rgb _color) + { + X = _x; + Y = _y; + color = _color; + } + } +} diff --git a/Raster3D/Graphics/Vec2D.cs b/Raster3D/Graphics/Vec2D.cs new file mode 100644 index 0000000..761e627 --- /dev/null +++ b/Raster3D/Graphics/Vec2D.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Raster3D.Engine.Graphics +{ + public struct Vec2D + { + public int X; + public int Y; + + public Vec2D(int x, int y) + { + X = x; + Y = y; + } + } +} diff --git a/Raster3D/Graphics/rgb.cs b/Raster3D/Graphics/rgb.cs new file mode 100644 index 0000000..154c3f1 --- /dev/null +++ b/Raster3D/Graphics/rgb.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Raster3D.Engine.Graphics +{ + public struct rgb + { + public float r; + public float g; + public float b; + + public rgb(float _r, float _g, float _b) + { + r = _r; + g = _g; + b = _b; + } + } +} diff --git a/Raster3D/Icon.ico b/Raster3D/Icon.ico new file mode 100644 index 0000000..7d9dec1 Binary files /dev/null and b/Raster3D/Icon.ico differ diff --git a/Raster3D/Impl/CGameLoop.cs b/Raster3D/Impl/CGameLoop.cs new file mode 100644 index 0000000..be00c23 --- /dev/null +++ b/Raster3D/Impl/CGameLoop.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Raster3D.Engine; + +namespace Raster3D.Engine.Impl +{ + public abstract class CGameLoop + { + public abstract void exec(Engine engine); + } +} diff --git a/Raster3D/Impl/IObject.cs b/Raster3D/Impl/IObject.cs new file mode 100644 index 0000000..82d9c02 --- /dev/null +++ b/Raster3D/Impl/IObject.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Raster3D.Engine.Impl +{ + public interface IObject + { + IObject[] children { get; set; } + void _Draw(); + void _Free(); + } +} diff --git a/Raster3D/Impl/IRunnable.cs b/Raster3D/Impl/IRunnable.cs new file mode 100644 index 0000000..7121d88 --- /dev/null +++ b/Raster3D/Impl/IRunnable.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Raster3D.Engine.Impl +{ + public interface IRunnable + { + string WindowTitle { get; set; } + void Run(string[] args); + } +} diff --git a/Raster3D/OObjects.cs b/Raster3D/OObjects.cs new file mode 100644 index 0000000..88bc03f --- /dev/null +++ b/Raster3D/OObjects.cs @@ -0,0 +1,78 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Raster3D.Engine.Graphics; + +namespace Raster3D.Engine +{ + public class OObjects + { + public void Line(Vec2D pos1, Vec2D pos2, rgb clr, Engine engine) + { + int x0 = (int)pos1.X; + int y0 = (int)pos1.Y; + int x1 = (int)pos2.X; + int y1 = (int)pos2.Y; + + int dx = Math.Abs(x1 - x0); + int dy = Math.Abs(y1 - y0); + + int sx = x0 < x1 ? 1 : -1; + int sy = y0 < y1 ? 1 : -1; + + int err = dx - dy; + + int screenWidth = engine.GraphicsDevice.Viewport.Width; + int screenHeight = engine.GraphicsDevice.Viewport.Height; + + while (true) + { + if (x0 >= 0 && x0 < screenWidth && y0 >= 0 && y0 < screenHeight) + { + int index = (y0 * screenWidth) + x0; + engine.pixels[index] = new Pixel(x0, y0, clr); + } + + if (x0 == x1 && y0 == y1) break; + + int e2 = 2 * err; + + if (e2 > -dy) + { + err -= dy; + x0 += sx; + } + + if (e2 < dx) + { + err += dx; + y0 += sy; + } + } + } + + public void Triangle(Vec2D[] positions, rgb[] colors, Engine engine) + { + // positions should have a length of 3 and exactly 3 + // colors has 3 points + + // this just draws an array of lines + + // line 1 + Line(positions[0], positions[1], colors[0], engine); // pos1 - pos2 + + // line 2 + Line(positions[1], positions[2], colors[1], engine); // pos2 - pos3 + + // line 3 + Line(positions[2], positions[0], colors[2], engine); // pos3 - back to pos1 + } + + public void Square(Vec2D[] points, rgb[] colors, Engine engine) + { + // TODO: implemen t this + } + } +} diff --git a/Raster3D/Objects/Line.cs b/Raster3D/Objects/Line.cs new file mode 100644 index 0000000..ce956a6 --- /dev/null +++ b/Raster3D/Objects/Line.cs @@ -0,0 +1,123 @@ +using Raster3D.Engine.Graphics; +using Raster3D.Engine.Impl; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.ConstrainedExecution; +using System.Text; +using System.Threading.Tasks; + +namespace Raster3D.Engine.Objects +{ + public class Line : IObject + { + // This is the base class for all IObject things that use primative lines + + + // implement children + public IObject[] children { get; set; } + + + // cast variaibles + private Vec2D _pos1; + private Vec2D _pos2; + private rgb _clr; + private int _width; + private Engine _engine; + private bool canDraw = true; + + private enum ECastType + { + Standard, + PlainColour, + CustomWidth + } + + private ECastType castType; + + + // legacy cast for some ammount of backwards compat + public Line(Vec2D pos1, Vec2D pos2, rgb clr, Engine engine) + { + _pos1 = pos1; + _pos2 = pos2; + _clr = clr; + _engine = engine; + castType = ECastType.Standard; + } + + // csat with plain white colour + public Line(Vec2D pos1, Vec2D pos2, Engine engine) + { + _pos1 = pos1; + _pos2 = pos2; + _engine = engine; + _clr = new rgb(1.0f, 1.0f, 1.0f); + castType = ECastType.PlainColour; + } + + // cast with custom width + public Line(Vec2D pos1, Vec2D pos2, rgb clr, int width, Engine engine) + { + _pos1 = pos1; + _pos2 = pos2; + _clr = clr; + _engine = engine; + _width = width; + castType = ECastType.CustomWidth; + } + + // draw call + public void _Draw() + { + int x0 = (int)_pos1.X; + int y0 = (int)_pos1.Y; + int x1 = (int)_pos2.X; + int y1 = (int)_pos2.Y; + + int dx = Math.Abs(x1 - x0); + int dy = Math.Abs(y1 - y0); + + int sx = x0 < x1 ? 1 : -1; + int sy = y0 < y1 ? 1 : -1; + + int err = dx - dy; + + int screenWidth = _engine.GraphicsDevice.Viewport.Width; + int screenHeight = _engine.GraphicsDevice.Viewport.Height; + + while (canDraw) + { + if (x0 >= 0 && x0 < screenWidth && y0 >= 0 && y0 < screenHeight) + { + int index = (y0 * screenWidth) + x0; + _engine.pixels[index] = new Pixel(x0, y0, _clr); + } + + if (x0 == x1 && y0 == y1) break; + + int e2 = 2 * err; + + if (e2 > -dy) + { + err -= dy; + x0 += sx; + } + + if (e2 < dx) + { + err += dx; + y0 += sy; + } + } + + + } + + // destroy call + public void _Free() + { + + } + } +} diff --git a/Raster3D/Objects/Triangle.cs b/Raster3D/Objects/Triangle.cs new file mode 100644 index 0000000..88b1e88 --- /dev/null +++ b/Raster3D/Objects/Triangle.cs @@ -0,0 +1,39 @@ +using Raster3D.Engine.Graphics; +using Raster3D.Engine.Impl; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Raster3D.Engine.Objects +{ + public class Triangle : IObject + { + public IObject[] children { get; set; } = new IObject[3]; + + // positions array + private Vec2D[] _positions; + private rgb[] _clrs; + private Engine _engine; + + public Triangle(Vec2D[] positions, rgb[] colors, Engine engine) + { + _positions = positions; + _clrs = colors; + _engine = engine; + } + + public void _Draw() + { + children.Append(new Line(_positions[0], _positions[1], _clrs[0], _engine)); + children.Append(new Line(_positions[1], _positions[2], _clrs[1], _engine)); + children.Append(new Line(_positions[2], _positions[1], _clrs[2], _engine)); + } + + public void _Free() + { + throw new NotImplementedException(); + } + } +} diff --git a/Raster3D/Raster3D.Engine.csproj b/Raster3D/Raster3D.Engine.csproj new file mode 100644 index 0000000..834c7f3 --- /dev/null +++ b/Raster3D/Raster3D.Engine.csproj @@ -0,0 +1,18 @@ + + + Library + net9.0-windows + Major + false + false + true + + + app.manifest + Icon.ico + + + + + + \ No newline at end of file diff --git a/Raster3D/Renderer.cs b/Raster3D/Renderer.cs new file mode 100644 index 0000000..3350a0d --- /dev/null +++ b/Raster3D/Renderer.cs @@ -0,0 +1,39 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using Raster3D.Engine.Graphics; + +namespace Raster3D.Engine +{ + public class Renderer + { + private Texture2D _frameBufferTexture; + private Color[] _colorData; + + public void RenderFrame(Pixel[] pixels, SpriteBatch batch, GraphicsDevice device, int width, int height) + { + if (_frameBufferTexture == null || _frameBufferTexture.Width != width || _frameBufferTexture.Height != height) + { + _frameBufferTexture?.Dispose(); + _frameBufferTexture = new Texture2D(device, width, height); + _colorData = new Color[width * height]; + } + + for (int i = 0; i < _colorData.Length; i++) + { + _colorData[i] = Color.Black; + } + + foreach (var p in pixels) + { + if (p.X >= 0 && p.X < width && p.Y >= 0 && p.Y < height) + { + int index = (p.Y * width) + p.X; + _colorData[index] = new Color(p.color.r, p.color.g, p.color.b, 1.0f); + } + } + + _frameBufferTexture.SetData(_colorData); + batch.Draw(_frameBufferTexture, Vector2.Zero, Color.White); + } + } +} \ No newline at end of file diff --git a/Raster3D/app.manifest b/Raster3D/app.manifest new file mode 100644 index 0000000..a2f6071 --- /dev/null +++ b/Raster3D/app.manifest @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + permonitorv2,permonitor + + + + diff --git a/docs/Line.md b/docs/Line.md new file mode 100644 index 0000000..fcefe11 --- /dev/null +++ b/docs/Line.md @@ -0,0 +1,17 @@ +# Line + +### [RenderObject](RenderObject.md) < [Pixel](Pixel.md) < [Line](Line.md) + +## + +The line primitave is a simple one, comprised of 2 Vec2D points + +## +## Arguments + +| Name | Type | Need | +| ---- | ---- | ---- | +| pos1 | [Vec2D]() | The first position of a line | +| pos2 | [Vec2D]() | The second position of a line | +| color | [rgb]() | The fill color of the line | +| engine | [Engine]() | The call for the engine, used to access the pixbuf \ No newline at end of file diff --git a/docs/Objects.md b/docs/Objects.md new file mode 100644 index 0000000..68f4a84 --- /dev/null +++ b/docs/Objects.md @@ -0,0 +1,12 @@ +# Raster3D Objects docs + +Raster3D contains a few builtin objects that can be used to draw shapes and primitaves onscreen. + +Below is an exhaustive tree list of objects and links to their documentation. + + +- [RenderObject](RenderObject.md) + - [Pixel](Pixel.md) + - [Line](Line.md) + - [Triangle](Triangle.md) + - [Square](Square.md) \ No newline at end of file diff --git a/docs/Pixel.md b/docs/Pixel.md new file mode 100644 index 0000000..621163c --- /dev/null +++ b/docs/Pixel.md @@ -0,0 +1,3 @@ +# Pixel + +### [RenderObject]() < [Pixel](objects/Pixel.md) \ No newline at end of file diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/RenderObject.md b/docs/RenderObject.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/Triangle.md b/docs/Triangle.md new file mode 100644 index 0000000..504e2ae --- /dev/null +++ b/docs/Triangle.md @@ -0,0 +1,13 @@ +# Triangle + +### [RenderObject](RenderObject.md) < [Pixel](Pixel.md) < [Line](Line.md) < [Triangle](Triangle.md) + +## + +Description + +## +## Arguments + +| Name | Type | Need | +| ---- | ---- | ---- | diff --git a/docs/template.md b/docs/template.md new file mode 100644 index 0000000..15827b5 --- /dev/null +++ b/docs/template.md @@ -0,0 +1,13 @@ +# Template + +### [ThingThatExtended]() < [Thing]() + +## + +Description + +## +## Arguments + +| Name | Type | Need | +| ---- | ---- | ---- |