fixed shader creation and made plan for fixing switching scenes
This commit is contained in:
@@ -45,7 +45,8 @@ public class Scene
|
||||
// TODO: retrieve the transform component of the entity to generate the model matrix
|
||||
// TODO: make a record which holds the matrices and maybe more, so the parameter list doesn't explode
|
||||
var modelMatrix = Matrix4X4<float>.Identity;
|
||||
components.ForEach(c => c.Render(gl, projectionMatrix, viewMatrix, modelMatrix));
|
||||
var t = Matrix4X4.CreateTranslation(0, 0, -10f);
|
||||
components.ForEach(c => c.Render(gl, projectionMatrix, viewMatrix, t));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,10 +9,11 @@ public interface IEngine
|
||||
{
|
||||
void Start();
|
||||
void Stop();
|
||||
|
||||
Scene CreateScene();
|
||||
|
||||
Shader CreateShader(string vertexShaderPath, string fragmentShaderPath);
|
||||
Scene CreateScene();
|
||||
void SetCurrentScene(Scene scene);
|
||||
|
||||
Shader GetShader(string vertexShaderPath);
|
||||
}
|
||||
|
||||
public enum GraphicsAPI
|
||||
@@ -27,7 +28,7 @@ public static class EngineFactory
|
||||
{
|
||||
return api switch
|
||||
{
|
||||
GraphicsAPI.OpenGL => new OpenGLEngine(windowOptions),
|
||||
GraphicsAPI.OpenGL => OpenGLEngine.Create(windowOptions),
|
||||
GraphicsAPI.Vulkan => throw new NotSupportedException($"The graphics API {api} is not currently supported"),
|
||||
_ => throw new ArgumentException($"The graphics API {api} is unknown.", nameof(api))
|
||||
};
|
||||
|
||||
@@ -18,7 +18,7 @@ internal class OpenGLEngine : Engine
|
||||
private PerspectiveCamera _camera = null!;
|
||||
private Scene? _currentScene;
|
||||
|
||||
public OpenGLEngine(WindowOptions windowOptions)
|
||||
private OpenGLEngine(WindowOptions windowOptions)
|
||||
{
|
||||
_window = Window.Create(windowOptions);
|
||||
_window.Load += OnLoad;
|
||||
@@ -28,7 +28,15 @@ internal class OpenGLEngine : Engine
|
||||
|
||||
_scenes = [];
|
||||
}
|
||||
|
||||
|
||||
public static IEngine Create(WindowOptions windowOptions)
|
||||
{
|
||||
var engine = new OpenGLEngine(windowOptions);
|
||||
SingletonInstance = engine;
|
||||
|
||||
return engine;
|
||||
}
|
||||
|
||||
public override void Start()
|
||||
{
|
||||
_window.Run();
|
||||
@@ -39,6 +47,9 @@ internal class OpenGLEngine : Engine
|
||||
_window.Close();
|
||||
}
|
||||
|
||||
// TODO: pass in name as parameter
|
||||
// Name must be unique and is used to switch scenes while the application is running.
|
||||
// We need exactly one default scene which is the initial scene (call SetCurrentScene during the Load() method
|
||||
public override Scene CreateScene()
|
||||
{
|
||||
var scene = new Scene();
|
||||
@@ -46,32 +57,22 @@ internal class OpenGLEngine : Engine
|
||||
return scene;
|
||||
}
|
||||
|
||||
public override Shader CreateShader(string vertexShaderPath, string fragmentShaderPath)
|
||||
private void InitialiseShaders(IEnumerable<string> vertexShaderFiles)
|
||||
{
|
||||
if (_currentScene is null)
|
||||
foreach (var vertexShaderFile in vertexShaderFiles)
|
||||
{
|
||||
throw new InvalidOperationException("Cannot create a shader if there is no scene set as the current scene.");
|
||||
}
|
||||
|
||||
var shader = new Shader(vertexShaderPath, fragmentShaderPath);
|
||||
RegisterShader(_currentScene, shader);
|
||||
|
||||
return shader;
|
||||
}
|
||||
|
||||
protected override void InitialiseShaders(Scene scene)
|
||||
{
|
||||
if (_shaders.TryGetValue(scene, out var shaders))
|
||||
{
|
||||
shaders.ForEach(s => s.Initialize(_gl));
|
||||
var fragmentShaderFile = vertexShaderFile.Replace(".vert", ".frag");
|
||||
var shader = new Shader(vertexShaderFile, fragmentShaderFile);
|
||||
|
||||
shader.Initialize(_gl);
|
||||
_shaders.Add(vertexShaderFile, shader);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetCurrentScene(Scene scene)
|
||||
public override void SetCurrentScene(Scene scene)
|
||||
{
|
||||
_currentScene = scene;
|
||||
_currentScene.InitialiseComponents();
|
||||
InitialiseShaders(scene);
|
||||
}
|
||||
|
||||
private void OnLoad()
|
||||
@@ -83,6 +84,9 @@ internal class OpenGLEngine : Engine
|
||||
_gl.Enable(EnableCap.DepthTest);
|
||||
|
||||
_camera = new PerspectiveCamera(Vector3D<float>.Zero, _window.FramebufferSize);
|
||||
|
||||
InitialiseShaders(Directory.GetFiles("./assets/shaders", "*.vert"));
|
||||
// TODO: SetCurrentScene -> with the default scene
|
||||
}
|
||||
|
||||
private void OnUpdate(double deltaTime)
|
||||
|
||||
@@ -4,25 +4,27 @@ namespace EngineSharp.Core.Rendering;
|
||||
|
||||
internal abstract class Engine : IEngine
|
||||
{
|
||||
protected readonly Dictionary<Scene, List<Shader>> _shaders = [];
|
||||
protected static Engine? SingletonInstance
|
||||
{
|
||||
get;
|
||||
set => field = field is null
|
||||
? value
|
||||
: throw new InvalidOperationException("Only one engine can exist at a time.");
|
||||
}
|
||||
|
||||
protected readonly Dictionary<string, Shader> _shaders = [];
|
||||
|
||||
public static Engine Instance => SingletonInstance ?? throw new InvalidOperationException("No engine has been created yet. Cannot return an instance.");
|
||||
|
||||
public abstract void Start();
|
||||
public abstract void Stop();
|
||||
public abstract Scene CreateScene();
|
||||
public abstract Shader CreateShader(string vertexShaderPath, string fragmentShaderPath);
|
||||
public abstract void SetCurrentScene(Scene scene);
|
||||
|
||||
protected void RegisterShader(Scene scene, Shader shader)
|
||||
public Shader GetShader(string vertexShaderPath)
|
||||
{
|
||||
if (_shaders.TryGetValue(scene, out var shaders))
|
||||
{
|
||||
shaders.Add(shader);
|
||||
}
|
||||
else
|
||||
{
|
||||
_shaders.Add(scene, [shader]);
|
||||
}
|
||||
Instance._shaders.TryGetValue(vertexShaderPath, out var shader);
|
||||
return shader ?? throw new ArgumentException($"Shader '{vertexShaderPath}' does not exist.");
|
||||
}
|
||||
|
||||
protected abstract void InitialiseShaders(Scene scene);
|
||||
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
using System.IO;
|
||||
using EngineSharp.Core.Rendering.Exceptions;
|
||||
using EngineSharp.Core.Rendering.Exceptions;
|
||||
using Silk.NET.Maths;
|
||||
using Silk.NET.OpenGL;
|
||||
|
||||
@@ -15,15 +14,17 @@ public class Shader
|
||||
private GL? _gl; // not as a variable. In the future it should be possible to compile the shaders beforehand. Right now, all shaders are JIT compiled which isn't great
|
||||
private uint? _shaderProgramId;
|
||||
|
||||
// TODO: Make this public. The paths are then used as an index into a dictionary. This dictionary stores the shaderProgramId (maybe only use one path as an index, as the other shader should have the same name, just with a different file ending)
|
||||
// With this, the shaders can be compiled once the engine is started (shaders must be in folder "assets/shaders"). With this I don't have to worry how I can create the shader class and make it compile the shader etc.
|
||||
// Maybe the dict needs to also store the GL context so the shader can be used ans values can be set on it, but we will see
|
||||
internal Shader(string pathToVertexShader, string pathToFragmentShader)
|
||||
{
|
||||
_vertexCode = File.ReadAllText(pathToVertexShader);
|
||||
_fragmentCode = File.ReadAllText(pathToFragmentShader);
|
||||
}
|
||||
|
||||
public static Shader GetShader(string pathToVertexShader)
|
||||
{
|
||||
return Engine.Instance.GetShader(pathToVertexShader);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initialises the shader, by compiling it and making it ready to be used in the application. <br/>
|
||||
/// Only initialises the first time it is called. <b>Is a NoOp every subsequent call.</b>
|
||||
|
||||
@@ -18,7 +18,9 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="assets\" />
|
||||
<Content Include="assets\**">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -9,19 +9,20 @@ public class Planet : Core.ECS.LogicComponent
|
||||
|
||||
public override void Initialise()
|
||||
{
|
||||
// var material = new Material
|
||||
// {
|
||||
// Shader = shader,
|
||||
// };
|
||||
// var sphereGenerator = new IcoSphere
|
||||
// {
|
||||
// Resolution = 10,
|
||||
// Material = material,
|
||||
// };
|
||||
// PlanetMesh = new MeshRenderer
|
||||
// {
|
||||
// Mesh = sphereGenerator.CreateSphere(),
|
||||
// };
|
||||
var shader = Shader.GetShader("./assets/shaders/sphere.vert");
|
||||
var material = new Material
|
||||
{
|
||||
Shader = shader,
|
||||
};
|
||||
var sphereGenerator = new IcoSphere
|
||||
{
|
||||
Resolution = 10,
|
||||
Material = material,
|
||||
};
|
||||
PlanetMesh = new MeshRenderer
|
||||
{
|
||||
Mesh = sphereGenerator.CreateSphere(),
|
||||
};
|
||||
}
|
||||
|
||||
public override void OnUpdate(double deltaTime)
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
using Engine_silk.NET;
|
||||
using EngineSharp.Core;
|
||||
using EngineSharp.Core.Rendering;
|
||||
using EngineSharp.Core;
|
||||
using Silk.NET.Maths;
|
||||
using Silk.NET.Windowing;
|
||||
using GraphicsAPI = EngineSharp.Core.GraphicsAPI;
|
||||
@@ -9,6 +7,7 @@ namespace EngineSharp;
|
||||
|
||||
internal static class Program
|
||||
{
|
||||
|
||||
private static void Main(string[] args)
|
||||
{
|
||||
var options = WindowOptions.Default with
|
||||
@@ -20,11 +19,10 @@ internal static class Program
|
||||
var engine = EngineFactory.Create(GraphicsAPI.OpenGL, options);
|
||||
var mainScene = engine.CreateScene();
|
||||
var planet = mainScene.CreateEntity("planet");
|
||||
|
||||
var shader = engine.CreateShader("./assets/shaders/sphere.vert", "./assets/shaders/sphere.frag");
|
||||
|
||||
planet.AddComponent(new Planet());
|
||||
|
||||
engine.SetCurrentScene(mainScene);
|
||||
engine.Start();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user