prepared pipeline for enable the rendering of meshes
This commit is contained in:
@@ -11,11 +11,11 @@ public struct Entity
|
||||
public readonly long Id;
|
||||
private Scene _scene;
|
||||
|
||||
public string Name { get; set; }
|
||||
public required string Name { get; set; }
|
||||
|
||||
internal Entity(long id, Scene scene)
|
||||
{
|
||||
this.Id = id;
|
||||
Id = id;
|
||||
_scene = scene;
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,10 @@ public class Scene
|
||||
|
||||
public Entity CreateEntity(string name)
|
||||
{
|
||||
return new Entity(_nextSceneId++, this);
|
||||
return new Entity(_nextSceneId++, this)
|
||||
{
|
||||
Name = name,
|
||||
};
|
||||
}
|
||||
|
||||
internal void StartComponents()
|
||||
|
||||
@@ -82,10 +82,7 @@ internal class OpenGLEngine : IEngine
|
||||
// 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)
|
||||
|
||||
if (_currentScene is not null)
|
||||
{
|
||||
_currentScene.RenderComponents(_gl);
|
||||
}
|
||||
_currentScene?.RenderComponents(_gl);
|
||||
}
|
||||
|
||||
private void OnResize(Vector2D<int> newDimensions)
|
||||
|
||||
52
src/EngineSharp.Core/EngineSharp.Core/Rendering/Material.cs
Normal file
52
src/EngineSharp.Core/EngineSharp.Core/Rendering/Material.cs
Normal file
@@ -0,0 +1,52 @@
|
||||
using Silk.NET.Maths;
|
||||
|
||||
namespace EngineSharp.Core.Rendering;
|
||||
|
||||
public class Material
|
||||
{
|
||||
public required Shader Shader { get; init; }
|
||||
|
||||
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.SetInt(name, value);
|
||||
}
|
||||
|
||||
public void SetFloat(string name, float value)
|
||||
{
|
||||
UseShader();
|
||||
Shader.SetFloat(name, value);
|
||||
}
|
||||
|
||||
public void SetVector(string name, Vector3D<double> value)
|
||||
{
|
||||
UseShader();
|
||||
Shader.SetVector(name, value);
|
||||
}
|
||||
|
||||
public void SetVector(string name, Vector3D<float> value)
|
||||
{
|
||||
UseShader();
|
||||
Shader.SetVector(name, value);
|
||||
}
|
||||
|
||||
public void SetMatrix(string name, Matrix4X4<double> matrix)
|
||||
{
|
||||
UseShader();
|
||||
Shader.SetMatrix(name, matrix);
|
||||
}
|
||||
|
||||
public void SetMatrix(string name, Matrix4X4<float> matrix)
|
||||
{
|
||||
UseShader();
|
||||
Shader.SetMatrix(name, matrix);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
@@ -4,6 +4,7 @@ namespace EngineSharp.Core.Rendering;
|
||||
|
||||
public class Mesh
|
||||
{
|
||||
public required Material Material { get; set; }
|
||||
public Vector3D<float>[] Vertices { get; set; } = [];
|
||||
public Vector3D<float>[] Normals { get; set; } = [];
|
||||
public uint[] Indices { get; set; } = [];
|
||||
@@ -30,8 +31,7 @@ public class Mesh
|
||||
var v2 = Vertices[i2];
|
||||
|
||||
var normal = Vector3D.Cross(v1-v0, v2-v0);
|
||||
// Commenting this out, will result in the normals being weighted based on the triangle area
|
||||
normal = Vector3D.Normalize(normal);
|
||||
normal = Vector3D.Normalize(normal); // Commenting this out, will result in the normals being weighted based on the triangle area
|
||||
Normals[i0] += normal;
|
||||
Normals[i1] += normal;
|
||||
Normals[i2] += normal;
|
||||
@@ -42,4 +42,7 @@ public class Mesh
|
||||
Normals[i] = Vector3D.Normalize(Normals[i]); // smoothing for shared vertices
|
||||
}
|
||||
}
|
||||
|
||||
// This is probably the location where the model, view, projection matrices will be set!
|
||||
internal void PrepareForRendering() => Material.UseShader();
|
||||
}
|
||||
@@ -5,7 +5,7 @@ namespace EngineSharp.Core.Rendering;
|
||||
|
||||
public class MeshRenderer : RenderComponent
|
||||
{
|
||||
public required Mesh Mesh { get; set; }
|
||||
public required Mesh Mesh { get; set; } // in the future this might be an array, or alternatively, a mesh can have submeshes. we will see
|
||||
|
||||
private uint vao, vbo, ebo;
|
||||
|
||||
@@ -24,6 +24,7 @@ public class MeshRenderer : RenderComponent
|
||||
if(vbo == 0) { vbo = gl.GenBuffer(); }
|
||||
if(ebo == 0) { ebo = gl.GenBuffer(); }
|
||||
|
||||
Mesh.PrepareForRendering();
|
||||
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)
|
||||
{
|
||||
|
||||
@@ -4,9 +4,12 @@ using Silk.NET.OpenGL;
|
||||
|
||||
namespace EngineSharp.Core.Rendering;
|
||||
|
||||
// Do the following to not JIT compile the shader:
|
||||
// use the file paths as an index to a dictionary; the dictionary stores the programID to the already compiled shader
|
||||
// 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;
|
||||
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;
|
||||
|
||||
public Shader(GL openGLContext, string pathToVertexShader, string pathToFragmentShader)
|
||||
@@ -21,36 +24,36 @@ public class Shader
|
||||
_shaderProgramId = CreateProgram(vertexShader, fragmentShader);
|
||||
}
|
||||
|
||||
public void Use() => _gl.UseProgram(_shaderProgramId);
|
||||
internal void Use() => _gl.UseProgram(_shaderProgramId);
|
||||
|
||||
#region Set uniforms
|
||||
public void SetInt(string name, int value)
|
||||
internal void SetInt(string name, int value)
|
||||
{
|
||||
_gl.Uniform1(_gl.GetUniformLocation(_shaderProgramId, name), value);
|
||||
}
|
||||
|
||||
public void SetFloat(string name, float value)
|
||||
internal void SetFloat(string name, float value)
|
||||
{
|
||||
_gl.Uniform1(_gl.GetUniformLocation(_shaderProgramId, name), value);
|
||||
}
|
||||
|
||||
public void SetVector(string name, Vector3D<double> value)
|
||||
internal void SetVector(string name, Vector3D<double> value)
|
||||
{
|
||||
_gl.Uniform3(_gl.GetUniformLocation(_shaderProgramId, name), value.X, value.Y, value.Z);
|
||||
}
|
||||
public void SetVector(string name, Vector3D<float> value)
|
||||
internal void SetVector(string name, Vector3D<float> value)
|
||||
{
|
||||
_gl.Uniform3(_gl.GetUniformLocation(_shaderProgramId, name), value.X, value.Y, value.Z);
|
||||
}
|
||||
|
||||
public void SetMatrix(string name, Matrix4X4<double> matrix)
|
||||
internal void SetMatrix(string name, Matrix4X4<double> matrix)
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
_gl.UniformMatrix4(_gl.GetUniformLocation(_shaderProgramId, name), 1, false, (double*) &matrix);
|
||||
}
|
||||
}
|
||||
public void SetMatrix(string name, Matrix4X4<float> matrix)
|
||||
internal void SetMatrix(string name, Matrix4X4<float> matrix)
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
@@ -61,9 +64,9 @@ public class Shader
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Compiles the given shadercode.
|
||||
/// Compiles the given shader code.
|
||||
/// </summary>
|
||||
/// <param name="shaderCode">The shadercode</param>
|
||||
/// <param name="shaderCode">The shader code</param>
|
||||
/// <param name="shaderType">The type of shader to compile</param>
|
||||
/// <returns>Returns the id of the compiled shader.</returns>
|
||||
/// <exception cref="ShaderCompileException"></exception>
|
||||
|
||||
@@ -6,6 +6,8 @@ namespace Engine_silk.NET;
|
||||
|
||||
public class IcoSphere
|
||||
{
|
||||
public required Material Material { get; set; }
|
||||
|
||||
private readonly IcoSphereGenerator _generator = new();
|
||||
|
||||
public required int Resolution
|
||||
@@ -25,7 +27,10 @@ public class IcoSphere
|
||||
|
||||
public Mesh CreateSphere()
|
||||
{
|
||||
var mesh = new Mesh();
|
||||
var mesh = new Mesh
|
||||
{
|
||||
Material = Material,
|
||||
};
|
||||
_generator.Generate(Resolution);
|
||||
|
||||
mesh.Vertices = _generator.Vertices;
|
||||
|
||||
@@ -20,9 +20,16 @@ static class Program
|
||||
var engine = EngineFactory.Create(GraphicsAPI.OpenGL, options);
|
||||
var mainScene = engine.CreateScene();
|
||||
var cube = mainScene.CreateEntity("cube");
|
||||
|
||||
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
|
||||
Resolution = 10,
|
||||
Material = material,
|
||||
};
|
||||
var cubeMeshRenderer = new MeshRenderer
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user