Progress on adding GL shader system.

This commit is contained in:
Harrison Deng 2020-05-28 13:51:44 -05:00
parent 93937a8b34
commit d269760c80
13 changed files with 212 additions and 33 deletions

View File

@ -0,0 +1,17 @@
using System;
namespace SlatedGameToolkit.Framework.Exceptions
{
public class OpenGLException : Exception {
public OpenGLException() : base() {
}
public OpenGLException(string message) : base(message) {
}
public OpenGLException(string message, Exception inner) : base(message, inner) {
}
}
}

View File

@ -136,7 +136,7 @@ namespace SlatedGameToolkit.Framework {
Keyboard.OnKeyReleased((Key) SDL_Event.key.keysym.sym);
break;
case SDL.SDL_EventType.SDL_WINDOWEVENT:
WindowContext handle = WindowManager.HandleFromID(SDL_Event.window.windowID);
WindowContext handle = WindowManager.ContextFromID(SDL_Event.window.windowID);
switch (SDL_Event.window.windowEvent)
{
case SDL.SDL_WindowEventID.SDL_WINDOWEVENT_SIZE_CHANGED:

View File

@ -3,15 +3,18 @@ using System;
namespace SlatedGameToolkit.Framework.Graphics.OpenGL
{
internal delegate void GLClearColour(float r, float g, float b);
internal delegate void GLClear(uint flags);
internal delegate void GLClear(GLEnums flags);
internal delegate void GLViewport(int x, int y, int width, int height);
internal delegate IntPtr GLCreateShader(GLEnums type);
internal delegate IntPtr GLShaderSource(IntPtr shaderHandle, int count, string program);
internal delegate void GLCompileShader(IntPtr shaderHandle);
internal delegate void GLGetShaderLogInfo(IntPtr shaderHandle, int maxLength, out int writtenLength, out string output);
internal delegate IntPtr GLCreateProgram();
internal delegate IntPtr GLDeleteProgram();
internal delegate void GLAttachShader(IntPtr program, IntPtr shader);
internal delegate void GLDetachShader(IntPtr program, IntPtr shader);
internal delegate void GLDeleteShader(IntPtr shader);
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);
}

View File

@ -0,0 +1,42 @@
using System;
using System.Runtime.InteropServices;
using SDL2;
using SlatedGameToolkit.Framework.Exceptions;
using SlatedGameToolkit.Framework.Graphics.Window;
namespace SlatedGameToolkit.Framework.Graphics.OpenGL
{
public abstract class GLProgram : IDisposable
{
private WindowContext context;
private protected UIntPtr handle;
private protected GLCreateProgram createProgram;
private protected GLDeleteProgram deleteProgram;
private protected GLLinkProgram linkProgram;
private protected GLGetProgramInfoLog getProgramInfoLog;
public GLProgram(WindowContext context) {
this.context = context;
context.MakeCurrent();
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();
handle = createProgram();
}
public virtual void Dispose()
{
deleteProgram(handle);
}
~GLProgram() {
Dispose();
}
}
}

View File

@ -0,0 +1,57 @@
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
{
public class ShaderProgram : GLProgram
{
private GLShader[] shaders;
private GLAttachShader attachShader;
private GLDetachShader detachShader;
private GLBindAttribLocation bindAttribLocation;
public ShaderProgram(WindowContext context, params GLShader[] shaders) : base(context) {
this.shaders = shaders;
attachShader = Marshal.GetDelegateForFunctionPointer<GLAttachShader>(SDL.SDL_GL_GetProcAddress("glAttachShader"));
if (attachShader == null) throw new FrameworkSDLException();
bindAttribLocation = Marshal.GetDelegateForFunctionPointer<GLBindAttribLocation>(SDL.SDL_GL_GetProcAddress("glBindAttribLocation"));
if (bindAttribLocation == null) throw new FrameworkSDLException();
detachShader = Marshal.GetDelegateForFunctionPointer<GLDetachShader>(SDL.SDL_GL_GetProcAddress("glDetachShader"));
if (detachShader == null) throw new FrameworkSDLException();
foreach (GLShader shader in shaders)
{
attachShader(handle, shader.Handle);
}
linkProgram(handle);
uint length;
string log;
getProgramInfoLog(handle, 1024, out length, out log);
if (length > 0) {
Dispose();
throw new OpenGLException(log);
}
foreach (GLShader shader in shaders)
{
detachShader(handle, shader.Handle);
}
}
public override void Dispose() {
foreach (GLShader shader in shaders)
{
shader.Dispose();
}
base.Dispose();
}
~ShaderProgram() {
Dispose();
}
}
}

View File

@ -1,13 +0,0 @@
using System;
namespace SlatedGameToolkit.Framework.Graphics.OpenGL
{
public class ShaderHandle
{
private IntPtr shaderProgram;
public ShaderHandle() {
}
}
}

View File

@ -0,0 +1,42 @@
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(WindowContext context) {
context.MakeCurrent();
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();
}
}
}

