Began implementing an asset loading system.

This commit is contained in:
Harrison Deng 2020-06-03 01:36:24 -05:00
parent 484dbbece3
commit 23597f02b1
18 changed files with 288 additions and 118 deletions

View File

@ -10,3 +10,7 @@ The toolkit is split into 2 portions:
- Framework
The Utility portion is a lightweight program that aids in producing some of the more commonly used file data structures by the framework. The framework itself is the part that provides the libraries and SFML implementation to allow for a smoother game development experience.
## Design Objectives
Leave access to low level function calls, but have abstraction layers that makes common game development tasks simple. Ideally, this means that if a client decides to use this Toolkit to make a game that doesn't require low level access, they should be able to do so without ever really needing to touch the lower level libraries. Ultimately, this means that SDL2 and other lower level functions that are implemented can be accessed.

View File

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

View File

@ -6,99 +6,109 @@ using SlatedGameToolkit.Framework.Exceptions;
namespace SlatedGameToolkit.Framework.Graphics
{
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void GLClearColour(float r, float g, float b);
public delegate void GLClearColour(float r, float g, float b);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void GLClear(GLEnums flags);
public delegate void GLClear(GLEnums flags);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal 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)]
internal delegate UIntPtr GLCreateShader(GLEnums type);
public delegate UIntPtr GLCreateShader(GLEnums type);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal 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)]
internal delegate void GLCompileShader(UIntPtr shaderHandle);
public delegate void GLCompileShader(UIntPtr shaderHandle);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void GLGetShaderLogInfo(UIntPtr shader, uint maxLength, out uint writtenLength, out string output);
public delegate void GLGetShaderLogInfo(UIntPtr shader, uint maxLength, out uint writtenLength, out string output);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate UIntPtr GLCreateProgram();
public delegate UIntPtr GLCreateProgram();
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate UIntPtr GLDeleteProgram(UIntPtr program);
public delegate UIntPtr GLDeleteProgram(UIntPtr program);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void GLAttachShader(UIntPtr program, UIntPtr shader);
public delegate void GLAttachShader(UIntPtr program, UIntPtr shader);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void GLDetachShader(UIntPtr program, UIntPtr shader);
public delegate void GLDetachShader(UIntPtr program, UIntPtr shader);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void GLDeleteShader(UIntPtr shader);
public delegate void GLDeleteShader(UIntPtr shader);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void GLBindAttribLocation(UIntPtr program, uint index, string name);
public delegate void GLBindAttribLocation(UIntPtr program, uint index, string name);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void GLGetProgramInfoLog(UIntPtr program, uint maxLength, out uint writtenLength, out string output);
public delegate void GLGetProgramInfoLog(UIntPtr program, uint maxLength, out uint writtenLength, out string output);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void GLLinkProgram(UIntPtr program);
public delegate void GLLinkProgram(UIntPtr program);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void GLProgramParameter(UIntPtr program, GLEnums parameterName, int value);
public delegate void GLProgramParameter(UIntPtr program, GLEnums parameterName, int value);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void GLUseProgram(UIntPtr program);
public delegate void GLUseProgram(UIntPtr program);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void GLGenProgramPipelines(uint size, UIntPtr[] pipelines);
public delegate void GLGenProgramPipelines(uint size, UIntPtr[] pipelines);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void GLDeleteProgramPipelines(uint size, UIntPtr[] pipelines);
public delegate void GLDeleteProgramPipelines(uint size, UIntPtr[] pipelines);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void GLBindProgramPipeline(UIntPtr pipeline);
public delegate void GLBindProgramPipeline(UIntPtr pipeline);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void GLUseProgramStages(UIntPtr pipeline, GLEnums bitField, UIntPtr program);
public delegate void GLUseProgramStages(UIntPtr pipeline, GLEnums bitField, UIntPtr program);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate uint GLGetError();
public delegate uint GLGetError();
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate int GLGetAttribLocation(UIntPtr program, string attribName);
public delegate int GLGetAttribLocation(UIntPtr program, string attribName);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void GLBindBuffer(GLEnums target, UIntPtr buffer);
public delegate void GLBindBuffer(GLEnums target, UIntPtr buffer);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void GLGenBuffers(uint size, UIntPtr[] buffers);
public delegate void GLGenBuffers(uint size, UIntPtr[] buffers);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal unsafe delegate void GLBufferData(GLEnums target, uint size, Array data, GLEnums usage);
public unsafe delegate void GLBufferData(GLEnums target, uint size, Array data, GLEnums usage);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void GLDeleteBuffers(uint size, UIntPtr[] buffers);
public delegate void GLDeleteBuffers(uint size, UIntPtr[] buffers);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void GLVertexAttribPointer(uint index, int size, GLEnums type, bool normalized, uint stride, uint offset);
public delegate void GLVertexAttribPointer(uint index, int size, GLEnums type, bool normalized, uint stride, uint offset);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void GLGenVertexArrays(uint amount, UIntPtr[] arrays);
public delegate void GLGenVertexArrays(uint amount, UIntPtr[] arrays);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void GLDeleteVertexArrays(uint amount, UIntPtr[] arrays);
public delegate void GLDeleteVertexArrays(uint amount, UIntPtr[] arrays);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void GLBindVertexArray(UIntPtr array);
public delegate void GLBindVertexArray(UIntPtr array);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void GLEnableVertexAttribArray(uint attribIndex);
public delegate void GLEnableVertexAttribArray(uint attribIndex);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void GLDisableVertexAttribArray(uint attribIndex);
public delegate void GLDisableVertexAttribArray(uint attribIndex);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void GLDrawArrays(GLEnums mode, int first, uint count);
public delegate void GLDrawArrays(GLEnums mode, int first, uint count);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void GLDrawElements(GLEnums mode, uint count, int offset);
public delegate void GLDrawElements(GLEnums mode, uint count, int offset);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void GLMultiDrawArrays(GLEnums mode, int[] first, uint[] count, uint primout);
public delegate void GLMultiDrawArrays(GLEnums mode, int[] first, uint[] count, uint primout);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void GLMultiDrawElements(GLEnums mode, uint[] count, GLEnums type, IntPtr indices, int length);
public delegate void GLMultiDrawElements(GLEnums mode, uint[] count, GLEnums type, IntPtr indices, int length);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void GLGenTextures(uint n, UIntPtr[] textureHandles);
public delegate void GLGenTextures(uint n, UIntPtr[] textureHandles);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void GLBindTexture(GLEnums target, UIntPtr texture);
public delegate void GLBindTexture(GLEnums target, UIntPtr texture);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void GLDeleteTextures(uint n, UIntPtr[] textureHandles);
public delegate void GLDeleteTextures(uint n, UIntPtr[] textureHandles);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void GLTexParameteri(GLEnums target, GLEnums pname, int value);
public delegate void GLTexParameteri(GLEnums target, GLEnums pname, int value);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void GLTexParameterf(GLEnums target, GLEnums pname, float value);
public delegate void GLTexParameterf(GLEnums target, GLEnums pname, float value);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void GLTexParameteriv(GLEnums target, GLEnums pname, int[] values);
public delegate void GLTexParameteriv(GLEnums target, GLEnums pname, int[] values);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void GLTexParameterfv(GLEnums target, GLEnums pname, float[] values);
public delegate void GLTexParameterfv(GLEnums target, GLEnums pname, float[] values);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void GLTexImage2D(GLEnums target, int level, int internalFormat, uint width, uint height, int border, GLEnums format, GLEnums type, byte[] data);
public delegate void GLTexImage2D(GLEnums target, int level, int publicFormat, uint width, uint height, int border, GLEnums format, GLEnums type, byte[] data);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void GLGenerateMipMap(GLEnums target);
public delegate void GLGenerateMipMap(GLEnums target);
internal static class GLFunctionUtils {
public static class GLFunctionUtils {
/// <summary>
/// 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
/// lead to a CLR error on usage.
///
/// Uses SDL2 as the function address retriever.
/// </summary>
/// <param name="functionName">The process name, case sensitive, exactly as OpenGL defines it.</param>
/// <typeparam name="T">The delegate type to cast to.</typeparam>
/// <returns>The delegate associated with the retrieved path.</returns>
public static T RetrieveGLDelegate<T>(string functionName) where T : Delegate {
GameEngine.Logger.Debug(String.Format("Retrieving function with name: {0}", functionName));
IntPtr functionAddress = SDL.SDL_GL_GetProcAddress(functionName);

View File

@ -6,16 +6,21 @@ using SlatedGameToolkit.Framework.Graphics.Window;
namespace SlatedGameToolkit.Framework.Graphics.Programs
{
/// <summary>
/// Represents a GL Program.
/// This class is abstract and serves as a parent to the possible types of programs.
/// Gives access to common OpenGL program associated function calls.
/// </summary>
public abstract class GLProgram : IDisposable
{
private WindowContext context;
private protected readonly UIntPtr handle;
private protected GLCreateProgram createProgram;
private protected GLDeleteProgram deleteProgram;
private protected GLLinkProgram linkProgram;
private protected GLGetProgramInfoLog getProgramInfoLog;
private protected GLProgramParameter programParameter;
private protected GLUseProgram useProgram;
protected readonly UIntPtr handle;
protected GLCreateProgram createProgram;
protected GLDeleteProgram deleteProgram;
protected GLLinkProgram linkProgram;
protected GLGetProgramInfoLog getProgramInfoLog;
protected GLProgramParameter programParameter;
private GLUseProgram useProgram;
/// <summary>
/// Creates an OpenGL program.

View File

@ -18,6 +18,8 @@ namespace SlatedGameToolkit.Framework.Graphics.Programs
bindAttribLocation = GLFunctionUtils.RetrieveGLDelegate<GLBindAttribLocation>("glBindAttribLocation");
detachShader = GLFunctionUtils.RetrieveGLDelegate<GLDetachShader>("glDetachShader");
Use();
foreach (GLShader shader in shaders)
{
attachShader(handle, shader.Handle);

View File

@ -2,6 +2,7 @@ using System;
using System.Runtime.InteropServices;
using SDL2;
using SlatedGameToolkit.Framework.Exceptions;
using SlatedGameToolkit.Framework.Graphics.Programs;
using SlatedGameToolkit.Framework.Graphics.Window;
namespace SlatedGameToolkit.Framework.Graphics.Shaders
@ -10,14 +11,14 @@ namespace SlatedGameToolkit.Framework.Graphics.Shaders
private WindowContext context;
public UIntPtr Handle { get; private protected set; }
private protected GLCreateShader createShader;
private protected GLShaderSource shaderSource;
private protected GLCompileShader compileShader;
private protected GLGetShaderLogInfo getShaderLogInfo;
private protected GLGetAttribLocation getAttribLocation;
protected GLCreateShader createShader;
protected GLShaderSource shaderSource;
protected GLCompileShader compileShader;
protected GLGetShaderLogInfo getShaderLogInfo;
protected GLGetAttribLocation getAttribLocation;
private GLDeleteShader deleteShader;
internal GLShader() {
public GLShader() {
context = WindowContextsManager.CurrentWindowContext;
createShader = GLFunctionUtils.RetrieveGLDelegate<GLCreateShader>("glCreateShader");
shaderSource = GLFunctionUtils.RetrieveGLDelegate<GLShaderSource>("glShaderSource");

View File

@ -4,7 +4,7 @@ using SlatedGameToolkit.Framework.Exceptions;
namespace SlatedGameToolkit.Framework.Graphics.Shaders
{
public class GLVertexArraySet : IDisposable {
public sealed class GLVertexArraySet : IDisposable {
private bool disposed;
public int Count { get; private set; }
private UIntPtr[] arrayBufferHandles;

View File

@ -5,7 +5,7 @@ using SlatedGameToolkit.Framework.Graphics.Textures;
namespace SlatedGameToolkit.Framework.Graphics
{
public class GLTexture2DSet : IDisposable
public sealed class GLTexture2DSet : IDisposable
{
private bool disposed;
public int Count { get; private set; }
@ -17,12 +17,8 @@ namespace SlatedGameToolkit.Framework.Graphics
private GLBindTexture bindTexture;
private GLGenerateMipMap generateMipMap;
private readonly UIntPtr[] handle;
private readonly bool linear, mipmap;
public GLTexture2DSet(TextureData[] textureDatas, bool linear = false, bool mipmap = false)
{
this.linear = linear;
this.mipmap = mipmap;
genTextures = GLFunctionUtils.RetrieveGLDelegate<GLGenTextures>("glGenTextures");
deleteTextures = GLFunctionUtils.RetrieveGLDelegate<GLDeleteTextures>("glDeleteTextures");
bindTexture = GLFunctionUtils.RetrieveGLDelegate<GLBindTexture>("glBindTexture");
@ -42,15 +38,30 @@ namespace SlatedGameToolkit.Framework.Graphics
}
private void Setup(uint index, TextureData textureData) {
bindTexture(GLEnums.GL_TEXTURE_2D, handle[index]);
texParameteri(GLEnums.GL_TEXTURE_2D, GLEnums.GL_TEXTURE_WRAP_S, (int)GLEnums.GL_CLAMP_TO_EDGE);
texParameteri(GLEnums.GL_TEXTURE_2D, GLEnums.GL_TEXTURE_WRAP_S, (int)GLEnums.GL_CLAMP_TO_EDGE);
texParameteri(GLEnums.GL_TEXTURE_2D, GLEnums.GL_TEXTURE_MIN_FILTER, (int)(linear ? (mipmap ? GLEnums.GL_LINEAR_MIPMAP_LINEAR : GLEnums.GL_LINEAR) : (mipmap ? GLEnums.GL_NEAREST_MIPMAP_LINEAR : GLEnums.GL_NEAREST)));
texParameteri(GLEnums.GL_TEXTURE_2D, GLEnums.GL_TEXTURE_MAG_FILTER, (int)(linear ? GLEnums.GL_LINEAR : GLEnums.GL_NEAREST));
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);
generateMipMap(GLEnums.GL_TEXTURE_2D);
}
/// <summary>
/// Binds the given index's texture.
/// Sets the properties given the index of the OpenGL 2D texture.
/// </summary>
/// <param name="index">The index of the texture.</param>
/// <param name="linear">Whether or not to have linear filtering.</param>
/// <param name="mipmap">Whether or not to use MipMap</param>
public void SetProperties(uint index, GLEnums min, GLEnums mag) {
Bind(index);
texParameteri(GLEnums.GL_TEXTURE_2D, GLEnums.GL_TEXTURE_WRAP_S, (int)GLEnums.GL_CLAMP_TO_EDGE);
texParameteri(GLEnums.GL_TEXTURE_2D, GLEnums.GL_TEXTURE_WRAP_T, (int)GLEnums.GL_CLAMP_TO_EDGE);
texParameteri(GLEnums.GL_TEXTURE_2D, GLEnums.GL_TEXTURE_MIN_FILTER, (int) min);
texParameteri(GLEnums.GL_TEXTURE_2D, GLEnums.GL_TEXTURE_MAG_FILTER, (int) mag);
}
/// <summary>
/// Binds a GL texture to the active unit.
/// </summary>
/// <param name="index">The index of the texture in this set.</param>
public void Bind(uint index) {
bindTexture(GLEnums.GL_TEXTURE_2D, handle[index]);

View File

@ -1,8 +1,8 @@
using System;
using SlatedGameToolkit.Framework.Loader;
namespace SlatedGameToolkit.Framework.Graphics.Textures
{
public class Texture : IDisposable
public class Texture : IAssetUseable
{
private readonly GLTexture2DSet glTexture2DSet;
private readonly uint index;

View File

@ -1,6 +1,8 @@
using SlatedGameToolkit.Framework.Loader;
namespace SlatedGameToolkit.Framework.Graphics.Textures
{
public struct TextureData
public class TextureData
{
public byte[] data;
public uint width;

View File

@ -14,7 +14,7 @@ namespace SlatedGameToolkit.Framework.Graphics.Window
/// </summary>
/// <param name="hitPoint">The window coordinates that are being interacted with.</param>
/// <returns>The region type.</returns>
public delegate WindowRegion WindowRegionHit(Vector2 hitPoint);
public delegate SDL.SDL_HitTestResult WindowRegionHit(Vector2 hitPoint);
/// <summary>
/// A delegate that represents a function to be called on a window resize.
@ -260,9 +260,9 @@ namespace SlatedGameToolkit.Framework.Graphics.Window
/// <summary>
/// Instantiates a window handle.
/// </summary>
public WindowContext(string title, int x = -1, int y = -1, int width = 640, int height = 480, bool specialRegions = false, WindowOption options = default(WindowOption)) {
public WindowContext(string title, int x = -1, int y = -1, int width = 640, int height = 480, bool specialRegions = false, SDL.SDL_WindowFlags options = default(SDL.SDL_WindowFlags)) {
GameEngine.Logger.Information(String.Format("Starting openGL window with title \"{0}\"", title));
windowHandle = SDL.SDL_CreateWindow(title, x < 0 ? SDL.SDL_WINDOWPOS_CENTERED : x, y < 0 ? SDL.SDL_WINDOWPOS_CENTERED : y, width, height, SDL.SDL_WindowFlags.SDL_WINDOW_INPUT_FOCUS | SDL.SDL_WindowFlags.SDL_WINDOW_OPENGL | SDL.SDL_WindowFlags.SDL_WINDOW_MOUSE_FOCUS | (SDL.SDL_WindowFlags) options);
windowHandle = SDL.SDL_CreateWindow(title, x < 0 ? SDL.SDL_WINDOWPOS_CENTERED : x, y < 0 ? SDL.SDL_WINDOWPOS_CENTERED : y, width, height, SDL.SDL_WindowFlags.SDL_WINDOW_INPUT_FOCUS | SDL.SDL_WindowFlags.SDL_WINDOW_OPENGL | SDL.SDL_WindowFlags.SDL_WINDOW_MOUSE_FOCUS | options);
if (windowHandle == null) {
throw new FrameworkSDLException();
}
@ -292,8 +292,8 @@ namespace SlatedGameToolkit.Framework.Graphics.Window
private SDL.SDL_HitTestResult SpecialRegionHit(IntPtr window, IntPtr hitPtr, IntPtr data) {
SDL.SDL_Point SDLPoint = Marshal.PtrToStructure<SDL.SDL_Point>(hitPtr);
Vector2 point = new Vector2(SDLPoint.x, SDLPoint.y);
WindowRegion region = windowRegionHitEvent.Invoke(point);
return (SDL.SDL_HitTestResult) region;
SDL.SDL_HitTestResult region = windowRegionHitEvent.Invoke(point);
return region;
}
internal void SwapBuffer() {

View File

@ -1,19 +0,0 @@
using System;
using SDL2;
using SlatedGameToolkit.Framework.Exceptions;
namespace SlatedGameToolkit.Framework.Graphics.Window
{
public enum WindowRegion {
NORMAL = SDL.SDL_HitTestResult.SDL_HITTEST_NORMAL,
DRAGGABLE = SDL.SDL_HitTestResult.SDL_HITTEST_DRAGGABLE,
TOP_LEFT = SDL.SDL_HitTestResult.SDL_HITTEST_RESIZE_TOPLEFT,
TOP_RIGHT = SDL.SDL_HitTestResult.SDL_HITTEST_RESIZE_TOPRIGHT,
BOTTOM_LEFT = SDL.SDL_HitTestResult.SDL_HITTEST_RESIZE_BOTTOMLEFT,
BOTTOM_RIGHT = SDL.SDL_HitTestResult.SDL_HITTEST_RESIZE_BOTTOMRIGHT,
TOP = SDL.SDL_HitTestResult.SDL_HITTEST_RESIZE_TOP,
BOTTOM = SDL.SDL_HitTestResult.SDL_HITTEST_RESIZE_BOTTOM,
RIGHT = SDL.SDL_HitTestResult.SDL_HITTEST_RESIZE_RIGHT,
LEFT = SDL.SDL_HitTestResult.SDL_HITTEST_RESIZE_LEFT,
}
}

View File

@ -1,11 +0,0 @@
using SDL2;
namespace SlatedGameToolkit.Framework.Graphics.Window
{
public enum WindowOption : uint
{
SHOWN = SDL.SDL_WindowFlags.SDL_WINDOW_SHOWN,
HIGH_DPI = SDL.SDL_WindowFlags.SDL_WINDOW_ALLOW_HIGHDPI,
HIDDEN = SDL.SDL_WindowFlags.SDL_WINDOW_HIDDEN,
}
}

View File

@ -0,0 +1,104 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Threading;
namespace SlatedGameToolkit.Framework.Loader {
public class AssetManager : IDisposable {
private readonly object assetThreadLock = new object();
private Thread thread;
private ConcurrentQueue<ILoadable> loadables;
private volatile bool load;
public bool Complete {
get {
return loadables.Count == 0;
}
}
private ConcurrentDictionary<string, IAssetUseable> assets;
public ConcurrentDictionary<Type, PathModifier> PathModifiers {get; private set; }
public AssetManager() {
this.loadables = new ConcurrentQueue<ILoadable>();
this.assets = new ConcurrentDictionary<string, IAssetUseable>();
this.PathModifiers = new ConcurrentDictionary<Type, PathModifier>();
thread = new Thread(Process);
this.load = true;
thread.Name = "Asset-Loader";
thread.IsBackground = true;
thread.Start();
}
/// <summary>
/// Queue's the loadable for batched loading.
/// The file name of the loadable is the one the loadable is saved under.
/// </summary>
/// <param name="loadable">The loadable.</param>
public void QueueLoad(ILoadable loadable) {
loadables.Enqueue(loadable);
}
private void Process() {
lock (assetThreadLock)
{
ILoadable loadable;
while (load) {
while (loadables.TryDequeue(out loadable)) {
Load(loadable);
}
Monitor.Pulse(loadable);
}
}
}
/// <summary>
/// Loads the loadable and stores it under the filename given to the loadable.
/// </summary>
/// <param name="loadable">The loadable to load.</param>
public void Load(ILoadable loadable) {
string name = loadable.FileName;
assets[name] = loadable.Load(PathModifiers[loadable.GetType()]);
}
/// <summary>
/// Loads the currently queued asynchronously.
/// </summary>
public void LoadQueued() {
if (Monitor.TryEnter(assetThreadLock)) {
Monitor.Pulse(assetThreadLock);
}
}
/// <summary>
/// Unloads the asset under the given name.
/// This disposes the asset as well as removes it from the manager.
/// </summary>
/// <param name="name">The name of the asset to unload.</param>
public void Unload(string name) {
IAssetUseable asset;
assets.TryRemove(name, out asset);
asset.Dispose();
}
/// <summary>
/// Removes all the assets.
/// </summary>
public void UnloadAll() {
foreach (string name in assets.Keys)
{
Unload(name);
}
}
/// <summary>
/// Disposes of all the stored assets.
/// </summary>
public void Dispose()
{
load = false;
UnloadAll();
}
~AssetManager() {
Dispose();
}
}
}

View File

@ -0,0 +1,9 @@
using System;
namespace SlatedGameToolkit.Framework.Loader
{
public interface IAssetUseable : IDisposable
{
}
}

View File

@ -0,0 +1,31 @@
namespace SlatedGameToolkit.Framework.Loader
{
/// <summary>
/// The method should modify the path.
/// </summary>
/// <param name="path">The path to modify.</param>
/// <returns>The modified path.</returns>
public delegate string PathModifier(string path);
/// <summary>
/// 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.
/// </summary>
public interface ILoadable
{
/// <summary>
/// The name of the file to load.
/// This is what the asset manager stores the results under.
/// </summary>
/// <value>A string representing the name to load.</value>
string FileName { get; }
/// <summary>
/// Loads the asset.
/// </summary>
/// <param name="pathModifier">Modifies the path. May be null. Default is null.</param>
/// <typeparam name="Useable">The loadable type.</typeparam>
/// <returns>The loadable type.</returns>
IAssetUseable Load(PathModifier pathModifier = null);
}
}

View File

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

View File

@ -1,8 +0,0 @@
namespace SlatedGameToolkit.Framework.Loaders
{
public interface ILoadable
{
bool RequiresLoading { get; }
void Load();
}
}