improved architecture; made first steps to compiling shaders on engine startup and not JIT
This commit is contained in:
@ -1,9 +1,7 @@
|
||||
namespace EngineSharp.Core.ECS;
|
||||
|
||||
// TODO: A LogicComponent would have a list of Components. A LogicComponent is basically what will be stored in the scene graph and all components of all LogicComponents will have their Update methods etc. be called
|
||||
|
||||
public abstract class LogicComponent : IComponent
|
||||
public abstract class LogicComponent : IComponent // Kinda like Unity's MonoBehaviour
|
||||
{
|
||||
public abstract void Start();
|
||||
public abstract void Initialise();
|
||||
public abstract void OnUpdate(double deltaTime);
|
||||
}
|
||||
@ -1,8 +1,9 @@
|
||||
using Silk.NET.OpenGL;
|
||||
using Silk.NET.Maths;
|
||||
using Silk.NET.OpenGL;
|
||||
|
||||
namespace EngineSharp.Core.ECS;
|
||||
|
||||
public abstract class RenderComponent : IComponent
|
||||
{
|
||||
internal abstract void Render(GL gl);
|
||||
internal abstract void Render(GL gl, Matrix4X4<float> projectionMatrix, Matrix4X4<float> viewMatrix, Matrix4X4<float> modelMatrix);
|
||||
}
|
||||
@ -1,11 +1,13 @@
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Silk.NET.Maths;
|
||||
using Silk.NET.OpenGL;
|
||||
|
||||
namespace EngineSharp.Core.ECS;
|
||||
|
||||
public class Scene
|
||||
{
|
||||
// TODO: Maybe instead of a List, use a HashSet instead. Maybe implement a equality comparer to ensure, only one element per type can be present
|
||||
// TODO: Maybe instead of a List, use a HashSet. Implement a equality comparer to ensure, only one element per type can be present
|
||||
private readonly Dictionary<long, List<LogicComponent>> _logicComponents = new();
|
||||
private readonly Dictionary<long, List<DataComponent>> _dataComponents = new();
|
||||
private readonly Dictionary<long, List<RenderComponent>> _renderComponents = new();
|
||||
@ -20,11 +22,11 @@ public class Scene
|
||||
};
|
||||
}
|
||||
|
||||
internal void StartComponents()
|
||||
internal void InitialiseComponents()
|
||||
{
|
||||
foreach (var components in _logicComponents.Values)
|
||||
{
|
||||
components.ForEach(c => c.Start());
|
||||
components.ForEach(c => c.Initialise());
|
||||
}
|
||||
}
|
||||
|
||||
@ -36,11 +38,14 @@ public class Scene
|
||||
}
|
||||
}
|
||||
|
||||
internal void RenderComponents(GL gl)
|
||||
internal void RenderComponents(GL gl, Matrix4X4<float> projectionMatrix, Matrix4X4<float> viewMatrix)
|
||||
{
|
||||
foreach (var components in _renderComponents.Values)
|
||||
{
|
||||
components.ForEach(c => c.Render(gl));
|
||||
// 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));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,4 +1,6 @@
|
||||
namespace EngineSharp.Core;
|
||||
using System;
|
||||
|
||||
namespace EngineSharp.Core;
|
||||
|
||||
public static class NumberExtensions
|
||||
{
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
using Silk.NET.Maths;
|
||||
using System;
|
||||
using Silk.NET.Maths;
|
||||
|
||||
namespace EngineSharp.Core;
|
||||
|
||||
|
||||
@ -1,4 +1,6 @@
|
||||
using EngineSharp.Core.ECS;
|
||||
using System;
|
||||
using EngineSharp.Core.ECS;
|
||||
using EngineSharp.Core.Rendering;
|
||||
using Silk.NET.Windowing;
|
||||
|
||||
namespace EngineSharp.Core;
|
||||
@ -9,6 +11,8 @@ public interface IEngine
|
||||
void Stop();
|
||||
|
||||
Scene CreateScene();
|
||||
|
||||
Shader CreateShader(string vertexShaderPath, string fragmentShaderPath);
|
||||
}
|
||||
|
||||
public enum GraphicsAPI
|
||||
|
||||
@ -1,4 +1,6 @@
|
||||
using Silk.NET.Input;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Silk.NET.Input;
|
||||
|
||||
namespace EngineSharp.Core;
|
||||
|
||||
|
||||
@ -1,17 +1,19 @@
|
||||
using System.Drawing;
|
||||
using EngineSharp.Core.ECS;
|
||||
using EngineSharp.Core.Rendering;
|
||||
using Silk.NET.Input;
|
||||
using Silk.NET.Maths;
|
||||
using Silk.NET.OpenGL;
|
||||
using Silk.NET.Windowing;
|
||||
using Shader = EngineSharp.Core.Rendering.Shader;
|
||||
|
||||
namespace EngineSharp.Core;
|
||||
|
||||
internal class OpenGLEngine : IEngine
|
||||
internal class OpenGLEngine : Engine
|
||||
{
|
||||
private readonly IWindow _window;
|
||||
private readonly List<Scene> _scenes;
|
||||
private GL _gl = null!; // because between constructing the engine and OnLoad being called nothing should be able to call these fields. Therefore, we do this to get rid of warnings
|
||||
private GL _gl = null!; // because between constructing the engine and OnLoad being called nothing should call these fields. Therefore, we do "!" to get rid of warnings
|
||||
private Input _input = null!;
|
||||
private PerspectiveCamera _camera = null!;
|
||||
private Scene? _currentScene;
|
||||
@ -24,30 +26,52 @@ internal class OpenGLEngine : IEngine
|
||||
_window.Render += OnRender;
|
||||
_window.Resize += OnResize;
|
||||
|
||||
_scenes = new();
|
||||
_scenes = [];
|
||||
}
|
||||
|
||||
public void Start()
|
||||
public override void Start()
|
||||
{
|
||||
_window.Run();
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
public override void Stop()
|
||||
{
|
||||
_window.Close();
|
||||
}
|
||||
|
||||
public Scene CreateScene()
|
||||
public override Scene CreateScene()
|
||||
{
|
||||
var scene = new Scene();
|
||||
_scenes.Add(scene);
|
||||
return scene;
|
||||
}
|
||||
|
||||
public override Shader CreateShader(string vertexShaderPath, string fragmentShaderPath)
|
||||
{
|
||||
if (_currentScene is null)
|
||||
{
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
public void SetCurrentScene(Scene scene)
|
||||
{
|
||||
_currentScene = scene;
|
||||
_currentScene.StartComponents();
|
||||
_currentScene.InitialiseComponents();
|
||||
InitialiseShaders(scene);
|
||||
}
|
||||
|
||||
private void OnLoad()
|
||||
@ -68,10 +92,7 @@ internal class OpenGLEngine : IEngine
|
||||
_window.Close();
|
||||
}
|
||||
|
||||
if (_currentScene is not null)
|
||||
{
|
||||
_currentScene.UpdateComponents(deltaTime);
|
||||
}
|
||||
_currentScene?.UpdateComponents(deltaTime);
|
||||
}
|
||||
|
||||
private void OnRender(double deltaTime)
|
||||
@ -79,15 +100,13 @@ internal class OpenGLEngine : IEngine
|
||||
var projectionMatrix = _camera.ProjectionMatrix;
|
||||
var viewMatrix = _camera.ViewMatrix;
|
||||
|
||||
// TODO: Here render all meshes etc.
|
||||
// MeshRenderer contains a mesh; Mesh contains a material; Material contains a shader and the values for all uniforms of the shader (apart from the matrices; I am not sure how to best handle the model matrix with this approach)
|
||||
|
||||
_currentScene?.RenderComponents(_gl);
|
||||
_currentScene?.RenderComponents(_gl, projectionMatrix, viewMatrix);
|
||||
}
|
||||
|
||||
private void OnResize(Vector2D<int> newDimensions)
|
||||
{
|
||||
// when using an entity component system the camera should probably read the aspect ratio from a central location or should listen to the "Resize" event rather than the engine updating the aspect on the camera
|
||||
// when using an entity component system the camera should probably read the aspect ratio from a central location or should listen to the "Resize" event rather than the engine updating the aspect on the camera.
|
||||
// Especially if more than one camera should be able to exist simultaneously
|
||||
_camera.UpdateAspect(newDimensions);
|
||||
}
|
||||
}
|
||||
@ -1,4 +1,5 @@
|
||||
using Silk.NET.Maths;
|
||||
using System;
|
||||
using Silk.NET.Maths;
|
||||
|
||||
namespace EngineSharp.Core;
|
||||
|
||||
|
||||
28
src/EngineSharp.Core/EngineSharp.Core/Rendering/Engine.cs
Normal file
28
src/EngineSharp.Core/EngineSharp.Core/Rendering/Engine.cs
Normal file
@ -0,0 +1,28 @@
|
||||
using EngineSharp.Core.ECS;
|
||||
|
||||
namespace EngineSharp.Core.Rendering;
|
||||
|
||||
internal abstract class Engine : IEngine
|
||||
{
|
||||
protected readonly Dictionary<Scene, List<Shader>> _shaders = [];
|
||||
|
||||
public abstract void Start();
|
||||
public abstract void Stop();
|
||||
public abstract Scene CreateScene();
|
||||
public abstract Shader CreateShader(string vertexShaderPath, string fragmentShaderPath);
|
||||
|
||||
protected void RegisterShader(Scene scene, Shader shader)
|
||||
{
|
||||
if (_shaders.TryGetValue(scene, out var shaders))
|
||||
{
|
||||
shaders.Add(shader);
|
||||
}
|
||||
else
|
||||
{
|
||||
_shaders.Add(scene, [shader]);
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract void InitialiseShaders(Scene scene);
|
||||
|
||||
}
|
||||
@ -1,4 +1,5 @@
|
||||
using Silk.NET.OpenGL;
|
||||
using System;
|
||||
using Silk.NET.OpenGL;
|
||||
|
||||
namespace EngineSharp.Core.Rendering.Exceptions;
|
||||
|
||||
|
||||
@ -1,4 +1,6 @@
|
||||
namespace EngineSharp.Core.Rendering.Exceptions;
|
||||
using System;
|
||||
|
||||
namespace EngineSharp.Core.Rendering.Exceptions;
|
||||
|
||||
public class ShaderLinkException : Exception
|
||||
{
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
using Silk.NET.Maths;
|
||||
using Silk.NET.OpenGL;
|
||||
|
||||
namespace EngineSharp.Core.Rendering;
|
||||
|
||||
@ -6,44 +7,44 @@ public class Material
|
||||
{
|
||||
public required Shader Shader { get; init; }
|
||||
|
||||
internal void UseShader() => Shader.Use();
|
||||
internal void UseShader() => Shader.Use();
|
||||
|
||||
#region Set uniforms
|
||||
// All of this just relays to the shader. While it is a lot of "unnecessary" code it ensures that everything unsafe of OpenGL/Vulkan specific is abstracted away
|
||||
|
||||
public void SetInt(string name, int value)
|
||||
{
|
||||
UseShader();
|
||||
Shader.Use();
|
||||
Shader.SetInt(name, value);
|
||||
}
|
||||
|
||||
public void SetFloat(string name, float value)
|
||||
{
|
||||
UseShader();
|
||||
Shader.Use();
|
||||
Shader.SetFloat(name, value);
|
||||
}
|
||||
|
||||
public void SetVector(string name, Vector3D<double> value)
|
||||
{
|
||||
UseShader();
|
||||
Shader.Use();
|
||||
Shader.SetVector(name, value);
|
||||
}
|
||||
|
||||
public void SetVector(string name, Vector3D<float> value)
|
||||
{
|
||||
UseShader();
|
||||
Shader.Use();
|
||||
Shader.SetVector(name, value);
|
||||
}
|
||||
|
||||
public void SetMatrix(string name, Matrix4X4<double> matrix)
|
||||
{
|
||||
UseShader();
|
||||
Shader.Use();
|
||||
Shader.SetMatrix(name, matrix);
|
||||
}
|
||||
|
||||
public void SetMatrix(string name, Matrix4X4<float> matrix)
|
||||
{
|
||||
UseShader();
|
||||
Shader.Use();
|
||||
Shader.SetMatrix(name, matrix);
|
||||
}
|
||||
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
using Silk.NET.Maths;
|
||||
using Silk.NET.OpenGL;
|
||||
|
||||
namespace EngineSharp.Core.Rendering;
|
||||
|
||||
@ -44,5 +45,13 @@ public class Mesh
|
||||
}
|
||||
|
||||
// This is probably the location where the model, view, projection matrices will be set!
|
||||
internal void PrepareForRendering() => Material.UseShader();
|
||||
internal void PrepareForRendering(Matrix4X4<float> projectionMatrix, Matrix4X4<float> viewMatrix, Matrix4X4<float> modelMatrix)
|
||||
{
|
||||
Material.UseShader();
|
||||
|
||||
// We would also need the inverse (see comment in any of the shaders) and probably other stuff. This other stuff might be automatically added before compiling the shader. kinda like an include for ALL shaders
|
||||
Material.SetMatrix("projectionMatrix", projectionMatrix);
|
||||
Material.SetMatrix("viewMatrix", viewMatrix);
|
||||
Material.SetMatrix("modelMatrix", modelMatrix);
|
||||
}
|
||||
}
|
||||
@ -1,4 +1,6 @@
|
||||
using EngineSharp.Core.ECS;
|
||||
using System;
|
||||
using EngineSharp.Core.ECS;
|
||||
using Silk.NET.Maths;
|
||||
using Silk.NET.OpenGL;
|
||||
|
||||
namespace EngineSharp.Core.Rendering;
|
||||
@ -9,14 +11,14 @@ public class MeshRenderer : RenderComponent
|
||||
|
||||
private uint vao, vbo, ebo;
|
||||
|
||||
internal override void Render(GL gl)
|
||||
internal override void Render(GL gl, Matrix4X4<float> projectionMatrix, Matrix4X4<float> viewMatrix, Matrix4X4<float> modelMatrix)
|
||||
{
|
||||
GenerateRenderableMesh(gl);
|
||||
GenerateRenderableMesh(gl, projectionMatrix, viewMatrix, modelMatrix);
|
||||
gl.BindVertexArray(vao);
|
||||
gl.DrawElements(PrimitiveType.Triangles, (uint)Mesh.Indices.Length, DrawElementsType.UnsignedInt, 0);
|
||||
}
|
||||
|
||||
private void GenerateRenderableMesh(GL gl)
|
||||
private void GenerateRenderableMesh(GL gl, Matrix4X4<float> projectionMatrix, Matrix4X4<float> viewMatrix, Matrix4X4<float> modelMatrix)
|
||||
{
|
||||
if(vao == 0) { vao = gl.CreateVertexArray(); }
|
||||
gl.BindVertexArray(vao);
|
||||
@ -24,7 +26,7 @@ public class MeshRenderer : RenderComponent
|
||||
if(vbo == 0) { vbo = gl.GenBuffer(); }
|
||||
if(ebo == 0) { ebo = gl.GenBuffer(); }
|
||||
|
||||
Mesh.PrepareForRendering();
|
||||
Mesh.PrepareForRendering(projectionMatrix, viewMatrix, modelMatrix);
|
||||
var meshData = new float[Mesh.Vertices.Length * 3 + Mesh.Indices.Length * 3];
|
||||
for (int i = 0, insert = 0; i < Mesh.Vertices.Length; i++, insert += 6)
|
||||
{
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
using EngineSharp.Core.Rendering.Exceptions;
|
||||
using System.IO;
|
||||
using EngineSharp.Core.Rendering.Exceptions;
|
||||
using Silk.NET.Maths;
|
||||
using Silk.NET.OpenGL;
|
||||
|
||||
@ -9,55 +10,102 @@ namespace EngineSharp.Core.Rendering;
|
||||
// I don't know if Vulkan also uses an ID as a uint but I think so. If so, this change would decouple the shader from OpenGL (but the question is, do I want to decouple the shader? Maybe not, as this could then couple the material to OpenGL)
|
||||
public class Shader
|
||||
{
|
||||
private readonly GL _gl; // not as a variable. Add it as a parameter to the methods probably (in the future it should be possible to compile the shaders beforehand. if context is passed as parameter, all shaders are JIT compiled which isn't great
|
||||
private readonly uint _shaderProgramId;
|
||||
private readonly string _vertexCode, _fragmentCode;
|
||||
|
||||
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;
|
||||
|
||||
public Shader(GL openGLContext, string pathToVertexShader, string pathToFragmentShader)
|
||||
// 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)
|
||||
{
|
||||
_gl = openGLContext;
|
||||
var vertexCode = File.ReadAllText(pathToVertexShader);
|
||||
var fragmentCode = File.ReadAllText(pathToFragmentShader);
|
||||
|
||||
var vertexShader = CompileShader(vertexCode, ShaderType.VertexShader);
|
||||
var fragmentShader = CompileShader(fragmentCode, ShaderType.FragmentShader);
|
||||
|
||||
_shaderProgramId = CreateProgram(vertexShader, fragmentShader);
|
||||
_vertexCode = File.ReadAllText(pathToVertexShader);
|
||||
_fragmentCode = File.ReadAllText(pathToFragmentShader);
|
||||
}
|
||||
|
||||
internal void Use() => _gl.UseProgram(_shaderProgramId);
|
||||
|
||||
#region Set uniforms
|
||||
internal void SetInt(string name, int value)
|
||||
/// <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>
|
||||
/// </summary>
|
||||
/// <param name="glContext"></param>
|
||||
internal void Initialize(GL glContext)
|
||||
{
|
||||
_gl.Uniform1(_gl.GetUniformLocation(_shaderProgramId, name), value);
|
||||
if (_gl is not null || _shaderProgramId is not null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_gl = glContext;
|
||||
var vertexShader = CompileShader(_vertexCode, ShaderType.VertexShader);
|
||||
var fragmentShader = CompileShader(_fragmentCode, ShaderType.FragmentShader);
|
||||
|
||||
_shaderProgramId = CreateProgram(vertexShader, fragmentShader);
|
||||
}
|
||||
|
||||
internal void SetFloat(string name, float value)
|
||||
/// <summary>
|
||||
/// Can only be called after <see cref="Initialize"/> has been called.
|
||||
/// </summary>
|
||||
internal void Use()
|
||||
{
|
||||
_gl.Uniform1(_gl.GetUniformLocation(_shaderProgramId, name), value);
|
||||
}
|
||||
|
||||
internal void SetVector(string name, Vector3D<double> value)
|
||||
{
|
||||
_gl.Uniform3(_gl.GetUniformLocation(_shaderProgramId, name), value.X, value.Y, value.Z);
|
||||
}
|
||||
internal void SetVector(string name, Vector3D<float> value)
|
||||
{
|
||||
_gl.Uniform3(_gl.GetUniformLocation(_shaderProgramId, name), value.X, value.Y, value.Z);
|
||||
if (_shaderProgramId is null || _gl is null)
|
||||
{
|
||||
throw new InvalidOperationException("This shader has not been initialized and can therefore not be used.");
|
||||
}
|
||||
|
||||
_gl.UseProgram(_shaderProgramId.Value);
|
||||
}
|
||||
|
||||
#region Set uniforms
|
||||
/// <summary>
|
||||
/// Call <see cref="Use"/> before calling this method, otherwise the value might be set for the wrong shader.
|
||||
/// </summary>
|
||||
internal void SetInt(string name, int value)
|
||||
{
|
||||
_gl!.Uniform1(_gl.GetUniformLocation(_shaderProgramId!.Value, name), value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Call <see cref="Use"/> before calling this method, otherwise the value might be set for the wrong shader.
|
||||
/// </summary>
|
||||
internal void SetFloat(string name, float value)
|
||||
{
|
||||
_gl!.Uniform1(_gl.GetUniformLocation(_shaderProgramId!.Value, name), value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Call <see cref="Use"/> before calling this method, otherwise the value might be set for the wrong shader.
|
||||
/// </summary>
|
||||
internal void SetVector(string name, Vector3D<double> value)
|
||||
{
|
||||
_gl!.Uniform3(_gl.GetUniformLocation(_shaderProgramId!.Value, name), value.X, value.Y, value.Z);
|
||||
}
|
||||
/// <summary>
|
||||
/// Call <see cref="Use"/> before calling this method, otherwise the value might be set for the wrong shader.
|
||||
/// </summary>
|
||||
internal void SetVector(string name, Vector3D<float> value)
|
||||
{
|
||||
_gl!.Uniform3(_gl.GetUniformLocation(_shaderProgramId!.Value, name), value.X, value.Y, value.Z);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Call <see cref="Use"/> before calling this method, otherwise the value might be set for the wrong shader.
|
||||
/// </summary>
|
||||
internal void SetMatrix(string name, Matrix4X4<double> matrix)
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
_gl.UniformMatrix4(_gl.GetUniformLocation(_shaderProgramId, name), 1, false, (double*) &matrix);
|
||||
_gl!.UniformMatrix4(_gl.GetUniformLocation(_shaderProgramId!.Value, name), 1, false, (double*) &matrix);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Call <see cref="Use"/> before calling this method, otherwise the value might be set for the wrong shader.
|
||||
/// </summary>
|
||||
internal void SetMatrix(string name, Matrix4X4<float> matrix)
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
_gl.UniformMatrix4(_gl.GetUniformLocation(_shaderProgramId, name), 1, false, (float*) &matrix);
|
||||
_gl!.UniformMatrix4(_gl.GetUniformLocation(_shaderProgramId!.Value, name), 1, false, (float*) &matrix);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
using Silk.NET.Maths;
|
||||
using System;
|
||||
using Silk.NET.Maths;
|
||||
|
||||
namespace EngineSharp.Extensions;
|
||||
|
||||
|
||||
@ -17,4 +17,8 @@
|
||||
<PackageReference Include="Silk.NET.Windowing" Version="2.22.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="assets\" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@ -1,4 +1,6 @@
|
||||
using EngineSharp.Core.Rendering;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using EngineSharp.Core.Rendering;
|
||||
using EngineSharp.Extensions;
|
||||
using Silk.NET.Maths;
|
||||
|
||||
|
||||
31
src/EngineSharp/Planet.cs
Normal file
31
src/EngineSharp/Planet.cs
Normal file
@ -0,0 +1,31 @@
|
||||
using Engine_silk.NET;
|
||||
using EngineSharp.Core.Rendering;
|
||||
|
||||
namespace EngineSharp;
|
||||
|
||||
public class Planet : Core.ECS.LogicComponent
|
||||
{
|
||||
public MeshRenderer PlanetMesh;
|
||||
|
||||
public override void Initialise()
|
||||
{
|
||||
// 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)
|
||||
{
|
||||
// Nothing to do at the moment
|
||||
}
|
||||
}
|
||||
@ -7,9 +7,9 @@ using GraphicsAPI = EngineSharp.Core.GraphicsAPI;
|
||||
|
||||
namespace EngineSharp;
|
||||
|
||||
static class Program
|
||||
internal static class Program
|
||||
{
|
||||
static void Main(string[] args)
|
||||
private static void Main(string[] args)
|
||||
{
|
||||
var options = WindowOptions.Default with
|
||||
{
|
||||
@ -19,26 +19,11 @@ static class Program
|
||||
|
||||
var engine = EngineFactory.Create(GraphicsAPI.OpenGL, options);
|
||||
var mainScene = engine.CreateScene();
|
||||
var cube = mainScene.CreateEntity("cube");
|
||||
var planet = mainScene.CreateEntity("planet");
|
||||
|
||||
var shader = new Shader(null, "", ""); // make a factory in IEngine so I don't have to pass graphics library specific values
|
||||
var material = new Material
|
||||
{
|
||||
Shader = shader,
|
||||
};
|
||||
var sphereGenerator = new IcoSphere
|
||||
{
|
||||
Resolution = 10,
|
||||
Material = material,
|
||||
};
|
||||
var cubeMeshRenderer = new MeshRenderer
|
||||
{
|
||||
Mesh = sphereGenerator.CreateSphere(),
|
||||
};
|
||||
var shader = engine.CreateShader("./assets/shaders/sphere.vert", "./assets/shaders/sphere.frag");
|
||||
|
||||
cube.AddComponent(cubeMeshRenderer);
|
||||
|
||||
// TODO: ensure that model matrix etc. will be set correctly on rendering, so that the icosphere can actually be rendered
|
||||
planet.AddComponent(new Planet());
|
||||
|
||||
engine.Start();
|
||||
}
|
||||
|
||||
13
src/EngineSharp/assets/shaders/sphere.frag
Normal file
13
src/EngineSharp/assets/shaders/sphere.frag
Normal file
@ -0,0 +1,13 @@
|
||||
#version 330 core
|
||||
|
||||
out vec4 FragColour;
|
||||
|
||||
in vec3 FragPos;
|
||||
in vec3 Normal;
|
||||
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 col = vec3(1.0, 0.5, 0.2) * FragPos;
|
||||
FragColour = vec4(col, 1);
|
||||
}
|
||||
20
src/EngineSharp/assets/shaders/sphere.vert
Normal file
20
src/EngineSharp/assets/shaders/sphere.vert
Normal file
@ -0,0 +1,20 @@
|
||||
#version 330 core
|
||||
|
||||
layout (location = 0) in vec3 aPosition;
|
||||
layout (location = 1) in vec3 normalVector;
|
||||
|
||||
uniform mat4 modelMatrix;
|
||||
uniform mat4 viewMatrix;
|
||||
uniform mat4 projectionMatrix;
|
||||
|
||||
out vec3 FragPos;
|
||||
out vec3 Normal;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 pos = vec4(aPosition, 1.0);
|
||||
// TODO: calculate the inverse of the model matrix beforehand since "inverse()" is very costly to calculate for every vertex
|
||||
Normal = mat3(transpose(inverse(modelMatrix))) * normalVector;
|
||||
FragPos = vec3(modelMatrix * pos);
|
||||
gl_Position = projectionMatrix * viewMatrix * modelMatrix * pos;
|
||||
}
|
||||
Reference in New Issue
Block a user