You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
174 lines
4.5 KiB
174 lines
4.5 KiB
/* |
|
* Copyright (C) 2022,2024 Riyyi |
|
* |
|
* SPDX-License-Identifier: MIT |
|
*/ |
|
|
|
#pragma once |
|
|
|
#include <cstdint> // int32_t, uint32_t |
|
#include <memory> // std::shared_ptr, std::unique_ptr, std::make_shared, std::make_unique |
|
|
|
#include "glm/ext/matrix_float4x4.hpp" // glm::mat4 |
|
#include "glm/ext/vector_float2.hpp" // glm::vec2 |
|
#include "glm/ext/vector_float3.hpp" // glm::vec3 |
|
#include "glm/ext/vector_float4.hpp" // glm::vec4 |
|
#include "ruc/singleton.h" |
|
|
|
namespace Inferno { |
|
|
|
class Shader; |
|
class Texture; |
|
class TransformComponent; |
|
class VertexArray; |
|
|
|
struct QuadVertex { |
|
glm::vec3 position { 0.0f, 0.0f, 0.0f }; |
|
glm::vec4 color { 1.0f, 1.0f, 1.0f, 1.0f }; |
|
glm::vec2 textureCoordinates { 0.0f, 0.0f }; |
|
float textureIndex = 0; |
|
}; |
|
|
|
struct CubemapVertex { |
|
glm::vec3 position { 0.0f, 0.0f, 0.0f }; |
|
glm::vec4 color { 1.0f, 1.0f, 1.0f, 1.0f }; |
|
float textureIndex = 0; |
|
}; |
|
|
|
struct SymbolVertex { |
|
QuadVertex quad; |
|
|
|
// Font |
|
float width = 0.44f; |
|
float edge = 0.15f; |
|
// Outline |
|
float borderWidth = 0.7f; |
|
float borderEdge = 0.1f; |
|
glm::vec4 borderColor { 1.0f, 1.0f, 1.0f, 1.0f }; |
|
// Dropshadow |
|
float offset = 0.0f; |
|
}; |
|
|
|
// ------------------------------------- |
|
|
|
template<typename T> |
|
class Renderer { |
|
public: |
|
static constexpr const uint32_t vertexPerQuad = 4; |
|
static constexpr const uint32_t indexPerQuad = 6; |
|
static constexpr const uint32_t quadPerCube = 6; |
|
|
|
// When to start a new batch |
|
static constexpr const uint32_t maxQuads = 20000; |
|
static constexpr const uint32_t maxVertices = maxQuads * vertexPerQuad; |
|
static constexpr const uint32_t maxIndices = maxQuads * indexPerQuad; |
|
static constexpr const uint32_t maxTextureSlots = 32; |
|
|
|
virtual void beginScene(glm::mat4 cameraProjection, glm::mat4 cameraView); |
|
virtual void endScene(); |
|
|
|
protected: |
|
Renderer() {} |
|
virtual ~Renderer() { destroy(); }; |
|
|
|
void initialize(); |
|
void destroy(); |
|
|
|
uint32_t addTextureUnit(std::shared_ptr<Texture> texture); |
|
|
|
void bind(); |
|
void unbind(); |
|
|
|
virtual void loadShader() = 0; |
|
virtual void flush(); |
|
virtual void startBatch(); |
|
virtual void nextBatch(); |
|
|
|
protected: |
|
// CPU quad vertices |
|
uint32_t m_quadIndex { 0 }; |
|
T* m_vertexBufferBase { nullptr }; |
|
T* m_vertexBufferPtr { nullptr }; |
|
|
|
// Texture units |
|
static uint32_t m_maxSupportedTextureSlots; |
|
uint32_t m_textureSlotIndex { 1 }; |
|
std::array<std::shared_ptr<Texture>, maxTextureSlots> m_textureSlots; |
|
|
|
// GPU objects |
|
bool m_enableDepthBuffer { true }; |
|
std::shared_ptr<Shader> m_shader; |
|
std::shared_ptr<VertexArray> m_vertexArray; |
|
}; |
|
|
|
// TOOD: |
|
// - Deduplicate flush() |
|
// v Add bool for disabling depth buffer |
|
// - Add Size for uploadData (this is prob not needed, we got T already) |
|
// - Decide if its worth to remove template<T> from Renderer, just cast vertexBufferPtr before usage |
|
|
|
// ------------------------------------- |
|
|
|
class Renderer2D final |
|
: public Renderer<QuadVertex> |
|
, public ruc::Singleton<Renderer2D> { |
|
public: |
|
Renderer2D(s); |
|
virtual ~Renderer2D() {}; |
|
|
|
using Singleton<Renderer2D>::destroy; |
|
|
|
virtual void beginScene(glm::mat4 cameraProjection, glm::mat4 cameraView) override; |
|
|
|
void drawQuad(const TransformComponent& transform, glm::vec4 color); |
|
void drawQuad(const TransformComponent& transform, glm::mat4 color); |
|
void drawQuad(const TransformComponent& transform, glm::vec4 color, std::shared_ptr<Texture> texture); |
|
void drawQuad(const TransformComponent& transform, glm::mat4 color, std::shared_ptr<Texture> texture); |
|
|
|
private: |
|
void loadShader() override; |
|
|
|
// Default quad vertex positions |
|
glm::vec4 m_vertexPositions[vertexPerQuad]; |
|
}; |
|
// ------------------------------------- |
|
|
|
class RendererCubemap final |
|
: public Renderer<CubemapVertex> |
|
, public ruc::Singleton<RendererCubemap> { |
|
public: |
|
RendererCubemap(s); |
|
virtual ~RendererCubemap() {}; |
|
|
|
using Singleton<RendererCubemap>::destroy; |
|
|
|
virtual void beginScene(glm::mat4 cameraProjection, glm::mat4 cameraView) override; |
|
|
|
void drawCubemap(const TransformComponent& transform, glm::vec4 color, std::shared_ptr<Texture> texture); |
|
void drawCubemap(const TransformComponent& transform, glm::mat4 color, std::shared_ptr<Texture> texture); |
|
|
|
private: |
|
void loadShader() override; |
|
|
|
// Default cubemap vertex positions |
|
glm::vec4 m_vertexPositions[vertexPerQuad * quadPerCube]; |
|
}; |
|
|
|
// ------------------------------------- |
|
|
|
class RendererFont final |
|
: public Renderer<SymbolVertex> |
|
, public ruc::Singleton<RendererFont> { |
|
public: |
|
RendererFont(s); |
|
virtual ~RendererFont() {}; |
|
|
|
using Singleton<RendererFont>::destroy; |
|
|
|
void drawSymbol(std::array<SymbolVertex, vertexPerQuad>& symbolQuad, std::shared_ptr<Texture> texture); |
|
|
|
private: |
|
void loadShader() override; |
|
}; |
|
|
|
} // namespace Inferno
|
|
|