diff --git a/src/Bliss.Test/Game.cs b/src/Bliss.Test/Game.cs
index 9b2bbfc..15b00da 100644
--- a/src/Bliss.Test/Game.cs
+++ b/src/Bliss.Test/Game.cs
@@ -98,7 +98,10 @@ public void Run() {
this.SetTargetFps(this.Settings.TargetFps);
Logger.Info("Initialize command list...");
- this.CommandList = this.GraphicsDevice.ResourceFactory.CreateCommandList();
+ this.CommandList = graphicsDevice.ResourceFactory.CreateCommandList();
+
+ Logger.Info("Initialize global resources...");
+ GlobalResource.Init(graphicsDevice);
Logger.Info("Initialize input...");
if (this.MainWindow is Sdl3Window) {
@@ -133,7 +136,7 @@ public void Run() {
this._fixedUpdateTimer -= this._fixedUpdateTimeStep;
}
- this.Draw(this.GraphicsDevice, this.CommandList);
+ this.Draw(graphicsDevice, this.CommandList);
Input.End();
}
@@ -217,7 +220,7 @@ protected virtual void Draw(GraphicsDevice graphicsDevice, CommandList commandLi
commandList.ResolveTexture(this.FullScreenTexture.ColorTexture, this.FullScreenTexture.DestinationTexture);
}
- commandList.SetFramebuffer(this.GraphicsDevice.SwapchainFramebuffer);
+ commandList.SetFramebuffer(graphicsDevice.SwapchainFramebuffer);
commandList.ClearColorTarget(0, Color.DarkGray.ToRgbaFloat());
this.FullScreenRenderPass.Draw(commandList, this.FullScreenTexture, SamplerType.Point);
@@ -249,6 +252,10 @@ protected override void Dispose(bool disposing) {
this.GraphicsDevice.Dispose();
this.MainWindow.Dispose();
Input.Destroy();
+ GlobalResource.Destroy();
+
+ this._playerModel.Dispose();
+ this._planeModel.Dispose();
}
}
}
\ No newline at end of file
diff --git a/src/Bliss/CSharp/Effects/Effect.cs b/src/Bliss/CSharp/Effects/Effect.cs
index ff8363f..25b51ce 100644
--- a/src/Bliss/CSharp/Effects/Effect.cs
+++ b/src/Bliss/CSharp/Effects/Effect.cs
@@ -6,6 +6,7 @@
* https://github.com/MrScautHD/Bliss/blob/main/LICENSE
*/
+using Bliss.CSharp.Graphics.Pipelines;
using Bliss.CSharp.Logging;
using Veldrid;
using Veldrid.SPIRV;
@@ -14,6 +15,11 @@ namespace Bliss.CSharp.Effects;
public class Effect : Disposable {
+ ///
+ /// The graphics device used for creating and managing graphical resources.
+ ///
+ public GraphicsDevice GraphicsDevice { get; private set; }
+
///
/// Represents a pair of shaders consisting of a vertex shader and a fragment shader.
///
@@ -25,31 +31,40 @@ public class Effect : Disposable {
public readonly VertexLayoutDescription VertexLayout;
///
- /// Initializes a new instance of the class by loading and compiling shaders and setting up the vertex layout.
+ /// A cache of pipelines created for specific pipeline descriptions, enabling reuse.
///
- /// The resource factory used to create GPU resources.
- /// The vertex layout description to be used with this effect.
+ private Dictionary _cachedPipelines;
+
+ ///
+ /// Initializes a new instance of the class by loading shaders from file paths.
+ ///
+ /// The graphics device used for creating resources.
+ /// The vertex layout description for the pipeline.
/// The file path to the vertex shader source code.
/// The file path to the fragment shader source code.
- public Effect(ResourceFactory resourceFactory, VertexLayoutDescription vertexLayout, string vertPath, string fragPath) : this(resourceFactory, vertexLayout, LoadBytecode(vertPath), LoadBytecode(fragPath)) { }
-
+ public Effect(GraphicsDevice graphicsDevice, VertexLayoutDescription vertexLayout, string vertPath, string fragPath) : this(graphicsDevice, vertexLayout, LoadBytecode(vertPath), LoadBytecode(fragPath)) { }
+
///
- /// Initializes a new instance of the class with the specified vertex layout and shader bytecode.
+ /// Initializes a new instance of the class with precompiled shader bytecode.
///
- /// The resource factory used to create shaders and resources.
- /// The layout of the vertex data for this effect.
- /// A byte array containing the vertex shader bytecode.
- /// A byte array containing the fragment shader bytecode.
- public Effect(ResourceFactory resourceFactory, VertexLayoutDescription vertexLayout, byte[] vertBytes, byte[] fragBytes) {
+ /// The graphics device used for creating resources.
+ /// The vertex layout description for the pipeline.
+ /// The bytecode for the vertex shader.
+ /// The bytecode for the fragment shader.
+ public Effect(GraphicsDevice graphicsDevice, VertexLayoutDescription vertexLayout, byte[] vertBytes, byte[] fragBytes) {
+ this.GraphicsDevice = graphicsDevice;
+
ShaderDescription vertDescription = new ShaderDescription(ShaderStages.Vertex, vertBytes, "main");
ShaderDescription fragDescription = new ShaderDescription(ShaderStages.Fragment, fragBytes, "main");
- Shader[] shaders = resourceFactory.CreateFromSpirv(vertDescription, fragDescription);
+ Shader[] shaders = graphicsDevice.ResourceFactory.CreateFromSpirv(vertDescription, fragDescription);
this.Shader.Item1 = shaders[0];
this.Shader.Item2 = shaders[1];
this.VertexLayout = vertexLayout;
+
+ this._cachedPipelines = new Dictionary();
}
///
@@ -69,9 +84,26 @@ private static byte[] LoadBytecode(string path) {
Logger.Info($"Shader bytes loaded successfully from path: [{path}]");
return File.ReadAllBytes(path);
}
+
+ ///
+ /// Retrieves or creates a pipeline for the given pipeline description.
+ ///
+ /// The description of the pipeline to retrieve or create.
+ /// A configured with the specified description.
+ public SimplePipeline GetPipeline(SimplePipelineDescription pipelineDescription) {
+ if (!this._cachedPipelines.TryGetValue(pipelineDescription, out SimplePipeline? pipeline)) {
+ SimplePipeline newPipeline = new SimplePipeline(this.GraphicsDevice, pipelineDescription);
+
+ Logger.Error(pipelineDescription.ToString());
+
+ this._cachedPipelines.Add(pipelineDescription, newPipeline);
+ return newPipeline;
+ }
+
+ return pipeline;
+ }
// TODO: Adding Location system, for Material(Texture, Color) and in generel for buffers...
-
// TODO: ADD MATERIAL param here.
///
/// Apply the state effect immediately before rendering it.
@@ -82,6 +114,10 @@ protected override void Dispose(bool disposing) {
if (disposing) {
this.Shader.Item1.Dispose();
this.Shader.Item2.Dispose();
+
+ foreach (SimplePipeline pipeline in this._cachedPipelines.Values) {
+ pipeline.Dispose();
+ }
}
}
}
\ No newline at end of file
diff --git a/src/Bliss/CSharp/Geometry/Animations/Keyframes/QuatKey.cs b/src/Bliss/CSharp/Geometry/Animations/Keyframes/QuatKey.cs
index 03018f5..e7bf861 100644
--- a/src/Bliss/CSharp/Geometry/Animations/Keyframes/QuatKey.cs
+++ b/src/Bliss/CSharp/Geometry/Animations/Keyframes/QuatKey.cs
@@ -1,3 +1,11 @@
+/*
+ * Copyright (c) 2024 Elias Springer (@MrScautHD)
+ * License-Identifier: Bliss License 1.0
+ *
+ * For full license details, see:
+ * https://github.com/MrScautHD/Bliss/blob/main/LICENSE
+ */
+
using System.Numerics;
namespace Bliss.CSharp.Geometry.Animations.Keyframes;
diff --git a/src/Bliss/CSharp/Geometry/Animations/Keyframes/Vector3Key.cs b/src/Bliss/CSharp/Geometry/Animations/Keyframes/Vector3Key.cs
index 78ba972..5841be5 100644
--- a/src/Bliss/CSharp/Geometry/Animations/Keyframes/Vector3Key.cs
+++ b/src/Bliss/CSharp/Geometry/Animations/Keyframes/Vector3Key.cs
@@ -1,3 +1,11 @@
+/*
+ * Copyright (c) 2024 Elias Springer (@MrScautHD)
+ * License-Identifier: Bliss License 1.0
+ *
+ * For full license details, see:
+ * https://github.com/MrScautHD/Bliss/blob/main/LICENSE
+ */
+
using System.Numerics;
namespace Bliss.CSharp.Geometry.Animations.Keyframes;
diff --git a/src/Bliss/CSharp/Geometry/Animations/MeshAmateurBuilder.cs b/src/Bliss/CSharp/Geometry/Animations/MeshAmateurBuilder.cs
index c719f09..0288c61 100644
--- a/src/Bliss/CSharp/Geometry/Animations/MeshAmateurBuilder.cs
+++ b/src/Bliss/CSharp/Geometry/Animations/MeshAmateurBuilder.cs
@@ -218,8 +218,8 @@ private Matrix4x4 InterpolateScale(NodeAnimChannel channel, ModelAnimation anima
}
}
- Vector3Key currentFrame = channel.Scales[(int)frameIndex];
- Vector3Key nextFrame = channel.Scales[(int)((frameIndex + 1) % channel.Scales.Count)];
+ Vector3Key currentFrame = channel.Scales[(int) frameIndex];
+ Vector3Key nextFrame = channel.Scales[(int) ((frameIndex + 1) % channel.Scales.Count)];
double delta = (frameTime - currentFrame.Time) / (nextFrame.Time - currentFrame.Time);
diff --git a/src/Bliss/CSharp/Geometry/Animations/NodeAnimChannel.cs b/src/Bliss/CSharp/Geometry/Animations/NodeAnimChannel.cs
index d4a45cb..ecadc5d 100644
--- a/src/Bliss/CSharp/Geometry/Animations/NodeAnimChannel.cs
+++ b/src/Bliss/CSharp/Geometry/Animations/NodeAnimChannel.cs
@@ -1,3 +1,11 @@
+/*
+ * Copyright (c) 2024 Elias Springer (@MrScautHD)
+ * License-Identifier: Bliss License 1.0
+ *
+ * For full license details, see:
+ * https://github.com/MrScautHD/Bliss/blob/main/LICENSE
+ */
+
using Bliss.CSharp.Geometry.Animations.Keyframes;
namespace Bliss.CSharp.Geometry.Animations;
diff --git a/src/Bliss/CSharp/Geometry/Mesh.cs b/src/Bliss/CSharp/Geometry/Mesh.cs
index 6379c7e..93fb42e 100644
--- a/src/Bliss/CSharp/Geometry/Mesh.cs
+++ b/src/Bliss/CSharp/Geometry/Mesh.cs
@@ -24,12 +24,6 @@ namespace Bliss.CSharp.Geometry;
public class Mesh : Disposable {
- ///
- /// A dictionary that caches instances of SimplePipeline based on Material keys.
- /// This helps in reusing pipeline configurations for materials, enhancing rendering performance and reducing redundant pipeline creation.
- ///
- private static Dictionary _cachedPipelines = new(); // TODO: Take care of disposing it idk maybe a system that checks if its the last mesh that using it and dispose it with it.
-
///
/// Represents the graphics device used for rendering operations.
/// This property provides access to the underlying GraphicsDevice instance responsible for managing GPU resources and executing rendering commands.
@@ -101,6 +95,13 @@ public class Mesh : Disposable {
/// This buffer holds an array of structures representing bone matrices and is utilized during rendering to apply bone transformations to vertices.
///
private SimpleBuffer _boneBuffer;
+
+ ///
+ /// Defines the characteristics of the rendering pipeline used by the mesh.
+ /// This field specifies the pipeline configurations such as blending, depth stencil, rasterizer state,
+ /// primitive topology, associated buffers, texture layouts, shader set, and output descriptions.
+ ///
+ private SimplePipelineDescription _pipelineDescription;
///
/// Initializes a new instance of the class with the specified properties.
@@ -138,6 +139,8 @@ public Mesh(GraphicsDevice graphicsDevice, Material material, Vertex3D[]? vertic
}
this._boneBuffer.UpdateBufferImmediate();
+
+ this._pipelineDescription = this.CreatePipelineDescription();
}
///
@@ -191,6 +194,11 @@ public void Draw(CommandList commandList, OutputDescription output, Transform tr
this._modelMatrixBuffer.SetValue(1, cam3D.GetView());
this._modelMatrixBuffer.SetValue(2, transform.GetTransform());
this._modelMatrixBuffer.UpdateBuffer(commandList);
+
+ // Update pipeline description.
+ this._pipelineDescription.BlendState = this.Material.BlendState.Description;
+ this._pipelineDescription.TextureLayouts = this.Material.GetTextureLayouts();
+ this._pipelineDescription.Outputs = output;
if (this.IndexCount > 0) {
@@ -199,7 +207,7 @@ public void Draw(CommandList commandList, OutputDescription output, Transform tr
commandList.SetIndexBuffer(this._indexBuffer, IndexFormat.UInt32);
// Set pipeline.
- commandList.SetPipeline(this.GetOrCreatePipeline(this.Material, output).Pipeline);
+ commandList.SetPipeline(this.Material.Effect.GetPipeline(this._pipelineDescription).Pipeline);
// Set projection view buffer.
commandList.SetGraphicsResourceSet(0, this._modelMatrixBuffer.ResourceSet);
@@ -226,7 +234,7 @@ public void Draw(CommandList commandList, OutputDescription output, Transform tr
commandList.SetVertexBuffer(0, this._vertexBuffer);
// Set pipeline.
- commandList.SetPipeline(this.GetOrCreatePipeline(this.Material, output).Pipeline);
+ commandList.SetPipeline(this.Material.Effect.GetPipeline(this._pipelineDescription).Pipeline);
// Set projection view buffer.
commandList.SetGraphicsResourceSet(0, this._modelMatrixBuffer.ResourceSet);
@@ -252,49 +260,35 @@ public void Draw(CommandList commandList, OutputDescription output, Transform tr
this.Material.SetMapColor(MaterialMapType.Albedo.ToString(), cachedColor);
}
- ///
- /// Retrieves an existing pipeline associated with the given material and output description, or creates a new one if it doesn't exist.
- ///
- /// The material associated with the pipeline.
- /// The output description for the pipeline.
- /// A pipeline that matches the specified material and output description.
- private SimplePipeline GetOrCreatePipeline(Material material, OutputDescription output) {
- if (!_cachedPipelines.TryGetValue(material, out SimplePipeline? pipeline)) {
- SimplePipeline newPipeline = new SimplePipeline(this.GraphicsDevice, new SimplePipelineDescription() {
- BlendState = material.BlendState.Description,
- DepthStencilState = new DepthStencilStateDescription(true, true, ComparisonKind.LessEqual),
- RasterizerState = new RasterizerStateDescription() {
- CullMode = FaceCullMode.Back,
- FillMode = PolygonFillMode.Solid,
- FrontFace = FrontFace.Clockwise,
- DepthClipEnabled = true,
- ScissorTestEnabled = false
- },
- PrimitiveTopology = PrimitiveTopology.TriangleList,
- Buffers = [
- this._modelMatrixBuffer,
- this._boneBuffer
+ private SimplePipelineDescription CreatePipelineDescription() {
+ return new SimplePipelineDescription() {
+ BlendState = this.Material.BlendState.Description,
+ DepthStencilState = new DepthStencilStateDescription(true, true, ComparisonKind.LessEqual),
+ RasterizerState = new RasterizerStateDescription() {
+ CullMode = FaceCullMode.Back,
+ FillMode = PolygonFillMode.Solid,
+ FrontFace = FrontFace.Clockwise,
+ DepthClipEnabled = true,
+ ScissorTestEnabled = false
+ },
+ PrimitiveTopology = PrimitiveTopology.TriangleList,
+ Buffers = [
+ this._modelMatrixBuffer,
+ this._boneBuffer
+ ],
+ TextureLayouts = this.Material.GetTextureLayouts(),
+ ShaderSet = new ShaderSetDescription() {
+ VertexLayouts = [
+ this.Material.Effect.VertexLayout
],
- TextureLayouts = material.GetTextureLayouts(),
- ShaderSet = new ShaderSetDescription() {
- VertexLayouts = [
- material.Effect.VertexLayout
- ],
- Shaders = [
- material.Effect.Shader.Item1,
- material.Effect.Shader.Item2
- ]
- },
- Outputs = output
- });
-
- _cachedPipelines.Add(material, newPipeline);
- return newPipeline;
- }
-
- return pipeline;
+ Shaders = [
+ this.Material.Effect.Shader.Item1,
+ this.Material.Effect.Shader.Item2
+ ]
+ }
+ };
}
-
+
///
/// Calculates the bounding box for the current mesh based on its vertices.
///
diff --git a/src/Bliss/CSharp/Geometry/Model.cs b/src/Bliss/CSharp/Geometry/Model.cs
index f5c6904..42ea848 100644
--- a/src/Bliss/CSharp/Geometry/Model.cs
+++ b/src/Bliss/CSharp/Geometry/Model.cs
@@ -62,18 +62,6 @@ public class Model : Disposable {
new FBXImportCamerasConfig(false),
new FBXStrictModeConfig(false)
];
-
- ///
- /// The default effect applied to models.
- /// This is instantiated with shaders for rendering models, and includes configuration for vertex layout.
- ///
- private static Effect? _defaultEffect;
-
- ///
- /// The default texture used when no other texture is specified.
- /// Typically a 1x1 pixel texture with a solid color.
- ///
- private static Texture2D? _defaultTexture;
///
/// The graphics device used for rendering the model.
@@ -126,7 +114,6 @@ public static Model Load(GraphicsDevice graphicsDevice, string path, bool loadMa
}
Scene scene = context.ImportFile(path, DefaultPostProcessSteps);
-
List meshes = new List();
List animations = new List();
@@ -181,11 +168,11 @@ public static Model Load(GraphicsDevice graphicsDevice, string path, bool loadMa
ShaderMaterialProperties shaderProperties = aMaterial.Shaders;
if (shaderProperties.HasVertexShader && shaderProperties.HasFragmentShader) {
- effect = new Effect(graphicsDevice.ResourceFactory, Vertex3D.VertexLayout, Encoding.UTF8.GetBytes(shaderProperties.VertexShader), Encoding.UTF8.GetBytes(shaderProperties.FragmentShader));
+ effect = new Effect(graphicsDevice, Vertex3D.VertexLayout, Encoding.UTF8.GetBytes(shaderProperties.VertexShader), Encoding.UTF8.GetBytes(shaderProperties.FragmentShader));
}
}
- effect ??= GetDefaultEffect(graphicsDevice);
+ effect ??= GlobalResource.DefaultModelEffect;
// Load material maps.
Material material = new Material(graphicsDevice, effect);
@@ -240,7 +227,7 @@ public static Model Load(GraphicsDevice graphicsDevice, string path, bool loadMa
}
else {
material.AddMaterialMap(MaterialMapType.Albedo.ToString(), new MaterialMap() {
- Texture = GetDefaultTexture(graphicsDevice),
+ Texture = GlobalResource.DefaultModelTexture,
Color = Color.White
});
}
@@ -322,32 +309,6 @@ public static Model Load(GraphicsDevice graphicsDevice, string path, bool loadMa
return new Model(graphicsDevice, meshes.ToArray(), animations.ToArray());
}
- ///
- /// Retrieves the default effect for the model.
- /// If the default effect is not already created, it initializes a new with the specified graphics device.
- ///
- /// The graphics device used to create the default effect.
- /// The default for the model.
- private static Effect GetDefaultEffect(GraphicsDevice graphicsDevice) { // TODO: Take care to dispose it!
- return _defaultEffect ??= new Effect(graphicsDevice.ResourceFactory, Vertex3D.VertexLayout, "content/shaders/default_model.vert", "content/shaders/default_model.frag");
- }
-
- ///
- /// Retrieves the default texture for the specified graphics device.
- ///
- /// The graphics device to associate with the default texture.
- /// Returns a new instance of the class with a default solid color texture.
- private static Texture2D GetDefaultTexture(GraphicsDevice graphicsDevice) { // TODO: Take care to dispose it!
- if (_defaultTexture != null) {
- return _defaultTexture;
- }
- else {
- using (Image image = new Image(1, 1, new Rgba32(128, 128, 128, 255))) {
- return _defaultTexture ??= new Texture2D(graphicsDevice, image);
- }
- }
- }
-
///
/// Loads a texture from a material and returns it as a Texture2D object. If the texture is embedded, it extracts from the embedded data.
///
diff --git a/src/Bliss/CSharp/GlobalResource.cs b/src/Bliss/CSharp/GlobalResource.cs
new file mode 100644
index 0000000..5f78654
--- /dev/null
+++ b/src/Bliss/CSharp/GlobalResource.cs
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2024 Elias Springer (@MrScautHD)
+ * License-Identifier: Bliss License 1.0
+ *
+ * For full license details, see:
+ * https://github.com/MrScautHD/Bliss/blob/main/LICENSE
+ */
+
+using Bliss.CSharp.Effects;
+using Bliss.CSharp.Graphics.VertexTypes;
+using Bliss.CSharp.Textures;
+using SixLabors.ImageSharp;
+using SixLabors.ImageSharp.PixelFormats;
+using Veldrid;
+
+namespace Bliss.CSharp;
+
+public static class GlobalResource {
+
+ ///
+ /// Provides access to the global graphics device used for rendering operations.
+ ///
+ public static GraphicsDevice GraphicsDevice { get; private set; }
+
+ ///
+ /// The default effect used for rendering 3D models.
+ ///
+ public static Effect DefaultModelEffect { get; private set; }
+
+ ///
+ /// The default texture used for rendering 3D models.
+ ///
+ public static Texture2D DefaultModelTexture { get; private set; }
+
+ ///
+ /// Initializes global resources.
+ ///
+ /// The graphics device to be used for resource creation and rendering.
+ public static void Init(GraphicsDevice graphicsDevice) {
+ GraphicsDevice = graphicsDevice;
+
+ // Default model effect.
+ DefaultModelEffect = new Effect(graphicsDevice, Vertex3D.VertexLayout, "content/shaders/default_model.vert", "content/shaders/default_model.frag");
+
+ // Default model texture.
+ using (Image image = new Image(1, 1, new Rgba32(128, 128, 128, 255))) {
+ DefaultModelTexture = new Texture2D(graphicsDevice, image);
+ }
+ }
+
+ ///
+ /// Releases and disposes of all global resources.
+ ///
+ public static void Destroy() {
+ DefaultModelEffect.Dispose();
+ DefaultModelTexture.Dispose();
+ }
+}
\ No newline at end of file
diff --git a/src/Bliss/CSharp/Graphics/Pipelines/SimplePipeline.cs b/src/Bliss/CSharp/Graphics/Pipelines/SimplePipeline.cs
index d7d9246..8e3cb68 100644
--- a/src/Bliss/CSharp/Graphics/Pipelines/SimplePipeline.cs
+++ b/src/Bliss/CSharp/Graphics/Pipelines/SimplePipeline.cs
@@ -76,6 +76,15 @@ public SimplePipeline(GraphicsDevice graphicsDevice, SimplePipelineDescription p
public ISimpleBuffer? GetBuffer(string name) {
return this.PipelineDescription.Buffers.FirstOrDefault(buffer => buffer.Name == name);
}
+
+ ///
+ /// Retrieves the texture layout associated with the specified name from the pipeline description.
+ ///
+ /// The name of the texture layout to retrieve.
+ /// The associated with the specified name, or null if no layout with the given name exists.
+ public SimpleTextureLayout? GetTextureLayout(string name) {
+ return this.PipelineDescription.TextureLayouts.FirstOrDefault(buffer => buffer.Name == name);
+ }
protected override void Dispose(bool disposing) {
if (disposing) {
diff --git a/src/Bliss/CSharp/Graphics/Pipelines/SimplePipelineDescription.cs b/src/Bliss/CSharp/Graphics/Pipelines/SimplePipelineDescription.cs
index 5074aad..d216e9f 100644
--- a/src/Bliss/CSharp/Graphics/Pipelines/SimplePipelineDescription.cs
+++ b/src/Bliss/CSharp/Graphics/Pipelines/SimplePipelineDescription.cs
@@ -12,7 +12,7 @@
namespace Bliss.CSharp.Graphics.Pipelines;
-public struct SimplePipelineDescription {
+public struct SimplePipelineDescription : IEquatable {
///
/// Defines the blend state configuration, controlling how colors are blended in the pipeline.
@@ -81,7 +81,7 @@ public SimplePipelineDescription(BlendStateDescription blendState, DepthStencilS
this.Outputs = outputs;
this.ResourceBindingModel = null;
}
-
+
///
/// Initializes a new instance of the struct.
///
@@ -89,4 +89,88 @@ public SimplePipelineDescription() {
this.Buffers = [];
this.TextureLayouts = [];
}
+
+ ///
+ /// Determines whether two instances are equal based on their properties.
+ ///
+ /// The first instance to compare.
+ /// The second instance to compare.
+ /// true if the instances are equal; otherwise, false.
+ public static bool operator ==(SimplePipelineDescription left, SimplePipelineDescription right) => left.Equals(right);
+
+ ///
+ /// Determines whether two instances are equal.
+ ///
+ /// The first to compare.
+ /// The second to compare.
+ /// True if both instances are equal; otherwise, false.
+ public static bool operator !=(SimplePipelineDescription left, SimplePipelineDescription right) => !left.Equals(right);
+
+ ///
+ /// Determines whether the current instance is equal to another specified instance.
+ ///
+ /// The other instance to compare with the current instance.
+ /// A boolean value indicating whether the two instances are equal.
+ public bool Equals(SimplePipelineDescription other) {
+ return this.BlendState.Equals(other.BlendState) &&
+ this.DepthStencilState.Equals(other.DepthStencilState) &&
+ this.RasterizerState.Equals(other.RasterizerState) &&
+ this.PrimitiveTopology == other.PrimitiveTopology &&
+ this.Buffers.Select(buffer => buffer.Name).SequenceEqual(other.Buffers.Select(buffer => buffer.Name)) &&
+ this.TextureLayouts.Select(layout => layout.Name).SequenceEqual(other.TextureLayouts.Select(layout => layout.Name)) &&
+ this.ShaderSet.Equals(other.ShaderSet) &&
+ this.Outputs.Equals(other.Outputs) &&
+ this.ResourceBindingModel == other.ResourceBindingModel;
+ }
+
+ ///
+ /// Determines whether the specified object is equal to the current instance.
+ ///
+ /// The object to compare with the current instance.
+ /// A boolean value indicating whether the specified object is equal to the current instance.
+ public override bool Equals(object? obj) {
+ return obj is SimplePipelineDescription other && this.Equals(other);
+ }
+
+ ///
+ /// Returns a hash code for this instance of .
+ ///
+ /// A 32-bit signed integer hash code that is representative of the object's current state and its members.
+ public override int GetHashCode() {
+ HashCode hashCode = new HashCode();
+ hashCode.Add(this.BlendState);
+ hashCode.Add(this.DepthStencilState);
+ hashCode.Add(this.RasterizerState);
+ hashCode.Add((int) this.PrimitiveTopology);
+
+ foreach (ISimpleBuffer buffer in this.Buffers) {
+ hashCode.Add(buffer.Name);
+ }
+
+ foreach (SimpleTextureLayout layout in this.TextureLayouts) {
+ hashCode.Add(layout.Name);
+ }
+
+ hashCode.Add(this.ShaderSet);
+ hashCode.Add(this.Outputs);
+ hashCode.Add(this.ResourceBindingModel);
+ return hashCode.ToHashCode();
+ }
+
+ ///
+ /// Returns a string representation of the instance, detailing its configuration and properties.
+ ///
+ /// A string that includes the blend state, depth-stencil state, rasterizer state, primitive topology, buffers, texture layouts, shader set, outputs, and resource binding model of the pipeline description.
+ public override string ToString() {
+ return $"SimplePipelineDescription: \n" +
+ $"\t> BlendState = {this.BlendState}, \n" +
+ $"\t> DepthStencilState = {this.DepthStencilState}, \n" +
+ $"\t> RasterizerState = {this.RasterizerState}, \n" +
+ $"\t> PrimitiveTopology = {this.PrimitiveTopology}, \n" +
+ $"\t> Buffers = [{string.Join(", ", this.Buffers.Select(buffer => buffer.Name))}], \n" +
+ $"\t> TextureLayouts = [{string.Join(", ", this.TextureLayouts.Select(layout => layout.Name))}], \n" +
+ $"\t> ShaderSet = {this.ShaderSet}, \n" +
+ $"\t> Outputs = {this.Outputs}, \n" +
+ $"\t> ResourceBindingModel = {(this.ResourceBindingModel.HasValue ? this.ResourceBindingModel.Value : "NULL")}";
+ }
}
\ No newline at end of file
diff --git a/src/Bliss/CSharp/Graphics/Rendering/Batches/Primitives/PrimitiveBatch.cs b/src/Bliss/CSharp/Graphics/Rendering/Batches/Primitives/PrimitiveBatch.cs
index 5b43bb9..3a08498 100644
--- a/src/Bliss/CSharp/Graphics/Rendering/Batches/Primitives/PrimitiveBatch.cs
+++ b/src/Bliss/CSharp/Graphics/Rendering/Batches/Primitives/PrimitiveBatch.cs
@@ -118,7 +118,7 @@ public PrimitiveBatch(GraphicsDevice graphicsDevice, IWindow window, OutputDescr
this.Capacity = capacity;
// Create effects.
- this._effect = new Effect(graphicsDevice.ResourceFactory, PrimitiveVertex2D.VertexLayout, "content/shaders/primitive.vert", "content/shaders/primitive.frag");
+ this._effect = new Effect(graphicsDevice, PrimitiveVertex2D.VertexLayout, "content/shaders/primitive.vert", "content/shaders/primitive.frag");
// Create projection view buffer.
this._projViewBuffer = new SimpleBuffer(graphicsDevice, "ProjectionViewBuffer", 2, SimpleBufferType.Uniform, ShaderStages.Vertex);
diff --git a/src/Bliss/CSharp/Graphics/Rendering/Batches/Sprites/SpriteBatch.cs b/src/Bliss/CSharp/Graphics/Rendering/Batches/Sprites/SpriteBatch.cs
index c6a374e..6580557 100644
--- a/src/Bliss/CSharp/Graphics/Rendering/Batches/Sprites/SpriteBatch.cs
+++ b/src/Bliss/CSharp/Graphics/Rendering/Batches/Sprites/SpriteBatch.cs
@@ -181,7 +181,7 @@ public SpriteBatch(GraphicsDevice graphicsDevice, IWindow window, OutputDescript
this._cachedPipelines = new Dictionary<(Effect, BlendState), SimplePipeline>();
// Create default effect.
- this._defaultEffect = new Effect(this.GraphicsDevice.ResourceFactory, SpriteVertex2D.VertexLayout, "content/shaders/sprite.vert", "content/shaders/sprite.frag");
+ this._defaultEffect = new Effect(graphicsDevice, SpriteVertex2D.VertexLayout, "content/shaders/sprite.vert", "content/shaders/sprite.frag");
// Create vertex buffer.
this._vertices = new SpriteVertex2D[capacity * VerticesPerQuad];
diff --git a/src/Bliss/CSharp/Graphics/Rendering/Passes/FullScreenRenderPass.cs b/src/Bliss/CSharp/Graphics/Rendering/Passes/FullScreenRenderPass.cs
index d59838e..35c2528 100644
--- a/src/Bliss/CSharp/Graphics/Rendering/Passes/FullScreenRenderPass.cs
+++ b/src/Bliss/CSharp/Graphics/Rendering/Passes/FullScreenRenderPass.cs
@@ -60,7 +60,7 @@ public FullScreenRenderPass(GraphicsDevice graphicsDevice, OutputDescription out
this.GraphicsDevice = graphicsDevice;
this.Output = output;
- this._effect = new Effect(graphicsDevice.ResourceFactory, SpriteVertex2D.VertexLayout, "content/shaders/full_screen_render_pass.vert", "content/shaders/full_screen_render_pass.frag");
+ this._effect = new Effect(graphicsDevice, SpriteVertex2D.VertexLayout, "content/shaders/full_screen_render_pass.vert", "content/shaders/full_screen_render_pass.frag");
// Create texture layout.
this._textureLayout = new SimpleTextureLayout(graphicsDevice, "fTexture");
diff --git a/src/Bliss/CSharp/Materials/Material.cs b/src/Bliss/CSharp/Materials/Material.cs
index 93b74b7..d670bc4 100644
--- a/src/Bliss/CSharp/Materials/Material.cs
+++ b/src/Bliss/CSharp/Materials/Material.cs
@@ -26,11 +26,11 @@ public class Material : Disposable {
/// The effect (shader program) applied to this material.
///
public Effect Effect { get; private set; }
-
+
///
/// Specifies the blend state for rendering, determining how colors are blended on the screen.
///
- public BlendState BlendState { get; private set; }
+ public BlendState BlendState;
///
/// A list of floating-point parameters for configuring material properties.
@@ -63,7 +63,7 @@ public Material(GraphicsDevice graphicsDevice, Effect effect, BlendState? blendS
this._textureLayouts = new Dictionary();
this._maps = new Dictionary();
}
-
+
///
/// Retrieves a associated with the specified layout and map name.
///
diff --git a/src/Bliss/content/shaders/default_model.vert b/src/Bliss/content/shaders/default_model.vert
index 78921e1..937d6e4 100644
--- a/src/Bliss/content/shaders/default_model.vert
+++ b/src/Bliss/content/shaders/default_model.vert
@@ -33,7 +33,11 @@ layout (location = 2) out vec3 fNormal;
layout (location = 3) out vec3 fTangent;
layout (location = 4) out vec4 fColor;
-mat4x4 getBoneTransformation() { // TODO: Do a second shader and Vertex3D one with skinned mesh and one without to fix the issue that no project is rendered.
+mat4x4 getBoneTransformation() {
+ if (length(vBoneWeights) == 0.0F) {
+ return mat4x4(1.0F);
+ }
+
mat4x4 boneTransformation = uBonesTransformations[vBoneIndices.x] * vBoneWeights.x;
boneTransformation += uBonesTransformations[vBoneIndices.y] * vBoneWeights.y;
boneTransformation += uBonesTransformations[vBoneIndices.z] * vBoneWeights.z;