Skip to content
This repository was archived by the owner on Mar 11, 2025. It is now read-only.

Add IGeometry, QuadShape, Drawable hierarchy #22

Merged
merged 1 commit into from
Feb 17, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 17 additions & 22 deletions App/Src/Main.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include <imgui.h>
#include <Tkge/Engine.hpp>
#include <Tkge/Graphics/Drawable.hpp>
#include <Tkge/Graphics/Shader.hpp>
#include <klib/assert.hpp>
#include <kvf/time.hpp>
Expand Down Expand Up @@ -52,27 +53,19 @@ namespace
const auto& renderDevice = engine.RenderDevice();
if (!shader.Load(renderDevice.get_device(), vertexSpirV, fragmentSpirV)) { throw std::runtime_error{"Failed to load shaders"}; }

static constexpr auto Vertices = std::array{
Tkge::Graphics::Vertex{.position = {-200.0f, -200.0f}},
Tkge::Graphics::Vertex{.position = {200.0f, -200.0f}},
Tkge::Graphics::Vertex{.position = {200.0f, 200.0f}},
Tkge::Graphics::Vertex{.position = {-200.0f, 200.0f}},
};
auto quad = Tkge::Graphics::Quad{};
quad.Create(glm::vec2{400.0f});
quad.transform.position.x = -250.0f;
quad.tint = kvf::magenta_v;

static constexpr auto Indices = std::array{
0u, 1u, 2u, 2u, 3u, 0u,
};
auto instancedQuad = Tkge::Graphics::InstancedQuad{};
instancedQuad.Create(glm::vec2{150.0f});

static constexpr auto Primitive = Tkge::Graphics::Primitive{
.vertices = Vertices,
.indices = Indices,
};

auto instances = std::array<Tkge::Graphics::RenderInstance, 2>{};
instances[0].transform.position.x = -250.0f;
instances[0].tint = kvf::cyan_v;
instances[1].transform.position.x = 250.0f;
instances[1].tint = kvf::yellow_v;
instancedQuad.instances.resize(2);
instancedQuad.instances[0].transform.position = {250.0f, -100.0f};
instancedQuad.instances[0].tint = kvf::cyan_v;
instancedQuad.instances[1].transform.position = {250.0f, 100.0f};
instancedQuad.instances[1].tint = kvf::yellow_v;

auto wireframe = false;
auto lineWidth = 3.0f;
Expand All @@ -87,8 +80,9 @@ namespace
const auto dt = deltaTime.tick();
elapsed += dt;

instances[0].tint.w = kvf::Color::to_u8((0.5f * std::sin(elapsed.count())) + 0.5f);
instances[1].tint.w = kvf::Color::to_u8((0.5f * std::sin(-elapsed.count())) + 0.5f);
instancedQuad.instances[0].tint.w = kvf::Color::to_u8((0.5f * std::sin(elapsed.count())) + 0.5f);
instancedQuad.instances[1].tint.w = kvf::Color::to_u8((0.5f * std::sin(-elapsed.count())) + 0.5f);
quad.tint.w = kvf::Color::to_u8((0.5f * std::cos(elapsed.count())) + 0.5f);

if (ImGui::Begin("Misc"))
{
Expand All @@ -102,7 +96,8 @@ namespace
renderer.BindShader(shader);
renderer.SetLineWidth(lineWidth);
renderer.SetWireframe(wireframe);
renderer.Draw(Primitive, instances);
instancedQuad.Draw(renderer);
quad.Draw(renderer);
}

engine.Present();
Expand Down
50 changes: 50 additions & 0 deletions Lib/Include/Tkge/Graphics/Drawable.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#pragma once
#include <Tkge/Graphics/Renderer.hpp>
#include <Tkge/Graphics/Shape.hpp>
#include <concepts>

