Skip to content

Commit

Permalink
Added Renderable and SimpleRenderSystem
Browse files Browse the repository at this point in the history
  • Loading branch information
MrScautHD committed Jul 21, 2024
1 parent 0612ead commit 5091897
Show file tree
Hide file tree
Showing 7 changed files with 182 additions and 28 deletions.
43 changes: 19 additions & 24 deletions src/Bliss.Test/Game.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,16 @@ public Game() {
public void Run() {
Logger.Info("Hello World! Bliss start...");

this.Vk = Vk.GetApi();
Logger.Info("Initialize Vulkan...");
this.Vk = Vk.GetApi();

Logger.Info("Initialize Window...");
this.Window = SilkWindow.Create(WindowOptions.DefaultVulkan with {
Title = "Test Game!",
Size = new Vector2D<int>(1270, 720)
});

this.Window.Load += this.Init;
this.Window.Update += this.Update;

this.Window.Update += this.RunLoop;
this.Window.Render += this.Draw;

this.Window.Initialize();
Expand All @@ -49,30 +49,27 @@ public void Run() {
throw new PlatformNotSupportedException("Windowing platform doesn't support Vulkan.");
}

Logger.Info("Initialize Window...");

this.Device = new BlissDevice(this.Vk, this.Window);
Logger.Info("Initialize Device...");
this.Device = new BlissDevice(this.Vk, this.Window);

this.Renderer = new BlissRenderer(this.Vk, this.Window, this.Device, false);
Logger.Info("Initialize Renderer...");
this.Renderer = new BlissRenderer(this.Vk, this.Window, this.Device, false);

Logger.Info("Initialize Global Pool...");
this.GlobalPool = new BlissDescriptorPoolBuilder(this.Vk, this.Device)
.SetMaxSets(BlissSwapChain.MaxDefaultFramesInFlight)
.AddSize(DescriptorType.UniformBuffer, BlissSwapChain.MaxDefaultFramesInFlight)
.Build();
Logger.Info("Initialize Global Pool...");

this.Init();

Logger.Info("Start main Loop...");
this.Window.Run();
this.Vk.DeviceWaitIdle(this.Device.GetVkDevice());
}

protected virtual void Init() {

}

protected virtual void Update(double delta) {

protected virtual void RunLoop(double delta) {
this.Update(delta);
this.AfterUpdate(delta);

this._timer += delta;
Expand All @@ -82,17 +79,15 @@ protected virtual void Update(double delta) {
}
}

protected virtual void AfterUpdate(double delta) {

}
protected virtual void Init() { }

protected virtual void FixedUpdate() {

}
protected virtual void Update(double delta) { }

protected virtual void Draw(double delta) {

}
protected virtual void AfterUpdate(double delta) { }

protected virtual void FixedUpdate() { }

protected virtual void Draw(double delta) { }

protected override void Dispose(bool disposing) {
if (disposing) {
Expand Down
22 changes: 22 additions & 0 deletions src/Bliss/CSharp/Rendering/Renderable.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using Bliss.CSharp.Colors;
using Bliss.CSharp.Geometry;
using Bliss.CSharp.Transformations;

namespace Bliss.CSharp.Rendering;

public class Renderable {

public Model Model;
public Color Color;
public Transform Transform;

public readonly uint Id;
private static uint _ids;

public Renderable(Model model, Color color, Transform transform) {
this.Id = ++_ids;
this.Model = model;
this.Color = color;
this.Transform = transform;
}
}
17 changes: 17 additions & 0 deletions src/Bliss/CSharp/Rendering/Systems/SimplePushConstantData.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using System.Numerics;

namespace Bliss.CSharp.Rendering.Systems;

public struct SimplePushConstantData {

public Matrix4x4 ModelMatrix;
public Matrix4x4 NormalMatrix;

/// <summary>
/// Represents a container class for simple push constant data used in rendering systems.
/// </summary>
public SimplePushConstantData() {
this.ModelMatrix = Matrix4x4.Identity;
this.NormalMatrix = Matrix4x4.Identity;
}
}
86 changes: 86 additions & 0 deletions src/Bliss/CSharp/Rendering/Systems/SimpleRenderSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
using System.Diagnostics;
using System.Runtime.InteropServices;
using Bliss.CSharp.Rendering.Vulkan;
using Silk.NET.Vulkan;

namespace Bliss.CSharp.Rendering.Systems;

public class SimpleRenderSystem : Disposable {

public readonly Vk Vk;
public readonly BlissDevice Device;

private BlissPipeline _pipeline;
private PipelineLayout _pipelineLayout;

public SimpleRenderSystem(Vk vk, BlissDevice device, RenderPass renderPass, DescriptorSetLayout globalSetLayout) {

Check warning on line 16 in src/Bliss/CSharp/Rendering/Systems/SimpleRenderSystem.cs

View workflow job for this annotation

GitHub Actions / build

Non-nullable field '_pipeline' must contain a non-null value when exiting constructor. Consider declaring the field as nullable.
this.Vk = vk;
this.Device = device;

this.CreatePipelineLayout(globalSetLayout);
this.CreatePipeline(renderPass);
}

public unsafe void Render(FrameInfo frameInfo) {
this._pipeline.Bind(frameInfo.CommandBuffer);
this.Vk.CmdBindDescriptorSets(frameInfo.CommandBuffer, PipelineBindPoint.Graphics, this._pipelineLayout, 0, 1, frameInfo.GlobalDescriptorSet, 0, null);

Check warning on line 26 in src/Bliss/CSharp/Rendering/Systems/SimpleRenderSystem.cs

View workflow job for this annotation

GitHub Actions / build

Argument 6 should be passed with 'ref' or 'in' keyword

foreach (Renderable renderable in frameInfo.RenderableObjects) {
SimplePushConstantData push = new() {
ModelMatrix = renderable.Transform.GetMatrix(),
NormalMatrix = renderable.Transform.GetNormalMatrix()
};

this.Vk.CmdPushConstants(frameInfo.CommandBuffer, this._pipelineLayout, ShaderStageFlags.VertexBit | ShaderStageFlags.FragmentBit, 0, (uint) Marshal.SizeOf<SimplePushConstantData>(), ref push);

renderable.Model.Bind(frameInfo.CommandBuffer);
renderable.Model.Draw(frameInfo.CommandBuffer);
}
}

private unsafe void CreatePipelineLayout(DescriptorSetLayout globalSetLayout) {
DescriptorSetLayout[] descriptorSetLayouts = new DescriptorSetLayout[] {
globalSetLayout
};

PushConstantRange pushConstantRange = new() {
StageFlags = ShaderStageFlags.VertexBit | ShaderStageFlags.FragmentBit,
Offset = 0,
Size = (uint) Marshal.SizeOf<SimplePushConstantData>()
};

fixed (DescriptorSetLayout* descriptorSetLayoutPtr = descriptorSetLayouts) {
PipelineLayoutCreateInfo pipelineLayoutInfo = new() {
SType = StructureType.PipelineLayoutCreateInfo,
SetLayoutCount = (uint) descriptorSetLayouts.Length,
PSetLayouts = descriptorSetLayoutPtr,
PushConstantRangeCount = 1,
PPushConstantRanges = &pushConstantRange,
};

if (this.Vk.CreatePipelineLayout(this.Device.GetVkDevice(), pipelineLayoutInfo, null, out this._pipelineLayout) != Result.Success) {

Check warning on line 61 in src/Bliss/CSharp/Rendering/Systems/SimpleRenderSystem.cs

View workflow job for this annotation

GitHub Actions / build

Argument 2 should be passed with 'ref' or 'in' keyword
throw new Exception("Failed to create pipeline layout!");
}
}
}

private void CreatePipeline(RenderPass renderPass) {
Debug.Assert(this._pipelineLayout.Handle != 0, "Cannot create pipeline before pipeline layout");

PipelineConfigInfo pipelineConfig = new();
BlissPipeline.GetDefaultPipelineConfigInfo(ref pipelineConfig);
BlissPipeline.EnableMultiSampling(ref pipelineConfig, this.Device.MsaaSamples);

pipelineConfig.RenderPass = renderPass;
pipelineConfig.PipelineLayout = this._pipelineLayout;

this._pipeline = new BlissPipeline(this.Vk, this.Device, "simpleShader.vert.spv", "simpleShader.frag.spv", pipelineConfig);
}

protected override unsafe void Dispose(bool disposing) {
if (disposing) {
this._pipeline.Dispose();
this.Vk.DestroyPipelineLayout(this.Device.GetVkDevice(), this._pipelineLayout, null);
}
}
}
2 changes: 1 addition & 1 deletion src/Bliss/CSharp/Rendering/Vulkan/BlissPipeline.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public BlissPipeline(Vk vk, BlissDevice device, string vertPath, string fragPath
/// Retrieves the default pipeline configuration information.
/// </summary>
/// <param name="configInfo">The pipeline configuration information.</param>
public unsafe void GetDefaultPipelineConfigInfo(ref PipelineConfigInfo configInfo) {
public static unsafe void GetDefaultPipelineConfigInfo(ref PipelineConfigInfo configInfo) {
configInfo.InputAssemblyInfo.SType = StructureType.PipelineInputAssemblyStateCreateInfo;
configInfo.InputAssemblyInfo.Topology = PrimitiveTopology.TriangleList;
configInfo.InputAssemblyInfo.PrimitiveRestartEnable = Vk.False;
Expand Down
4 changes: 2 additions & 2 deletions src/Bliss/CSharp/Rendering/Vulkan/FrameInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@ public struct FrameInfo {
public float FrameTime;
public CommandBuffer CommandBuffer;
public ICam Camera;
public DescriptorSet DescriptorSet;
//public Dictionary<uint, Renderable> RenderObjects;
public DescriptorSet GlobalDescriptorSet;
public List<Renderable> RenderableObjects;
}
36 changes: 35 additions & 1 deletion src/Bliss/CSharp/Transformations/Transform.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ public struct Transform {
/// <summary>
/// Represents the position of an object in 3D space.
/// </summary>
public Vector3 Position;
public Vector3 Translation;

/// <summary>
/// Represents the rotation of an object in 3D space.
Expand All @@ -18,4 +18,38 @@ public struct Transform {
/// Represents the scale of an object in 3D space.
/// </summary>
public Vector3 Scale;

/// <summary>
/// Initializes a new instance of the <see cref="Transform"/> class with default values.
/// </summary>
public Transform() {
this.Translation = Vector3.Zero;
this.Rotation = Quaternion.Identity;
this.Scale = Vector3.Zero;
}

/// <summary>
/// Returns the transformation matrix for the current Transform object.
/// </summary>
/// <returns>The transformation matrix.</returns>
public Matrix4x4 GetMatrix() {
Matrix4x4 matTranslate = Matrix4x4.CreateTranslation(this.Translation);
Matrix4x4 matRot = Matrix4x4.CreateFromQuaternion(this.Rotation);
Matrix4x4 matScale = Matrix4x4.CreateScale(this.Scale);

return matTranslate * matRot * matScale;
}

/// <summary>
/// Returns the normal transformation matrix for the current Transform object.
/// </summary>
/// <returns>The normal transformation matrix.</returns>
public Matrix4x4 GetNormalMatrix() {
Vector3 invScale = new Vector3(1.0F / this.Scale.X, 1.0F / this.Scale.Y, 1.0F / this.Scale.Z);

Matrix4x4 matScale = Matrix4x4.CreateScale(invScale);
Matrix4x4 matRot = Matrix4x4.CreateFromQuaternion(this.Rotation);

return matScale * matRot;
}
}

0 comments on commit 5091897

Please sign in to comment.