114 lines
3.0 KiB
C++

#pragma once
#if !defined(SDL_GPU_TEST_PRIVATE_SDL_GPU_TEST_6_UI_UI_UI_RENDERER_HPP_INCLUDED)
#define SDL_GPU_TEST_PRIVATE_SDL_GPU_TEST_6_UI_UI_UI_RENDERER_HPP_INCLUDED 1
#include <glm/vec2.hpp>
#include <glm/vec4.hpp>
#include "../application.hpp"
#include "../sdlpp/gpu.hpp"
#include "../util/font_map.hpp"
#include "../util/texture_atlas.hpp"
namespace sdl_gpu_test::inline app6
{
struct UIVertex
{
glm::vec2 pos;
glm::vec2 texcoord;
glm::vec4 color = glm::vec4(1.f);
};
struct MeasureTextArgs
{
std::string_view text;
float height = 38;
};
struct DrawTextArgs
{
float x = 0.f;
float y = 0.f;
float height = 38.f;
std::string_view text;
glm::vec4 color = glm::vec4(1.f);
};
struct DrawCharArgs
{
float x = 0.f;
float y = 0.f;
float height = 38.f;
char chr;
glm::vec4 color = glm::vec4(1.f);
};
struct DrawQuadArgs
{
std::string texture;
float x = 0.f;
float y = 0.f;
float width;
float height;
glm::vec4 color = glm::vec4(1.f);
};
struct UIRendererRenderArgs
{
const sdlpp::GPUCommandBuffer* cmdBuffer;
const sdlpp::GPUTexture* targetTexture;
unsigned targetTextureWidth;
unsigned targetTextureHeight;
};
class UIRenderer
{
public:
using primitive_id_t = std::uint64_t;
static constexpr primitive_id_t UNSET_PRIMITIVE_ID = 0;
private:
Application* mApplication = nullptr;
sdlpp::GPUBuffer mVertexBuffer;
sdlpp::GPUGraphicsPipeline mPipeline;
sdlpp::GPUTexture mTexture;
sdlpp::GPUSampler mSampler;
std::vector<UIVertex> mVertices;
std::vector<primitive_id_t> mTriangleOwners;
primitive_id_t mNextOwner = 1;
UVTextureAtlas mTextureAtlas;
UVFontMap mFontMap;
bool mVerticesDirty = true;
std::size_t mVertexBufferSize = 0;
public:
[[nodiscard]]
std::size_t getNumVertices() const noexcept { return mVertices.size(); }
void init(Application& application);
void render(const UIRendererRenderArgs& args);
[[nodiscard]]
std::pair<float, float> measureText(const MeasureTextArgs& args) const;
void drawText(const DrawTextArgs& args, primitive_id_t* outPrimitiveId = nullptr);
void drawTextCentered(DrawTextArgs args, primitive_id_t* outPrimitiveId = nullptr);
float drawChar(const DrawCharArgs& args, primitive_id_t* outPrimitiveId = nullptr);
void drawQuad(const DrawQuadArgs& args, primitive_id_t* outPrimitiveId = nullptr);
bool removePrimitive(primitive_id_t primitiveId);
private:
struct DrawQuadInternalArgs
{
glm::vec2 topLeft;
glm::vec2 bottomRight;
glm::vec2 uvTopLeft;
glm::vec2 uvBottomRight;
glm::vec4 color = glm::vec4(1.f);
};
void drawQuadInternal(const DrawQuadInternalArgs& args, primitive_id_t primitiveId);
void addTriangleInternal(const UIVertex& vtx0, const UIVertex& vtx1, const UIVertex& vtx2, primitive_id_t primitiveId);
void uploadVertices();
};
} // namespace sdl_gpu_test::inline app6
#endif // !defined(SDL_GPU_TEST_PRIVATE_SDL_GPU_TEST_6_UI_UI_UI_RENDERER_HPP_INCLUDED)