More progress on shader implementation.

Changed engine OpenGL version to 4.1.

Added OpenGL program pipeline handles.

Added fragment shaders.

Some class name changes.
This commit is contained in:
Harrison Deng 2020-05-28 23:22:44 -05:00
parent d269760c80
commit 51cfc84cc7
14 changed files with 964 additions and 836 deletions

View File

@ -4,7 +4,6 @@ using SDL2;
using Serilog; using Serilog;
using Serilog.Core; using Serilog.Core;
using SlatedGameToolkit.Framework.Exceptions; using SlatedGameToolkit.Framework.Exceptions;
using SlatedGameToolkit.Framework.Graphics;
using SlatedGameToolkit.Framework.Graphics.Window; using SlatedGameToolkit.Framework.Graphics.Window;
using SlatedGameToolkit.Framework.Input; using SlatedGameToolkit.Framework.Input;
using SlatedGameToolkit.Framework.Input.Devices; using SlatedGameToolkit.Framework.Input.Devices;
@ -136,7 +135,7 @@ namespace SlatedGameToolkit.Framework {
Keyboard.OnKeyReleased((Key) SDL_Event.key.keysym.sym); Keyboard.OnKeyReleased((Key) SDL_Event.key.keysym.sym);
break; break;
case SDL.SDL_EventType.SDL_WINDOWEVENT: case SDL.SDL_EventType.SDL_WINDOWEVENT:
WindowContext handle = WindowManager.ContextFromID(SDL_Event.window.windowID); WindowContext handle = WindowContextsManager.ContextFromWindowID(SDL_Event.window.windowID);
switch (SDL_Event.window.windowEvent) switch (SDL_Event.window.windowEvent)
{ {
case SDL.SDL_WindowEventID.SDL_WINDOWEVENT_SIZE_CHANGED: case SDL.SDL_WindowEventID.SDL_WINDOWEVENT_SIZE_CHANGED:
@ -227,7 +226,7 @@ namespace SlatedGameToolkit.Framework {
throw new FrameworkSDLException(); throw new FrameworkSDLException();
} }
if (SDL.SDL_GL_SetAttribute(SDL.SDL_GLattr.SDL_GL_CONTEXT_MAJOR_VERSION, 3) < 0) throw new FrameworkSDLException(); if (SDL.SDL_GL_SetAttribute(SDL.SDL_GLattr.SDL_GL_CONTEXT_MAJOR_VERSION, 4) < 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();

View File

@ -1,6 +1,6 @@
namespace SlatedGameToolkit.Framework.Graphics.OpenGL namespace SlatedGameToolkit.Framework.Graphics.OpenGL
{ {
internal enum GLEnums: uint { internal enum GLEnums: uint {
GL_DEPTH_BUFFER_BIT = 0x00000100, GL_DEPTH_BUFFER_BIT = 0x00000100,
GL_STENCIL_BUFFER_BIT = 0x00000400, GL_STENCIL_BUFFER_BIT = 0x00000400,
GL_COLOR_BUFFER_BIT = 0x00004000, GL_COLOR_BUFFER_BIT = 0x00004000,
@ -806,6 +806,10 @@ internal enum GLEnums: uint {
GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY = 0x910D, GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY = 0x910D,
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,
}
} }

View File

@ -17,4 +17,10 @@ namespace SlatedGameToolkit.Framework.Graphics.OpenGL
internal delegate void GLBindAttribLocation(UIntPtr program, uint index, string name); 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 GLGetProgramInfoLog(UIntPtr program, uint maxLength, out uint writtenLength, out string output);
internal delegate void GLLinkProgram(UIntPtr program); 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);
} }

View File

@ -4,19 +4,21 @@ using SDL2;
using SlatedGameToolkit.Framework.Exceptions; using SlatedGameToolkit.Framework.Exceptions;
using SlatedGameToolkit.Framework.Graphics.Window; using SlatedGameToolkit.Framework.Graphics.Window;
namespace SlatedGameToolkit.Framework.Graphics.OpenGL namespace SlatedGameToolkit.Framework.Graphics.OpenGL.Programs
{ {
public abstract class GLProgram : IDisposable public abstract class GLProgram : IDisposable
{ {
private WindowContext context; private WindowContext context;
private protected UIntPtr handle; internal readonly UIntPtr handle;
private protected GLCreateProgram createProgram; private protected GLCreateProgram createProgram;
private protected GLDeleteProgram deleteProgram; private protected GLDeleteProgram deleteProgram;
private protected GLLinkProgram linkProgram; private protected GLLinkProgram linkProgram;
private protected GLGetProgramInfoLog getProgramInfoLog; private protected GLGetProgramInfoLog getProgramInfoLog;
private protected GLProgramParameter programParameter;
private protected GLUseProgram useProgram;
public GLProgram(WindowContext context) { public GLProgram(bool separable = true) {
this.context = context; this.context = WindowContextsManager.CurrentWindowContext();
context.MakeCurrent(); context.MakeCurrent();
createProgram = Marshal.GetDelegateForFunctionPointer<GLCreateProgram>(SDL.SDL_GL_GetProcAddress("glCreateProgram")); createProgram = Marshal.GetDelegateForFunctionPointer<GLCreateProgram>(SDL.SDL_GL_GetProcAddress("glCreateProgram"));
if (createProgram == null) throw new FrameworkSDLException(); if (createProgram == null) throw new FrameworkSDLException();
@ -26,8 +28,19 @@ namespace SlatedGameToolkit.Framework.Graphics.OpenGL
if (linkProgram == null) throw new FrameworkSDLException(); if (linkProgram == null) throw new FrameworkSDLException();
getProgramInfoLog = Marshal.GetDelegateForFunctionPointer<GLGetProgramInfoLog>(SDL.SDL_GL_GetProcAddress("glGetProgramInfoLog")); getProgramInfoLog = Marshal.GetDelegateForFunctionPointer<GLGetProgramInfoLog>(SDL.SDL_GL_GetProcAddress("glGetProgramInfoLog"));
if (getProgramInfoLog == null) throw new FrameworkSDLException(); 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(); handle = createProgram();
if (separable) {
programParameter(handle, GLEnums.GL_PROGRAM_SEPARABLE, (int) GLEnums.GL_TRUE);
}
}
public void Use() {
useProgram(handle);
} }
public virtual void Dispose() public virtual void Dispose()

View File

@ -0,0 +1,49 @@
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();
}
}
}

View File

@ -5,15 +5,15 @@ using SlatedGameToolkit.Framework.Exceptions;
using SlatedGameToolkit.Framework.Graphics.OpenGL.Shaders; using SlatedGameToolkit.Framework.Graphics.OpenGL.Shaders;
using SlatedGameToolkit.Framework.Graphics.Window; using SlatedGameToolkit.Framework.Graphics.Window;
namespace SlatedGameToolkit.Framework.Graphics.OpenGL namespace SlatedGameToolkit.Framework.Graphics.OpenGL.Programs
{ {
public class ShaderProgram : GLProgram public class GLShaderProgram : GLProgram
{ {
private GLShader[] shaders; private readonly GLShader[] shaders;
private GLAttachShader attachShader; private readonly GLAttachShader attachShader;
private GLDetachShader detachShader; private readonly GLDetachShader detachShader;
private GLBindAttribLocation bindAttribLocation; private GLBindAttribLocation bindAttribLocation;
public ShaderProgram(WindowContext context, params GLShader[] shaders) : base(context) { public GLShaderProgram(WindowContext context, bool separable = true, params GLShader[] shaders) : base(separable) {
this.shaders = shaders; this.shaders = shaders;
attachShader = Marshal.GetDelegateForFunctionPointer<GLAttachShader>(SDL.SDL_GL_GetProcAddress("glAttachShader")); attachShader = Marshal.GetDelegateForFunctionPointer<GLAttachShader>(SDL.SDL_GL_GetProcAddress("glAttachShader"));
if (attachShader == null) throw new FrameworkSDLException(); if (attachShader == null) throw new FrameworkSDLException();
@ -50,7 +50,7 @@ namespace SlatedGameToolkit.Framework.Graphics.OpenGL
base.Dispose(); base.Dispose();
} }
~ShaderProgram() { ~GLShaderProgram() {
Dispose(); Dispose();
} }
} }

View File

@ -0,0 +1,18 @@
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);
}
}
}

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 GLFragmentShader : GLShader {
public GLFragmentShader(WindowContext context, string shader) : base() {
Handle = createShader(GLEnums.GL_FRAGMENT_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);
}
~GLFragmentShader() {
Dispose();
}
}
}

