From 047f294de1b4d385b811ac9f5afc393d81cc4ae9 Mon Sep 17 00:00:00 2001 From: rtk0c Date: Sat, 16 Aug 2025 11:23:49 -0700 Subject: Copy changes from the no-history fork, generated back in 2023 Original commit message: > commit f138311d2d2e0cc9ba0496d523bb46f2c1c9fb73 > Author: rtk0c > Date: Wed Sep 20 23:58:58 2023 -0700 > > Copy from the PlasticSCM repo, replace vendored glm wtih conan In reality, this also introduced a few uncommitted changes in the original PlasticSCM repo. See the modified and new files in this patch. --- source/30-game/Shader.cpp | 160 ++++++++++++++-------------------------------- source/30-game/Shader.hpp | 81 ++++++++++++----------- 2 files changed, 91 insertions(+), 150 deletions(-) (limited to 'source/30-game') diff --git a/source/30-game/Shader.cpp b/source/30-game/Shader.cpp index dbfda0b..9bf2e0e 100644 --- a/source/30-game/Shader.cpp +++ b/source/30-game/Shader.cpp @@ -7,6 +7,7 @@ #include #include +#include #include #include #include @@ -34,10 +35,6 @@ void ShaderSamplerVariable::ShowInfo() const { PRINTF_STRING_VIEW(Metadata::EnumToString(semantic))); } -bool ShaderThingId::IsValid() const { - return kind == KD_Invalid; -} - namespace ProjectBrussel_UNITY_ID { GLuint FindLocation(const std::vector& vars, Tags::VertexElementSemantic semantic) { for (auto& var : vars) { @@ -79,16 +76,6 @@ GLuint ShaderInfo::FindOutputLocation(Tags::VertexElementSemantic semantic) { return FindLocation(outputs, semantic); } -ShaderVariable* ShaderInfo::FindVariable(const ShaderThingId& thing) { - switch (thing.kind) { - case ShaderThingId::KD_Input: return &inputs[thing.index]; - case ShaderThingId::KD_Output: return &outputs[thing.index]; - case ShaderThingId::KD_Uniform: return uniforms[thing.index].get(); - case ShaderThingId::KD_Invalid: break; - } - return nullptr; -} - Shader::Shader() { } @@ -161,35 +148,45 @@ Shader::ErrorCode Shader::InitFromSources(const ShaderSources& sources) { ScopeGuard sg = [&]() { glDeleteProgram(program); }; GLuint vertex = 0; - DEFER { glDeleteShader(vertex); }; + DEFER { + glDeleteShader(vertex); + }; if (!sources.vertex.empty()) { CATCH_ERROR(CreateShader(vertex, sources.vertex, GL_VERTEX_SHADER)); glAttachShader(program, vertex); } GLuint geometry = 0; - DEFER { glDeleteShader(geometry); }; + DEFER { + glDeleteShader(geometry); + }; if (!sources.geometry.empty()) { CATCH_ERROR(CreateShader(geometry, sources.geometry, GL_GEOMETRY_SHADER)); glAttachShader(program, geometry); } GLuint tessControl = 0; - DEFER { glDeleteShader(tessControl); }; + DEFER { + glDeleteShader(tessControl); + }; if (!sources.tessControl.empty()) { CATCH_ERROR(CreateShader(tessControl, sources.tessControl, GL_TESS_CONTROL_SHADER)); glAttachShader(program, tessControl); } GLuint tessEval = 0; - DEFER { glDeleteShader(tessEval); }; + DEFER { + glDeleteShader(tessEval); + }; if (!sources.tessEval.empty()) { CATCH_ERROR(CreateShader(tessEval, sources.tessEval, GL_TESS_EVALUATION_SHADER)); glAttachShader(program, tessEval); } GLuint fragment = 0; - DEFER { glDeleteShader(fragment); }; + DEFER { + glDeleteShader(fragment); + }; if (!sources.fragment.empty()) { CATCH_ERROR(CreateShader(fragment, sources.fragment, GL_FRAGMENT_SHADER)); glAttachShader(program, fragment); @@ -209,19 +206,29 @@ Shader::ErrorCode Shader::InitFromSource(std::string_view source) { using namespace ProjectBrussel_UNITY_ID; GLuint vertex = 0; - DEFER { glDeleteShader(vertex); }; + DEFER { + glDeleteShader(vertex); + }; GLuint geometry = 0; - DEFER { glDeleteShader(geometry); }; + DEFER { + glDeleteShader(geometry); + }; GLuint tessControl = 0; - DEFER { glDeleteShader(tessControl); }; + DEFER { + glDeleteShader(tessControl); + }; GLuint tessEval = 0; - DEFER { glDeleteShader(tessEval); }; + DEFER { + glDeleteShader(tessEval); + }; GLuint fragment = 0; - DEFER { glDeleteShader(fragment); }; + DEFER { + glDeleteShader(fragment); + }; int prevBegin = -1; // Excluding #type marker int prevEnd = -1; // [begin, end) @@ -434,27 +441,27 @@ bool QuerySamplerInfo(GLenum type) { return false; } -std::unique_ptr CreateVariable(GLenum type, GLuint loc) { +std::variant CreateVariable(GLenum type, GLuint loc) { GLenum scalarType; int width; int height; if (QueryMathInfo(type, scalarType, width, height)) { - auto res = std::make_unique(); - res->location = loc; - res->scalarType = type; - res->width = width; - res->height = height; + ShaderMathVariable res; + res.location = loc; + res.scalarType = type; + res.width = width; + res.height = height; return res; } if (QuerySamplerInfo(type)) { - auto res = std::make_unique(); - res->location = loc; - res->type = type; + ShaderSamplerVariable res; + res.location = loc; + res.samplerType = type; return res; } - return nullptr; + throw std::runtime_error(fmt::format("Unknown OpenGL shader uniform type {}", type)); } } // namespace ProjectBrussel_UNITY_ID @@ -530,64 +537,6 @@ bool Shader::IsValid() const { return mProgram != 0; } -namespace ProjectBrussel_UNITY_ID { -void WriteShaderVariable(rapidjson::Value& value, rapidjson::Document& root, const ShaderVariable& var) { - value.AddMember("Name", var.name, root.GetAllocator()); - value.AddMember("Semantic", rapidjson::StringRef(Metadata::EnumToString(var.semantic)), root.GetAllocator()); - value.AddMember("OpenGLLocation", var.location, root.GetAllocator()); -} - -bool ReadShaderVariable(const rapidjson::Value& value, ShaderVariable& var) { - using namespace Tags; - - BRUSSEL_JSON_GET(value, "Name", std::string, var.name, return false); - { // Semantic - auto rvSemantic = rapidjson::GetProperty(value, rapidjson::kStringType, "Semantic"sv); - if (!rvSemantic) { - var.semantic = VES_Generic; - } else { - auto str = rapidjson::AsStringView(*rvSemantic); - auto lookup = Metadata::EnumFromString(str); - var.semantic = lookup.value_or(VES_Generic); - } - } - BRUSSEL_JSON_GET_DEFAULT(value, "OpenGLLocation", int, var.location, 0); - return true; -} - -void WriteShaderMathVariable(rapidjson::Value& value, rapidjson::Document& root, const ShaderMathVariable& var) { - WriteShaderVariable(value, root, var); - value.AddMember("ScalarType", rapidjson::StringRef(Tags::GLTypeToString(var.scalarType)), root.GetAllocator()); - value.AddMember("Width", var.width, root.GetAllocator()); - value.AddMember("Height", var.height, root.GetAllocator()); - value.AddMember("ArrayLength", var.arrayLength, root.GetAllocator()); -} - -bool ReadShaderMathVariable(const rapidjson::Value& value, ShaderMathVariable& var) { - if (!ReadShaderVariable(value, var)) return false; - { - auto rvScalar = rapidjson::GetProperty(value, rapidjson::kStringType, "ScalarType"sv); - if (!rvScalar) return false; - var.scalarType = Tags::GLTypeFromString(rapidjson::AsStringView(*rvScalar)); - } - BRUSSEL_JSON_GET(value, "Width", int, var.width, return false); - BRUSSEL_JSON_GET(value, "Height", int, var.height, return false); - BRUSSEL_JSON_GET_DEFAULT(value, "ArrayLength", int, var.arrayLength, 1); - return true; -} - -void WriteShaderSamplerVariable(rapidjson::Value& value, rapidjson::Document& root, const ShaderSamplerVariable& var) { - WriteShaderVariable(value, root, var); - // TODO -} - -bool ReadShaderSamplerVariable(const rapidjson::Value& value, ShaderSamplerVariable& var) { - if (!ReadShaderVariable(value, var)) return false; - BRUSSEL_JSON_GET_DEFAULT(value, "ArrayLength", int, var.arrayLength, 1); - return true; -} -} // namespace ProjectBrussel_UNITY_ID - IresShader::IresShader() : IresObject(KD_Shader) { InvalidateInstance(); @@ -640,7 +589,7 @@ void IresShader::ShowEditor(IEditor& editor) { } if (ImGui::CollapsingHeader("Uniforms")) { for (auto& uniform : info.uniforms) { - uniform->ShowInfo(); + std::visit([](auto&& v) { v.ShowInfo(); }, uniform); } if (auto loc = mInstance->autofill_Transform; loc != kInvalidLocation) { ImGui::BulletText("(Autofill)\nLocation: %d\nName: %s", loc, kAfnTransform); @@ -661,25 +610,8 @@ void IresShader::Write(IresWritingContext& ctx, rapidjson::Value& value, rapidjs using namespace ProjectBrussel_UNITY_ID; IresObject::Write(ctx, value, root); - - auto& shaderInfo = mInstance->mInfo; - - value.AddMember("SourceFile", mSourceFile, root.GetAllocator()); - - auto SaveMathVars = [&](const char* name, const std::vector& vars) { - rapidjson::Value rvThings(rapidjson::kArrayType); - for (auto& thing : vars) { - rapidjson::Value rvThing(rapidjson::kObjectType); - WriteShaderMathVariable(rvThing, root, thing); - - rvThings.PushBack(rvThing, root.GetAllocator()); - } - value.AddMember(rapidjson::StringRef(name), rvThings, root.GetAllocator()); - }; - SaveMathVars("Inputs", shaderInfo.inputs); - SaveMathVars("Outputs", shaderInfo.outputs); - - // TODO uniforms + json_dto::json_output_t out( value, root.GetAllocator() ); + out << mInstance->mInfo; } void IresShader::Read(IresLoadingContext& ctx, const rapidjson::Value& value) { @@ -698,7 +630,9 @@ void IresShader::Read(IresLoadingContext& ctx, const rapidjson::Value& value) { auto shaderFile = Utils::OpenCstdioFile(shaderFilePath, Utils::Read); if (!shaderFile) return; - DEFER { fclose(shaderFile); }; + DEFER { + fclose(shaderFile); + }; fseek(shaderFile, 0, SEEK_END); auto shaderFileSize = ftell(shaderFile); diff --git a/source/30-game/Shader.hpp b/source/30-game/Shader.hpp index 707e6cc..cb980cd 100644 --- a/source/30-game/Shader.hpp +++ b/source/30-game/Shader.hpp @@ -7,8 +7,10 @@ #include #include +#include #include #include +#include #include // TODO move to variable after pattern matching is in the language @@ -17,44 +19,44 @@ class Shader; class IresShader; -struct ShaderVariable { - enum Kind { - KD_Math, - KD_Sampler, - }; - +struct ShaderMathVariable { std::string name; - Kind kind; GLuint location; Tags::VertexElementSemantic semantic = Tags::VES_Generic; - - virtual void ShowInfo() const = 0; - -protected: - ShaderVariable(Kind kind) - : kind{ kind } {} -}; - -struct ShaderMathVariable : public ShaderVariable { GLenum scalarType; - int arrayLength; int width; int height; - - ShaderMathVariable() - : ShaderVariable(KD_Math) {} - - virtual void ShowInfo() const override; + int arrayLength = 1; + + void ShowInfo() const; + + template + void json_io(TJsonIo& io) { + io& json_dto::mandatory("Name", name); + io& json_dto::mandatory("Semantic", static_cast(semantic)); + io& json_dto::mandatory("ScalarType", scalarType); + io& json_dto::mandatory("Width", width); + io& json_dto::mandatory("Height", height); + io& json_dto::optional("ArrayLength", arrayLength, 1); + } }; -struct ShaderSamplerVariable : public ShaderVariable { - GLenum type; - int arrayLength; - - ShaderSamplerVariable() - : ShaderVariable(KD_Sampler) {} - - virtual void ShowInfo() const override; +struct ShaderSamplerVariable { + std::string name; + GLuint location; + Tags::VertexElementSemantic semantic = Tags::VES_Generic; + GLenum samplerType; + int arrayLength = 1; + + void ShowInfo() const; + + template + void json_io(TJsonIo& io) { + io& json_dto::mandatory("Name", name); + io& json_dto::mandatory("Semantic", static_cast(semantic)); + io& json_dto::mandatory("SamplerType", samplerType); + io& json_dto::optional("ArrayLength", arrayLength, 1); + } }; struct ShaderThingId { @@ -62,24 +64,29 @@ struct ShaderThingId { KD_Input, KD_Output, KD_Uniform, - KD_Invalid, }; - Kind kind = KD_Invalid; - int index = 0; - - bool IsValid() const; + Kind kind; + int index; }; struct ShaderInfo { robin_hood::unordered_map things; std::vector inputs; std::vector outputs; - std::vector> uniforms; + std::vector> uniforms; + // Find the first variable with the matching semantic GLuint FindInputLocation(Tags::VertexElementSemantic semantic); GLuint FindOutputLocation(Tags::VertexElementSemantic semantic); - ShaderVariable* FindVariable(const ShaderThingId& thing); + + template + void json_io(TJsonIo& io) { + io& json_dto::mandatory("Inputs", inputs); + io& json_dto::mandatory("Outputs", outputs); + // TODO make json_dto support std::variant +// io& json_dto::mandatory("Uniforms", uniforms); + } }; class Shader : public RefCounted { -- cgit v1.2.3-70-g09d2