aboutsummaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorrtk0c <[email protected]>2025-08-16 11:23:49 -0700
committerrtk0c <[email protected]>2025-08-16 11:23:49 -0700
commit047f294de1b4d385b811ac9f5afc393d81cc4ae9 (patch)
treef96100a813a4ffb28dcd074455d3a2f8ee426430 /source
parent488fb8b4b9da7f99a5cc37e39fff9f1cb700f2a8 (diff)
Copy changes from the no-history fork, generated back in 2023
Original commit message: > commit f138311d2d2e0cc9ba0496d523bb46f2c1c9fb73 > Author: rtk0c <[email protected]> > 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.
Diffstat (limited to 'source')
-rw-r--r--source/10-common/DtoHelper.hpp10
-rw-r--r--source/10-common/Utils.hpp1
-rw-r--r--source/30-game/Shader.cpp160
-rw-r--r--source/30-game/Shader.hpp73
4 files changed, 97 insertions, 147 deletions
diff --git a/source/10-common/DtoHelper.hpp b/source/10-common/DtoHelper.hpp
new file mode 100644
index 0000000..871f9c6
--- /dev/null
+++ b/source/10-common/DtoHelper.hpp
@@ -0,0 +1,10 @@
+#pragma once
+
+#include <rapidjson/document.h>
+#include <json_dto/pub.hpp>
+
+namespace json_dto {
+
+
+
+}
diff --git a/source/10-common/Utils.hpp b/source/10-common/Utils.hpp
index 82569d8..668261b 100644
--- a/source/10-common/Utils.hpp
+++ b/source/10-common/Utils.hpp
@@ -33,7 +33,6 @@ bool ReadCstdioLine(FILE* file, char* buffer, size_t bufferSize, size_t* outLine
std::string ReadFileAsString(const std::filesystem::path& path);
-
constexpr float Abs(float v) noexcept {
return v < 0.0f ? -v : v;
}
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);
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 <glad/glad.h>
#include <robin_hood.h>
+#include <json_dto/pub.hpp>
#include <memory>
#include <string_view>
+#include <variant>
#include <vector>
// 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;
+ int arrayLength = 1;
- ShaderMathVariable()
- : ShaderVariable(KD_Math) {}
+ void ShowInfo() const;
- virtual void ShowInfo() const override;
+ template <typename TJsonIo>
+ void json_io(TJsonIo& io) {
+ io& json_dto::mandatory("Name", name);
+ io& json_dto::mandatory("Semantic", static_cast<int>(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;
+struct ShaderSamplerVariable {
+ std::string name;
+ GLuint location;
+ Tags::VertexElementSemantic semantic = Tags::VES_Generic;
+ GLenum samplerType;
+ int arrayLength = 1;
- ShaderSamplerVariable()
- : ShaderVariable(KD_Sampler) {}
+ void ShowInfo() const;
- virtual void ShowInfo() const override;
+ template <typename TJsonIo>
+ void json_io(TJsonIo& io) {
+ io& json_dto::mandatory("Name", name);
+ io& json_dto::mandatory("Semantic", static_cast<int>(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<std::string, ShaderThingId, StringHash, StringEqual> things;
std::vector<ShaderMathVariable> inputs;
std::vector<ShaderMathVariable> outputs;
- std::vector<std::unique_ptr<ShaderVariable>> uniforms;
+ std::vector<std::variant<ShaderMathVariable, ShaderSamplerVariable>> 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 <typename TJsonIo>
+ 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 {