Lots of progress on rendering textures.
This commit is contained in:
parent
23597f02b1
commit
1c4ca6c97b
6
.vscode/launch.json
vendored
6
.vscode/launch.json
vendored
@ -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
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -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)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
@ -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,
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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>
|
||||||
|
@ -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>
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
103
src/SlatedGameToolkit.Framework/Graphics/Render/Camera.cs
Normal file
103
src/SlatedGameToolkit.Framework/Graphics/Render/Camera.cs
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
22
src/SlatedGameToolkit.Framework/Graphics/Render/Camera2D.cs
Normal file
22
src/SlatedGameToolkit.Framework/Graphics/Render/Camera2D.cs
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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; }
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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() {
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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();
|
||||||
}
|
}
|
||||||
|
@ -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.
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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()
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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>
|
||||||
|
@ -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>();
|
||||||
|
|
||||||
|
@ -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()]);
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
11
src/SlatedGameToolkit.Framework/Resources/default.frag
Normal file
11
src/SlatedGameToolkit.Framework/Resources/default.frag
Normal 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;
|
||||||
|
}
|
17
src/SlatedGameToolkit.Framework/Resources/default.vert
Normal file
17
src/SlatedGameToolkit.Framework/Resources/default.vert
Normal 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);
|
||||||
|
}
|
@ -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>
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
@ -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.
|
||||||
|
@ -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;
|
@ -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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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) { }
|
||||||
|
}
|
||||||
|
}
|
@ -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
|
||||||
{
|
{
|
@ -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
|
||||||
{
|
{
|
@ -1,4 +1,4 @@
|
|||||||
namespace SlatedGameToolkit.Tools.System.Interaction
|
namespace SlatedGameToolkit.Tools.CommandSystem.Interaction
|
||||||
{
|
{
|
||||||
public interface IInteractable
|
public interface IInteractable
|
||||||
{
|
{
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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
|
||||||
{
|
{
|
||||||
|
@ -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
|
||||||
{
|
{
|
||||||
|
@ -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.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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
|
||||||
{
|
{
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
BIN
src/SlatedGameToolkit.Tools/Resources/Playground/yhdnbgnc.png
Normal file
BIN
src/SlatedGameToolkit.Tools/Resources/Playground/yhdnbgnc.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 40 KiB |
@ -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>
|
||||||
|
@ -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)
|
Loading…
x
Reference in New Issue
Block a user