Lots of progress on rendering textures.

This commit is contained in:
Harrison Deng 2020-06-05 23:49:45 -05:00
parent 23597f02b1
commit 1c4ca6c97b
47 changed files with 620 additions and 246 deletions

6
.vscode/launch.json vendored
View File

@ -5,16 +5,16 @@
"version": "0.2.0", "version": "0.2.0",
"configurations": [ "configurations": [
{ {
"name": ".NET Core Launch (console)", "name": "SlatedGameToolkit.Tools",
"type": "coreclr", "type": "coreclr",
"request": "launch", "request": "launch",
"preLaunchTask": "build", "preLaunchTask": "build",
// If you have changed target frameworks, make sure to update the program path. // If you have changed target frameworks, make sure to update the program path.
"program": "${workspaceFolder}/src/SlatedGameToolkit.Tools/bin/Debug/netcoreapp3.1/SlatedGameToolkit.Tools.dll", "program": "${workspaceFolder}/src/SlatedGameToolkit.Tools/bin/Debug/netcoreapp3.1/SlatedGameToolkit.Tools.exe",
"args": [], "args": [],
"cwd": "${workspaceFolder}/src/SlatedGameToolkit.Tools", "cwd": "${workspaceFolder}/src/SlatedGameToolkit.Tools",
// For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console // For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console
"console": "internalConsole", "console": "integratedTerminal",
"stopAtEntry": false "stopAtEntry": false
}, },
{ {

View File

@ -21,8 +21,8 @@ namespace SlatedGameToolkit.Framework.Exceptions
/// </summary> /// </summary>
public static void CheckGLErrorStatus() { public static void CheckGLErrorStatus() {
uint errorCode = WindowContextsManager.CurrentWindowContext.GetGLStatus(); uint errorCode = WindowContextsManager.CurrentWindowContext.GetGLStatus();
if (errorCode != (uint) GLEnums.GL_NO_ERROR) { if (errorCode != (uint) GLEnum.GL_NO_ERROR) {
throw new OpenGLErrorException(errorCode, "OpenGL error: " + errorCode.ToString()); throw new OpenGLErrorException(errorCode, string.Format("OpenGL error ({0}): {1}", errorCode, ((GLEnum) errorCode)));
} }
} }
} }

View File

@ -4,6 +4,7 @@ using SDL2;
using Serilog; using Serilog;
using Serilog.Core; using Serilog.Core;
using SlatedGameToolkit.Framework.Exceptions; using SlatedGameToolkit.Framework.Exceptions;
using SlatedGameToolkit.Framework.Graphics;
using SlatedGameToolkit.Framework.Graphics.Window; using SlatedGameToolkit.Framework.Graphics.Window;
using SlatedGameToolkit.Framework.Input; using SlatedGameToolkit.Framework.Input;
using SlatedGameToolkit.Framework.Input.Devices; using SlatedGameToolkit.Framework.Input.Devices;
@ -76,9 +77,10 @@ namespace SlatedGameToolkit.Framework {
private static void Loop(Object o) { private static void Loop(Object o) {
if (!(o is IState)) throw new InternalFrameworkException(String.Format("Expected initial state object for asynchronous loop. Got {0}", o)); if (!(o is IState)) throw new InternalFrameworkException(String.Format("Expected initial state object for asynchronous loop. Got {0}", o));
IState initialState = (IState) o; StateManager manager = new StateManager();
Manager manager = new Manager(initialState);
try { try {
IState initialState = (IState) o;
manager.Initialize(initialState);
DateTime currentTime = DateTime.Now; DateTime currentTime = DateTime.Now;
TimeSpan timePassedFromLastUpdate = TimeSpan.Zero; TimeSpan timePassedFromLastUpdate = TimeSpan.Zero;
TimeSpan timePassedFromLastRender = TimeSpan.Zero; TimeSpan timePassedFromLastRender = TimeSpan.Zero;
@ -170,6 +172,8 @@ namespace SlatedGameToolkit.Framework {
timePassedFromLastRender = TimeSpan.Zero; timePassedFromLastRender = TimeSpan.Zero;
} }
} }
} catch (Exception e) {
Logger.Fatal(e.ToString());
} finally { } finally {
stopped = true; stopped = true;
manager.Dispose(); manager.Dispose();
@ -228,8 +232,8 @@ namespace SlatedGameToolkit.Framework {
throw new FrameworkSDLException(); 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_MAJOR_VERSION, OpenGL.OpenGLMajorVersion) < 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_MINOR_VERSION, OpenGL.OpenGLMinorVersion) < 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(); 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();
thread = new Thread(Loop); thread = new Thread(Loop);

View File

@ -1,6 +1,6 @@
namespace SlatedGameToolkit.Framework.Graphics namespace SlatedGameToolkit.Framework.Graphics
{ {
public enum GLEnums: uint { public enum GLEnum: uint {
GL_DEPTH_BUFFER_BIT = 0x00000100, GL_DEPTH_BUFFER_BIT = 0x00000100,
GL_STENCIL_BUFFER_BIT = 0x00000400, GL_STENCIL_BUFFER_BIT = 0x00000400,
GL_COLOR_BUFFER_BIT = 0x00004000, GL_COLOR_BUFFER_BIT = 0x00004000,

View File

@ -6,9 +6,9 @@ namespace SlatedGameToolkit.Framework.Graphics.Meshes
{ {
public abstract class RectangleMesh : IMeshable public abstract class RectangleMesh : IMeshable
{ {
private bool changed = true; private Matrix4x4 matRot;
private Matrix4x4 matRot, matTrans, matScale; private bool changed;
private Vector3 rotation, translation, scale; private Vector3 rotation;
private Vector2 origin, dimensions; private Vector2 origin, dimensions;
protected readonly Vector2[] textureCoords = new Vector2[4]; protected readonly Vector2[] textureCoords = new Vector2[4];
private ValueTuple<Vector3, Vector2>[] vertices = new ValueTuple<Vector3, Vector2>[4]; private ValueTuple<Vector3, Vector2>[] vertices = new ValueTuple<Vector3, Vector2>[4];
@ -78,35 +78,6 @@ namespace SlatedGameToolkit.Framework.Graphics.Meshes
public uint[] Elements { get {return indices; } } 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 public Vector3 Rotation
{ {
get get
@ -122,16 +93,16 @@ namespace SlatedGameToolkit.Framework.Graphics.Meshes
} }
} }
private void CalculateVertices() { private void CalculateVertices() {
if (!changed) return;
Vector3[] baseVerts = new Vector3[4]; Vector3[] baseVerts = new Vector3[4];
baseVerts[0] = new Vector3(this.origin, 0); baseVerts[0] = new Vector3(this.origin, 0);
baseVerts[1] = new Vector3(this.origin.X + this.dimensions.X, this.origin.Y, 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[2] = new Vector3(baseVerts[1].X, this.origin.Y + this.dimensions.Y, 0);
baseVerts[3] = new Vector3(this.origin.X, baseVerts[2].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++) for (int i = 0; i < vertices.Length; i++)
{ {
vertices[i] = new ValueTuple<Vector3, Vector2>(Vector3.Transform(baseVerts[i], transform), textureCoords[i]); vertices[i] = new ValueTuple<Vector3, Vector2>(Vector3.Transform(baseVerts[i], matRot), textureCoords[i]);
} }
changed = false; changed = false;
} }

View File

@ -2,23 +2,25 @@ using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using SDL2; using SDL2;
using SlatedGameToolkit.Framework.Exceptions; using SlatedGameToolkit.Framework.Exceptions;
using SlatedGameToolkit.Framework.Graphics.Programs;
using SlatedGameToolkit.Framework.Graphics.Shaders;
namespace SlatedGameToolkit.Framework.Graphics namespace SlatedGameToolkit.Framework.Graphics
{ {
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void GLClearColour(float r, float g, float b); public delegate void GLClearColour(float r, float g, float b);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void GLClear(GLEnums flags); public delegate void GLClear(GLEnum flags);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void GLViewport(int x, int y, int width, int height); public delegate void GLViewport(int x, int y, int width, int height);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate UIntPtr GLCreateShader(GLEnums type); public delegate UIntPtr GLCreateShader(GLEnum type);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate UIntPtr GLShaderSource(UIntPtr shaderHandle, uint count, string program, int[] length); public delegate UIntPtr GLShaderSource(UIntPtr shaderHandle, uint count, string[] program, int[] length);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void GLCompileShader(UIntPtr shaderHandle); public delegate void GLCompileShader(UIntPtr shaderHandle);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void GLGetShaderLogInfo(UIntPtr shader, uint maxLength, out uint writtenLength, out string output); public delegate void GLGetShaderInfoLog(UIntPtr shader, uint maxLength, out uint writtenLength, byte[] output);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate UIntPtr GLCreateProgram(); public delegate UIntPtr GLCreateProgram();
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
@ -32,11 +34,11 @@ namespace SlatedGameToolkit.Framework.Graphics
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void GLBindAttribLocation(UIntPtr program, uint index, string name); public delegate void GLBindAttribLocation(UIntPtr program, uint index, string name);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void GLGetProgramInfoLog(UIntPtr program, uint maxLength, out uint writtenLength, out string output); public delegate void GLGetProgramInfoLog(UIntPtr program, uint maxLength, out uint writtenLength, byte[] output);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void GLLinkProgram(UIntPtr program); public delegate void GLLinkProgram(UIntPtr program);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void GLProgramParameter(UIntPtr program, GLEnums parameterName, int value); public delegate void GLProgramParameter(UIntPtr program, GLEnum parameterName, int value);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void GLUseProgram(UIntPtr program); public delegate void GLUseProgram(UIntPtr program);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
@ -46,21 +48,21 @@ namespace SlatedGameToolkit.Framework.Graphics
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void GLBindProgramPipeline(UIntPtr pipeline); public delegate void GLBindProgramPipeline(UIntPtr pipeline);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void GLUseProgramStages(UIntPtr pipeline, GLEnums bitField, UIntPtr program); public delegate void GLUseProgramStages(UIntPtr pipeline, GLEnum bitField, UIntPtr program);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate uint GLGetError(); public delegate uint GLGetError();
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate int GLGetAttribLocation(UIntPtr program, string attribName); public delegate int GLGetAttribLocation(UIntPtr program, string attribName);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void GLBindBuffer(GLEnums target, UIntPtr buffer); public delegate void GLBindBuffer(GLEnum target, UIntPtr buffer);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void GLGenBuffers(uint size, UIntPtr[] buffers); public delegate void GLGenBuffers(uint size, UIntPtr[] buffers);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public unsafe delegate void GLBufferData(GLEnums target, uint size, Array data, GLEnums usage); public unsafe delegate void GLBufferData(GLEnum target, uint size, Array data, GLEnum usage);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void GLDeleteBuffers(uint size, UIntPtr[] buffers); public delegate void GLDeleteBuffers(uint size, UIntPtr[] buffers);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void GLVertexAttribPointer(uint index, int size, GLEnums type, bool normalized, uint stride, uint offset); public delegate void GLVertexAttribPointer(uint index, int size, GLEnum type, bool normalized, uint stride, uint offset);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void GLGenVertexArrays(uint amount, UIntPtr[] arrays); public delegate void GLGenVertexArrays(uint amount, UIntPtr[] arrays);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
@ -72,33 +74,39 @@ namespace SlatedGameToolkit.Framework.Graphics
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void GLDisableVertexAttribArray(uint attribIndex); public delegate void GLDisableVertexAttribArray(uint attribIndex);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void GLDrawArrays(GLEnums mode, int first, uint count); public delegate void GLDrawArrays(GLEnum mode, int first, uint count);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void GLDrawElements(GLEnums mode, uint count, int offset); public delegate void GLDrawElements(GLEnum mode, uint count, int offset);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void GLMultiDrawArrays(GLEnums mode, int[] first, uint[] count, uint primout); public delegate void GLMultiDrawArrays(GLEnum mode, int[] first, uint[] count, uint primout);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void GLMultiDrawElements(GLEnums mode, uint[] count, GLEnums type, IntPtr indices, int length); public delegate void GLMultiDrawElements(GLEnum mode, uint[] count, GLEnum type, uint[] indiceOffsets, int length);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void GLGenTextures(uint n, UIntPtr[] textureHandles); public delegate void GLGenTextures(uint n, UIntPtr[] textureHandles);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void GLBindTexture(GLEnums target, UIntPtr texture); public delegate void GLBindTexture(GLEnum target, UIntPtr texture);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void GLDeleteTextures(uint n, UIntPtr[] textureHandles); public delegate void GLDeleteTextures(uint n, UIntPtr[] textureHandles);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void GLTexParameteri(GLEnums target, GLEnums pname, int value); public delegate void GLTexParameteri(GLEnum target, GLEnum pname, int value);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void GLTexParameterf(GLEnums target, GLEnums pname, float value); public delegate void GLTexParameterf(GLEnum target, GLEnum pname, float value);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void GLTexParameteriv(GLEnums target, GLEnums pname, int[] values); public delegate void GLTexParameteriv(GLEnum target, GLEnum pname, int[] values);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void GLTexParameterfv(GLEnums target, GLEnums pname, float[] values); public delegate void GLTexParameterfv(GLEnum target, GLEnum pname, float[] values);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void GLTexImage2D(GLEnums target, int level, int publicFormat, uint width, uint height, int border, GLEnums format, GLEnums type, byte[] data); public delegate void GLTexImage2D(GLEnum target, int level, int publicFormat, uint width, uint height, int border, GLEnum format, GLEnum type, byte[] data);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void GLGenerateMipMap(GLEnums target); public delegate void GLGenerateMipmap(GLEnum target);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate int GLGetUniformLocation(UIntPtr program, string name);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void GLUniformMatrix4fv(int index, uint count, bool transpose, float[] matrix);
public static class GLFunctionUtils { public static class OpenGL {
public const int OpenGLMajorVersion = 3;
public const int OpenGLMinorVersion = 3;
/// <summary> /// <summary>
/// Attempts to retrieve and instantiate an OpenGL function as a C# delegate. /// Attempts to retrieve and instantiate an OpenGL function as a C# delegate.
/// Make sure the delegates signature is correct as failing to do so will potentially /// Make sure the delegates signature is correct as failing to do so will potentially
@ -112,7 +120,7 @@ namespace SlatedGameToolkit.Framework.Graphics
public static T RetrieveGLDelegate<T>(string functionName) where T : Delegate { public static T RetrieveGLDelegate<T>(string functionName) where T : Delegate {
GameEngine.Logger.Debug(String.Format("Retrieving function with name: {0}", functionName)); GameEngine.Logger.Debug(String.Format("Retrieving function with name: {0}", functionName));
IntPtr functionAddress = SDL.SDL_GL_GetProcAddress(functionName); IntPtr functionAddress = SDL.SDL_GL_GetProcAddress(functionName);
if (functionAddress == null) throw new FrameworkSDLException(); if (functionAddress.Equals(IntPtr.Zero)) throw new FrameworkSDLException();
return Marshal.GetDelegateForFunctionPointer<T>(functionAddress); return Marshal.GetDelegateForFunctionPointer<T>(functionAddress);
} }
} }

View File

@ -1,7 +1,10 @@
using System; using System;
using System.Numerics;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Text;
using SDL2; using SDL2;
using SlatedGameToolkit.Framework.Exceptions; using SlatedGameToolkit.Framework.Exceptions;
using SlatedGameToolkit.Framework.Graphics;
using SlatedGameToolkit.Framework.Graphics.Window; using SlatedGameToolkit.Framework.Graphics.Window;
namespace SlatedGameToolkit.Framework.Graphics.Programs namespace SlatedGameToolkit.Framework.Graphics.Programs
@ -21,6 +24,10 @@ namespace SlatedGameToolkit.Framework.Graphics.Programs
protected GLGetProgramInfoLog getProgramInfoLog; protected GLGetProgramInfoLog getProgramInfoLog;
protected GLProgramParameter programParameter; protected GLProgramParameter programParameter;
private GLUseProgram useProgram; private GLUseProgram useProgram;
private readonly GLGetAttribLocation getAttribLocation;
private readonly GLGetUniformLocation getUniformLocation;
private readonly GLUniformMatrix4fv uniformMatrix4Fv;
/// <summary> /// <summary>
/// Creates an OpenGL program. /// Creates an OpenGL program.
@ -29,14 +36,43 @@ namespace SlatedGameToolkit.Framework.Graphics.Programs
/// </summary> /// </summary>
internal GLProgram() { internal GLProgram() {
this.context = WindowContextsManager.CurrentWindowContext; this.context = WindowContextsManager.CurrentWindowContext;
createProgram = GLFunctionUtils.RetrieveGLDelegate<GLCreateProgram>("glCreateProgram"); createProgram = OpenGL.RetrieveGLDelegate<GLCreateProgram>("glCreateProgram");
deleteProgram = GLFunctionUtils.RetrieveGLDelegate<GLDeleteProgram>("glDeleteProgram"); deleteProgram = OpenGL.RetrieveGLDelegate<GLDeleteProgram>("glDeleteProgram");
linkProgram = GLFunctionUtils.RetrieveGLDelegate<GLLinkProgram>("glLinkProgram"); linkProgram = OpenGL.RetrieveGLDelegate<GLLinkProgram>("glLinkProgram");
getProgramInfoLog = GLFunctionUtils.RetrieveGLDelegate<GLGetProgramInfoLog>("glGetProgramInfoLog"); getProgramInfoLog = OpenGL.RetrieveGLDelegate<GLGetProgramInfoLog>("glGetProgramInfoLog");
programParameter = GLFunctionUtils.RetrieveGLDelegate<GLProgramParameter>("glProgramParameteri"); programParameter = OpenGL.RetrieveGLDelegate<GLProgramParameter>("glProgramParameteri");
useProgram = GLFunctionUtils.RetrieveGLDelegate<GLUseProgram>("glUseProgram"); useProgram = OpenGL.RetrieveGLDelegate<GLUseProgram>("glUseProgram");
getAttribLocation = OpenGL.RetrieveGLDelegate<GLGetAttribLocation>("glGetAttribLocation");
getUniformLocation = OpenGL.RetrieveGLDelegate<GLGetUniformLocation>("glGetUniformLocation");
uniformMatrix4Fv = OpenGL.RetrieveGLDelegate<GLUniformMatrix4fv>("glUniformMatrix4fv");
handle = createProgram(); handle = createProgram();
OpenGLErrorException.CheckGLErrorStatus();
}
public int GetAttributeLocation(string name) {
int res = getAttribLocation(handle, name);
OpenGLErrorException.CheckGLErrorStatus();
return res;
}
public int GetUniformLocation(string name) {
int res = getUniformLocation(handle, name);
OpenGLErrorException.CheckGLErrorStatus();
return res;
}
public void SetUniformMatrix4x4(int location, Matrix4x4 matrix, bool transpose = false) {
Use();
float[] mat4 = new float[] {
matrix.M11, matrix.M21, matrix.M31, matrix.M41,
matrix.M21, matrix.M22, matrix.M23, matrix.M24,
matrix.M31, matrix.M32, matrix.M33, matrix.M34,
matrix.M41, matrix.M42, matrix.M43, matrix.M44
};
uniformMatrix4Fv(location, 1, transpose, mat4);
OpenGLErrorException.CheckGLErrorStatus();
} }
/// <summary> /// <summary>
@ -44,6 +80,13 @@ namespace SlatedGameToolkit.Framework.Graphics.Programs
/// </summary> /// </summary>
public virtual void Use() { public virtual void Use() {
useProgram(handle); useProgram(handle);
uint written;
byte[] log = new byte[2048];
getProgramInfoLog(handle, (uint)log.Length, out written, log);
if (written > 0) {
throw new OpenGLException(Encoding.UTF8.GetString(log));
}
OpenGLErrorException.CheckGLErrorStatus();
} }
/// <summary> /// <summary>

View File

@ -1,5 +1,7 @@
using System; using System;
using System.Text;
using SlatedGameToolkit.Framework.Exceptions; using SlatedGameToolkit.Framework.Exceptions;
using SlatedGameToolkit.Framework.Graphics;
using SlatedGameToolkit.Framework.Graphics.Shaders; using SlatedGameToolkit.Framework.Graphics.Shaders;
namespace SlatedGameToolkit.Framework.Graphics.Programs namespace SlatedGameToolkit.Framework.Graphics.Programs
@ -9,37 +11,38 @@ namespace SlatedGameToolkit.Framework.Graphics.Programs
private readonly GLShader[] shaders; private readonly GLShader[] shaders;
private readonly GLAttachShader attachShader; private readonly GLAttachShader attachShader;
private readonly GLDetachShader detachShader; private readonly GLDetachShader detachShader;
private GLBindAttribLocation bindAttribLocation; public GLShaderProgram(params GLShader[] shaders) : base() {
public GLShaderProgram(bool separable = true, params GLShader[] shaders) : base() {
if (shaders.Length == 0) throw new ArgumentException("Requires at least one shader for shader program."); if (shaders.Length == 0) throw new ArgumentException("Requires at least one shader for shader program.");
this.shaders = shaders; this.shaders = shaders;
attachShader = OpenGL.RetrieveGLDelegate<GLAttachShader>("glAttachShader");
detachShader = OpenGL.RetrieveGLDelegate<GLDetachShader>("glDetachShader");
attachShader = GLFunctionUtils.RetrieveGLDelegate<GLAttachShader>("glAttachShader");
bindAttribLocation = GLFunctionUtils.RetrieveGLDelegate<GLBindAttribLocation>("glBindAttribLocation");
detachShader = GLFunctionUtils.RetrieveGLDelegate<GLDetachShader>("glDetachShader");
Use();
foreach (GLShader shader in shaders) foreach (GLShader shader in shaders)
{ {
attachShader(handle, shader.Handle); attachShader(handle, shader.Handle);
OpenGLErrorException.CheckGLErrorStatus();
} }
linkProgram(handle); linkProgram(handle);
uint length; uint length;
string log; byte[] log = new byte[2048];
getProgramInfoLog(handle, 1024, out length, out log); getProgramInfoLog(handle, (uint)log.Length, out length, log);
if (length > 0) { if (length > 0) {
Dispose(); Dispose();
throw new OpenGLException(log); throw new OpenGLException(Encoding.UTF8.GetString(log));
} }
OpenGLErrorException.CheckGLErrorStatus();
foreach (GLShader shader in shaders) foreach (GLShader shader in shaders)
{ {
detachShader(handle, shader.Handle); detachShader(handle, shader.Handle);
OpenGLErrorException.CheckGLErrorStatus();
} }
} }
/// <summary> /// <summary>
/// Disposes of the shaders and this program. /// Disposes of the shaders and this program.
/// </summary> /// </summary>

View File

@ -5,47 +5,60 @@ using SlatedGameToolkit.Framework.Graphics.Meshes;
using SlatedGameToolkit.Framework.Graphics; using SlatedGameToolkit.Framework.Graphics;
using SlatedGameToolkit.Framework.Graphics.Textures; using SlatedGameToolkit.Framework.Graphics.Textures;
using SlatedGameToolkit.Framework.Graphics.Shaders; using SlatedGameToolkit.Framework.Graphics.Shaders;
using SlatedGameToolkit.Framework.Graphics.Programs;
using SlatedGameToolkit.Framework.Exceptions;
namespace SlatedGameToolkit.Framework.Graphics.Render namespace SlatedGameToolkit.Framework.Graphics.Render
{ {
public class Batch : IDisposable { public class Batch : IDisposable {
private int projLoc, viewLoc, modelLoc;
private Camera camera;
private GLShaderProgram shaderProgram;
private Texture texture; private Texture texture;
private bool disposed; private bool disposed;
private VertexArray vertexArray; private VertexArray vertexArray;
private const int VERTEX_LENGTH = 6; private const int VERTEX_LENGTH = 9;
private GLMultiDrawElements multiDrawElements; private GLMultiDrawElements multiDrawElements;
public bool Batching { get; private set; } public bool Batching { get; private set; }
private Matrix4x4 modelsMatrix;
private float[] data; private float[] data;
private uint[] indices; private uint[] indices;
private uint[] lengths; private uint[] lengths;
private uint[] offsets; private uint[] offsets;
private uint dataIndex, indicesIndex, lengthsIndex; private uint dataIndex, indicesIndex, lengthsIndex;
public Batch(uint BatchVertexSize = 4096) { public Batch(Camera camera, GLShaderProgram shaderProgram, uint BatchVertexSize = 4096) {
multiDrawElements = GLFunctionUtils.RetrieveGLDelegate<GLMultiDrawElements>("glMultiDrawElements"); multiDrawElements = OpenGL.RetrieveGLDelegate<GLMultiDrawElements>("glMultiDrawElements");
this.camera = camera;
this.shaderProgram = shaderProgram;
indices = new uint[BatchVertexSize]; indices = new uint[BatchVertexSize];
lengths = new uint[BatchVertexSize]; lengths = new uint[BatchVertexSize];
offsets = new uint[BatchVertexSize]; offsets = new uint[BatchVertexSize];
data = new float[BatchVertexSize * VERTEX_LENGTH]; data = new float[BatchVertexSize * VERTEX_LENGTH];
vertexArray = new VertexArray(); vertexArray = new VertexArray();
GLGetAttribLocation attribLocation = OpenGL.RetrieveGLDelegate<GLGetAttribLocation>("glGetAttribLocation");
VertexAttributeDefinition[] definitions = new VertexAttributeDefinition[3]; VertexAttributeDefinition[] definitions = new VertexAttributeDefinition[3];
definitions[0] = new VertexAttributeDefinition(0, 3, 3 * sizeof(float), 0); definitions[0] = new VertexAttributeDefinition((uint)shaderProgram.GetAttributeLocation("aPosition"), 3, 3 * sizeof(float), 0);
definitions[1] = new VertexAttributeDefinition(1, 4, 1 * sizeof(float), 3 * sizeof(float)); definitions[1] = new VertexAttributeDefinition((uint)shaderProgram.GetAttributeLocation("aColor"), 4, 4 * sizeof(float), 3 * sizeof(float));
definitions[2] = new VertexAttributeDefinition(2, 2, 2 * sizeof(float), 4 * sizeof(float)); definitions[2] = new VertexAttributeDefinition((uint)shaderProgram.GetAttributeLocation("aTexCoord"), 2, 2 * sizeof(float), (4 + 3) * sizeof(float));
modelLoc = shaderProgram.GetUniformLocation("models");
viewLoc = shaderProgram.GetUniformLocation("view");
projLoc = shaderProgram.GetUniformLocation("projection");
vertexArray.defineVertexAttributes(definitions: definitions); vertexArray.defineVertexAttributes(definitions: definitions);
} }
public virtual void Begin(Texture texture) { public virtual void Begin(Texture texture, Matrix4x4 modelsMatrix) {
if (Batching) throw new InvalidOperationException("This batch is already started."); if (Batching) throw new InvalidOperationException("This batch is already started.");
this.texture = texture ?? throw new ArgumentNullException("texture"); this.texture = texture ?? throw new ArgumentNullException("texture");
this.Batching = true; this.Batching = true;
this.modelsMatrix = modelsMatrix;
} }
public virtual void Dispose() public virtual void Dispose()
{ {
if (disposed) return; if (disposed) return;
if (Batching) End();
disposed = true; disposed = true;
vertexArray.Dispose(); vertexArray.Dispose();
} }
@ -62,7 +75,13 @@ namespace SlatedGameToolkit.Framework.Graphics.Render
data[dataIndex] = vertices[i].Item1.Z; data[dataIndex] = vertices[i].Item1.Z;
dataIndex++; dataIndex++;
data[dataIndex] = color.ToArgb(); data[dataIndex] = (float) color.A / byte.MaxValue;
dataIndex++;
data[dataIndex] = (float) color.R / byte.MaxValue;
dataIndex++;
data[dataIndex] = (float) color.G / byte.MaxValue;
dataIndex++;
data[dataIndex] = (float) color.B / byte.MaxValue;
dataIndex++; dataIndex++;
data[dataIndex] = vertices[i].Item2.X; data[dataIndex] = vertices[i].Item2.X;
@ -93,7 +112,10 @@ namespace SlatedGameToolkit.Framework.Graphics.Render
dataIndex = 0; dataIndex = 0;
indicesIndex = 0; indicesIndex = 0;
lengthsIndex = 0; lengthsIndex = 0;
multiDrawElements(GLEnums.GL_TRIANGLE_STRIP, lengths, GLEnums.GL_UNSIGNED_INT, IntPtr.Zero, lengths.Length); shaderProgram.SetUniformMatrix4x4(modelLoc, modelsMatrix);
shaderProgram.SetUniformMatrix4x4(viewLoc, camera.ViewMatrix);
shaderProgram.SetUniformMatrix4x4(projLoc, camera.ProjectionMatrix);
multiDrawElements(GLEnum.GL_TRIANGLE_STRIP, lengths, GLEnum.GL_UNSIGNED_INT, offsets, lengths.Length);
} }
} }
} }

View File

@ -0,0 +1,103 @@
using System.Numerics;
namespace SlatedGameToolkit.Framework.Graphics.Render
{
public class Camera {
private bool viewUpdated, projectionUpdated;
public virtual Vector3 Up { get; set; }
private Vector3 trans, lookAt;
private float nearField, farField;
private float width, height;
private Matrix4x4 lookAtMatrix;
private Matrix4x4 view, projection;
public virtual bool Orthographic { get; set; }
public virtual Vector3 Position {
get {
return trans;
}
set {
this.trans = value;
viewUpdated = true;
}
}
public Vector3 LookAt {
get {
return lookAt;
}
set {
this.lookAt = value;
lookAtMatrix = Matrix4x4.CreateLookAt(-trans, value, Up);
viewUpdated = true;
}
}
public virtual float NearField {
get {
return nearField;
}
set {
nearField = value;
projectionUpdated = true;
}
}
public virtual float FarField {
get {
return farField;
}
set {
farField = value;
projectionUpdated = true;
}
}
public virtual float Width {
get {
return width;
}
set {
width = value;
projectionUpdated = true;
}
}
public virtual float Height {
get {
return height;
}
set {
height = value;
projectionUpdated = true;
}
}
public Matrix4x4 ViewMatrix {
get {
if (viewUpdated) {
view = Matrix4x4.CreateTranslation(-trans) * lookAtMatrix;
viewUpdated = false;
}
return view;
}
}
public Matrix4x4 ProjectionMatrix {
get {
if (projectionUpdated) {
if (Orthographic) {
projection = Matrix4x4.CreateOrthographic(width, height, nearField, farField);
} else {
projection = Matrix4x4.CreatePerspective(width, height, nearField, farField);
}
projectionUpdated = false;
}
return projection;
}
}
}
}

View File

@ -0,0 +1,22 @@
using System.Numerics;
namespace SlatedGameToolkit.Framework.Graphics.Render
{
public class Camera2D : Camera {
public new Vector2 Position {
get {
return new Vector2(base.Position.X, base.Position.Y);
}
set {
base.Position = new Vector3(value, 0);
}
}
public Camera2D() {
this.Orthographic = true;
this.Up = Vector3.UnitY;
this.LookAt = new Vector3(0, 0, 1);
}
}
}

View File

@ -1,3 +1,4 @@
using System.Drawing;
using SlatedGameToolkit.Framework.Graphics.Meshes; using SlatedGameToolkit.Framework.Graphics.Meshes;
using SlatedGameToolkit.Framework.Graphics.Textures; using SlatedGameToolkit.Framework.Graphics.Textures;
@ -6,5 +7,6 @@ namespace SlatedGameToolkit.Framework.Graphics.Render
public interface IRenderable : IMeshable public interface IRenderable : IMeshable
{ {
Texture Texture { get; } Texture Texture { get; }
Color Color { get; }
} }
} }

View File

@ -1,5 +1,8 @@
using System; using System;
using System.Drawing; using System.Drawing;
using System.Numerics;
using SlatedGameToolkit.Framework.Exceptions;
using SlatedGameToolkit.Framework.Graphics.Programs;
using SlatedGameToolkit.Framework.Graphics.Textures; using SlatedGameToolkit.Framework.Graphics.Textures;
namespace SlatedGameToolkit.Framework.Graphics.Render namespace SlatedGameToolkit.Framework.Graphics.Render
@ -13,8 +16,8 @@ namespace SlatedGameToolkit.Framework.Graphics.Render
this.batch = batch; this.batch = batch;
} }
public Renderer() { public Renderer(Camera camera, GLShaderProgram program, uint BatchVertexSize = 4096) {
this.batch = new Batch(); this.batch = new Batch(camera, program, BatchVertexSize);
} }
public void Dispose() public void Dispose()
@ -22,14 +25,13 @@ namespace SlatedGameToolkit.Framework.Graphics.Render
batch.Dispose(); batch.Dispose();
} }
public void Queue(IRenderable renderable, Color color) { public void Queue(IRenderable renderable, Matrix4x4 modelsMatrix) {
if (renderable.Texture != currentTexture) { if (renderable.Texture != currentTexture) {
if (batch.Batching) batch.End(); if (batch.Batching) batch.End();
currentTexture = renderable.Texture; currentTexture = renderable.Texture;
currentTexture.Use(); batch.Begin(currentTexture, modelsMatrix);
batch.Begin(currentTexture);
} }
batch.Add(renderable, color); batch.Add(renderable, renderable.Color);
} }
public void Render() { public void Render() {

View File

@ -1,3 +1,4 @@
using System.Drawing;
using SlatedGameToolkit.Framework.Graphics.Meshes; using SlatedGameToolkit.Framework.Graphics.Meshes;
using SlatedGameToolkit.Framework.Graphics.Textures; using SlatedGameToolkit.Framework.Graphics.Textures;
@ -6,7 +7,10 @@ namespace SlatedGameToolkit.Framework.Graphics.Render
public class Sprite2D : RectangleMesh, IRenderable public class Sprite2D : RectangleMesh, IRenderable
{ {
public Texture Texture { get; private set; } public Texture Texture { get; private set; }
public Sprite2D(Texture texture) {
public Color Color { get; private set; }
public Sprite2D(Texture texture, Color color) {
this.Texture = texture; this.Texture = texture;
this.textureCoords[0].X = -1; this.textureCoords[0].X = -1;
this.textureCoords[0].Y = -1; this.textureCoords[0].Y = -1;
@ -19,6 +23,8 @@ namespace SlatedGameToolkit.Framework.Graphics.Render
this.textureCoords[3].X = -1; this.textureCoords[3].X = -1;
this.textureCoords[3].Y = 1; this.textureCoords[3].Y = 1;
this.Color = color;
} }
} }
} }

View File

@ -1,4 +1,6 @@
using System.Text;
using SlatedGameToolkit.Framework.Exceptions; using SlatedGameToolkit.Framework.Exceptions;
using SlatedGameToolkit.Framework.Graphics;
namespace SlatedGameToolkit.Framework.Graphics.Shaders namespace SlatedGameToolkit.Framework.Graphics.Shaders
{ {
@ -9,15 +11,15 @@ namespace SlatedGameToolkit.Framework.Graphics.Shaders
/// </summary> /// </summary>
/// <param name="shader">A string representing the GLSL code to run.</param> /// <param name="shader">A string representing the GLSL code to run.</param>
public GLFragmentShader(string shader) : base() { public GLFragmentShader(string shader) : base() {
Handle = createShader(GLEnums.GL_FRAGMENT_SHADER); Handle = createShader(GLEnum.GL_FRAGMENT_SHADER);
shaderSource(Handle, 1, shader, null); shaderSource(Handle, 1, new string[] {shader}, null);
compileShader(Handle); compileShader(Handle);
uint logLength; uint logLength;
string shaderLog; byte[] log = new byte[2048];
getShaderLogInfo(Handle, 1024, out logLength, out shaderLog); getShaderInfoLog(Handle, (uint)log.Length, out logLength, log);
if (logLength > 0) { if (logLength > 0) {
Dispose(); Dispose();
throw new OpenGLException(shaderLog); throw new OpenGLException(Encoding.UTF8.GetString(log));
} }
OpenGLErrorException.CheckGLErrorStatus(); OpenGLErrorException.CheckGLErrorStatus();
} }

View File

@ -2,6 +2,7 @@ using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using SDL2; using SDL2;
using SlatedGameToolkit.Framework.Exceptions; using SlatedGameToolkit.Framework.Exceptions;
using SlatedGameToolkit.Framework.Graphics;
using SlatedGameToolkit.Framework.Graphics.Programs; using SlatedGameToolkit.Framework.Graphics.Programs;
using SlatedGameToolkit.Framework.Graphics.Window; using SlatedGameToolkit.Framework.Graphics.Window;
@ -9,35 +10,23 @@ namespace SlatedGameToolkit.Framework.Graphics.Shaders
{ {
public abstract class GLShader : IDisposable { public abstract class GLShader : IDisposable {
private WindowContext context; private WindowContext context;
public UIntPtr Handle { get; private protected set; } public virtual UIntPtr Handle { get; protected set; }
protected GLCreateShader createShader; protected GLCreateShader createShader;
protected GLShaderSource shaderSource; protected GLShaderSource shaderSource;
protected GLCompileShader compileShader; protected GLCompileShader compileShader;
protected GLGetShaderLogInfo getShaderLogInfo; protected GLGetShaderInfoLog getShaderInfoLog;
protected GLGetAttribLocation getAttribLocation;
private GLDeleteShader deleteShader; private GLDeleteShader deleteShader;
public GLShader() { public GLShader() {
context = WindowContextsManager.CurrentWindowContext; context = WindowContextsManager.CurrentWindowContext;
createShader = GLFunctionUtils.RetrieveGLDelegate<GLCreateShader>("glCreateShader"); createShader = OpenGL.RetrieveGLDelegate<GLCreateShader>("glCreateShader");
shaderSource = GLFunctionUtils.RetrieveGLDelegate<GLShaderSource>("glShaderSource"); shaderSource = OpenGL.RetrieveGLDelegate<GLShaderSource>("glShaderSource");
compileShader = GLFunctionUtils.RetrieveGLDelegate<GLCompileShader>("glCompileShader"); compileShader = OpenGL.RetrieveGLDelegate<GLCompileShader>("glCompileShader");
getShaderLogInfo = GLFunctionUtils.RetrieveGLDelegate<GLGetShaderLogInfo>("glGetShaderLogInfo"); getShaderInfoLog = OpenGL.RetrieveGLDelegate<GLGetShaderInfoLog>("glGetShaderInfoLog");
deleteShader = GLFunctionUtils.RetrieveGLDelegate<GLDeleteShader>("glDeleteShader"); deleteShader = OpenGL.RetrieveGLDelegate<GLDeleteShader>("glDeleteShader");
getAttribLocation = GLFunctionUtils.RetrieveGLDelegate<GLGetAttribLocation>("glGetAttribLocation");
} }
/// <summary>
/// Gets the attribute location.
/// </summary>
/// <param name="attributeName">The name of the attribute.</param>
/// <returns>The attribute location index.</returns>
public int GetAttributeLocation(string attributeName) {
int index = getAttribLocation(Handle, attributeName);
OpenGLErrorException.CheckGLErrorStatus();
return index;
}
/// <summary> /// <summary>
/// Disposes of the shader at the handle. /// Disposes of the shader at the handle.

View File

@ -1,6 +1,7 @@
using System; using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using SlatedGameToolkit.Framework.Exceptions; using SlatedGameToolkit.Framework.Exceptions;
using SlatedGameToolkit.Framework.Graphics;
namespace SlatedGameToolkit.Framework.Graphics.Shaders namespace SlatedGameToolkit.Framework.Graphics.Shaders
{ {
@ -23,16 +24,16 @@ namespace SlatedGameToolkit.Framework.Graphics.Shaders
public GLVertexArraySet(uint amount) { public GLVertexArraySet(uint amount) {
if (amount > int.MaxValue) throw new ArgumentOutOfRangeException("amount"); if (amount > int.MaxValue) throw new ArgumentOutOfRangeException("amount");
this.Count = (int)amount; this.Count = (int)amount;
genBuffers = GLFunctionUtils.RetrieveGLDelegate<GLGenBuffers>("glGenBuffers"); genBuffers = OpenGL.RetrieveGLDelegate<GLGenBuffers>("glGenBuffers");
deleteBuffers = GLFunctionUtils.RetrieveGLDelegate<GLDeleteBuffers>("glDeleteBuffers"); deleteBuffers = OpenGL.RetrieveGLDelegate<GLDeleteBuffers>("glDeleteBuffers");
bindBuffer = GLFunctionUtils.RetrieveGLDelegate<GLBindBuffer>("glBindBuffer"); bindBuffer = OpenGL.RetrieveGLDelegate<GLBindBuffer>("glBindBuffer");
genVertexArrays = GLFunctionUtils.RetrieveGLDelegate<GLGenVertexArrays>("glGenVertexArrays"); genVertexArrays = OpenGL.RetrieveGLDelegate<GLGenVertexArrays>("glGenVertexArrays");
bindVertexArray = GLFunctionUtils.RetrieveGLDelegate<GLBindVertexArray>("glBindVertexArray"); bindVertexArray = OpenGL.RetrieveGLDelegate<GLBindVertexArray>("glBindVertexArray");
deleteVertexArrays = GLFunctionUtils.RetrieveGLDelegate<GLDeleteVertexArrays>("glDeleteVertexArrays"); deleteVertexArrays = OpenGL.RetrieveGLDelegate<GLDeleteVertexArrays>("glDeleteVertexArrays");
vertexAttribPointer = GLFunctionUtils.RetrieveGLDelegate<GLVertexAttribPointer>("glVertexAttribPointer"); vertexAttribPointer = OpenGL.RetrieveGLDelegate<GLVertexAttribPointer>("glVertexAttribPointer");
enableVertexAttribArray = GLFunctionUtils.RetrieveGLDelegate<GLEnableVertexAttribArray>("glEnableVertexAttribArray"); enableVertexAttribArray = OpenGL.RetrieveGLDelegate<GLEnableVertexAttribArray>("glEnableVertexAttribArray");
disableVertexAttribArray = GLFunctionUtils.RetrieveGLDelegate<GLDisableVertexAttribArray>("glDisableVertexAttribArray"); disableVertexAttribArray = OpenGL.RetrieveGLDelegate<GLDisableVertexAttribArray>("glDisableVertexAttribArray");
bufferData = GLFunctionUtils.RetrieveGLDelegate<GLBufferData>("glBufferData"); bufferData = OpenGL.RetrieveGLDelegate<GLBufferData>("glBufferData");
arrayBufferHandles = new UIntPtr[amount]; arrayBufferHandles = new UIntPtr[amount];
vertexArrayHandles = new UIntPtr[amount]; vertexArrayHandles = new UIntPtr[amount];
indexArrayHandles = new UIntPtr[amount]; indexArrayHandles = new UIntPtr[amount];
@ -47,20 +48,20 @@ namespace SlatedGameToolkit.Framework.Graphics.Shaders
public void Use(uint index) { public void Use(uint index) {
bindVertexArray(vertexArrayHandles[index]); bindVertexArray(vertexArrayHandles[index]);
OpenGLErrorException.CheckGLErrorStatus(); OpenGLErrorException.CheckGLErrorStatus();
bindBuffer(GLEnums.GL_ELEMENT_ARRAY_BUFFER, indexArrayHandles[index]); bindBuffer(GLEnum.GL_ELEMENT_ARRAY_BUFFER, indexArrayHandles[index]);
bindBuffer(GLEnums.GL_ARRAY_BUFFER, arrayBufferHandles[index]); bindBuffer(GLEnum.GL_ARRAY_BUFFER, arrayBufferHandles[index]);
OpenGLErrorException.CheckGLErrorStatus(); OpenGLErrorException.CheckGLErrorStatus();
} }
public unsafe void BufferVertices(uint index, float[] data, bool dynamic) { public unsafe void BufferVertices(uint index, float[] data, bool dynamic) {
Use(index); Use(index);
bufferData(GLEnums.GL_ARRAY_BUFFER, (uint) (sizeof(float) * data.Length), data, dynamic ? GLEnums.GL_DYNAMIC_DRAW : GLEnums.GL_STATIC_DRAW); bufferData(GLEnum.GL_ARRAY_BUFFER, (uint) (sizeof(float) * data.Length), data, dynamic ? GLEnum.GL_DYNAMIC_DRAW : GLEnum.GL_STATIC_DRAW);
OpenGLErrorException.CheckGLErrorStatus(); OpenGLErrorException.CheckGLErrorStatus();
} }
public unsafe void BufferIndices(uint index, uint[] data, bool dynamic) { public unsafe void BufferIndices(uint index, uint[] data, bool dynamic) {
Use(index); Use(index);
bufferData(GLEnums.GL_ELEMENT_ARRAY_BUFFER, (uint) (sizeof(float) * data.Length), data, dynamic ? GLEnums.GL_DYNAMIC_DRAW : GLEnums.GL_STATIC_DRAW); bufferData(GLEnum.GL_ELEMENT_ARRAY_BUFFER, (uint) (sizeof(float) * data.Length), data, dynamic ? GLEnum.GL_DYNAMIC_DRAW : GLEnum.GL_STATIC_DRAW);
OpenGLErrorException.CheckGLErrorStatus(); OpenGLErrorException.CheckGLErrorStatus();
} }
@ -75,7 +76,7 @@ namespace SlatedGameToolkit.Framework.Graphics.Shaders
Use(bufferIndex); Use(bufferIndex);
foreach (VertexAttributeDefinition definition in definitions) foreach (VertexAttributeDefinition definition in definitions)
{ {
vertexAttribPointer(definition.attributeIndex, definition.size, GLEnums.GL_FLOAT, false, definition.stride, definition.offset); vertexAttribPointer(definition.attributeIndex, definition.size, GLEnum.GL_FLOAT, false, definition.stride, definition.offset);
OpenGLErrorException.CheckGLErrorStatus(); OpenGLErrorException.CheckGLErrorStatus();
if (enableAttributes) enableVertexAttribArray(definition.attributeIndex); if (enableAttributes) enableVertexAttribArray(definition.attributeIndex);
} }

View File

@ -1,3 +1,4 @@
using System.Text;
using SlatedGameToolkit.Framework.Exceptions; using SlatedGameToolkit.Framework.Exceptions;
namespace SlatedGameToolkit.Framework.Graphics.Shaders namespace SlatedGameToolkit.Framework.Graphics.Shaders
@ -9,15 +10,15 @@ namespace SlatedGameToolkit.Framework.Graphics.Shaders
/// </summary> /// </summary>
/// <param name="shader">A string representing the GLSL code.</param> /// <param name="shader">A string representing the GLSL code.</param>
public GLVertexShader(string shader) : base() { public GLVertexShader(string shader) : base() {
Handle = createShader(GLEnums.GL_VERTEX_SHADER); Handle = createShader(GLEnum.GL_VERTEX_SHADER);
shaderSource(Handle, 1, shader, null); shaderSource(Handle, 1, new string[] {shader}, null);
compileShader(Handle); compileShader(Handle);
uint logLength; uint logLength;
string shaderLog; byte[] log = new byte[2048];
getShaderLogInfo(Handle, 1024, out logLength, out shaderLog); getShaderInfoLog(Handle, (uint)log.Length, out logLength, log);
if (logLength > 0) { if (logLength > 0) {
Dispose(); Dispose();
throw new OpenGLException(shaderLog); throw new OpenGLException(Encoding.UTF8.GetString(log));
} }
OpenGLErrorException.CheckGLErrorStatus(); OpenGLErrorException.CheckGLErrorStatus();
} }

View File

@ -0,0 +1,21 @@
using System;
using System.IO;
using System.Reflection;
namespace SlatedGameToolkit.Framework.Graphics.Shaders
{
public class NormalFragmentShader : GLShader
{
private GLFragmentShader shader;
public NormalFragmentShader() {
using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("SlatedGameToolkit.Framework.Resources.default.frag"))
{
using (StreamReader reader = new StreamReader(stream))
{
shader = new GLFragmentShader(reader.ReadToEnd());
}
}
this.Handle = shader.Handle;
}
}
}

View File

@ -0,0 +1,20 @@
using System;
using System.IO;
using System.Reflection;
namespace SlatedGameToolkit.Framework.Graphics.Shaders {
public class NormalVertexShader : GLShader
{
private GLVertexShader shader;
public NormalVertexShader() {
using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("SlatedGameToolkit.Framework.Resources.default.vert"))
{
using (StreamReader reader = new StreamReader(stream)) {
shader = new GLVertexShader(reader.ReadToEnd());
}
}
Handle = shader.Handle;
}
}
}

View File

@ -15,23 +15,23 @@ namespace SlatedGameToolkit.Framework.Graphics
private GLDeleteTextures deleteTextures; private GLDeleteTextures deleteTextures;
private GLTexImage2D texImage2D; private GLTexImage2D texImage2D;
private GLBindTexture bindTexture; private GLBindTexture bindTexture;
private GLGenerateMipMap generateMipMap; private GLGenerateMipmap generateMipmap;
private readonly UIntPtr[] handle; private readonly UIntPtr[] handle;
public GLTexture2DSet(TextureData[] textureDatas, bool linear = false, bool mipmap = false) public GLTexture2DSet(TextureData[] textureDatas, bool linear = false, bool mipmap = false)
{ {
genTextures = GLFunctionUtils.RetrieveGLDelegate<GLGenTextures>("glGenTextures"); genTextures = OpenGL.RetrieveGLDelegate<GLGenTextures>("glGenTextures");
deleteTextures = GLFunctionUtils.RetrieveGLDelegate<GLDeleteTextures>("glDeleteTextures"); deleteTextures = OpenGL.RetrieveGLDelegate<GLDeleteTextures>("glDeleteTextures");
bindTexture = GLFunctionUtils.RetrieveGLDelegate<GLBindTexture>("glBindTexture"); bindTexture = OpenGL.RetrieveGLDelegate<GLBindTexture>("glBindTexture");
texParameteri = GLFunctionUtils.RetrieveGLDelegate<GLTexParameteri>("glTexParameteri"); texParameteri = OpenGL.RetrieveGLDelegate<GLTexParameteri>("glTexParameteri");
texParameterfv = GLFunctionUtils.RetrieveGLDelegate<GLTexParameterfv>("glTexParameterfv"); texParameterfv = OpenGL.RetrieveGLDelegate<GLTexParameterfv>("glTexParameterfv");
texImage2D = GLFunctionUtils.RetrieveGLDelegate<GLTexImage2D>("glTexImage2D"); texImage2D = OpenGL.RetrieveGLDelegate<GLTexImage2D>("glTexImage2D");
generateMipMap = GLFunctionUtils.RetrieveGLDelegate<GLGenerateMipMap>("glGenerateMipMap"); generateMipmap = OpenGL.RetrieveGLDelegate<GLGenerateMipmap>("glGenerateMipmap");
handle = new UIntPtr[textureDatas.Length]; handle = new UIntPtr[textureDatas.Length];
genTextures((uint)textureDatas.Length, handle); genTextures((uint)textureDatas.Length, handle);
for (uint i = 0; i < textureDatas.Length; i++) { for (uint i = 0; i < textureDatas.Length; i++) {
Setup(i, textureDatas[i]); Setup(i, textureDatas[i]);
} }
bindTexture(GLEnums.GL_TEXTURE_2D, UIntPtr.Zero); bindTexture(GLEnum.GL_TEXTURE_2D, UIntPtr.Zero);
OpenGLErrorException.CheckGLErrorStatus(); OpenGLErrorException.CheckGLErrorStatus();
this.Count = textureDatas.Length; this.Count = textureDatas.Length;
@ -39,8 +39,10 @@ namespace SlatedGameToolkit.Framework.Graphics
private void Setup(uint index, TextureData textureData) { private void Setup(uint index, TextureData textureData) {
Bind(index); Bind(index);
texImage2D(GLEnums.GL_TEXTURE_2D, 0, (int)GLEnums.GL_RGBA, textureData.width, textureData.height, 0, GLEnums.GL_RGBA, GLEnums.GL_UNSIGNED_BYTE, textureData.data); texImage2D(GLEnum.GL_TEXTURE_2D, 0, (int)GLEnum.GL_RGBA, textureData.width, textureData.height, 0, GLEnum.GL_RGBA, GLEnum.GL_UNSIGNED_BYTE, textureData.data);
generateMipMap(GLEnums.GL_TEXTURE_2D); OpenGLErrorException.CheckGLErrorStatus();
generateMipmap(GLEnum.GL_TEXTURE_2D);
OpenGLErrorException.CheckGLErrorStatus();
} }
/// <summary> /// <summary>
@ -50,12 +52,12 @@ namespace SlatedGameToolkit.Framework.Graphics
/// <param name="index">The index of the texture.</param> /// <param name="index">The index of the texture.</param>
/// <param name="linear">Whether or not to have linear filtering.</param> /// <param name="linear">Whether or not to have linear filtering.</param>
/// <param name="mipmap">Whether or not to use MipMap</param> /// <param name="mipmap">Whether or not to use MipMap</param>
public void SetProperties(uint index, GLEnums min, GLEnums mag) { public void SetProperties(uint index, GLEnum min, GLEnum mag) {
Bind(index); Bind(index);
texParameteri(GLEnums.GL_TEXTURE_2D, GLEnums.GL_TEXTURE_WRAP_S, (int)GLEnums.GL_CLAMP_TO_EDGE); texParameteri(GLEnum.GL_TEXTURE_2D, GLEnum.GL_TEXTURE_WRAP_S, (int)GLEnum.GL_CLAMP_TO_EDGE);
texParameteri(GLEnums.GL_TEXTURE_2D, GLEnums.GL_TEXTURE_WRAP_T, (int)GLEnums.GL_CLAMP_TO_EDGE); texParameteri(GLEnum.GL_TEXTURE_2D, GLEnum.GL_TEXTURE_WRAP_T, (int)GLEnum.GL_CLAMP_TO_EDGE);
texParameteri(GLEnums.GL_TEXTURE_2D, GLEnums.GL_TEXTURE_MIN_FILTER, (int) min); texParameteri(GLEnum.GL_TEXTURE_2D, GLEnum.GL_TEXTURE_MIN_FILTER, (int) min);
texParameteri(GLEnums.GL_TEXTURE_2D, GLEnums.GL_TEXTURE_MAG_FILTER, (int) mag); texParameteri(GLEnum.GL_TEXTURE_2D, GLEnum.GL_TEXTURE_MAG_FILTER, (int) mag);
} }
/// <summary> /// <summary>
@ -63,8 +65,8 @@ namespace SlatedGameToolkit.Framework.Graphics
/// </summary> /// </summary>
/// <param name="index">The index of the texture in this set.</param> /// <param name="index">The index of the texture in this set.</param>
public void Bind(uint index) { public void Bind(uint index) {
bindTexture(GLEnums.GL_TEXTURE_2D, handle[index]); bindTexture(GLEnum.GL_TEXTURE_2D, handle[index]);
OpenGLErrorException.CheckGLErrorStatus();
} }
public void Dispose() public void Dispose()

View File

@ -1,3 +1,4 @@
using SlatedGameToolkit.Framework.Exceptions;
using SlatedGameToolkit.Framework.Loader; using SlatedGameToolkit.Framework.Loader;
namespace SlatedGameToolkit.Framework.Graphics.Textures namespace SlatedGameToolkit.Framework.Graphics.Textures
@ -15,6 +16,7 @@ namespace SlatedGameToolkit.Framework.Graphics.Textures
public Texture(TextureData textureData, bool linear = true, bool mipmap = true) { public Texture(TextureData textureData, bool linear = true, bool mipmap = true) {
TextureData[] textureDatas = new TextureData[] {textureData}; TextureData[] textureDatas = new TextureData[] {textureData};
this.glTexture2DSet = new GLTexture2DSet(textureDatas, linear, mipmap); this.glTexture2DSet = new GLTexture2DSet(textureDatas, linear, mipmap);
OpenGLErrorException.CheckGLErrorStatus();
this.index = 0; this.index = 0;
} }

View File

@ -92,18 +92,18 @@ namespace SlatedGameToolkit.Framework.Graphics.Window
WindowContext actual = WindowContextsManager.CurrentWindowContext; WindowContext actual = WindowContextsManager.CurrentWindowContext;
bool diff = false; bool diff = false;
if (actual != this) { if (actual != this) {
WindowContextsManager.CurrentWindowContext = this; MakeCurrent();
diff = true; diff = true;
} }
bool vSync = SDL.SDL_GL_GetSwapInterval() != 0; bool vSync = SDL.SDL_GL_GetSwapInterval() != 0;
if (diff) WindowContextsManager.CurrentWindowContext = actual; if (diff) actual.MakeCurrent();
return vSync; return vSync;
} }
set { set {
WindowContext actual = WindowContextsManager.CurrentWindowContext; WindowContext actual = WindowContextsManager.CurrentWindowContext;
bool diff = false; bool diff = false;
if (actual != this) { if (actual != this) {
WindowContextsManager.CurrentWindowContext = this; MakeCurrent();
diff = true; diff = true;
} }
if (SDL.SDL_GL_SetSwapInterval(value ? -1 : 0) < 0) { if (SDL.SDL_GL_SetSwapInterval(value ? -1 : 0) < 0) {
@ -111,7 +111,7 @@ namespace SlatedGameToolkit.Framework.Graphics.Window
throw new OptionalSDLException(); throw new OptionalSDLException();
} }
} }
if (diff) WindowContextsManager.CurrentWindowContext = actual; if (diff) actual.MakeCurrent();
} }
} }
@ -271,10 +271,10 @@ namespace SlatedGameToolkit.Framework.Graphics.Window
throw new FrameworkSDLException(); throw new FrameworkSDLException();
} }
clear = GLFunctionUtils.RetrieveGLDelegate<GLClear>("glClear"); clear = OpenGL.RetrieveGLDelegate<GLClear>("glClear");
clearColour = GLFunctionUtils.RetrieveGLDelegate<GLClearColour>("glClearColor"); clearColour = OpenGL.RetrieveGLDelegate<GLClearColour>("glClearColor");
viewport = GLFunctionUtils.RetrieveGLDelegate<GLViewport>("glViewport"); viewport = OpenGL.RetrieveGLDelegate<GLViewport>("glViewport");
getError = GLFunctionUtils.RetrieveGLDelegate<GLGetError>("glGetError"); getError = OpenGL.RetrieveGLDelegate<GLGetError>("glGetError");
if (specialRegions) { if (specialRegions) {
if (SDL.SDL_SetWindowHitTest(windowHandle, SpecialRegionHit, IntPtr.Zero) < 0) { if (SDL.SDL_SetWindowHitTest(windowHandle, SpecialRegionHit, IntPtr.Zero) < 0) {
@ -283,7 +283,7 @@ namespace SlatedGameToolkit.Framework.Graphics.Window
} }
WindowContextsManager.RegisterWindow(this); WindowContextsManager.RegisterWindow(this);
WindowContextsManager.CurrentWindowContext = this; MakeCurrent();
Vector2 drawable = GetDrawableDimensions(); Vector2 drawable = GetDrawableDimensions();
viewport(0, 0, (int)drawable.X, (int)drawable.Y); viewport(0, 0, (int)drawable.X, (int)drawable.Y);
@ -336,9 +336,10 @@ namespace SlatedGameToolkit.Framework.Graphics.Window
/// There can only be one window context active at any given time. /// There can only be one window context active at any given time.
/// </summary> /// </summary>
public void MakeCurrent() { public void MakeCurrent() {
if (WindowContextsManager.CurrentWindowContext != this) {
SDL.SDL_GL_MakeCurrent(windowHandle, glContextHandle); SDL.SDL_GL_MakeCurrent(windowHandle, glContextHandle);
WindowContextsManager.CurrentWindowContext = this; WindowContextsManager.current = this;
}
} }
/// <summary> /// <summary>

View File

@ -3,7 +3,7 @@ using System.Collections.Generic;
namespace SlatedGameToolkit.Framework.Graphics.Window namespace SlatedGameToolkit.Framework.Graphics.Window
{ {
public static class WindowContextsManager { public static class WindowContextsManager {
private static WindowContext current; internal static WindowContext current;
/// <summary> /// <summary>
/// The current window context. /// The current window context.
@ -13,13 +13,6 @@ namespace SlatedGameToolkit.Framework.Graphics.Window
get { get {
return current; return current;
} }
set {
if (current != value) {
current = value;
value.MakeCurrent();
}
}
} }
private static Dictionary<uint, WindowContext> existingWindows = new Dictionary<uint, WindowContext>(); private static Dictionary<uint, WindowContext> existingWindows = new Dictionary<uint, WindowContext>();

View File

@ -7,7 +7,7 @@ namespace SlatedGameToolkit.Framework.Loader {
public class AssetManager : IDisposable { public class AssetManager : IDisposable {
private readonly object assetThreadLock = new object(); private readonly object assetThreadLock = new object();
private Thread thread; private Thread thread;
private ConcurrentQueue<ILoadable> loadables; private ConcurrentQueue<ILoadable<IAssetUseable>> loadables;
private volatile bool load; private volatile bool load;
public bool Complete { public bool Complete {
get { get {
@ -17,7 +17,7 @@ namespace SlatedGameToolkit.Framework.Loader {
private ConcurrentDictionary<string, IAssetUseable> assets; private ConcurrentDictionary<string, IAssetUseable> assets;
public ConcurrentDictionary<Type, PathModifier> PathModifiers {get; private set; } public ConcurrentDictionary<Type, PathModifier> PathModifiers {get; private set; }
public AssetManager() { public AssetManager() {
this.loadables = new ConcurrentQueue<ILoadable>(); this.loadables = new ConcurrentQueue<ILoadable<IAssetUseable>>();
this.assets = new ConcurrentDictionary<string, IAssetUseable>(); this.assets = new ConcurrentDictionary<string, IAssetUseable>();
this.PathModifiers = new ConcurrentDictionary<Type, PathModifier>(); this.PathModifiers = new ConcurrentDictionary<Type, PathModifier>();
thread = new Thread(Process); thread = new Thread(Process);
@ -32,14 +32,14 @@ namespace SlatedGameToolkit.Framework.Loader {
/// The file name of the loadable is the one the loadable is saved under. /// The file name of the loadable is the one the loadable is saved under.
/// </summary> /// </summary>
/// <param name="loadable">The loadable.</param> /// <param name="loadable">The loadable.</param>
public void QueueLoad(ILoadable loadable) { public void QueueLoad(ILoadable<IAssetUseable> loadable) {
loadables.Enqueue(loadable); loadables.Enqueue(loadable);
} }
private void Process() { private void Process() {
lock (assetThreadLock) lock (assetThreadLock)
{ {
ILoadable loadable; ILoadable<IAssetUseable> loadable;
while (load) { while (load) {
while (loadables.TryDequeue(out loadable)) { while (loadables.TryDequeue(out loadable)) {
Load(loadable); Load(loadable);
@ -53,7 +53,7 @@ namespace SlatedGameToolkit.Framework.Loader {
/// Loads the loadable and stores it under the filename given to the loadable. /// Loads the loadable and stores it under the filename given to the loadable.
/// </summary> /// </summary>
/// <param name="loadable">The loadable to load.</param> /// <param name="loadable">The loadable to load.</param>
public void Load(ILoadable loadable) { public void Load(ILoadable<IAssetUseable> loadable) {
string name = loadable.FileName; string name = loadable.FileName;
assets[name] = loadable.Load(PathModifiers[loadable.GetType()]); assets[name] = loadable.Load(PathModifiers[loadable.GetType()]);
} }

View File

@ -11,7 +11,7 @@ namespace SlatedGameToolkit.Framework.Loader
/// A loader is to load an asset the game uses. /// A loader is to load an asset the game uses.
/// It is created whenever the asset needs to be loaded with a string representing the path to the file to actually load. /// It is created whenever the asset needs to be loaded with a string representing the path to the file to actually load.
/// </summary> /// </summary>
public interface ILoadable public interface ILoadable <UseableT> where UseableT : IAssetUseable
{ {
/// <summary> /// <summary>
/// The name of the file to load. /// The name of the file to load.
@ -26,6 +26,6 @@ namespace SlatedGameToolkit.Framework.Loader
/// <param name="pathModifier">Modifies the path. May be null. Default is null.</param> /// <param name="pathModifier">Modifies the path. May be null. Default is null.</param>
/// <typeparam name="Useable">The loadable type.</typeparam> /// <typeparam name="Useable">The loadable type.</typeparam>
/// <returns>The loadable type.</returns> /// <returns>The loadable type.</returns>
IAssetUseable Load(PathModifier pathModifier = null); UseableT Load(PathModifier pathModifier = null);
} }
} }

View File

@ -7,22 +7,22 @@ using SlatedGameToolkit.Framework.Loader;
namespace SlatedGameToolkit.Framework.Loader namespace SlatedGameToolkit.Framework.Loader
{ {
public class TextureLoader : ILoadable public class TextureLoader : ILoadable<Texture>
{ {
public string FileName {get; private set; } public string FileName {get; private set; }
public TextureLoader(string path) { public TextureLoader(string path) {
this.FileName = path; this.FileName = path;
} }
public IAssetUseable Load(PathModifier pathModifier = null) public Texture Load(PathModifier pathModifier = null)
{ {
IntPtr ptr = SDL_image.IMG_Load(pathModifier(FileName)); IntPtr ptr = SDL_image.IMG_Load(pathModifier == null ? FileName : pathModifier(FileName));
if (ptr == null) throw new FrameworkSDLException(); if (ptr.Equals(IntPtr.Zero)) throw new FrameworkSDLException();
SDL.SDL_Surface surface = Marshal.PtrToStructure<SDL.SDL_Surface>(ptr); SDL.SDL_Surface surface = Marshal.PtrToStructure<SDL.SDL_Surface>(ptr);
TextureData textureData = new TextureData(); TextureData textureData = new TextureData();
byte[] data = new byte[surface.pitch * surface.h]; textureData.data = new byte[surface.pitch * surface.h];
Marshal.Copy(surface.pixels, data, 0, data.Length); Marshal.Copy(surface.pixels, textureData.data, 0, textureData.data.Length);
IAssetUseable useable = new Texture(textureData); Texture useable = new Texture(textureData);
return useable; return useable;
} }
} }

View File

@ -0,0 +1,11 @@
#version 330 core
out vec4 outputColor;
in vec2 texCoord;
in vec4 color;
uniform sampler2D texture0;
void main()
{
outputColor = texture(texture0, texCoord) * color;
}

View File

@ -0,0 +1,17 @@
#version 330 core
in vec3 aPosition;
in vec4 aColor;
in vec2 aTexCoord;
uniform mat4 models;
uniform mat4 view;
uniform mat4 projection;
out vec2 texCoord;
out vec4 color;
void main()
{
texCoord = aTexCoord;
color = aColor;
gl_Position = projection * view * models * vec4(aPosition, 1.0f);
}

View File

@ -10,4 +10,7 @@
<PackageReference Include="Serilog.Sinks.File" Version="4.1.0" /> <PackageReference Include="Serilog.Sinks.File" Version="4.1.0" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Resources/**"/>
</ItemGroup>
</Project> </Project>

View File

@ -2,13 +2,14 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Drawing; using System.Drawing;
using System.Threading; using System.Threading;
using SlatedGameToolkit.Framework.Exceptions;
using SlatedGameToolkit.Framework.Graphics; using SlatedGameToolkit.Framework.Graphics;
using SlatedGameToolkit.Framework.Graphics.Window; using SlatedGameToolkit.Framework.Graphics.Window;
using SlatedGameToolkit.Framework.StateSystem.States; using SlatedGameToolkit.Framework.StateSystem.States;
namespace SlatedGameToolkit.Framework.StateSystem namespace SlatedGameToolkit.Framework.StateSystem
{ {
public sealed class Manager : IDisposable { public sealed class StateManager : IDisposable {
public Thread thread; public Thread thread;
public Color backgroundColour; public Color backgroundColour;
private IState currentState; private IState currentState;
@ -22,14 +23,17 @@ namespace SlatedGameToolkit.Framework.StateSystem
/// </summary> /// </summary>
/// <param name="initialState">The name of the initial state.</param> /// <param name="initialState">The name of the initial state.</param>
/// <param name="states">The initial set of game states to be added.</param> /// <param name="states">The initial set of game states to be added.</param>
internal Manager(IState initialState) { internal StateManager() {
backgroundColour = Color.Orange; backgroundColour = Color.Orange;
this.states = new Dictionary<string, IState>();
}
internal void Initialize(IState initialState) {
if (initialState == null) throw new ArgumentNullException("initialState"); if (initialState == null) throw new ArgumentNullException("initialState");
thread = Thread.CurrentThread; thread = Thread.CurrentThread;
this.states = new Dictionary<string, IState>();
addState(initialState);
currentState = initialState; currentState = initialState;
addState(initialState);
} }
internal void update(double delta) { internal void update(double delta) {
@ -44,8 +48,10 @@ namespace SlatedGameToolkit.Framework.StateSystem
internal void render(double delta) { internal void render(double delta) {
WindowContext windowContext = WindowContextsManager.CurrentWindowContext; WindowContext windowContext = WindowContextsManager.CurrentWindowContext;
windowContext.clearColour(backgroundColour.R / 254f, backgroundColour.G / 254f, backgroundColour.B / 254f); windowContext.clearColour((float)backgroundColour.R / byte.MaxValue, (float)backgroundColour.G / byte.MaxValue, (float)backgroundColour.B / byte.MaxValue);
windowContext.clear(GLEnums.GL_COLOR_BUFFER_BIT | GLEnums.GL_DEPTH_STENCIL); OpenGLErrorException.CheckGLErrorStatus();
windowContext.clear(GLEnum.GL_COLOR_BUFFER_BIT | GLEnum.GL_DEPTH_BUFFER_BIT);
OpenGLErrorException.CheckGLErrorStatus();
currentState.Render(delta); currentState.Render(delta);
windowContext.SwapBuffer(); windowContext.SwapBuffer();
} }
@ -87,8 +93,8 @@ namespace SlatedGameToolkit.Framework.StateSystem
public bool addState(IState state) { public bool addState(IState state) {
if (thread != Thread.CurrentThread) throw new ThreadStateException("Cannot add a state from a different thread."); if (thread != Thread.CurrentThread) throw new ThreadStateException("Cannot add a state from a different thread.");
try { try {
GameEngine.Logger.Debug("Adding state: " + state.getName()); GameEngine.Logger.Debug("Adding state: " + state.getName());
this.states.Add(state.getName(), state); this.states.Add(state.getName(), state);
} catch (ArgumentException) { } catch (ArgumentException) {
return false; return false;
} }
@ -108,7 +114,12 @@ namespace SlatedGameToolkit.Framework.StateSystem
if (states[name] == currentState) return false; if (states[name] == currentState) return false;
IState state = states[name]; IState state = states[name];
GameEngine.Logger.Debug("Removing state: " + name); GameEngine.Logger.Debug("Removing state: " + name);
state.Deinitialize(); try {
state.Deinitialize();
} catch (Exception e) {
GameEngine.Logger.Error(e.ToString());
GameEngine.Logger.Error("Failed to deinitialize state: " + state.getName());
}
return states.Remove(name); return states.Remove(name);
} }

View File

@ -44,7 +44,7 @@ namespace SlatedGameToolkit.Framework.StateSystem.States
/// Should be used to set up this state. /// Should be used to set up this state.
/// </summary> /// </summary>
/// <param name="manager">The manager that made this call.</param> /// <param name="manager">The manager that made this call.</param>
void Initialize(Manager manager); void Initialize(StateManager manager);
/// <summary> /// <summary>
/// The name of this state. /// The name of this state.

View File

@ -1,9 +1,9 @@
using System; using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using SlatedGameToolkit.Tools.System.Interaction; using SlatedGameToolkit.Tools.CommandSystem.Interaction;
namespace SlatedGameToolkit.Tools.System namespace SlatedGameToolkit.Tools.CommandSystem
{ {
public class CommandMap : ICollection<IInvocable>, IDisposable { public class CommandMap : ICollection<IInvocable>, IDisposable {
Dictionary<string, IInvocable> invocations; Dictionary<string, IInvocable> invocations;

View File

@ -1,22 +1,19 @@
using System; using System;
using SlatedGameToolkit.Tools.System.Interaction; using SlatedGameToolkit.Tools.CommandSystem.Interaction;
namespace SlatedGameToolkit.Tools.System namespace SlatedGameToolkit.Tools.CommandSystem
{ {
public class CommandProcessor public class CommandProcessor
{ {
private string generalHelpMessage;
CommandMap commandMap; CommandMap commandMap;
/// <summary> /// <summary>
/// The general help is the string that is printed when the input is not understood. /// The general help is the string that is printed when the input is not understood.
/// {input} in the string is replaced with the user input. /// {input} in the string is replaced with the user input.
/// </summary> /// </summary>
/// <param name="generalHelp"></param>
/// <param name="commands"></param> /// <param name="commands"></param>
public CommandProcessor(string generalHelp, CommandMap commands) { public CommandProcessor(CommandMap commands) {
this.commandMap = commands; this.commandMap = commands;
this.generalHelpMessage = generalHelp;
} }
public void Process(IInteractable interactable) { public void Process(IInteractable interactable) {
string message = interactable.Listen(); string message = interactable.Listen();
@ -27,11 +24,12 @@ namespace SlatedGameToolkit.Tools.System
if (invocable != null) { if (invocable != null) {
string[] args = new string[splitMessage.Length - 1]; string[] args = new string[splitMessage.Length - 1];
Array.Copy(splitMessage, 1, args, 0, splitMessage.Length - 1); Array.Copy(splitMessage, 1, args, 0, splitMessage.Length - 1);
if (invocable.Execute(interactable, args)) { if (!invocable.Execute(interactable, args)) {
return; interactable.Tell(string.Format("The command \"{0}\" was recognized, but arguments were incorrect. Please refer to Please type \"help {0}\" for more information.", invocation));
} }
return;
} }
interactable.Tell(generalHelpMessage.Replace("{input}", invocation)); interactable.Tell(string.Format("The input \"{0}\" was not understood. Please type \"help\" for more information.", invocation));
} }
} }
} }

View File

@ -0,0 +1,14 @@
using System;
using System.Runtime.Serialization;
namespace SlatedGameToolkit.Tools.CommandSystem.Exceptions
{
[Serializable]
public class FatalUsageException : Exception
{
public FatalUsageException() { }
public FatalUsageException(string message) : base(message) { }
public FatalUsageException(string message, Exception inner) : base(message, inner) { }
protected FatalUsageException(SerializationInfo info, StreamingContext context) : base(info, context) { }
}
}

View File

@ -1,7 +1,7 @@
using System; using System;
using SlatedGameToolkit.Tools.System.Interaction; using SlatedGameToolkit.Tools.CommandSystem.Interaction;
namespace SlatedGameToolkit.Tools.System namespace SlatedGameToolkit.Tools.CommandSystem
{ {
public interface IInvocable : IDisposable public interface IInvocable : IDisposable
{ {

View File

@ -1,6 +1,6 @@
using System; using System;
namespace SlatedGameToolkit.Tools.System.Interaction namespace SlatedGameToolkit.Tools.CommandSystem.Interaction
{ {
public class ConsoleInteraction : IInteractable public class ConsoleInteraction : IInteractable
{ {

View File

@ -1,4 +1,4 @@
namespace SlatedGameToolkit.Tools.System.Interaction namespace SlatedGameToolkit.Tools.CommandSystem.Interaction
{ {
public interface IInteractable public interface IInteractable
{ {

View File

@ -0,0 +1,30 @@
using System;
using SlatedGameToolkit.Tools.CommandSystem.Exceptions;
namespace SlatedGameToolkit.Tools.CommandSystem.Interaction
{
public class SingleConsoleInteraction : IInteractable
{
private bool interacted;
private string oneTime;
public SingleConsoleInteraction(string oneTime) {
this.oneTime = oneTime;
}
public string Listen()
{
if (interacted) throw new FatalUsageException("Command attempted to request for more information. This generally occurs if the command being ran requires more user input.");
interacted = true;
return oneTime;
}
public void Separate()
{
Console.WriteLine();
}
public void Tell(string message)
{
Console.WriteLine(message);
}
}
}

View File

@ -1,8 +1,8 @@
using SlatedGameToolkit.Framework; using SlatedGameToolkit.Framework;
using SlatedGameToolkit.Framework.StateSystem; using SlatedGameToolkit.Framework.StateSystem;
using SlatedGameToolkit.Tools.System; using SlatedGameToolkit.Tools.CommandSystem;
using SlatedGameToolkit.Tools.System.Interaction; using SlatedGameToolkit.Tools.CommandSystem.Interaction;
using SlatedGameToolkit.Tools.Utilities.GraphicalPlayground; using SlatedGameToolkit.Tools.Utilities.Playground;
namespace SlatedGameToolkit.Tools.Commands namespace SlatedGameToolkit.Tools.Commands
{ {

View File

@ -1,7 +1,7 @@
using System; using System;
using System.Text; using System.Text;
using SlatedGameToolkit.Tools.System; using SlatedGameToolkit.Tools.CommandSystem;
using SlatedGameToolkit.Tools.System.Interaction; using SlatedGameToolkit.Tools.CommandSystem.Interaction;
namespace SlatedGameToolkit.Tools.Commands namespace SlatedGameToolkit.Tools.Commands
{ {

View File

@ -0,0 +1,42 @@
using System.Reflection;
using SlatedGameToolkit.Framework;
using SlatedGameToolkit.Tools.CommandSystem;
using SlatedGameToolkit.Tools.CommandSystem.Interaction;
namespace SlatedGameToolkit.Tools.Commands
{
public class ListEmbeddedResourcesCommand : IInvocable
{
private string[] invokers = new string[] {"GetEmbedded"};
public void Dispose()
{
}
public bool Execute(IInteractable interactable, string[] args)
{
Assembly assembly = Assembly.GetAssembly(typeof(GameEngine));
string[] embeddedFiles = assembly.GetManifestResourceNames();
interactable.Tell("Loaded embedded files:");
foreach (string fileName in embeddedFiles)
{
interactable.Tell(fileName);
}
return true;
}
public string getDescription()
{
return "Returns a list of embedded resources in the given assembly.";
}
public string[] GetInvokers()
{
return invokers;
}
public string getUsage(string arg)
{
return "Usage: \"GetEmbedded\" to retrieve a list of embedded files in the framework and tools.";
}
}
}

View File

@ -1,5 +1,5 @@
using SlatedGameToolkit.Tools.System; using SlatedGameToolkit.Tools.CommandSystem;
using SlatedGameToolkit.Tools.System.Interaction; using SlatedGameToolkit.Tools.CommandSystem.Interaction;
namespace SlatedGameToolkit.Tools.Commands namespace SlatedGameToolkit.Tools.Commands
{ {

View File

@ -1,36 +1,43 @@
using System; using System;
using System.Reflection; using System.Reflection;
using System.Text;
using SlatedGameToolkit.Tools.Commands; using SlatedGameToolkit.Tools.Commands;
using SlatedGameToolkit.Tools.System; using SlatedGameToolkit.Tools.CommandSystem;
using SlatedGameToolkit.Tools.System.Interaction; using SlatedGameToolkit.Tools.CommandSystem.Interaction;
namespace SlatedGameToolkit.Tools namespace SlatedGameToolkit.Tools
{ {
class Program class Program
{ {
static private bool running; static private bool live;
static void Main(string[] args) static void Main(string[] args)
{ {
CommandMap commands = new CommandMap(); CommandMap commands = new CommandMap();
commands.Add(new StopCommand()); commands.Add(new StopCommand());
commands.Add(new HelpCommand(commands)); commands.Add(new HelpCommand(commands));
commands.Add(new ListEmbeddedResourcesCommand());
commands.Add(new GraphicalPlaygroundCommand()); commands.Add(new GraphicalPlaygroundCommand());
CommandProcessor processor = new CommandProcessor("The command \"{input}\" was not understood. Please type \"help\" for more information.", commands); CommandProcessor processor = new CommandProcessor(commands);
AssemblyName name = Assembly.GetExecutingAssembly().GetName(); AssemblyName name = Assembly.GetExecutingAssembly().GetName();
ConsoleInteraction consoleInteracter = new ConsoleInteraction("Tools"); IInteractable interactable = (args.Length > 0 ? (IInteractable) new SingleConsoleInteraction(string.Join(' ', args)) : (IInteractable) new ConsoleInteraction("Tools"));
consoleInteracter.Tell(String.Format("{0} Version: {1}", name.Name, name.Version)); interactable.Tell(String.Format("{0} Version: {1}", name.Name, name.Version));
consoleInteracter.Tell("Welcome to SlatedGameToolkit.Tools! These tools are meant for the developers using the SlatedGameToolkit. Type \"help\" for a list of things this tool can currently do."); if (args.Length > 0) {
running = true; interactable.Tell("Running in one time use mode.");
while (running) { processor.Process(interactable);
consoleInteracter.Separate(); } else {
processor.Process(consoleInteracter); interactable.Tell("Welcome to SlatedGameToolkit.Tools! These tools are meant for the developers using the SlatedGameToolkit. Type \"help\" for a list of things this tool can currently do.");
live = true;
while (live) {
interactable.Separate();
processor.Process(interactable);
}
} }
consoleInteracter.Tell("Exiting tool."); interactable.Tell("Exiting tool.");
commands.Dispose(); commands.Dispose();
} }
public static void Stop() { public static void Stop() {
running = false; live = false;
} }
} }
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

View File

@ -11,4 +11,7 @@
<Description>A tool to help with developing a game using SlatedGameToolkit.</Description> <Description>A tool to help with developing a game using SlatedGameToolkit.</Description>
</PropertyGroup> </PropertyGroup>
<ItemGroup>
<Content Include="Resources/**"/>
</ItemGroup>
</Project> </Project>

View File

@ -1,18 +1,25 @@
using System; using System;
using System.Drawing;
using System.Numerics;
using SlatedGameToolkit.Framework.Exceptions;
using SlatedGameToolkit.Framework.Graphics.Programs; using SlatedGameToolkit.Framework.Graphics.Programs;
using SlatedGameToolkit.Framework.Graphics.Render; using SlatedGameToolkit.Framework.Graphics.Render;
using SlatedGameToolkit.Framework.Graphics.Shaders; using SlatedGameToolkit.Framework.Graphics.Shaders;
using SlatedGameToolkit.Framework.Graphics.Textures; using SlatedGameToolkit.Framework.Graphics.Textures;
using SlatedGameToolkit.Framework.Graphics.Window; using SlatedGameToolkit.Framework.Graphics.Window;
using SlatedGameToolkit.Framework.Loader;
using SlatedGameToolkit.Framework.StateSystem; using SlatedGameToolkit.Framework.StateSystem;
using SlatedGameToolkit.Framework.StateSystem.States; using SlatedGameToolkit.Framework.StateSystem.States;
namespace SlatedGameToolkit.Tools.Utilities.GraphicalPlayground namespace SlatedGameToolkit.Tools.Utilities.Playground
{ {
public class MainState : IState public class MainState : IState
{ {
private WindowContext window; private WindowContext window;
private GLShaderProgram program;
private Camera2D camera;
private Renderer renderer; private Renderer renderer;
private Texture texture;
private Sprite2D sprite; private Sprite2D sprite;
public WindowContext CurrentWindow { get { return window;}} public WindowContext CurrentWindow { get { return window;}}
@ -30,6 +37,9 @@ namespace SlatedGameToolkit.Tools.Utilities.GraphicalPlayground
public void Deinitialize() public void Deinitialize()
{ {
window.Dispose(); window.Dispose();
program.Dispose();
texture.Dispose();
renderer.Dispose();
} }
public string getName() public string getName()
@ -37,14 +47,24 @@ namespace SlatedGameToolkit.Tools.Utilities.GraphicalPlayground
return "main state"; return "main state";
} }
public void Initialize(Manager manager) public void Initialize(StateManager manager)
{ {
window = new WindowContext("SlatedGameToolkit Playground"); window = new WindowContext("SlatedGameToolkit Playground");
renderer = new Renderer(); camera = new Camera2D();
camera.Width = window.WindowBoundaries.Width;
camera.Height = window.WindowBoundaries.Height;
camera.Position = new Vector2(camera.Width / 2, camera.Height / 2);
program = new GLShaderProgram(new NormalVertexShader(), new NormalFragmentShader());
renderer = new Renderer(camera, program);
texture = new TextureLoader("Resources/Playground/yhdnbgnc.png").Load();
sprite = new Sprite2D(texture, Color.White);
} }
public void Render(double delta) public void Render(double delta)
{ {
OpenGLErrorException.CheckGLErrorStatus();
renderer.Queue(sprite, Matrix4x4.Identity);
renderer.Render();
} }
public void Update(double delta) public void Update(double delta)