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