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.Core;
using SlatedGameToolkit.Framework.Exceptions;
using SlatedGameToolkit.Framework.Graphics;
using SlatedGameToolkit.Framework.Graphics.Window;
using SlatedGameToolkit.Framework.Input;
using SlatedGameToolkit.Framework.Input.Devices;
@ -136,7 +135,7 @@ namespace SlatedGameToolkit.Framework {
Keyboard.OnKeyReleased((Key) SDL_Event.key.keysym.sym);
break;
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)
{
case SDL.SDL_WindowEventID.SDL_WINDOWEVENT_SIZE_CHANGED:
@ -227,7 +226,7 @@ namespace SlatedGameToolkit.Framework {
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_PROFILE_MASK, SDL.SDL_GLprofile.SDL_GL_CONTEXT_PROFILE_CORE) < 0) throw new FrameworkSDLException();

File diff suppressed because it is too large Load Diff

View File

@ -17,4 +17,10 @@ namespace SlatedGameToolkit.Framework.Graphics.OpenGL
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);
}

View File

@ -4,19 +4,21 @@ using SDL2;
using SlatedGameToolkit.Framework.Exceptions;
using SlatedGameToolkit.Framework.Graphics.Window;
namespace SlatedGameToolkit.Framework.Graphics.OpenGL
namespace SlatedGameToolkit.Framework.Graphics.OpenGL.Programs
{
public abstract class GLProgram : IDisposable
{
private WindowContext context;
private protected UIntPtr handle;
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(WindowContext context) {
this.context = context;
public GLProgram(bool separable = true) {
this.context = WindowContextsManager.CurrentWindowContext();
context.MakeCurrent();
createProgram = Marshal.GetDelegateForFunctionPointer<GLCreateProgram>(SDL.SDL_GL_GetProcAddress("glCreateProgram"));
if (createProgram == null) throw new FrameworkSDLException();
@ -26,8 +28,19 @@ namespace SlatedGameToolkit.Framework.Graphics.OpenGL
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 void Use() {
useProgram(handle);
}
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.Window;
namespace SlatedGameToolkit.Framework.Graphics.OpenGL
namespace SlatedGameToolkit.Framework.Graphics.OpenGL.Programs
{
public class ShaderProgram : GLProgram
public class GLShaderProgram : GLProgram
{
private GLShader[] shaders;
private GLAttachShader attachShader;
private GLDetachShader detachShader;
private readonly GLShader[] shaders;
private readonly GLAttachShader attachShader;
private readonly GLDetachShader detachShader;
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;
attachShader = Marshal.GetDelegateForFunctionPointer<GLAttachShader>(SDL.SDL_GL_GetProcAddress("glAttachShader"));
if (attachShader == null) throw new FrameworkSDLException();
@ -43,14 +43,14 @@ namespace SlatedGameToolkit.Framework.Graphics.OpenGL
}
public override void Dispose() {
foreach (GLShader shader in shaders)
{
shader.Dispose();
}
base.Dispose();
foreach (GLShader shader in shaders)
{
shader.Dispose();
}
base.Dispose();
}
~ShaderProgram() {
~GLShaderProgram() {
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 GLDeleteShader deleteShader;
public GLShader(WindowContext context) {
context.MakeCurrent();
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"));

View File

@ -7,7 +7,7 @@ using SlatedGameToolkit.Framework.Graphics.Window;
namespace SlatedGameToolkit.Framework.Graphics.OpenGL.Shaders
{
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);
shaderSource(Handle, 1, shader, null);
compileShader(Handle);

View File

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

View File

@ -1,8 +1,9 @@
using System.Collections.Generic;
using SDL2;
namespace SlatedGameToolkit.Framework.Graphics.Window
{
internal static class WindowManager {
internal static class WindowContextsManager {
private static Dictionary<uint, WindowContext> existingWindows = new Dictionary<uint, WindowContext>();
internal static void RegisterWindow(WindowContext windowHandle) {
@ -15,8 +16,12 @@ namespace SlatedGameToolkit.Framework.Graphics.Window
existingWindows.Remove(windowHandle.WindowID);
}
internal static WindowContext ContextFromID(uint ID) {
public static WindowContext ContextFromWindowID(uint 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>
///
/// Begins a state change. The current stage will be notified, and so will the state that is being changed to.
/// </summary>
/// <param name="name"></param>
/// <param name="name">The name of the state that we are turning to.</param>
public void changeState(string name) {
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.");

View File

@ -1,5 +1,6 @@
using System;
using SlatedGameToolkit.Framework;
using SlatedGameToolkit.Framework.Graphics.OpenGL.Programs;
using SlatedGameToolkit.Framework.Graphics.Window;
using SlatedGameToolkit.Framework.StateSystem;
using SlatedGameToolkit.Framework.StateSystem.States;
@ -9,6 +10,7 @@ namespace SlatedGameToolkit.Tools.Utilities.GraphicalPlayground
public class MainState : IState
{
private WindowContext window;
private GLShaderProgram shader;
public WindowContext CurrentWindow { get { return window;}}