feat: revamp 2D pipeline to use SDF's for rendering

This commit is contained in:
2026-10-16 23:23:26 +02:00
parent 469bb287b7
commit faba4171ec
19 changed files with 676 additions and 502 deletions
@@ -1,45 +0,0 @@
#ifndef DESTRUM_QUADRENDERINGMANAGER_H
#define DESTRUM_QUADRENDERINGMANAGER_H
#include <vector>
#include <glm/glm.hpp>
#include <destrum/Graphics/ids.h>
#include <destrum/Singleton.h>
struct QuadSubmission {
glm::vec2 position;
glm::vec2 size;
float rotation;
glm::vec4 color;
ImageID textureId;
};
class QuadRenderingManager final : public Singleton<QuadRenderingManager> {
public:
friend class Singleton<QuadRenderingManager>;
void SubmitQuad(
const glm::vec2& position,
const glm::vec2& size,
const glm::vec4& color = glm::vec4{1.0f},
ImageID textureId = NULL_IMAGE_ID);
void SubmitQuad(
const glm::vec2& position,
const glm::vec2& size,
float rotation,
const glm::vec4& color = glm::vec4{1.0f},
ImageID textureId = NULL_IMAGE_ID);
[[nodiscard]] const std::vector<QuadSubmission>& GetQuads() const { return quads; }
void ClearQuads();
private:
QuadRenderingManager() = default;
std::vector<QuadSubmission> quads;
};
#endif // DESTRUM_QUADRENDERINGMANAGER_H
@@ -0,0 +1,108 @@
#ifndef DESTRUM_RENDERER2D_H
#define DESTRUM_RENDERER2D_H
#include <cstdint>
#include <vector>
#include <glm/glm.hpp>
#include <destrum/Graphics/ids.h>
#include <destrum/Singleton.h>
enum class Shape2DType : std::uint32_t {
Rect = 0,
Ellipse = 1,
Triangle = 2,
};
enum class TextureFilter : std::uint32_t {
Nearest = 0,
Linear = 1,
};
enum class LineCap {
Butt,
Square,
Round,
};
struct Texture2D {
ImageID id{NULL_IMAGE_ID};
glm::vec2 uvMin{0.0f, 0.0f};
glm::vec2 uvMax{1.0f, 1.0f};
TextureFilter filter{TextureFilter::Linear};
};
struct ShapeStyle {
glm::vec4 color{1.0f};
float outline{0.0f};
float rotation{0.0f};
float cornerRadius{0.0f};
Texture2D texture{};
};
// Mirrors Shape2D in shape2d.glsl (scalar layout)
struct Shape2D {
glm::vec2 center;
glm::vec2 halfSize;
glm::vec4 color;
glm::vec4 uvRect;
glm::vec2 p0;
glm::vec2 p1;
glm::vec2 p2;
float rotation;
float outline;
float cornerRadius;
Shape2DType type;
std::uint32_t textureId;
TextureFilter filter;
};
static_assert(sizeof(Shape2D) == 96);
// Screen space, in draw image pixels, origin top left, y down. Drawn in submission order.
class Renderer2D final : public Singleton<Renderer2D> {
public:
friend class Singleton<Renderer2D>;
void DrawRect(const glm::vec2& topLeft, const glm::vec2& size, const glm::vec4& color);
void DrawRect(const glm::vec2& topLeft, const glm::vec2& size, const ShapeStyle& style);
void DrawRectOutline(const glm::vec2& topLeft, const glm::vec2& size, float thickness, const glm::vec4& color);
void DrawTexturedRect(
const glm::vec2& topLeft,
const glm::vec2& size,
ImageID texture,
const glm::vec4& tint = glm::vec4{1.0f});
void DrawEllipse(const glm::vec2& center, const glm::vec2& radii, const glm::vec4& color);
void DrawEllipse(const glm::vec2& center, const glm::vec2& radii, const ShapeStyle& style);
void DrawEllipseOutline(const glm::vec2& center, const glm::vec2& radii, float thickness, const glm::vec4& color);
void DrawCircle(const glm::vec2& center, float radius, const glm::vec4& color);
void DrawTriangle(const glm::vec2& a, const glm::vec2& b, const glm::vec2& c, const glm::vec4& color);
void DrawTriangle(const glm::vec2& a, const glm::vec2& b, const glm::vec2& c, const ShapeStyle& style);
void DrawTriangleOutline(
const glm::vec2& a,
const glm::vec2& b,
const glm::vec2& c,
float thickness,
const glm::vec4& color);
void DrawLine(
const glm::vec2& from,
const glm::vec2& to,
float thickness,
const glm::vec4& color,
LineCap cap = LineCap::Butt);
[[nodiscard]] const std::vector<Shape2D>& GetShapes() const { return shapes; }
void Clear();
private:
Renderer2D() = default;
void submit(Shape2DType type, const glm::vec2& center, const glm::vec2& halfSize, const ShapeStyle& style);
std::vector<Shape2D> shapes;
};
#endif // DESTRUM_RENDERER2D_H
@@ -1,5 +1,5 @@
#ifndef DESTRUM_QUADRENDERERPASS_H
#define DESTRUM_QUADRENDERERPASS_H
#ifndef DESTRUM_RENDERER2DPASS_H
#define DESTRUM_RENDERER2DPASS_H
#include <cstddef>
#include <memory>
@@ -8,15 +8,14 @@
#include <vulkan/vulkan.h>
#include <destrum/Graphics/Resources/Buffer.h>
#include <destrum/Graphics/Resources/NBuffer.h>
class GfxDevice;
class Pipeline;
struct GPUImage;
class RenderResources;
class QuadRendererPass final {
class Renderer2DPass final {
public:
void init(GfxDevice& gfxDevice, RenderResources& resources, VkFormat drawImageFormat);
void draw(
@@ -27,21 +26,16 @@ public:
const glm::mat4& projection);
void cleanup(GfxDevice& gfxDevice);
private:
struct QuadVertex {
glm::vec2 position;
glm::vec2 uv;
glm::vec4 color;
std::uint32_t textureId;
};
// Top left origin, y down, in target pixels
[[nodiscard]] static glm::mat4 screenProjection(const GPUImage& target);
void ensureCapacity(GfxDevice& gfxDevice, std::size_t requiredQuads);
private:
void ensureCapacity(GfxDevice& gfxDevice, std::size_t requiredShapes);
VkPipelineLayout pipelineLayout{VK_NULL_HANDLE};
std::unique_ptr<Pipeline> pipeline;
GPUBuffer vertexBuffer{};
GPUBuffer indexBuffer{};
std::size_t quadCapacity{0};
NBuffer shapeBuffer;
std::size_t shapeCapacity{0};
};
#endif // DESTRUM_QUADRENDERERPASS_H
#endif // DESTRUM_RENDERER2DPASS_H
+3 -3
View File
@@ -9,7 +9,7 @@
#include <destrum/Graphics/Pipelines/LightCullingPipeline.h>
#include <destrum/Graphics/Pipelines/LineRenderingPass.h>
#include <destrum/Graphics/Pipelines/MeshPipeline.h>
#include <destrum/Graphics/Pipelines/QuadRendererPass.h>
#include <destrum/Graphics/Pipelines/Renderer2DPass.h>
#include <destrum/Graphics/Pipelines/ShadowMapPipeline.h>
#include <destrum/Graphics/ids.h>
#include <destrum/Graphics/MeshDrawCommand.h>
@@ -105,7 +105,7 @@ public:
return resources;
}
void drawQuads(
void draw2D(
VkCommandBuffer cmd,
GfxDevice& gfxDevice,
const glm::mat4& projection);
@@ -163,7 +163,7 @@ private:
std::unique_ptr<MeshPipeline> meshPipeline;
std::unique_ptr<SkyboxPipeline> skyboxPipeline;
std::unique_ptr<LineRenderingPass> lineRenderingPass;
std::unique_ptr<QuadRendererPass> quadRendererPass;
std::unique_ptr<Renderer2DPass> renderer2DPass;
std::unique_ptr<SkinningPipeline> skinningPipeline;
std::unique_ptr<LightCullingPipeline> lightCullingPipeline;