Extract renderer shader catalog

This commit is contained in:
2026-06-01 17:36:25 +02:00
parent ad255a6ddf
commit d61c7f37c3
7 changed files with 204 additions and 55 deletions

View File

@@ -1,12 +1,13 @@
#include "pch.h"
#include "app.h"
#include "renderer_api/shader_catalog.h"
#include "shader.h"
void App::initShaders()
{
#ifdef _DEBUG
if (!check_uniform_uniqueness())
std::logic_error("check_uniform_uniqueness() failed");
LOG("check_uniform_uniqueness() failed");
#endif // _DEBUG
render_task([] {
@@ -45,56 +46,19 @@ void App::initShaders()
LOG("Shader Extension shader_framebuffer_fetch: %s", ShaderManager::ext_framebuffer_fetch ? "enabled" : "disabled");
LOG("initializing shaders");
if (!ShaderManager::load(kShader::Texture, "data/shaders/texture.glsl"))
LOG("Failed to create shader Texture");
if (!ShaderManager::load(kShader::TextureAlpha, "data/shaders/texture-alpha.glsl"))
LOG("Failed to create shader TextureAlpha");
if (!ShaderManager::load(kShader::TextureMask, "data/shaders/texture-mask.glsl"))
LOG("Failed to create shader TextureMask");
if (!ShaderManager::load(kShader::TextureColorize, "data/shaders/texture-colorize.glsl"))
LOG("Failed to create shader TextureColorize");
if (!ShaderManager::load(kShader::TextureBlend, "data/shaders/texture-blend.glsl"))
LOG("Failed to create shader TextureBlend");
if (!ShaderManager::load(kShader::StrokePreview, "data/shaders/stroke-preview.glsl"))
LOG("Failed to create shader StrokePreview");
if (!ShaderManager::load(kShader::CompErase, "data/shaders/comp-erase.glsl"))
LOG("Failed to create shader CompErase");
if (!ShaderManager::load(kShader::CompDraw, "data/shaders/comp-draw.glsl"))
LOG("Failed to create shader CompDraw");
if (!ShaderManager::load(kShader::Color, "data/shaders/color.glsl"))
LOG("Failed to create shader Color");
if (!ShaderManager::load(kShader::ColorQuad, "data/shaders/color-quad.glsl"))
LOG("Failed to create shader ColorQuad");
if (!ShaderManager::load(kShader::ColorTri, "data/shaders/color-tri.glsl"))
LOG("Failed to create shader ColorTri");
if (!ShaderManager::load(kShader::ColorHue, "data/shaders/color-hue.glsl"))
LOG("Failed to create shader ColorHue");
if (!ShaderManager::load(kShader::UVs, "data/shaders/uvs.glsl"))
LOG("Failed to create shader UVs");
if (!ShaderManager::load(kShader::Font, "data/shaders/font.glsl"))
LOG("Failed to create shader Font");
if (!ShaderManager::load(kShader::Atlas, "data/shaders/atlas.glsl"))
LOG("Failed to create shader Atlas");
if (!ShaderManager::load(kShader::Stroke, "data/shaders/stroke.glsl"))
LOG("Failed to create shader Stroke");
if (!ShaderManager::load(kShader::StrokePad, "data/shaders/stroke-pad.glsl"))
LOG("Failed to create shader StrokePad");
if (!ShaderManager::load(kShader::StrokeDilate, "data/shaders/stroke-dilate.glsl"))
LOG("Failed to create shader StrokeDilate");
if (!ShaderManager::load(kShader::Checkerboard, "data/shaders/checkerboard.glsl"))
LOG("Failed to create shader Checkerboard");
if (!ShaderManager::load(kShader::Equirect, "data/shaders/equirect.glsl"))
LOG("Failed to create shader Equirect");
if (!ShaderManager::load(kShader::BrushStroke, "data/shaders/stroke-instanced.glsl"))
LOG("Failed to create shader BrushStroke");
if (!ShaderManager::load(kShader::VertexColor, "data/shaders/vertex-color.glsl"))
LOG("Failed to create shader VertexColor");
if (!ShaderManager::load(kShader::Lambert, "data/shaders/lambert.glsl"))
LOG("Failed to create shader Lambert");
if (!ShaderManager::load(kShader::LambertLightmap, "data/shaders/lightmap.glsl"))
LOG("Failed to create shader LambertLightmap");
if (!ShaderManager::load(kShader::BakeUV, "data/shaders/bake-uv.glsl"))
LOG("Failed to create shader BakeUV");
const auto shader_catalog = pp::renderer::panopainter_shader_catalog();
const auto catalog_status = pp::renderer::validate_shader_catalog(shader_catalog);
if (!catalog_status.ok())
{
LOG("Shader catalog validation failed: %s", catalog_status.message);
return;
}
for (const auto& shader : shader_catalog)
{
if (!ShaderManager::load(static_cast<kShader>(const_hash(shader.name)), shader.path))
LOG("Failed to create shader %s", shader.name);
}
LOG("shaders initialized");
}

View File

@@ -0,0 +1,91 @@
#include "renderer_api/shader_catalog.h"
#include <array>
#include <string_view>
namespace pp::renderer {
namespace {
constexpr std::array<ShaderCatalogEntry, 25> pano_catalog {
ShaderCatalogEntry { .name = "texture", .path = "data/shaders/texture.glsl" },
ShaderCatalogEntry { .name = "texture-alpha", .path = "data/shaders/texture-alpha.glsl" },
ShaderCatalogEntry { .name = "texture-mask", .path = "data/shaders/texture-mask.glsl" },
ShaderCatalogEntry { .name = "texture-colorize", .path = "data/shaders/texture-colorize.glsl" },
ShaderCatalogEntry { .name = "texture-blend", .path = "data/shaders/texture-blend.glsl" },
ShaderCatalogEntry { .name = "stroke-preview", .path = "data/shaders/stroke-preview.glsl" },
ShaderCatalogEntry { .name = "comp-erase", .path = "data/shaders/comp-erase.glsl" },
ShaderCatalogEntry { .name = "comp-draw", .path = "data/shaders/comp-draw.glsl" },
ShaderCatalogEntry { .name = "color", .path = "data/shaders/color.glsl" },
ShaderCatalogEntry { .name = "color-quad", .path = "data/shaders/color-quad.glsl" },
ShaderCatalogEntry { .name = "color-tri", .path = "data/shaders/color-tri.glsl" },
ShaderCatalogEntry { .name = "color-hue", .path = "data/shaders/color-hue.glsl" },
ShaderCatalogEntry { .name = "uvs", .path = "data/shaders/uvs.glsl" },
ShaderCatalogEntry { .name = "font", .path = "data/shaders/font.glsl" },
ShaderCatalogEntry { .name = "atlas", .path = "data/shaders/atlas.glsl" },
ShaderCatalogEntry { .name = "stroke", .path = "data/shaders/stroke.glsl" },
ShaderCatalogEntry { .name = "stroke-pad", .path = "data/shaders/stroke-pad.glsl" },
ShaderCatalogEntry { .name = "stroke-dilate", .path = "data/shaders/stroke-dilate.glsl" },
ShaderCatalogEntry { .name = "checkerboard", .path = "data/shaders/checkerboard.glsl" },
ShaderCatalogEntry { .name = "equirect", .path = "data/shaders/equirect.glsl" },
ShaderCatalogEntry { .name = "brush-stroke", .path = "data/shaders/stroke-instanced.glsl" },
ShaderCatalogEntry { .name = "vertex-color", .path = "data/shaders/vertex-color.glsl" },
ShaderCatalogEntry { .name = "lambert", .path = "data/shaders/lambert.glsl" },
ShaderCatalogEntry { .name = "lambert-lightmap", .path = "data/shaders/lightmap.glsl" },
ShaderCatalogEntry { .name = "bakeuv", .path = "data/shaders/bake-uv.glsl" },
};
[[nodiscard]] bool is_empty_c_string(const char* text) noexcept
{
return text == nullptr || text[0] == '\0';
}
[[nodiscard]] bool has_shader_extension(std::string_view path) noexcept
{
constexpr std::string_view extension = ".glsl";
return path.size() >= extension.size()
&& path.substr(path.size() - extension.size()) == extension;
}
}
std::span<const ShaderCatalogEntry> panopainter_shader_catalog() noexcept
{
return pano_catalog;
}
pp::foundation::Status validate_shader_catalog(std::span<const ShaderCatalogEntry> catalog) noexcept
{
if (catalog.empty()) {
return pp::foundation::Status::invalid_argument("shader catalog must not be empty");
}
if (catalog.size() > max_shader_catalog_entries) {
return pp::foundation::Status::out_of_range("shader catalog exceeds the configured limit");
}
for (std::size_t i = 0; i < catalog.size(); ++i) {
const auto& entry = catalog[i];
if (is_empty_c_string(entry.name)) {
return pp::foundation::Status::invalid_argument("shader catalog entry name must not be empty");
}
if (is_empty_c_string(entry.path)) {
return pp::foundation::Status::invalid_argument("shader catalog entry path must not be empty");
}
if (!has_shader_extension(entry.path)) {
return pp::foundation::Status::invalid_argument("shader catalog path must end with .glsl");
}
for (std::size_t j = i + 1U; j < catalog.size(); ++j) {
if (std::string_view(entry.name) == std::string_view(catalog[j].name)) {
return pp::foundation::Status::invalid_argument("shader catalog entry name is duplicated");
}
}
}
return pp::foundation::Status::success();
}
}

View File

@@ -0,0 +1,21 @@
#pragma once
#include "foundation/result.h"
#include <cstddef>
#include <span>
namespace pp::renderer {
constexpr std::size_t max_shader_catalog_entries = 256;
struct ShaderCatalogEntry {
const char* name = "";
const char* path = "";
};
[[nodiscard]] std::span<const ShaderCatalogEntry> panopainter_shader_catalog() noexcept;
[[nodiscard]] pp::foundation::Status validate_shader_catalog(
std::span<const ShaderCatalogEntry> catalog) noexcept;
}