View File

@ -16,8 +16,8 @@ namespace SlatedGameToolkit.Framework.Graphics.OpenGL.Shaders
private protected GLGetShaderLogInfo getShaderLogInfo; private protected GLGetShaderLogInfo getShaderLogInfo;
private protected GLDeleteShader deleteShader; private protected GLDeleteShader deleteShader;
public GLShader(WindowContext context) { public GLShader() {
context.MakeCurrent(); context = WindowContextsManager.CurrentWindowContext();
createShader = Marshal.GetDelegateForFunctionPointer<GLCreateShader>(SDL.SDL_GL_GetProcAddress("glCreateShader")); createShader = Marshal.GetDelegateForFunctionPointer<GLCreateShader>(SDL.SDL_GL_GetProcAddress("glCreateShader"));
if (createShader == null) throw new FrameworkSDLException(); if (createShader == null) throw new FrameworkSDLException();
shaderSource = Marshal.GetDelegateForFunctionPointer<GLShaderSource>(SDL.SDL_GL_GetProcAddress("glShaderSource")); shaderSource = Marshal.GetDelegateForFunctionPointer<GLShaderSource>(SDL.SDL_GL_GetProcAddress("glShaderSource"));

View File

@ -7,7 +7,7 @@ using SlatedGameToolkit.Framework.Graphics.Window;
namespace SlatedGameToolkit.Framework.Graphics.OpenGL.Shaders namespace SlatedGameToolkit.Framework.Graphics.OpenGL.Shaders
{ {
public class GLVertexShader : GLShader { public class GLVertexShader : GLShader {
public GLVertexShader(WindowContext context, string shader) : base(context) { public GLVertexShader(WindowContext context, 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);
compileShader(Handle); compileShader(Handle);

View File

@ -287,7 +287,7 @@ namespace SlatedGameToolkit.Framework.Graphics.Window
} }
} }
WindowManager.RegisterWindow(this); WindowContextsManager.RegisterWindow(this);
} }
/// <summary> /// <summary>
@ -337,7 +337,7 @@ namespace SlatedGameToolkit.Framework.Graphics.Window
/// </summary> /// </summary>
public void Dispose() public void Dispose()
{ {
WindowManager.DeregisterWindow(this); WindowContextsManager.DeregisterWindow(this);
SDL.SDL_GL_DeleteContext(glContext); SDL.SDL_GL_DeleteContext(glContext);
SDL.SDL_DestroyWindow(window); SDL.SDL_DestroyWindow(window);
} }

View File

@ -1,8 +1,9 @@
using System.Collections.Generic; using System.Collections.Generic;
using SDL2;
namespace SlatedGameToolkit.Framework.Graphics.Window namespace SlatedGameToolkit.Framework.Graphics.Window
{ {
internal static class WindowManager { internal static class WindowContextsManager {
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) {
@ -15,8 +16,12 @@ namespace SlatedGameToolkit.Framework.Graphics.Window
existingWindows.Remove(windowHandle.WindowID); existingWindows.Remove(windowHandle.WindowID);
} }
internal static WindowContext ContextFromID(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()));
}
} }
} }

View File

@ -54,9 +54,9 @@ namespace SlatedGameToolkit.Framework.StateSystem
} }
/// <summary> /// <summary>
/// /// Begins a state change. The current stage will be notified, and so will the state that is being changed to.
/// </summary> /// </summary>
/// <param name="name"></param> /// <param name="name">The name of the state that we are turning to.</param>
public void changeState(string name) { public void changeState(string name) {
if (thread != Thread.CurrentThread) throw new ThreadStateException("State cannot be changed from a different thread."); if (thread != Thread.CurrentThread) throw new ThreadStateException("State cannot be changed from a different thread.");
if (!states.TryGetValue(name, out nextState)) throw new ArgumentException("The requested state to change to does not exist in this manager."); if (!states.TryGetValue(name, out nextState)) throw new ArgumentException("The requested state to change to does not exist in this manager.");

View File

@ -1,5 +1,6 @@
using System; using System;
using SlatedGameToolkit.Framework; using SlatedGameToolkit.Framework;
using SlatedGameToolkit.Framework.Graphics.OpenGL.Programs;
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;
@ -9,6 +10,7 @@ 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;}}