View File

@ -0,0 +1,32 @@
using System;
using System.Runtime.InteropServices;
using SDL2;
using SlatedGameToolkit.Framework.Exceptions;
using SlatedGameToolkit.Framework.Graphics.Window;
namespace SlatedGameToolkit.Framework.Graphics.OpenGL.Shaders
{
public class GLVertexShader : GLShader {
public GLVertexShader(WindowContext context, string shader) : base(context) {
Handle = createShader(GLEnums.GL_VERTEX_SHADER);
shaderSource(Handle, 1, shader, null);
compileShader(Handle);
uint logLength;
string shaderLog;
getShaderLogInfo(Handle, 1024, out logLength, out shaderLog);
if (logLength > 0) {
Dispose();
throw new OpenGLException(shaderLog);
}
}
public override void Dispose()
{
deleteShader(Handle);
}
~GLVertexShader() {
Dispose();
}
}
}

View File

@ -58,6 +58,7 @@ namespace SlatedGameToolkit.Framework.Graphics.Window
internal readonly GLClear clear;
internal readonly GLViewport viewport;
/// <summary>
/// Whether or not to show this window.
/// </summary>
@ -90,7 +91,7 @@ namespace SlatedGameToolkit.Framework.Graphics.Window
IntPtr currentWindow = SDL.SDL_GL_GetCurrentWindow();
bool diff = false;
if (currentContext != glContext || currentWindow != window) {
DrawToWindow();
MakeCurrent();
diff = true;
}
bool vSync = SDL.SDL_GL_GetSwapInterval() != 0;
@ -102,7 +103,7 @@ namespace SlatedGameToolkit.Framework.Graphics.Window
IntPtr currentWindow = SDL.SDL_GL_GetCurrentWindow();
bool diff = false;
if (currentContext != glContext || currentWindow != window) {
DrawToWindow();
MakeCurrent();
diff = true;
}
if (SDL.SDL_GL_SetSwapInterval(value ? -1 : 0) < 0) {
@ -296,7 +297,7 @@ namespace SlatedGameToolkit.Framework.Graphics.Window
///
/// If the current context is already of this window, nothing happens.
/// </summary>
internal void DrawToWindow() {
internal void MakeCurrent() {
if (SDL.SDL_GL_GetCurrentContext() != glContext) {
SDL.SDL_GL_MakeCurrent(window, glContext);
}

View File

@ -15,7 +15,7 @@ namespace SlatedGameToolkit.Framework.Graphics.Window
existingWindows.Remove(windowHandle.WindowID);
}
internal static WindowContext HandleFromID(uint ID) {
internal static WindowContext ContextFromID(uint ID) {
return existingWindows[ID];
}
}

View File

@ -1,6 +1,4 @@
using System;
using SDL2;
using SlatedGameToolkit.Framework.Exceptions;
namespace SlatedGameToolkit.Framework.Graphics.Window
{

View File

@ -45,10 +45,10 @@ namespace SlatedGameToolkit.Framework.StateSystem
internal void render(double delta) {
if (CurrentWindow != currentState.CurrentWindow) {
CurrentWindow = currentState.CurrentWindow;
CurrentWindow.DrawToWindow();
CurrentWindow.MakeCurrent();
}
CurrentWindow.clearColour(backgroundColour.r, backgroundColour.g, backgroundColour.b);
CurrentWindow.clear((uint) (GLEnums.GL_COLOR_BUFFER_BIT | GLEnums.GL_DEPTH_STENCIL));
CurrentWindow.clear(GLEnums.GL_COLOR_BUFFER_BIT | GLEnums.GL_DEPTH_STENCIL);
currentState.Render(delta);
CurrentWindow.SwapBuffer();
}

View File

@ -31,7 +31,7 @@ namespace SlatedGameToolkit.Tools.Commands
} else if (args[0].Equals("status")) {
interactable.Tell("Running: " + GameEngine.IsRunning());
interactable.Tell("Target FPS: " + (GameEngine.targetFPS <= 0 ? "Not bounded." : GameEngine.targetFPS.ToString()));
interactable.Tell("Update Step: " + (GameEngine.UpdatesPerSecond <= 0 ? "Not bounded." : GameEngine.UpdatesPerSecond.ToString()));
interactable.Tell("Update Step: " + (GameEngine.UpdatesPerSecond <= 0 ? "Not Locked." : GameEngine.UpdatesPerSecond.ToString()));
return true;
}
return false;