diff --git a/src/SlatedGameToolkit.Framework/DataTypes/Colour.cs b/src/SlatedGameToolkit.Framework/DataTypes/Colour.cs
deleted file mode 100644
index cc2a00f..0000000
--- a/src/SlatedGameToolkit.Framework/DataTypes/Colour.cs
+++ /dev/null
@@ -1,7 +0,0 @@
-namespace SlatedGameToolkit.Framework.DataTypes
-{
- public struct Colour {
- public volatile float r, g, b;
-
- }
-}
\ No newline at end of file
diff --git a/src/SlatedGameToolkit.Framework/DataTypes/FloatRectangle.cs b/src/SlatedGameToolkit.Framework/DataTypes/FloatRectangle.cs
deleted file mode 100644
index 147f18a..0000000
--- a/src/SlatedGameToolkit.Framework/DataTypes/FloatRectangle.cs
+++ /dev/null
@@ -1,67 +0,0 @@
-using System;
-
-namespace SlatedGameToolkit.Framework.DataTypes
-{
- public struct FloatRectangle {
- public FloatVector2 BottomLeft, TopRight;
-
- public float Width {
- get {
- return Math.Abs(BottomLeft.x - TopRight.x);
- }
- set {
- TopRight.x = BottomLeft.x + value;
- }
- }
-
- public float Height {
- get {
- return Math.Abs(BottomLeft.y - TopRight.y);
- }
- set {
- TopRight.y = BottomLeft.y + value;
- }
- }
-
- public float X1 {
- get {
- return BottomLeft.x;
- }
-
- set {
- BottomLeft.x = value;
- }
- }
-
- public float X2 {
- get {
- return TopRight.x;
- }
-
- set {
- TopRight.x = value;
- }
- }
-
- public float Y1 {
- get {
- return BottomLeft.y;
- }
-
- set {
- BottomLeft.y = value;
- }
- }
-
- public float Y2 {
- get {
- return TopRight.y;
- }
-
- set {
- TopRight.y = value;
- }
- }
-
- }
-}
\ No newline at end of file
diff --git a/src/SlatedGameToolkit.Framework/DataTypes/FloatVector2.cs b/src/SlatedGameToolkit.Framework/DataTypes/FloatVector2.cs
deleted file mode 100644
index fd72c0d..0000000
--- a/src/SlatedGameToolkit.Framework/DataTypes/FloatVector2.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-namespace SlatedGameToolkit.Framework.DataTypes
-{
- public struct FloatVector2 {
- public volatile float x, y;
-
- public FloatVector2(float x, float y) {
- this.x = x;
- this.y = y;
- }
- }
-}
\ No newline at end of file
diff --git a/src/SlatedGameToolkit.Framework/Exceptions/OpenGLErrorException.cs b/src/SlatedGameToolkit.Framework/Exceptions/OpenGLErrorException.cs
new file mode 100644
index 0000000..110fdbd
--- /dev/null
+++ b/src/SlatedGameToolkit.Framework/Exceptions/OpenGLErrorException.cs
@@ -0,0 +1,29 @@
+using System;
+using SlatedGameToolkit.Framework.Graphics;
+using SlatedGameToolkit.Framework.Graphics.Window;
+
+namespace SlatedGameToolkit.Framework.Exceptions
+{
+ public class OpenGLErrorException : OpenGLException {
+ public uint ErrorCode { get; private set; }
+ public OpenGLErrorException(uint errorCode) : base() {
+ }
+
+ public OpenGLErrorException(uint errorCode, string message) : base(message) {
+
+ }
+
+ public OpenGLErrorException(uint errorCode, string message, Exception inner) : base(message, inner) {
+ }
+
+ ///
+ /// Checks the current context for OpenGL errors that has occurred and throws an exception if there is one.
+ ///
+ public static void CheckGLErrorStatus() {
+ uint errorCode = WindowContextsManager.CurrentWindowContext.GetGLStatus();
+ if (errorCode != (uint) GLEnums.GL_NO_ERROR) {
+ throw new OpenGLErrorException(errorCode, "OpenGL error: " + errorCode.ToString());
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/SlatedGameToolkit.Framework/Exceptions/OpenGLException.cs b/src/SlatedGameToolkit.Framework/Exceptions/OpenGLException.cs
index efaff0b..e7b18ab 100644
--- a/src/SlatedGameToolkit.Framework/Exceptions/OpenGLException.cs
+++ b/src/SlatedGameToolkit.Framework/Exceptions/OpenGLException.cs
@@ -1,4 +1,6 @@
using System;
+using SlatedGameToolkit.Framework.Graphics;
+using SlatedGameToolkit.Framework.Graphics.Window;
namespace SlatedGameToolkit.Framework.Exceptions
{
diff --git a/src/SlatedGameToolkit.Framework/GameEngine.cs b/src/SlatedGameToolkit.Framework/GameEngine.cs
index b62eda1..e0c2801 100644
--- a/src/SlatedGameToolkit.Framework/GameEngine.cs
+++ b/src/SlatedGameToolkit.Framework/GameEngine.cs
@@ -78,10 +78,10 @@ namespace SlatedGameToolkit.Framework {
IState initialState = (IState) o;
Manager manager = new Manager(initialState);
DateTime currentTime = DateTime.Now;
- TimeSpan timePassedFromLastUpdate;
- TimeSpan timePassedFromLastRender;
- TimeSpan updateDeltaTime;
- TimeSpan frameDeltaTime;
+ TimeSpan timePassedFromLastUpdate = TimeSpan.Zero;
+ TimeSpan timePassedFromLastRender = TimeSpan.Zero;
+ TimeSpan updateDeltaTime = GameEngine.updateDeltaTime;
+ TimeSpan frameDeltaTime = GameEngine.frameDeltaTime;
deltaChanged = true;
stopped = false;
Logger.Information("Game engine initiated.");
@@ -95,11 +95,6 @@ namespace SlatedGameToolkit.Framework {
}
deltaChanged = false;
}
-
- DateTime frameStart = DateTime.Now;
- TimeSpan difference = frameStart - currentTime;
- currentTime = frameStart;
-
//Events
SDL.SDL_Event SDL_Event;
while (SDL.SDL_PollEvent(out SDL_Event) != 0) {
@@ -154,7 +149,10 @@ namespace SlatedGameToolkit.Framework {
break;
}
}
-
+ DateTime frameStart = DateTime.Now;
+ TimeSpan difference = frameStart - currentTime;
+ currentTime = frameStart;
+
timePassedFromLastUpdate += difference;
while (timePassedFromLastUpdate > updateDeltaTime) {
//Updates.
@@ -226,7 +224,7 @@ namespace SlatedGameToolkit.Framework {
throw new FrameworkSDLException();
}
- if (SDL.SDL_GL_SetAttribute(SDL.SDL_GLattr.SDL_GL_CONTEXT_MAJOR_VERSION, 4) < 0) throw new FrameworkSDLException();
+ if (SDL.SDL_GL_SetAttribute(SDL.SDL_GLattr.SDL_GL_CONTEXT_MAJOR_VERSION, 3) < 0) throw new FrameworkSDLException();
if (SDL.SDL_GL_SetAttribute(SDL.SDL_GLattr.SDL_GL_CONTEXT_MINOR_VERSION, 1) < 0) throw new FrameworkSDLException();
if (SDL.SDL_GL_SetAttribute(SDL.SDL_GLattr.SDL_GL_CONTEXT_PROFILE_MASK, SDL.SDL_GLprofile.SDL_GL_CONTEXT_PROFILE_CORE) < 0) throw new FrameworkSDLException();
diff --git a/src/SlatedGameToolkit.Framework/Graphics/OpenGL/GLEnums.cs b/src/SlatedGameToolkit.Framework/Graphics/GLEnums.cs
similarity index 99%
rename from src/SlatedGameToolkit.Framework/Graphics/OpenGL/GLEnums.cs
rename to src/SlatedGameToolkit.Framework/Graphics/GLEnums.cs
index 5a01f1a..a8a131c 100644
--- a/src/SlatedGameToolkit.Framework/Graphics/OpenGL/GLEnums.cs
+++ b/src/SlatedGameToolkit.Framework/Graphics/GLEnums.cs
@@ -1,4 +1,4 @@
-namespace SlatedGameToolkit.Framework.Graphics.OpenGL
+namespace SlatedGameToolkit.Framework.Graphics
{
internal enum GLEnums: uint {
GL_DEPTH_BUFFER_BIT = 0x00000100,
@@ -807,9 +807,5 @@ namespace SlatedGameToolkit.Framework.Graphics.OpenGL
GL_MAX_COLOR_TEXTURE_SAMPLES = 0x910E,
GL_MAX_DEPTH_TEXTURE_SAMPLES = 0x910F,
GL_MAX_INTEGER_SAMPLES = 0x9110,
- //
- GL_PROGRAM_SEPARABLE = 0x8258,
- GL_FRAGMENT_SHADER_BIT = 0x00000002,
- GL_VERTEX_SHADER_BIT = 0x00000001,
}
}
\ No newline at end of file
diff --git a/src/SlatedGameToolkit.Framework/Graphics/GLFunctionDelegates.cs b/src/SlatedGameToolkit.Framework/Graphics/GLFunctionDelegates.cs
new file mode 100644
index 0000000..5c02247
--- /dev/null
+++ b/src/SlatedGameToolkit.Framework/Graphics/GLFunctionDelegates.cs
@@ -0,0 +1,62 @@
+using System;
+using System.Runtime.InteropServices;
+using SDL2;
+using SlatedGameToolkit.Framework.Exceptions;
+
+namespace SlatedGameToolkit.Framework.Graphics
+{
+ internal delegate void GLClearColour(float r, float g, float b);
+ internal delegate void GLClear(GLEnums flags);
+ internal delegate void GLViewport(int x, int y, int width, int height);
+ internal delegate UIntPtr GLCreateShader(GLEnums type);
+ internal delegate UIntPtr GLShaderSource(UIntPtr shaderHandle, uint count, string program, int[] length);
+ internal delegate void GLCompileShader(UIntPtr shaderHandle);
+ internal delegate void GLGetShaderLogInfo(UIntPtr shader, uint maxLength, out uint writtenLength, out string output);
+ internal delegate UIntPtr GLCreateProgram();
+ internal delegate UIntPtr GLDeleteProgram(UIntPtr program);
+ internal delegate void GLAttachShader(UIntPtr program, UIntPtr shader);
+ internal delegate void GLDetachShader(UIntPtr program, UIntPtr shader);
+ internal delegate void GLDeleteShader(UIntPtr shader);
+ internal delegate void GLBindAttribLocation(UIntPtr program, uint index, string name);
+ internal delegate void GLGetProgramInfoLog(UIntPtr program, uint maxLength, out uint writtenLength, out string output);
+ internal delegate void GLLinkProgram(UIntPtr program);
+ internal delegate void GLProgramParameter(UIntPtr program, GLEnums parameterName, int value);
+ internal delegate void GLUseProgram(UIntPtr program);
+ internal delegate void GLGenProgramPipelines(uint size, out UIntPtr[] pipelines);
+ internal delegate void GLDeleteProgramPipelines(uint size, UIntPtr[] pipelines);
+ internal delegate void GLBindProgramPipeline(UIntPtr pipeline);
+ internal delegate void GLUseProgramStages(UIntPtr pipeline, GLEnums bitField, UIntPtr program);
+ internal delegate uint GLGetError();
+ internal delegate int GLGetAttribLocation(UIntPtr program, string attribName);
+ internal delegate void GLBindBuffer(GLEnums target, UIntPtr buffer);
+ internal delegate void GLGenBuffers(uint size, UIntPtr[] buffers);
+ internal unsafe delegate void GLBufferData(GLEnums target, uint size, void* data, GLEnums usage);
+ internal delegate void GLDeleteBuffers(uint size, UIntPtr[] buffers);
+ internal delegate void GLVertexAttribPointer(uint index, int size, GLEnums type, bool normalized, uint stride, uint offset);
+ internal delegate void GLGenVertexArrays(uint amount, UIntPtr[] arrays);
+ internal delegate void GLDeleteVertexArrays(uint amount, UIntPtr[] arrays);
+ internal delegate void GLBindVertexArray(UIntPtr array);
+ internal delegate void GLEnableVertexAttribArray(uint attribIndex);
+ internal delegate void GLDisableVertexAttribArray(uint attribIndex);
+ internal delegate void GLDrawArrays(GLEnums mode, int first, uint count);
+ internal delegate void GLDrawElements(GLEnums mode, uint count, int offset);
+ internal delegate void GLMultiDrawArrays(GLEnums mode, int[] first, uint[] count, uint primout);
+ internal delegate void GLMultiDrawElements(GLEnums mode, uint[] count, GLEnums type, uint[] indices);
+ internal delegate void GLGenTextures(uint n, UIntPtr[] textureHandles);
+ internal delegate void GLBindTexture(GLEnums target, UIntPtr texture);
+ internal delegate void GLDeleteTextures(uint n, UIntPtr[] textureHandles);
+ internal delegate void GLTexParameteri(GLEnums target, GLEnums pname, int value);
+ internal delegate void GLTexParameterf(GLEnums target, GLEnums pname, float value);
+ internal delegate void GLTexParameteriv(GLEnums target, GLEnums pname, int[] values);
+ internal delegate void GLTexParameterfv(GLEnums target, GLEnums pname, float[] values);
+ internal delegate void GLTexImage2D(GLEnums target, int level, int internalFormat, uint width, uint height, int border, GLEnums format, GLEnums type, byte[] data);
+ internal delegate void GLGenerateMipMap(GLEnums target);
+
+ internal static class GLFunctionUtils {
+ public static T RetrieveGLDelegate(string functionName) where T : Delegate {
+ IntPtr functionAddress = SDL.SDL_GL_GetProcAddress(functionName);
+ if (functionAddress == null) throw new FrameworkSDLException();
+ return Marshal.GetDelegateForFunctionPointer(functionAddress);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/SlatedGameToolkit.Framework/Graphics/Meshes/IMeshable.cs b/src/SlatedGameToolkit.Framework/Graphics/Meshes/IMeshable.cs
index 8456221..87773c0 100644
--- a/src/SlatedGameToolkit.Framework/Graphics/Meshes/IMeshable.cs
+++ b/src/SlatedGameToolkit.Framework/Graphics/Meshes/IMeshable.cs
@@ -1,8 +1,20 @@
+
+using System;
+using System.Numerics;
+
namespace SlatedGameToolkit.Framework.Graphics.Meshes
{
public interface IMeshable
{
- float[] Vertices { get; }
- float[] Elements { get; }
+
+ ///
+ /// Each value in the array represents a 3D coordinate for the vertex, as well as a 2D texture coordinate.
+ ///
+ ///
+ ValueTuple[] Vertices { get; }
+ uint[] Elements { get; }
+ Vector3 Rotation { get; set; }
+ Vector3 Translation { get; set; }
+ Vector3 Scale { get; set; }
}
}
\ No newline at end of file
diff --git a/src/SlatedGameToolkit.Framework/Graphics/Meshes/RectangleMesh.cs b/src/SlatedGameToolkit.Framework/Graphics/Meshes/RectangleMesh.cs
new file mode 100644
index 0000000..04f85f4
--- /dev/null
+++ b/src/SlatedGameToolkit.Framework/Graphics/Meshes/RectangleMesh.cs
@@ -0,0 +1,130 @@
+using System;
+using System.Drawing;
+using System.Numerics;
+
+namespace SlatedGameToolkit.Framework.Graphics.Meshes
+{
+ public class RectangleMesh : IMeshable
+ {
+ private bool changed = true;
+ private Matrix4x4 matRot, matTrans, matScale;
+ private Vector3 rotation, translation, scale;
+ private Vector2 origin, dimensions;
+ public readonly Vector2[] texCoords = new Vector2[4];
+ private ValueTuple[] vertices = new ValueTuple[4];
+ private uint[] indices = new uint[] {0, 1, 3, 1, 2, 3};
+
+ public ValueTuple[] Vertices
+ {
+ get {
+ if (changed) CalculateVertices();
+ return vertices;
+ }
+ }
+
+ public float X {
+ get
+ {
+ return origin.X;
+ }
+
+ set
+ {
+ origin.X = X;
+ }
+ }
+
+ public float Y {
+ get
+ {
+ return origin.Y;
+ }
+
+ set
+ {
+ origin.Y = value;
+ }
+ }
+
+ public float Width
+ {
+ get
+ {
+ return dimensions.X;
+ }
+
+ set {
+ dimensions.X = value;
+ }
+ }
+
+ public float Height
+ {
+ get
+ {
+ return dimensions.Y;
+ }
+
+ set
+ {
+ dimensions.Y = value;
+ }
+ }
+
+ public uint[] Elements { get {return indices; } }
+
+ public Vector3 Translation
+ {
+ get {
+ return rotation;
+ }
+ set {
+ changed = true;
+ translation = value;
+ matTrans = Matrix4x4.CreateTranslation(value);
+ }
+ }
+
+ public Vector3 Scale
+ {
+ get {
+ return scale;
+ }
+
+ set {
+ changed = true;
+ scale = value;
+ matScale = Matrix4x4.CreateScale(value);
+ }
+ }
+
+ public Vector3 Rotation
+ {
+ get
+ {
+ return rotation;
+ }
+
+ set
+ {
+ changed = true;
+ rotation = value;
+ matRot = Matrix4x4.CreateFromYawPitchRoll(value.X, value.Y, value.Z);
+ }
+ }
+ private void CalculateVertices() {
+ Vector3[] baseVerts = new Vector3[4];
+ baseVerts[0] = new Vector3(this.origin, 0);
+ baseVerts[1] = new Vector3(this.origin.X + this.dimensions.X, this.origin.Y, 0);
+ baseVerts[2] = new Vector3(baseVerts[1].X, this.origin.Y + this.dimensions.Y, 0);
+ baseVerts[3] = new Vector3(this.origin.X, baseVerts[2].Y, 0);
+
+ Matrix4x4 transform = matTrans * matRot * matScale;
+ for (int i = 0; i < vertices.Length; i++)
+ {
+ vertices[i] = new ValueTuple(Vector3.Transform(baseVerts[i], transform), texCoords[i]);
+ }
+ changed = false;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/SlatedGameToolkit.Framework/Graphics/OpenGL/GLFunctionDelegates.cs b/src/SlatedGameToolkit.Framework/Graphics/OpenGL/GLFunctionDelegates.cs
deleted file mode 100644
index be93cf4..0000000
--- a/src/SlatedGameToolkit.Framework/Graphics/OpenGL/GLFunctionDelegates.cs
+++ /dev/null
@@ -1,27 +0,0 @@
-using System;
-
-namespace SlatedGameToolkit.Framework.Graphics.OpenGL
-{
- internal delegate void GLClearColour(float r, float g, float b);
- internal delegate void GLClear(GLEnums flags);
- internal delegate void GLViewport(int x, int y, int width, int height);
- internal delegate UIntPtr GLCreateShader(GLEnums type);
- internal delegate UIntPtr GLShaderSource(UIntPtr shaderHandle, uint count, string program, int[] length);
- internal delegate void GLCompileShader(UIntPtr shaderHandle);
- internal delegate void GLGetShaderLogInfo(UIntPtr shader, uint maxLength, out uint writtenLength, out string output);
- internal delegate UIntPtr GLCreateProgram();
- internal delegate UIntPtr GLDeleteProgram(UIntPtr program);
- internal delegate void GLAttachShader(UIntPtr program, UIntPtr shader);
- internal delegate void GLDetachShader(UIntPtr program, UIntPtr shader);
- internal delegate void GLDeleteShader(UIntPtr shader);
- internal delegate void GLBindAttribLocation(UIntPtr program, uint index, string name);
- internal delegate void GLGetProgramInfoLog(UIntPtr program, uint maxLength, out uint writtenLength, out string output);
- internal delegate void GLLinkProgram(UIntPtr program);
- internal delegate void GLProgramParameter(UIntPtr program, GLEnums parameterName, int value);
- internal delegate void GLUseProgram(UIntPtr program);
- internal delegate void GLGenProgramPipelines(uint size, out UIntPtr[] pipelines);
- internal delegate void GLDeleteProgramPipelines(uint size, UIntPtr[] pipelines);
- internal delegate void GLBindProgramPipeline(UIntPtr pipeline);
- internal delegate void GLUseProgramStages(UIntPtr pipeline, GLEnums bitField, UIntPtr program);
- internal delegate uint GLGetError();
-}
\ No newline at end of file
diff --git a/src/SlatedGameToolkit.Framework/Graphics/OpenGL/Programs/GLProgram.cs b/src/SlatedGameToolkit.Framework/Graphics/OpenGL/Programs/GLProgram.cs
deleted file mode 100644
index 168023d..0000000
--- a/src/SlatedGameToolkit.Framework/Graphics/OpenGL/Programs/GLProgram.cs
+++ /dev/null
@@ -1,54 +0,0 @@
-using System;
-using System.Runtime.InteropServices;
-using SDL2;
-using SlatedGameToolkit.Framework.Exceptions;
-using SlatedGameToolkit.Framework.Graphics.Window;
-
-namespace SlatedGameToolkit.Framework.Graphics.OpenGL.Programs
-{
- public abstract class GLProgram : IDisposable
- {
- private WindowContext context;
- internal readonly UIntPtr handle;
- private protected GLCreateProgram createProgram;
- private protected GLDeleteProgram deleteProgram;
- private protected GLLinkProgram linkProgram;
- private protected GLGetProgramInfoLog getProgramInfoLog;
- private protected GLProgramParameter programParameter;
- private protected GLUseProgram useProgram;
-
- public GLProgram(bool separable = true) {
- this.context = WindowContextsManager.CurrentWindowContext();
- createProgram = Marshal.GetDelegateForFunctionPointer(SDL.SDL_GL_GetProcAddress("glCreateProgram"));
- if (createProgram == null) throw new FrameworkSDLException();
- deleteProgram = Marshal.GetDelegateForFunctionPointer(SDL.SDL_GL_GetProcAddress("glDeleteProgram"));
- if (deleteProgram == null) throw new FrameworkSDLException();
- linkProgram = Marshal.GetDelegateForFunctionPointer(SDL.SDL_GL_GetProcAddress("glLinkProgram"));
- if (linkProgram == null) throw new FrameworkSDLException();
- getProgramInfoLog = Marshal.GetDelegateForFunctionPointer(SDL.SDL_GL_GetProcAddress("glGetProgramInfoLog"));
- if (getProgramInfoLog == null) throw new FrameworkSDLException();
- programParameter = Marshal.GetDelegateForFunctionPointer(SDL.SDL_GL_GetProcAddress("glProgramParameter"));
- if (programParameter == null) throw new FrameworkSDLException();
- useProgram = Marshal.GetDelegateForFunctionPointer(SDL.SDL_GL_GetProcAddress("glUseProgram"));
- if (useProgram == null) throw new FrameworkSDLException();
-
- handle = createProgram();
- if (separable) {
- programParameter(handle, GLEnums.GL_PROGRAM_SEPARABLE, (int) GLEnums.GL_TRUE);
- }
- }
-
- public virtual void Use() {
- useProgram(handle);
- }
-
- public virtual void Dispose()
- {
- deleteProgram(handle);
- }
-
- ~GLProgram() {
- Dispose();
- }
- }
-}
\ No newline at end of file
diff --git a/src/SlatedGameToolkit.Framework/Graphics/OpenGL/Programs/GLProgramPipeline.cs b/src/SlatedGameToolkit.Framework/Graphics/OpenGL/Programs/GLProgramPipeline.cs
deleted file mode 100644
index 5448dbd..0000000
--- a/src/SlatedGameToolkit.Framework/Graphics/OpenGL/Programs/GLProgramPipeline.cs
+++ /dev/null
@@ -1,49 +0,0 @@
-using System;
-using System.Runtime.InteropServices;
-using SDL2;
-using SlatedGameToolkit.Framework.Exceptions;
-using SlatedGameToolkit.Framework.Graphics.OpenGL.Shaders;
-using SlatedGameToolkit.Framework.Graphics.Window;
-
-namespace SlatedGameToolkit.Framework.Graphics.OpenGL.Programs
-{
- public abstract class GLProgramPipeline : IDisposable {
- private readonly WindowContext associatedContext;
- private UIntPtr[] pipelines;
- private protected UIntPtr PipelineHandle { get {return pipelines[0]; } }
- private protected GLGenProgramPipelines genProgramPipelines;
- private protected GLDeleteProgramPipelines deleteProgramPipelines;
- private protected GLBindProgramPipeline bindProgramPipeline;
- private protected GLUseProgramStages useProgramStages;
- private protected GLUseProgram useProgram;
- public GLProgramPipeline() {
- associatedContext = WindowContextsManager.CurrentWindowContext();
- genProgramPipelines = Marshal.GetDelegateForFunctionPointer(SDL.SDL_GL_GetProcAddress("glGenProgramPipelines"));
- if (genProgramPipelines == null) throw new FrameworkSDLException();
- useProgramStages = Marshal.GetDelegateForFunctionPointer(SDL.SDL_GL_GetProcAddress("glUseProgramStages"));
- if (useProgramStages == null) throw new FrameworkSDLException();
- useProgram = Marshal.GetDelegateForFunctionPointer(SDL.SDL_GL_GetProcAddress("glUseProgram"));
- if (useProgram == null) throw new FrameworkSDLException();
- bindProgramPipeline = Marshal.GetDelegateForFunctionPointer(SDL.SDL_GL_GetProcAddress("glBindProgramPipeline"));
- if (bindProgramPipeline == null) throw new FrameworkSDLException();
- deleteProgramPipelines = Marshal.GetDelegateForFunctionPointer(SDL.SDL_GL_GetProcAddress("glDeleteProgramPipelines"));
- if (deleteProgramPipelines == null) throw new FrameworkSDLException();
-
- genProgramPipelines(1, out pipelines);
-
- }
-
- public virtual void Use() {
- useProgram(UIntPtr.Zero);
- }
-
- public virtual void Dispose()
- {
- deleteProgramPipelines((uint) pipelines.Length, pipelines);
- }
-
- ~GLProgramPipeline() {
- Dispose();
- }
- }
-}
\ No newline at end of file
diff --git a/src/SlatedGameToolkit.Framework/Graphics/OpenGL/Programs/GLShaderProgramPipeline.cs b/src/SlatedGameToolkit.Framework/Graphics/OpenGL/Programs/GLShaderProgramPipeline.cs
deleted file mode 100644
index b261967..0000000
--- a/src/SlatedGameToolkit.Framework/Graphics/OpenGL/Programs/GLShaderProgramPipeline.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-namespace SlatedGameToolkit.Framework.Graphics.OpenGL.Programs
-{
- public class GLShaderProgramPipeline : GLProgramPipeline {
- private GLShaderProgram fragmentShader;
- private GLShaderProgram vertexShader;
- public GLShaderProgram FragmentShader { get { return fragmentShader; } set { fragmentShader = value; useProgramStages(PipelineHandle, GLEnums.GL_FRAGMENT_SHADER_BIT, value.handle); } }
- public GLShaderProgram VertexShader { get { return vertexShader; } set { vertexShader = value; useProgramStages(PipelineHandle, GLEnums.GL_VERTEX_SHADER_BIT, value.handle); } }
-
- public GLShaderProgramPipeline() : base() {
-
- }
-
- public override void Use() {
- base.Use();
- bindProgramPipeline(PipelineHandle);
- }
- }
-}
\ No newline at end of file
diff --git a/src/SlatedGameToolkit.Framework/Graphics/OpenGL/Shaders/GLShader.cs b/src/SlatedGameToolkit.Framework/Graphics/OpenGL/Shaders/GLShader.cs
deleted file mode 100644
index 526da9d..0000000
--- a/src/SlatedGameToolkit.Framework/Graphics/OpenGL/Shaders/GLShader.cs
+++ /dev/null
@@ -1,42 +0,0 @@
-using System;
-using System.Runtime.InteropServices;
-using SDL2;
-using SlatedGameToolkit.Framework.Exceptions;
-using SlatedGameToolkit.Framework.Graphics.Window;
-
-namespace SlatedGameToolkit.Framework.Graphics.OpenGL.Shaders
-{
- public abstract class GLShader : IDisposable {
- private WindowContext context;
- public UIntPtr Handle { get; private protected set; }
-
- private protected GLCreateShader createShader;
- private protected GLShaderSource shaderSource;
- private protected GLCompileShader compileShader;
- private protected GLGetShaderLogInfo getShaderLogInfo;
- private protected GLDeleteShader deleteShader;
-
- public GLShader() {
- context = WindowContextsManager.CurrentWindowContext();
- createShader = Marshal.GetDelegateForFunctionPointer(SDL.SDL_GL_GetProcAddress("glCreateShader"));
- if (createShader == null) throw new FrameworkSDLException();
- shaderSource = Marshal.GetDelegateForFunctionPointer(SDL.SDL_GL_GetProcAddress("glShaderSource"));
- if (shaderSource == null) throw new FrameworkSDLException();
- compileShader = Marshal.GetDelegateForFunctionPointer(SDL.SDL_GL_GetProcAddress("glCompileShader"));
- if (compileShader == null) throw new FrameworkSDLException();
- getShaderLogInfo = Marshal.GetDelegateForFunctionPointer(SDL.SDL_GL_GetProcAddress("glGetShaderLogInfo"));
- if(getShaderLogInfo == null) throw new FrameworkSDLException();
- deleteShader = Marshal.GetDelegateForFunctionPointer(SDL.SDL_GL_GetProcAddress("glDeleteShader"));
- if (deleteShader == null) throw new FrameworkSDLException();
-
- }
-
- public virtual void Dispose()
- {
- }
-
- ~GLShader() {
- Dispose();
- }
- }
-}
\ No newline at end of file
diff --git a/src/SlatedGameToolkit.Framework/Graphics/Programs/GLProgram.cs b/src/SlatedGameToolkit.Framework/Graphics/Programs/GLProgram.cs
new file mode 100644
index 0000000..da8dbce
--- /dev/null
+++ b/src/SlatedGameToolkit.Framework/Graphics/Programs/GLProgram.cs
@@ -0,0 +1,57 @@
+using System;
+using System.Runtime.InteropServices;
+using SDL2;
+using SlatedGameToolkit.Framework.Exceptions;
+using SlatedGameToolkit.Framework.Graphics.Window;
+
+namespace SlatedGameToolkit.Framework.Graphics.Programs
+{
+ public abstract class GLProgram : IDisposable
+ {
+ private WindowContext context;
+ private protected readonly UIntPtr handle;
+ private protected GLCreateProgram createProgram;
+ private protected GLDeleteProgram deleteProgram;
+ private protected GLLinkProgram linkProgram;
+ private protected GLGetProgramInfoLog getProgramInfoLog;
+ private protected GLProgramParameter programParameter;
+ private protected GLUseProgram useProgram;
+
+ ///
+ /// Creates an OpenGL program.
+ ///
+ /// This is bound to the current context.
+ ///
+ internal GLProgram() {
+ this.context = WindowContextsManager.CurrentWindowContext;
+ createProgram = GLFunctionUtils.RetrieveGLDelegate("glCreateProgram");
+ deleteProgram = GLFunctionUtils.RetrieveGLDelegate("glDeleteProgram");
+ linkProgram = GLFunctionUtils.RetrieveGLDelegate("glLinkProgram");
+ getProgramInfoLog = GLFunctionUtils.RetrieveGLDelegate("glGetProgramInfoLog");
+ programParameter = GLFunctionUtils.RetrieveGLDelegate("glProgramParameteri");
+ useProgram = GLFunctionUtils.RetrieveGLDelegate("glUseProgram");
+
+ handle = createProgram();
+ }
+
+ ///
+ /// Binds this program.
+ ///
+ public virtual void Use() {
+ useProgram(handle);
+ }
+
+ ///
+ /// Disposes of the program.
+ ///
+ public virtual void Dispose()
+ {
+ deleteProgram(handle);
+ OpenGLErrorException.CheckGLErrorStatus();
+ }
+
+ ~GLProgram() {
+ Dispose();
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/SlatedGameToolkit.Framework/Graphics/OpenGL/Programs/GLShaderProgram.cs b/src/SlatedGameToolkit.Framework/Graphics/Programs/GLShaderProgram.cs
similarity index 60%
rename from src/SlatedGameToolkit.Framework/Graphics/OpenGL/Programs/GLShaderProgram.cs
rename to src/SlatedGameToolkit.Framework/Graphics/Programs/GLShaderProgram.cs
index a6b4823..286d78c 100644
--- a/src/SlatedGameToolkit.Framework/Graphics/OpenGL/Programs/GLShaderProgram.cs
+++ b/src/SlatedGameToolkit.Framework/Graphics/Programs/GLShaderProgram.cs
@@ -1,11 +1,8 @@
using System;
-using System.Runtime.InteropServices;
-using SDL2;
using SlatedGameToolkit.Framework.Exceptions;
-using SlatedGameToolkit.Framework.Graphics.OpenGL.Shaders;
-using SlatedGameToolkit.Framework.Graphics.Window;
+using SlatedGameToolkit.Framework.Graphics.Shaders;
-namespace SlatedGameToolkit.Framework.Graphics.OpenGL.Programs
+namespace SlatedGameToolkit.Framework.Graphics.Programs
{
public class GLShaderProgram : GLProgram
{
@@ -13,15 +10,13 @@ namespace SlatedGameToolkit.Framework.Graphics.OpenGL.Programs
private readonly GLAttachShader attachShader;
private readonly GLDetachShader detachShader;
private GLBindAttribLocation bindAttribLocation;
- public GLShaderProgram(bool separable = true, params GLShader[] shaders) : base(separable) {
+ public GLShaderProgram(bool separable = true, params GLShader[] shaders) : base() {
if (shaders.Length == 0) throw new ArgumentException("Requires at least one shader for shader program.");
this.shaders = shaders;
- attachShader = Marshal.GetDelegateForFunctionPointer(SDL.SDL_GL_GetProcAddress("glAttachShader"));
- if (attachShader == null) throw new FrameworkSDLException();
- bindAttribLocation = Marshal.GetDelegateForFunctionPointer(SDL.SDL_GL_GetProcAddress("glBindAttribLocation"));
- if (bindAttribLocation == null) throw new FrameworkSDLException();
- detachShader = Marshal.GetDelegateForFunctionPointer(SDL.SDL_GL_GetProcAddress("glDetachShader"));
- if (detachShader == null) throw new FrameworkSDLException();
+
+ attachShader = GLFunctionUtils.RetrieveGLDelegate("glAttachShader");
+ bindAttribLocation = GLFunctionUtils.RetrieveGLDelegate("glBindAttribLocation");
+ detachShader = GLFunctionUtils.RetrieveGLDelegate("glDetachShader");
foreach (GLShader shader in shaders)
{
@@ -43,6 +38,9 @@ namespace SlatedGameToolkit.Framework.Graphics.OpenGL.Programs
}
}
+ ///
+ /// Disposes of the shaders and this program.
+ ///
public override void Dispose() {
foreach (GLShader shader in shaders)
{
diff --git a/src/SlatedGameToolkit.Framework/Graphics/Render/Batch.cs b/src/SlatedGameToolkit.Framework/Graphics/Render/Batch.cs
new file mode 100644
index 0000000..97d7018
--- /dev/null
+++ b/src/SlatedGameToolkit.Framework/Graphics/Render/Batch.cs
@@ -0,0 +1,99 @@
+using System;
+using System.Drawing;
+using System.Numerics;
+using SlatedGameToolkit.Framework.Graphics.Meshes;
+using SlatedGameToolkit.Framework.Graphics;
+using SlatedGameToolkit.Framework.Graphics.Textures;
+using SlatedGameToolkit.Framework.Graphics.Shaders;
+
+namespace SlatedGameToolkit.Framework.Graphics.Render
+{
+ public class Batch : IDisposable {
+ private Texture texture;
+ private bool disposed;
+ private VertexArray vertexArray;
+ private const int VERTEX_LENGTH = 6;
+ private GLMultiDrawElements multiDrawElements;
+ public bool Batching { get; private set; }
+ private float[] data;
+ private uint[] indices;
+ private uint[] lengths;
+ private uint[] offsets;
+ private uint dataIndex, indicesIndex, lengthsIndex;
+
+ public Batch(uint BatchVertexSize = 4096) {
+ multiDrawElements = GLFunctionUtils.RetrieveGLDelegate("glMultDrawElements");
+ indices = new uint[BatchVertexSize];
+ lengths = new uint[BatchVertexSize];
+ offsets = new uint[BatchVertexSize];
+ data = new float[BatchVertexSize * VERTEX_LENGTH];
+
+ vertexArray = new VertexArray();
+
+ VertexAttributeDefinition[] definitions = new VertexAttributeDefinition[3];
+ definitions[0] = new VertexAttributeDefinition(0, 3, 3 * sizeof(float), 0);
+ definitions[1] = new VertexAttributeDefinition(1, 4, 1 * sizeof(float), 3 * sizeof(float));
+ definitions[2] = new VertexAttributeDefinition(2, 2, 2 * sizeof(float), 4 * sizeof(float));
+ vertexArray.defineVertexAttributes(definitions: definitions);
+ }
+
+ public virtual void Begin(Texture texture) {
+ if (Batching) throw new InvalidOperationException("This batch is already started.");
+ this.texture = texture ?? throw new ArgumentNullException("texture");
+ this.Batching = true;
+ }
+
+ public virtual void Dispose()
+ {
+ if (disposed) return;
+ disposed = true;
+ vertexArray.Dispose();
+ }
+
+ public virtual void Draw(IMeshable meshable, Color color) {
+ ValueTuple[] vertices = meshable.Vertices;
+ uint[] indices = meshable.Elements;
+ if (vertices.Length * VERTEX_LENGTH + dataIndex >= data.Length || indices.Length + indicesIndex >= indicesIndex) Flush();
+ for (int i = 0; i < vertices.Length; i++) {
+ data[dataIndex] = vertices[i].Item1.X;
+ dataIndex++;
+ data[dataIndex] = vertices[i].Item1.Y;
+ dataIndex++;
+ data[dataIndex] = vertices[i].Item1.Z;
+ dataIndex++;
+
+ data[dataIndex] = color.ToArgb();
+ dataIndex++;
+
+ data[dataIndex] = vertices[i].Item2.X;
+ dataIndex++;
+ data[dataIndex] = vertices[i].Item2.Y;
+ dataIndex++;
+
+ uint elementsCount = (uint)indices.Length;
+ Array.Copy(indices, indices, elementsCount);
+ indicesIndex += elementsCount;
+
+ lengths[lengthsIndex] = elementsCount;
+ lengthsIndex ++;
+ }
+ }
+
+ public virtual void End() {
+ if (!Batching) throw new InvalidOperationException("This batch was never started.");
+ this.Batching = false;
+ Flush();
+ }
+
+ protected virtual void Flush() {
+ texture.Use();
+ vertexArray.Use();
+ vertexArray.BufferVertices(data);
+ vertexArray.BufferIndices(indices);
+ dataIndex = 0;
+ indicesIndex = 0;
+ lengthsIndex = 0;
+ multiDrawElements(GLEnums.GL_TRIANGLE_STRIP, lengths, GLEnums.GL_UNSIGNED_INT, offsets);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/SlatedGameToolkit.Framework/Graphics/Render/IRenderable.cs b/src/SlatedGameToolkit.Framework/Graphics/Render/IRenderable.cs
new file mode 100644
index 0000000..77de1ca
--- /dev/null
+++ b/src/SlatedGameToolkit.Framework/Graphics/Render/IRenderable.cs
@@ -0,0 +1,10 @@
+using SlatedGameToolkit.Framework.Graphics.Meshes;
+using SlatedGameToolkit.Framework.Graphics.Textures;
+
+namespace SlatedGameToolkit.Framework.Graphics.Render
+{
+ public interface IRenderable : IMeshable
+ {
+ Texture Texture { get; }
+ }
+}
\ No newline at end of file
diff --git a/src/SlatedGameToolkit.Framework/Graphics/Render/Renderer.cs b/src/SlatedGameToolkit.Framework/Graphics/Render/Renderer.cs
new file mode 100644
index 0000000..98022eb
--- /dev/null
+++ b/src/SlatedGameToolkit.Framework/Graphics/Render/Renderer.cs
@@ -0,0 +1,25 @@
+using System.Drawing;
+using SlatedGameToolkit.Framework.Graphics.Textures;
+
+namespace SlatedGameToolkit.Framework.Graphics.Render
+{
+ public class Renderer
+ {
+ private Batch batch;
+ private Texture currentTexture;
+
+ public void Queue(IRenderable renderable, Color color) {
+ if (renderable.Texture != currentTexture) {
+ if (batch.Batching) batch.End();
+ currentTexture = renderable.Texture;
+ currentTexture.Use();
+ batch.Begin(currentTexture);
+ }
+ batch.Draw(renderable, color);
+ }
+
+ public void Render() {
+ if (batch.Batching) batch.End();
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/SlatedGameToolkit.Framework/Graphics/Render/Sprite2D.cs b/src/SlatedGameToolkit.Framework/Graphics/Render/Sprite2D.cs
new file mode 100644
index 0000000..54716d7
--- /dev/null
+++ b/src/SlatedGameToolkit.Framework/Graphics/Render/Sprite2D.cs
@@ -0,0 +1,6 @@
+namespace SlatedGameToolkit.Framework.Graphics.Render
+{
+ public class Sprite2D
+ {
+ }
+}
\ No newline at end of file
diff --git a/src/SlatedGameToolkit.Framework/Graphics/OpenGL/Shaders/GLFragmentShader.cs b/src/SlatedGameToolkit.Framework/Graphics/Shaders/GLFragmentShader.cs
similarity index 63%
rename from src/SlatedGameToolkit.Framework/Graphics/OpenGL/Shaders/GLFragmentShader.cs
rename to src/SlatedGameToolkit.Framework/Graphics/Shaders/GLFragmentShader.cs
index 0e50b8b..432dd41 100644
--- a/src/SlatedGameToolkit.Framework/Graphics/OpenGL/Shaders/GLFragmentShader.cs
+++ b/src/SlatedGameToolkit.Framework/Graphics/Shaders/GLFragmentShader.cs
@@ -1,12 +1,13 @@
-using System;
-using System.Runtime.InteropServices;
-using SDL2;
using SlatedGameToolkit.Framework.Exceptions;
-using SlatedGameToolkit.Framework.Graphics.Window;
-namespace SlatedGameToolkit.Framework.Graphics.OpenGL.Shaders
+namespace SlatedGameToolkit.Framework.Graphics.Shaders
{
public class GLFragmentShader : GLShader {
+
+ ///
+ /// Creates an OpenGL fragment shader.
+ ///
+ /// A string representing the GLSL code to run.
public GLFragmentShader(string shader) : base() {
Handle = createShader(GLEnums.GL_FRAGMENT_SHADER);
shaderSource(Handle, 1, shader, null);
@@ -18,15 +19,7 @@ namespace SlatedGameToolkit.Framework.Graphics.OpenGL.Shaders
Dispose();
throw new OpenGLException(shaderLog);
}
- }
-
- public override void Dispose()
- {
- deleteShader(Handle);
- }
-
- ~GLFragmentShader() {
- Dispose();
+ OpenGLErrorException.CheckGLErrorStatus();
}
}
}
\ No newline at end of file
diff --git a/src/SlatedGameToolkit.Framework/Graphics/Shaders/GLShader.cs b/src/SlatedGameToolkit.Framework/Graphics/Shaders/GLShader.cs
new file mode 100644
index 0000000..a9d141a
--- /dev/null
+++ b/src/SlatedGameToolkit.Framework/Graphics/Shaders/GLShader.cs
@@ -0,0 +1,54 @@
+using System;
+using System.Runtime.InteropServices;
+using SDL2;
+using SlatedGameToolkit.Framework.Exceptions;
+using SlatedGameToolkit.Framework.Graphics.Window;
+
+namespace SlatedGameToolkit.Framework.Graphics.Shaders
+{
+ public abstract class GLShader : IDisposable {
+ private WindowContext context;
+ public UIntPtr Handle { get; private protected set; }
+
+ private protected GLCreateShader createShader;
+ private protected GLShaderSource shaderSource;
+ private protected GLCompileShader compileShader;
+ private protected GLGetShaderLogInfo getShaderLogInfo;
+ private protected GLGetAttribLocation getAttribLocation;
+ private GLDeleteShader deleteShader;
+
+ internal GLShader() {
+ context = WindowContextsManager.CurrentWindowContext;
+ createShader = GLFunctionUtils.RetrieveGLDelegate("glCreateShader");
+ shaderSource = GLFunctionUtils.RetrieveGLDelegate("glShaderSource");
+ compileShader = GLFunctionUtils.RetrieveGLDelegate("glCompileShader");
+ getShaderLogInfo = GLFunctionUtils.RetrieveGLDelegate("glGetShaderLogInfo");
+ deleteShader = GLFunctionUtils.RetrieveGLDelegate("glDeleteShader");
+ getAttribLocation = GLFunctionUtils.RetrieveGLDelegate("glGetAttribLocation");
+ }
+
+ ///
+ /// Gets the attribute location.
+ ///
+ /// The name of the attribute.
+ /// The attribute location index.
+ public int GetAttributeLocation(string attributeName) {
+ int index = getAttribLocation(Handle, attributeName);
+ OpenGLErrorException.CheckGLErrorStatus();
+ return index;
+ }
+
+ ///
+ /// Disposes of the shader at the handle.
+ ///
+ public virtual void Dispose()
+ {
+ deleteShader(Handle);
+ OpenGLErrorException.CheckGLErrorStatus();
+ }
+
+ ~GLShader() {
+ Dispose();
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/SlatedGameToolkit.Framework/Graphics/Shaders/GLVertexArraySet.cs b/src/SlatedGameToolkit.Framework/Graphics/Shaders/GLVertexArraySet.cs
new file mode 100644
index 0000000..5202eb3
--- /dev/null
+++ b/src/SlatedGameToolkit.Framework/Graphics/Shaders/GLVertexArraySet.cs
@@ -0,0 +1,141 @@
+using System;
+using System.Runtime.InteropServices;
+using SlatedGameToolkit.Framework.Exceptions;
+
+namespace SlatedGameToolkit.Framework.Graphics.Shaders
+{
+ public class GLVertexArraySet : IDisposable {
+ private bool disposed;
+ public int Count { get; private set; }
+ private UIntPtr[] arrayBufferHandles;
+ private UIntPtr[] vertexArrayHandles;
+ private UIntPtr[] indexArrayHandles;
+ private GLBindBuffer bindBuffer;
+ private GLGenBuffers genBuffers;
+ private GLDeleteBuffers deleteBuffers;
+ private GLGenVertexArrays genVertexArrays;
+ private GLBindVertexArray bindVertexArray;
+ private GLDeleteVertexArrays deleteVertexArrays;
+ private GLVertexAttribPointer vertexAttribPointer;
+ private GLEnableVertexAttribArray enableVertexAttribArray;
+ private GLDisableVertexAttribArray disableVertexAttribArray;
+ private GLBufferData bufferData;
+
+ public GLVertexArraySet(uint amount) {
+ if (amount > int.MaxValue) throw new ArgumentOutOfRangeException("amount");
+ this.Count = (int)amount;
+ genBuffers = GLFunctionUtils.RetrieveGLDelegate("glGenBuffers");
+ deleteBuffers = GLFunctionUtils.RetrieveGLDelegate("glDeleteBuffers");
+ bindBuffer = GLFunctionUtils.RetrieveGLDelegate("glBindBuffer");
+ genVertexArrays = GLFunctionUtils.RetrieveGLDelegate("glGenVertexArrays");
+ bindVertexArray = GLFunctionUtils.RetrieveGLDelegate("glBindVertexArray");
+ deleteVertexArrays = GLFunctionUtils.RetrieveGLDelegate("glDeleteVertexArrays");
+ vertexAttribPointer = GLFunctionUtils.RetrieveGLDelegate("glVertexAttribPointer");
+ enableVertexAttribArray = GLFunctionUtils.RetrieveGLDelegate("glEnableVertexAttribArray");
+ disableVertexAttribArray = GLFunctionUtils.RetrieveGLDelegate("glDisableVertexAttribArray");
+ bufferData = GLFunctionUtils.RetrieveGLDelegate("glBufferData");
+
+ genBuffers(amount, arrayBufferHandles);
+ OpenGLErrorException.CheckGLErrorStatus();
+ genVertexArrays(amount, vertexArrayHandles);
+ OpenGLErrorException.CheckGLErrorStatus();
+ genBuffers(amount, indexArrayHandles);
+ }
+
+ public void Use(uint index) {
+ bindVertexArray(vertexArrayHandles[index]);
+ OpenGLErrorException.CheckGLErrorStatus();
+ bindBuffer(GLEnums.GL_ELEMENT_ARRAY_BUFFER, indexArrayHandles[index]);
+ bindBuffer(GLEnums.GL_ARRAY_BUFFER, arrayBufferHandles[index]);
+ OpenGLErrorException.CheckGLErrorStatus();
+ }
+
+ public unsafe void BufferVertices(uint index, float[] data, bool dynamic) {
+ Use(index);
+ fixed (void* arrayData = &data[0]) {
+ bufferData(GLEnums.GL_ARRAY_BUFFER, (uint) (sizeof(float) * data.Length), arrayData, dynamic ? GLEnums.GL_DYNAMIC_DRAW : GLEnums.GL_STATIC_DRAW);
+ }
+ OpenGLErrorException.CheckGLErrorStatus();
+ }
+
+ public unsafe void BufferIndices(uint index, uint[] data, bool dynamic) {
+ Use(index);
+ fixed (void* arrayData = &data[0]) {
+ bufferData(GLEnums.GL_ELEMENT_ARRAY_BUFFER, (uint) (sizeof(float) * data.Length), arrayData, dynamic ? GLEnums.GL_DYNAMIC_DRAW : GLEnums.GL_STATIC_DRAW);
+ }
+ OpenGLErrorException.CheckGLErrorStatus();
+ }
+
+ ///
+ /// Defines the vertex attributes in an OpenGL vertex array object.
+ /// Sends as floats.
+ ///
+ /// The buffer in this set to affect.
+ /// Whether or not to automatically enable the attributes that are being defined. Defaults to true.
+ /// The definitions for the vertex array object.
+ public void defineVertexAttributes(uint bufferIndex, bool enableAttributes = true, params VertexAttributeDefinition[] definitions) {
+ Use(bufferIndex);
+ foreach (VertexAttributeDefinition definition in definitions)
+ {
+ vertexAttribPointer(definition.attributeIndex, definition.size, GLEnums.GL_FLOAT, false, definition.stride, definition.offset);
+ OpenGLErrorException.CheckGLErrorStatus();
+ if (enableAttributes) enableVertexAttribArray(definition.attributeIndex);
+ }
+ }
+
+ ///
+ /// Enaables the vertex array object's definitions at the given attribute indices.
+ ///
+ /// The buffer index in this set this should affect.
+ /// The attribute indices to be enabled.
+ public void EnableAttributes(uint bufferIndex, params uint[] attributeIndices) {
+ Use(bufferIndex);
+ foreach (uint attrib in attributeIndices)
+ {
+ enableVertexAttribArray(attrib);
+ }
+ }
+
+ ///
+ /// Disables the vertex array object's definitions at the given attribute indices.
+ ///
+ /// The buffer index in this set that should be affected.
+ /// The attribute indices to be disabled.
+ public void DisableAttributes(uint bufferIndex, params uint[] attributeIndices) {
+ Use(bufferIndex);
+ foreach (uint attrib in attributeIndices)
+ {
+ disableVertexAttribArray(attrib);
+ }
+ }
+
+ public void Dispose()
+ {
+ if (this.disposed) return;
+ this.disposed = true;
+ deleteBuffers((uint)arrayBufferHandles.Length, arrayBufferHandles);
+ OpenGLErrorException.CheckGLErrorStatus();
+ deleteVertexArrays((uint)vertexArrayHandles.Length, vertexArrayHandles);
+ OpenGLErrorException.CheckGLErrorStatus();
+ GC.SuppressFinalize(this);
+ }
+
+ ~GLVertexArraySet() {
+ Dispose();
+ }
+ }
+
+ public struct VertexAttributeDefinition {
+ public uint attributeIndex;
+ public int size;
+ public uint stride;
+ public uint offset;
+
+ public VertexAttributeDefinition(uint attributeIndex, int size, uint stride, uint offset) {
+ this.attributeIndex = attributeIndex;
+ this.size = size;
+ this.stride = stride;
+ this.offset = offset;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/SlatedGameToolkit.Framework/Graphics/OpenGL/Shaders/GLVertexShader.cs b/src/SlatedGameToolkit.Framework/Graphics/Shaders/GLVertexShader.cs
similarity index 63%
rename from src/SlatedGameToolkit.Framework/Graphics/OpenGL/Shaders/GLVertexShader.cs
rename to src/SlatedGameToolkit.Framework/Graphics/Shaders/GLVertexShader.cs
index 2c7b832..5967752 100644
--- a/src/SlatedGameToolkit.Framework/Graphics/OpenGL/Shaders/GLVertexShader.cs
+++ b/src/SlatedGameToolkit.Framework/Graphics/Shaders/GLVertexShader.cs
@@ -1,12 +1,13 @@
-using System;
-using System.Runtime.InteropServices;
-using SDL2;
using SlatedGameToolkit.Framework.Exceptions;
-using SlatedGameToolkit.Framework.Graphics.Window;
-namespace SlatedGameToolkit.Framework.Graphics.OpenGL.Shaders
+namespace SlatedGameToolkit.Framework.Graphics.Shaders
{
public class GLVertexShader : GLShader {
+
+ ///
+ /// Creates an OpenGL vertex shader.
+ ///
+ /// A string representing the GLSL code.
public GLVertexShader(string shader) : base() {
Handle = createShader(GLEnums.GL_VERTEX_SHADER);
shaderSource(Handle, 1, shader, null);
@@ -18,15 +19,7 @@ namespace SlatedGameToolkit.Framework.Graphics.OpenGL.Shaders
Dispose();
throw new OpenGLException(shaderLog);
}
- }
-
- public override void Dispose()
- {
- deleteShader(Handle);
- }
-
- ~GLVertexShader() {
- Dispose();
+ OpenGLErrorException.CheckGLErrorStatus();
}
}
}
\ No newline at end of file
diff --git a/src/SlatedGameToolkit.Framework/Graphics/Shaders/VertexArray.cs b/src/SlatedGameToolkit.Framework/Graphics/Shaders/VertexArray.cs
new file mode 100644
index 0000000..5a5547c
--- /dev/null
+++ b/src/SlatedGameToolkit.Framework/Graphics/Shaders/VertexArray.cs
@@ -0,0 +1,63 @@
+using System;
+
+namespace SlatedGameToolkit.Framework.Graphics.Shaders
+{
+ public class VertexArray : IDisposable
+ {
+ private GLVertexArraySet glVertexArraySet;
+ private uint index;
+
+ public VertexArray(GLVertexArraySet gLVertexArraySet, uint index) {
+ this.glVertexArraySet = gLVertexArraySet;
+ this.index = index;
+ }
+
+ public VertexArray() {
+ this.glVertexArraySet = new GLVertexArraySet(1);
+ this.index = 0;
+ }
+
+ public unsafe void BufferVertices(float[] data, bool dynamic = true) {
+ glVertexArraySet.BufferVertices(index, data, dynamic);
+ }
+
+ public unsafe void BufferIndices(uint[] data, bool dynamic = true) {
+ glVertexArraySet.BufferIndices(index, data, dynamic);
+ }
+
+ ///
+ /// Defines the vertex attributes in an OpenGL vertex array object.
+ /// Sends as floats.
+ ///
+ /// Whether or not to automatically enable the attributes that are being defined. Defaults to true.
+ /// The definitions for the vertex array object.
+ public void defineVertexAttributes(bool enableAttributes = true, params VertexAttributeDefinition[] definitions) {
+ this.glVertexArraySet.defineVertexAttributes(index, enableAttributes, definitions);
+ }
+
+ ///
+ /// Enaables the vertex array object's definitions at the given attribute indices.
+ ///
+ /// The attribute indices to be enabled.
+ public void EnableAttributes(params uint[] attributeIndices) {
+ glVertexArraySet.EnableAttributes(index, attributeIndices);
+ }
+
+ ///
+ /// Disables the vertex array object's definitions at the given attribute indices.
+ ///
+ /// The attribute indices to be disabled.
+ public void DisableAttributes(params uint[] attributeIndices) {
+ glVertexArraySet.DisableAttributes(index, attributeIndices);
+ }
+
+ public void Use() {
+ glVertexArraySet.Use(index);
+ }
+
+ public void Dispose()
+ {
+ this.glVertexArraySet.Dispose();
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/SlatedGameToolkit.Framework/Graphics/Textures/GLTexture2DSet.cs b/src/SlatedGameToolkit.Framework/Graphics/Textures/GLTexture2DSet.cs
new file mode 100644
index 0000000..1e7da56
--- /dev/null
+++ b/src/SlatedGameToolkit.Framework/Graphics/Textures/GLTexture2DSet.cs
@@ -0,0 +1,67 @@
+using System;
+using SlatedGameToolkit.Framework.Exceptions;
+using SlatedGameToolkit.Framework.Graphics;
+using SlatedGameToolkit.Framework.Graphics.Textures;
+
+namespace SlatedGameToolkit.Framework.Graphics
+{
+ public class GLTexture2DSet : IDisposable
+ {
+ private bool disposed;
+ public int Count { get; private set; }
+ private GLGenTextures genTextures;
+ private GLTexParameteri texParameteri;
+ private GLTexParameterfv texParameterfv;
+ private GLDeleteTextures deleteTextures;
+ private GLTexImage2D texImage2D;
+ private GLBindTexture bindTexture;
+ private GLGenerateMipMap generateMipMap;
+ private readonly UIntPtr[] handle;
+ private readonly bool linear, mipmap;
+
+ public GLTexture2DSet(TextureData[] textureDatas, bool linear = false, bool mipmap = false)
+ {
+ this.linear = linear;
+ genTextures = GLFunctionUtils.RetrieveGLDelegate("glGenTextures");
+ deleteTextures = GLFunctionUtils.RetrieveGLDelegate("glDeleteTextures");
+ bindTexture = GLFunctionUtils.RetrieveGLDelegate("glBindTexture");
+ texParameteri = GLFunctionUtils.RetrieveGLDelegate("glTexParameteri");
+ texParameterfv = GLFunctionUtils.RetrieveGLDelegate("glTexParameterfv");
+ texImage2D = GLFunctionUtils.RetrieveGLDelegate("glTexImage2D");
+ generateMipMap = GLFunctionUtils.RetrieveGLDelegate("glGenerateMipMap");
+
+ genTextures((uint)textureDatas.Length, handle);
+ for (uint i = 0; i < textureDatas.Length; i++) {
+ Setup(i, textureDatas[i]);
+ }
+ bindTexture(GLEnums.GL_TEXTURE_2D, UIntPtr.Zero);
+ OpenGLErrorException.CheckGLErrorStatus();
+
+ this.Count = textureDatas.Length;
+ }
+
+ private void Setup(uint index, TextureData textureData) {
+ bindTexture(GLEnums.GL_TEXTURE_2D, handle[index]);
+ texParameteri(GLEnums.GL_TEXTURE_2D, GLEnums.GL_TEXTURE_WRAP_S, (int)GLEnums.GL_CLAMP_TO_EDGE);
+ texParameteri(GLEnums.GL_TEXTURE_2D, GLEnums.GL_TEXTURE_WRAP_S, (int)GLEnums.GL_CLAMP_TO_EDGE);
+ texParameteri(GLEnums.GL_TEXTURE_2D, GLEnums.GL_TEXTURE_MIN_FILTER, (int)(linear ? (mipmap ? GLEnums.GL_LINEAR_MIPMAP_LINEAR : GLEnums.GL_LINEAR) : (mipmap ? GLEnums.GL_NEAREST_MIPMAP_LINEAR : GLEnums.GL_NEAREST)));
+ texParameteri(GLEnums.GL_TEXTURE_2D, GLEnums.GL_TEXTURE_MAG_FILTER, (int)(linear ? GLEnums.GL_LINEAR : GLEnums.GL_NEAREST));
+ texImage2D(GLEnums.GL_TEXTURE_2D, 0, (int)GLEnums.GL_RGBA, textureData.width, textureData.height, 0, GLEnums.GL_RGBA, GLEnums.GL_UNSIGNED_BYTE, textureData.data);
+ generateMipMap(GLEnums.GL_TEXTURE_2D);
+ }
+
+ public void Bind(uint index) {
+ bindTexture(GLEnums.GL_TEXTURE_2D, handle[index]);
+
+ }
+
+ public void Dispose()
+ {
+ if (disposed) return;
+ this.disposed = true;
+ deleteTextures((uint)handle.Length, handle);
+ OpenGLErrorException.CheckGLErrorStatus();
+ GC.SuppressFinalize(this);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/SlatedGameToolkit.Framework/Graphics/Textures/Texture.cs b/src/SlatedGameToolkit.Framework/Graphics/Textures/Texture.cs
new file mode 100644
index 0000000..5074052
--- /dev/null
+++ b/src/SlatedGameToolkit.Framework/Graphics/Textures/Texture.cs
@@ -0,0 +1,30 @@
+using System;
+
+namespace SlatedGameToolkit.Framework.Graphics.Textures
+{
+ public class Texture : IDisposable
+ {
+ private readonly GLTexture2DSet glTexture2DSet;
+ private readonly uint index;
+
+ public Texture(GLTexture2DSet set, uint index) {
+ this.glTexture2DSet = set;
+ this.index = index;
+ }
+
+ public Texture(TextureData textureData, bool linear = true, bool mipmap = true) {
+ TextureData[] textureDatas = new TextureData[] {textureData};
+ this.glTexture2DSet = new GLTexture2DSet(textureDatas, linear, mipmap);
+ this.index = 0;
+ }
+
+ public void Use() {
+ this.glTexture2DSet.Bind(index);
+ }
+
+ public void Dispose()
+ {
+ this.glTexture2DSet.Dispose();
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/SlatedGameToolkit.Framework/Graphics/Textures/TextureData.cs b/src/SlatedGameToolkit.Framework/Graphics/Textures/TextureData.cs
new file mode 100644
index 0000000..be23a4d
--- /dev/null
+++ b/src/SlatedGameToolkit.Framework/Graphics/Textures/TextureData.cs
@@ -0,0 +1,9 @@
+namespace SlatedGameToolkit.Framework.Graphics.Textures
+{
+ public struct TextureData
+ {
+ public byte[] data;
+ public uint width;
+ public uint height;
+ }
+}
\ No newline at end of file
diff --git a/src/SlatedGameToolkit.Framework/Graphics/Window/WindowContext.cs b/src/SlatedGameToolkit.Framework/Graphics/Window/WindowContext.cs
index 2e72ffb..b05c621 100644
--- a/src/SlatedGameToolkit.Framework/Graphics/Window/WindowContext.cs
+++ b/src/SlatedGameToolkit.Framework/Graphics/Window/WindowContext.cs
@@ -1,9 +1,10 @@
using System;
+using System.Drawing;
+using System.Numerics;
using System.Runtime.InteropServices;
using SDL2;
-using SlatedGameToolkit.Framework.DataTypes;
using SlatedGameToolkit.Framework.Exceptions;
-using SlatedGameToolkit.Framework.Graphics.OpenGL;
+using SlatedGameToolkit.Framework.Graphics;
namespace SlatedGameToolkit.Framework.Graphics.Window
{
@@ -13,7 +14,7 @@ namespace SlatedGameToolkit.Framework.Graphics.Window
///
/// The window coordinates that are being interacted with.
/// The region type.
- public delegate WindowRegion WindowRegionHit(FloatVector2 hitPoint);
+ public delegate WindowRegion WindowRegionHit(Vector2 hitPoint);
///
/// A delegate that represents a function to be called on a window resize.
@@ -36,12 +37,12 @@ namespace SlatedGameToolkit.Framework.Graphics.Window
///
/// The pointer referencing the SDL window.
///
- private readonly IntPtr window;
+ private readonly IntPtr windowHandle;
///
/// The pointer referencing the OpenGL context.
///
- private readonly IntPtr glContext;
+ private readonly IntPtr glContextHandle;
public event WindowOperation focusGainedEvent, focusLostEvent;
///
@@ -57,6 +58,7 @@ namespace SlatedGameToolkit.Framework.Graphics.Window
internal readonly GLClearColour clearColour;
internal readonly GLClear clear;
internal readonly GLViewport viewport;
+ private readonly GLGetError getError;
///
@@ -66,14 +68,14 @@ namespace SlatedGameToolkit.Framework.Graphics.Window
public bool Shown {
set {
if (value) {
- SDL.SDL_ShowWindow(window);
+ SDL.SDL_ShowWindow(windowHandle);
} else {
- SDL.SDL_HideWindow(window);
+ SDL.SDL_HideWindow(windowHandle);
}
}
get {
- return ((SDL.SDL_WindowFlags) Enum.Parse(typeof(SDL.SDL_WindowFlags), SDL.SDL_GetWindowFlags(window).ToString())).HasFlag(SDL.SDL_WindowFlags.SDL_WINDOW_SHOWN);
+ return ((SDL.SDL_WindowFlags) Enum.Parse(typeof(SDL.SDL_WindowFlags), SDL.SDL_GetWindowFlags(windowHandle).ToString())).HasFlag(SDL.SDL_WindowFlags.SDL_WINDOW_SHOWN);
}
}
@@ -87,23 +89,21 @@ namespace SlatedGameToolkit.Framework.Graphics.Window
///
public bool VSync {
get {
- IntPtr currentContext = SDL.SDL_GL_GetCurrentContext();
- IntPtr currentWindow = SDL.SDL_GL_GetCurrentWindow();
+ WindowContext actual = WindowContextsManager.CurrentWindowContext;
bool diff = false;
- if (currentContext != glContext || currentWindow != window) {
- MakeCurrent();
+ if (actual != this) {
+ WindowContextsManager.CurrentWindowContext = this;
diff = true;
}
bool vSync = SDL.SDL_GL_GetSwapInterval() != 0;
- if (diff) SDL.SDL_GL_MakeCurrent(currentWindow, currentContext);
+ if (diff) WindowContextsManager.CurrentWindowContext = actual;
return vSync;
}
set {
- IntPtr currentContext = SDL.SDL_GL_GetCurrentContext();
- IntPtr currentWindow = SDL.SDL_GL_GetCurrentWindow();
+ WindowContext actual = WindowContextsManager.CurrentWindowContext;
bool diff = false;
- if (currentContext != glContext || currentWindow != window) {
- MakeCurrent();
+ if (actual != this) {
+ WindowContextsManager.CurrentWindowContext = this;
diff = true;
}
if (SDL.SDL_GL_SetSwapInterval(value ? -1 : 0) < 0) {
@@ -111,7 +111,7 @@ namespace SlatedGameToolkit.Framework.Graphics.Window
throw new OptionalSDLException();
}
}
- if (diff) SDL.SDL_GL_MakeCurrent(currentWindow, currentContext);
+ if (diff) WindowContextsManager.CurrentWindowContext = actual;
}
}
@@ -121,11 +121,11 @@ namespace SlatedGameToolkit.Framework.Graphics.Window
/// A string that represents whats to be displayed as the title of the window.
public string WindowTitle {
set {
- SDL.SDL_SetWindowTitle(window, value);
+ SDL.SDL_SetWindowTitle(windowHandle, value);
}
get {
- return SDL.SDL_GetWindowTitle(window);
+ return SDL.SDL_GetWindowTitle(windowHandle);
}
}
@@ -135,12 +135,12 @@ namespace SlatedGameToolkit.Framework.Graphics.Window
/// True if displaying borders.
public bool WindowBordered {
set {
- SDL.SDL_SetWindowBordered(window, value ? SDL.SDL_bool.SDL_TRUE : SDL.SDL_bool.SDL_FALSE);
+ SDL.SDL_SetWindowBordered(windowHandle, value ? SDL.SDL_bool.SDL_TRUE : SDL.SDL_bool.SDL_FALSE);
}
get {
int top, bottom, left, right;
- int errorCode = SDL.SDL_GetWindowBordersSize(window, out top, out left, out bottom, out right);
+ int errorCode = SDL.SDL_GetWindowBordersSize(windowHandle, out top, out left, out bottom, out right);
if (errorCode < 0) throw new OptionalSDLException();
return top > 0 || bottom > 0 || left > 0 || right > 0;
}
@@ -152,10 +152,10 @@ namespace SlatedGameToolkit.Framework.Graphics.Window
/// True if resizeable.
public bool WindowResizable {
set {
- SDL.SDL_SetWindowResizable(window, value ? SDL.SDL_bool.SDL_TRUE : SDL.SDL_bool.SDL_FALSE);
+ SDL.SDL_SetWindowResizable(windowHandle, value ? SDL.SDL_bool.SDL_TRUE : SDL.SDL_bool.SDL_FALSE);
}
get {
- return ((SDL.SDL_WindowFlags) Enum.Parse(typeof(SDL.SDL_WindowFlags), SDL.SDL_GetWindowFlags(window).ToString())).HasFlag(SDL.SDL_WindowFlags.SDL_WINDOW_RESIZABLE);
+ return ((SDL.SDL_WindowFlags) Enum.Parse(typeof(SDL.SDL_WindowFlags), SDL.SDL_GetWindowFlags(windowHandle).ToString())).HasFlag(SDL.SDL_WindowFlags.SDL_WINDOW_RESIZABLE);
}
}
@@ -164,21 +164,20 @@ namespace SlatedGameToolkit.Framework.Graphics.Window
/// as well as the current width and height of this window.
///
/// Rectangle representing the boundaries of the window.
- public FloatRectangle WindowBoundaries {
+ public Rectangle WindowBoundaries {
set {
- SDL.SDL_SetWindowPosition(window, (int)value.X1, (int)value.Y1);
- SDL.SDL_SetWindowSize(window, (int)value.Width, (int)value.Height);
+ SDL.SDL_SetWindowPosition(windowHandle, value.X, value.Y);
+ SDL.SDL_SetWindowSize(windowHandle, value.Width, value.Height);
}
get {
int x, y, width, height;
- SDL.SDL_GetWindowSize(window, out x, out y);
- SDL.SDL_GetWindowPosition(window, out width, out height);
- FloatRectangle rectangle = new FloatRectangle();
- rectangle.X1 = x;
- rectangle.Y2 = y;
+ SDL.SDL_GetWindowSize(windowHandle, out x, out y);
+ SDL.SDL_GetWindowPosition(windowHandle, out width, out height);
+ Rectangle rectangle = new Rectangle();
+ rectangle.X = x;
+ rectangle.Y = y;
rectangle.Width = width;
rectangle.Height = height;
-
return rectangle;
}
}
@@ -187,16 +186,16 @@ namespace SlatedGameToolkit.Framework.Graphics.Window
/// The maximum size the window can be at any given time.
///
/// A vector that represents the maximum width and height of the window with the x and y components respectively.
- public FloatVector2 MaximumSize {
+ public Vector2 MaximumSize {
set {
- SDL.SDL_SetWindowMaximumSize(window, (int)value.x, (int)value.y);
+ SDL.SDL_SetWindowMaximumSize(windowHandle, (int)value.X, (int)value.Y);
}
get {
int width, height;
- SDL.SDL_GetWindowMaximumSize(window, out width, out height);
- FloatVector2 maxSize = new FloatVector2();
- maxSize.x = width;
- maxSize.y = height;
+ SDL.SDL_GetWindowMaximumSize(windowHandle, out width, out height);
+ Vector2 maxSize = new Vector2();
+ maxSize.X = width;
+ maxSize.Y = height;
return maxSize;
}
}
@@ -205,16 +204,16 @@ namespace SlatedGameToolkit.Framework.Graphics.Window
/// The minimum size the window can be at any given time.
///
/// A vector that represents the minimum width and height of the window with the x and y components respectively.
- public FloatVector2 MinimumSize {
+ public Vector2 MinimumSize {
set {
- SDL.SDL_SetWindowMinimumSize(window, (int)value.x, (int)value.y);
+ SDL.SDL_SetWindowMinimumSize(windowHandle, (int)value.X, (int)value.Y);
}
get {
int width, height;
- SDL.SDL_GetWindowMinimumSize(window, out width, out height);
- FloatVector2 maxSize = new FloatVector2();
- maxSize.x = width;
- maxSize.y = height;
+ SDL.SDL_GetWindowMinimumSize(windowHandle, out width, out height);
+ Vector2 maxSize = new Vector2();
+ maxSize.X = width;
+ maxSize.Y = height;
return maxSize;
}
}
@@ -226,12 +225,12 @@ namespace SlatedGameToolkit.Framework.Graphics.Window
/// A float with bounds of [0, 1] representing the opacity of the window.
public float Opacity {
set {
- int errorCode = SDL.SDL_SetWindowOpacity(window, value);
+ int errorCode = SDL.SDL_SetWindowOpacity(windowHandle, value);
if (errorCode < 0) throw new OptionalSDLException();
}
get {
float value;
- int errorCode = SDL.SDL_GetWindowOpacity(window, out value);
+ int errorCode = SDL.SDL_GetWindowOpacity(windowHandle, out value);
if (errorCode < 0) throw new OptionalSDLException();
return value;
}
@@ -243,16 +242,16 @@ namespace SlatedGameToolkit.Framework.Graphics.Window
/// True if grabbing.
public bool GrabbingInput {
set {
- SDL.SDL_SetWindowGrab(window, value ? SDL.SDL_bool.SDL_TRUE : SDL.SDL_bool.SDL_FALSE);
+ SDL.SDL_SetWindowGrab(windowHandle, value ? SDL.SDL_bool.SDL_TRUE : SDL.SDL_bool.SDL_FALSE);
}
get {
- return SDL.SDL_GetWindowGrab(window) == SDL.SDL_bool.SDL_TRUE ? true : false;
+ return SDL.SDL_GetWindowGrab(windowHandle) == SDL.SDL_bool.SDL_TRUE ? true : false;
}
}
internal uint WindowID {
get {
- uint id = SDL.SDL_GetWindowID(window);
+ uint id = SDL.SDL_GetWindowID(windowHandle);
if (id == 0) throw new FrameworkSDLException();
return id;
}
@@ -263,85 +262,45 @@ namespace SlatedGameToolkit.Framework.Graphics.Window
///
public WindowContext(string title, int x = -1, int y = -1, int width = 640, int height = 480, bool specialRegions = false, WindowOption options = default(WindowOption)) {
GameEngine.Logger.Information(String.Format("Starting openGL window with title \"{0}\"", title));
- window = SDL.SDL_CreateWindow(title, x < 0 ? SDL.SDL_WINDOWPOS_CENTERED : x, y < 0 ? SDL.SDL_WINDOWPOS_CENTERED : y, width, height, SDL.SDL_WindowFlags.SDL_WINDOW_INPUT_FOCUS | SDL.SDL_WindowFlags.SDL_WINDOW_OPENGL | SDL.SDL_WindowFlags.SDL_WINDOW_MOUSE_FOCUS | (SDL.SDL_WindowFlags) options);
- if (window == null) {
+ windowHandle = SDL.SDL_CreateWindow(title, x < 0 ? SDL.SDL_WINDOWPOS_CENTERED : x, y < 0 ? SDL.SDL_WINDOWPOS_CENTERED : y, width, height, SDL.SDL_WindowFlags.SDL_WINDOW_INPUT_FOCUS | SDL.SDL_WindowFlags.SDL_WINDOW_OPENGL | SDL.SDL_WindowFlags.SDL_WINDOW_MOUSE_FOCUS | (SDL.SDL_WindowFlags) options);
+ if (windowHandle == null) {
throw new FrameworkSDLException();
}
- glContext = SDL.SDL_GL_CreateContext(window);
- if (glContext == null) {
+ glContextHandle = SDL.SDL_GL_CreateContext(windowHandle);
+ if (glContextHandle == null) {
throw new FrameworkSDLException();
}
- clear = Marshal.GetDelegateForFunctionPointer(SDL.SDL_GL_GetProcAddress("glClear"));
- if (clear == null) throw new FrameworkSDLException();
- clearColour = Marshal.GetDelegateForFunctionPointer(SDL.SDL_GL_GetProcAddress("glClearColor"));
- if (clearColour == null) throw new FrameworkSDLException();
- viewport = Marshal.GetDelegateForFunctionPointer(SDL.SDL_GL_GetProcAddress("glViewport"));
- if (viewport == null) throw new FrameworkSDLException();
-
-
+ clear = GLFunctionUtils.RetrieveGLDelegate("glClear");
+ clearColour = GLFunctionUtils.RetrieveGLDelegate("glClearColor");
+ viewport = GLFunctionUtils.RetrieveGLDelegate("glViewport");
+ getError = GLFunctionUtils.RetrieveGLDelegate("glGetError");
if (specialRegions) {
- if (SDL.SDL_SetWindowHitTest(window, SpecialRegionHit, IntPtr.Zero) < 0) {
+ if (SDL.SDL_SetWindowHitTest(windowHandle, SpecialRegionHit, IntPtr.Zero) < 0) {
throw new OptionalSDLException();
}
}
WindowContextsManager.RegisterWindow(this);
- }
+ WindowContextsManager.CurrentWindowContext = this;
- ///
- /// Makes this window the window that is currently being drawn to.
- /// More specifically, it sets the OpenGL Context associated with this window to be the one
- /// that is actively receiving all OpenGL calls.
- ///
- /// If the current context is already of this window, nothing happens.
- ///
- internal void MakeCurrent() {
- if (SDL.SDL_GL_GetCurrentContext() != glContext) {
- SDL.SDL_GL_MakeCurrent(window, glContext);
- }
- }
-
- internal void SwapBuffer() {
- SDL.SDL_GL_SwapWindow(window);
- }
-
- ///
- /// Attempts to raise the window to the top.
- ///
- public void RaiseToTop() {
- SDL.SDL_RestoreWindow(window);
- SDL.SDL_RaiseWindow(window);
- }
-
- ///
- /// Gets the index of the display that this window resides within.
- ///
- /// An integer representing the display this window resides within.
- public int GetDisplayIndex() {
- int index = SDL.SDL_GetWindowDisplayIndex(window);
- if (index < 0) throw new FrameworkSDLException();
- return index;
+ Vector2 drawable = GetDrawableDimensions();
+ viewport(0, 0, (int)drawable.X, (int)drawable.Y);
}
private SDL.SDL_HitTestResult SpecialRegionHit(IntPtr window, IntPtr hitPtr, IntPtr data) {
SDL.SDL_Point SDLPoint = Marshal.PtrToStructure(hitPtr);
- FloatVector2 point = new FloatVector2(SDLPoint.x, SDLPoint.y);
+ Vector2 point = new Vector2(SDLPoint.x, SDLPoint.y);
WindowRegion region = windowRegionHitEvent.Invoke(point);
return (SDL.SDL_HitTestResult) region;
}
- ///
- /// Disposes of this window and it's associated handles.
- ///
- public void Dispose()
- {
- WindowContextsManager.DeregisterWindow(this);
- SDL.SDL_GL_DeleteContext(glContext);
- SDL.SDL_DestroyWindow(window);
+ internal void SwapBuffer() {
+ SDL.SDL_GL_SwapWindow(windowHandle);
}
+
internal void OnResize(int width, int height) {
resizeEvent?.Invoke(width, height);
}
@@ -354,6 +313,62 @@ namespace SlatedGameToolkit.Framework.Graphics.Window
focusGainedEvent?.Invoke();
}
+ ///
+ /// Gets the current GL error code.
+ ///
+ /// The unsigned int representing the status of OpenGL.
+ public uint GetGLStatus() {
+ return getError();
+ }
+
+ ///
+ /// Gets the current drawable area of the window.
+ ///
+ /// A vector with x component representing the width and y component representing the height of the drawable area.
+ public Vector2 GetDrawableDimensions() {
+ int width, height;
+ SDL.SDL_GL_GetDrawableSize(windowHandle, out width, out height);
+ return new Vector2(width, height);
+ }
+
+ ///
+ /// Makes this window context the active one.
+ /// There can only be one window context active at any given time.
+ ///
+ public void MakeCurrent() {
+
+ SDL.SDL_GL_MakeCurrent(windowHandle, glContextHandle);
+ WindowContextsManager.CurrentWindowContext = this;
+ }
+
+ ///
+ /// Attempts to raise the window to the top.
+ ///
+ public void RaiseToTop() {
+ SDL.SDL_RestoreWindow(windowHandle);
+ SDL.SDL_RaiseWindow(windowHandle);
+ }
+
+ ///
+ /// Gets the index of the display that this window resides within.
+ ///
+ /// An integer representing the display this window resides within.
+ public int GetDisplayIndex() {
+ int index = SDL.SDL_GetWindowDisplayIndex(windowHandle);
+ if (index < 0) throw new FrameworkSDLException();
+ return index;
+ }
+
+ ///
+ /// Disposes of this window and it's associated handles.
+ ///
+ public void Dispose()
+ {
+ WindowContextsManager.DeregisterWindow(this);
+ SDL.SDL_GL_DeleteContext(glContextHandle);
+ SDL.SDL_DestroyWindow(windowHandle);
+ }
+
~WindowContext() {
Dispose();
}
diff --git a/src/SlatedGameToolkit.Framework/Graphics/Window/WindowContextsManager.cs b/src/SlatedGameToolkit.Framework/Graphics/Window/WindowContextsManager.cs
index 7507097..291bafb 100644
--- a/src/SlatedGameToolkit.Framework/Graphics/Window/WindowContextsManager.cs
+++ b/src/SlatedGameToolkit.Framework/Graphics/Window/WindowContextsManager.cs
@@ -1,9 +1,26 @@
using System.Collections.Generic;
-using SDL2;
namespace SlatedGameToolkit.Framework.Graphics.Window
{
- internal static class WindowContextsManager {
+ public static class WindowContextsManager {
+ private static WindowContext current;
+
+ ///
+ /// The current window context.
+ ///
+ /// The currently active window context.
+ public static WindowContext CurrentWindowContext {
+ get {
+ return current;
+ }
+
+ set {
+ if (current != value) {
+ current = value;
+ value.MakeCurrent();
+ }
+ }
+ }
private static Dictionary existingWindows = new Dictionary();
internal static void RegisterWindow(WindowContext windowHandle) {
@@ -19,9 +36,5 @@ namespace SlatedGameToolkit.Framework.Graphics.Window
public static WindowContext ContextFromWindowID(uint ID) {
return existingWindows[ID];
}
-
- public static WindowContext CurrentWindowContext() {
- return ContextFromWindowID(SDL.SDL_GetWindowID(SDL.SDL_GL_GetCurrentWindow()));
- }
}
}
\ No newline at end of file
diff --git a/src/SlatedGameToolkit.Framework/Loaders/ILoadable.cs b/src/SlatedGameToolkit.Framework/Loaders/ILoadable.cs
new file mode 100644
index 0000000..9857d0c
--- /dev/null
+++ b/src/SlatedGameToolkit.Framework/Loaders/ILoadable.cs
@@ -0,0 +1,8 @@
+namespace SlatedGameToolkit.Framework.Loaders
+{
+ public interface ILoadable
+ {
+ bool RequiresLoading { get; }
+ void Load();
+ }
+}
\ No newline at end of file
diff --git a/src/SlatedGameToolkit.Framework/SDL2-bindings/SDL2.cs b/src/SlatedGameToolkit.Framework/SDL2-bindings/SDL2.cs
index b35d6a2..270526e 100644
--- a/src/SlatedGameToolkit.Framework/SDL2-bindings/SDL2.cs
+++ b/src/SlatedGameToolkit.Framework/SDL2-bindings/SDL2.cs
@@ -1097,7 +1097,7 @@ namespace SDL2
[StructLayout(LayoutKind.Sequential)]
public struct SDL_MessageBoxColorScheme
{
- [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.Struct, SizeConst = (int)SDL_MessageBoxColorType.SDL_MESSAGEBOX_COLOR_MAX)]
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = (int)SDL_MessageBoxColorType.SDL_MESSAGEBOX_COLOR_MAX)]
public SDL_MessageBoxColor[] colors;
}
diff --git a/src/SlatedGameToolkit.Framework/SlatedGameToolkit.Framework.csproj b/src/SlatedGameToolkit.Framework/SlatedGameToolkit.Framework.csproj
index 4cfed17..b926bd5 100644
--- a/src/SlatedGameToolkit.Framework/SlatedGameToolkit.Framework.csproj
+++ b/src/SlatedGameToolkit.Framework/SlatedGameToolkit.Framework.csproj
@@ -1,7 +1,7 @@
- netstandard2.0
+ netstandard2.1
true
diff --git a/src/SlatedGameToolkit.Framework/StateSystem/Manager.cs b/src/SlatedGameToolkit.Framework/StateSystem/Manager.cs
index f70503c..15ea52c 100644
--- a/src/SlatedGameToolkit.Framework/StateSystem/Manager.cs
+++ b/src/SlatedGameToolkit.Framework/StateSystem/Manager.cs
@@ -1,18 +1,16 @@
using System;
using System.Collections.Generic;
+using System.Drawing;
using System.Threading;
-using SDL2;
-using SlatedGameToolkit.Framework.DataTypes;
-using SlatedGameToolkit.Framework.Graphics.OpenGL;
+using SlatedGameToolkit.Framework.Graphics;
using SlatedGameToolkit.Framework.Graphics.Window;
using SlatedGameToolkit.Framework.StateSystem.States;
namespace SlatedGameToolkit.Framework.StateSystem
{
public sealed class Manager : IDisposable {
- public WindowContext CurrentWindow { get; private set; }
public Thread thread;
- public Colour backgroundColour;
+ public Color backgroundColour;
private IState currentState;
private IState nextState;
private Dictionary states;
@@ -25,9 +23,7 @@ namespace SlatedGameToolkit.Framework.StateSystem
/// The name of the initial state.
/// The initial set of game states to be added.
internal Manager(IState initialState) {
- backgroundColour.r = 0.5f;
- backgroundColour.g = 0.5f;
- backgroundColour.b = 0.5f;
+ backgroundColour = Color.Orange;
if (initialState == null) throw new ArgumentNullException("initialState");
thread = Thread.CurrentThread;
@@ -47,14 +43,11 @@ namespace SlatedGameToolkit.Framework.StateSystem
}
internal void render(double delta) {
- if (CurrentWindow != currentState.CurrentWindow) {
- CurrentWindow = currentState.CurrentWindow;
- CurrentWindow.MakeCurrent();
- }
- CurrentWindow.clearColour(backgroundColour.r, backgroundColour.g, backgroundColour.b);
- CurrentWindow.clear(GLEnums.GL_COLOR_BUFFER_BIT | GLEnums.GL_DEPTH_STENCIL);
+ WindowContext windowContext = WindowContextsManager.CurrentWindowContext;
+ windowContext.clearColour(backgroundColour.R / 254f, backgroundColour.G / 254f, backgroundColour.B / 254f);
+ windowContext.clear(GLEnums.GL_COLOR_BUFFER_BIT | GLEnums.GL_DEPTH_STENCIL);
currentState.Render(delta);
- CurrentWindow.SwapBuffer();
+ windowContext.SwapBuffer();
}
///
@@ -134,6 +127,7 @@ namespace SlatedGameToolkit.Framework.StateSystem
public void Dispose()
{
+ if (currentState == null) return;
currentState = null;
removeAllStates();
}
diff --git a/src/SlatedGameToolkit.Framework/StateSystem/States/IState.cs b/src/SlatedGameToolkit.Framework/StateSystem/States/IState.cs
index 3e53871..f6f3260 100644
--- a/src/SlatedGameToolkit.Framework/StateSystem/States/IState.cs
+++ b/src/SlatedGameToolkit.Framework/StateSystem/States/IState.cs
@@ -5,8 +5,6 @@ namespace SlatedGameToolkit.Framework.StateSystem.States
{
public interface IState
{
- WindowContext CurrentWindow { get; }
-
///
/// Called when this state should be deactivated.
/// Deactivate may be called multiple times:
diff --git a/src/SlatedGameToolkit.Tools/SlatedGameToolkit.Tools.csproj b/src/SlatedGameToolkit.Tools/SlatedGameToolkit.Tools.csproj
index b466f31..327b64e 100644
--- a/src/SlatedGameToolkit.Tools/SlatedGameToolkit.Tools.csproj
+++ b/src/SlatedGameToolkit.Tools/SlatedGameToolkit.Tools.csproj
@@ -7,6 +7,8 @@
Exe
netcoreapp3.1
+ 1.0.0.0
+ A tool to help with developing a game using SlatedGameToolkit.
diff --git a/src/SlatedGameToolkit.Tools/Utilities/GraphicalPlayground/MainState.cs b/src/SlatedGameToolkit.Tools/Utilities/GraphicalPlayground/MainState.cs
index 7869dd4..9d5ab32 100644
--- a/src/SlatedGameToolkit.Tools/Utilities/GraphicalPlayground/MainState.cs
+++ b/src/SlatedGameToolkit.Tools/Utilities/GraphicalPlayground/MainState.cs
@@ -1,6 +1,6 @@
using System;
-using SlatedGameToolkit.Framework.Graphics.OpenGL.Programs;
-using SlatedGameToolkit.Framework.Graphics.OpenGL.Shaders;
+using SlatedGameToolkit.Framework.Graphics.Programs;
+using SlatedGameToolkit.Framework.Graphics.Shaders;
using SlatedGameToolkit.Framework.Graphics.Window;
using SlatedGameToolkit.Framework.StateSystem;
using SlatedGameToolkit.Framework.StateSystem.States;
@@ -10,7 +10,6 @@ namespace SlatedGameToolkit.Tools.Utilities.GraphicalPlayground
public class MainState : IState
{
private WindowContext window;
- private GLShaderProgram shader;
public WindowContext CurrentWindow { get { return window;}}
@@ -37,7 +36,6 @@ namespace SlatedGameToolkit.Tools.Utilities.GraphicalPlayground
public void Initialize(Manager manager)
{
window = new WindowContext("SlatedGameToolkit Playground");
- shader = new GLShaderProgram();
window.RaiseToTop();
}
diff --git a/tests/UnitTest1.cs b/tests/UnitTest1.cs
deleted file mode 100644
index 2bc5a40..0000000
--- a/tests/UnitTest1.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-using NUnit.Framework;
-
-namespace tests
-{
- public class Tests
- {
- [SetUp]
- public void Setup()
- {
- }
-
- [Test]
- public void Test1()
- {
- Assert.Pass();
- }
- }
-}
\ No newline at end of file
diff --git a/tests/tests.csproj b/tests/tests.csproj
deleted file mode 100644
index 43f0ccc..0000000
--- a/tests/tests.csproj
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
-
- netcoreapp3.1
-
- false
-
-
-
-
-
-
-
-
-