aboutsummaryrefslogtreecommitdiff
path: root/source/30-game/Shader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/30-game/Shader.cpp')
-rw-r--r--source/30-game/Shader.cpp160
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);