namespace Tkge::Graphics
{
class IDrawable : public klib::Polymorphic
{
public:
[[nodiscard]] virtual Primitive GetPrimitive() const = 0;
[[nodiscard]] virtual std::span<const RenderInstance> GetInstances() const = 0;

virtual void Draw(Renderer& renderer) const { renderer.Draw(GetPrimitive(), GetInstances()); }
};

template <std::derived_from<IGeometry> TGeometry>
class BasicDrawable : public TGeometry, public IDrawable
{
public:
[[nodiscard]] Primitive GetPrimitive() const final
{
return Primitive{
.vertices = this->GetVertices(),
.indices = this->GetIndices(),
.topology = this->GetTopology(),
};
}
};

template <std::derived_from<IGeometry> TGeometry>
class Drawable : public BasicDrawable<TGeometry>, public RenderInstance
{
public:
[[nodiscard]] std::span<const RenderInstance> GetInstances() const final { return {static_cast<const RenderInstance*>(this), 1}; }
};

template <std::derived_from<IGeometry> TGeometry>
class InstancedDrawable : public BasicDrawable<TGeometry>
{
public:
[[nodiscard]] std::span<const RenderInstance> GetInstances() const final { return instances; }

std::vector<RenderInstance> instances{};
};

using Quad = Drawable<QuadShape>;
using InstancedQuad = InstancedDrawable<QuadShape>;

} // namespace Tkge::Graphics
16 changes: 16 additions & 0 deletions Lib/Include/Tkge/Graphics/IGeometry.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#pragma once
#include <Tkge/Graphics/Vertex.hpp>
#include <klib/polymorphic.hpp>
#include <cstdint>
#include <span>

namespace Tkge::Graphics
{
class IGeometry : public klib::Polymorphic
{
public:
[[nodiscard]] virtual std::span<const Vertex> GetVertices() const = 0;
[[nodiscard]] virtual std::span<const std::uint32_t> GetIndices() const = 0;
[[nodiscard]] virtual vk::PrimitiveTopology GetTopology() const = 0;
};
} // namespace Tkge::Graphics
30 changes: 30 additions & 0 deletions Lib/Include/Tkge/Graphics/Shape.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#pragma once
#include <Tkge/Graphics/IGeometry.hpp>
#include <kvf/color.hpp>
#include <kvf/rect.hpp>
#include <array>

namespace Tkge::Graphics
{
class QuadShape : public IGeometry
{
public:
static constexpr auto Indices = std::array{0u, 1u, 2u, 2u, 3u, 0u};
static constexpr std::size_t VertexCount{6};

[[nodiscard]] std::span<const Vertex> GetVertices() const final { return m_vertices; }
[[nodiscard]] std::span<const std::uint32_t> GetIndices() const final { return Indices; }
[[nodiscard]] vk::PrimitiveTopology GetTopology() const final { return vk::PrimitiveTopology::eTriangleList; }

void Create(const kvf::Rect<>& rect, const kvf::UvRect& uv = kvf::uv_rect_v, kvf::Color colour = kvf::white_v);
void Create(const glm::vec2 size) { Create(kvf::Rect<>::from_size(size)); }

[[nodiscard]] kvf::Rect<> GetRect() const;
[[nodiscard]] kvf::UvRect GetUv() const;
[[nodiscard]] glm::vec2 GetSize() const { return GetRect().size(); }
[[nodiscard]] kvf::Color GetColour() const { return m_vertices.front().colour; }

private:
std::array<Vertex, VertexCount> m_vertices{};
};
} // namespace Tkge::Graphics
25 changes: 25 additions & 0 deletions Lib/Src/Graphics/Shape.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#include <Tkge/Graphics/Shape.hpp>

namespace Tkge::Graphics
{
namespace
{
constexpr std::size_t LeftBottom{0};
constexpr std::size_t RightBottom{1};
constexpr std::size_t RightTop{2};
constexpr std::size_t LeftTop{3};
} // namespace

void QuadShape::Create(const kvf::Rect<>& rect, const kvf::UvRect& uv, const kvf::Color colour)
{
m_vertices[LeftBottom] = Vertex{.position = rect.bottom_left(), .colour = colour.to_linear(), .uv = uv.bottom_left()};
m_vertices[RightBottom] = Vertex{.position = rect.bottom_right(), .colour = colour.to_linear(), .uv = uv.bottom_right()};
m_vertices[RightTop] = Vertex{.position = rect.top_right(), .colour = colour.to_linear(), .uv = uv.top_right()};
m_vertices[LeftTop] = Vertex{.position = rect.top_left(), .colour = colour.to_linear(), .uv = uv.top_left()};
}

kvf::Rect<> QuadShape::GetRect() const { return kvf::Rect<>{.lt = m_vertices[LeftTop].position, .rb = m_vertices[RightBottom].position}; }

[[nodiscard]] kvf::UvRect QuadShape::GetUv() const { return {.lt = m_vertices[LeftTop].uv, .rb = m_vertices[RightBottom].uv}; }

} // namespace Tkge::Graphics