diff options
Diffstat (limited to 'source/30-game/Shader.cpp')
-rw-r--r-- | source/30-game/Shader.cpp | 160 |
1 files changed, 47 insertions, 113 deletions
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 <ScopeGuard.hpp> #include <Utils.hpp> +#include <fmt/format.h> #include <imgui.h> #include <misc/cpp/imgui_stdlib.h> #include <rapidjson/document.h> @@ -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<ShaderMathVariable>& 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<ShaderVariable> CreateVariable(GLenum type, GLuint loc) { +std::variant<ShaderMathVariable, ShaderSamplerVariable> CreateVariable(GLenum type, GLuint loc) { GLenum scalarType; int width; int height; if (QueryMathInfo(type, scalarType, width, height)) { - auto res = std::make_unique<ShaderMathVariable>(); - 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<ShaderSamplerVariable>(); - 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<VertexElementSemantic>(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<ShaderMathVariable>& 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); |