aboutsummaryrefslogtreecommitdiff
path: root/source/Shader.cpp
diff options
context:
space:
mode:
authorrtk0c <[email protected]>2022-04-19 12:36:02 -0700
committerrtk0c <[email protected]>2022-04-19 12:36:02 -0700
commit3290bb2b2dec223f0312c6d5fc3edf71d5d6e46f (patch)
tree1293b330f07ef410b1aea22e338c99c5ca07356b /source/Shader.cpp
parent07e8754e4d799e44678b595177e79e6eaa621268 (diff)
Changeset: 12 Add hardcoded dependencies for IresManager, migrate Shader to Ires
Diffstat (limited to 'source/Shader.cpp')
-rw-r--r--source/Shader.cpp214
1 files changed, 106 insertions, 108 deletions
diff --git a/source/Shader.cpp b/source/Shader.cpp
index 61e80a1..fd68a0c 100644
--- a/source/Shader.cpp
+++ b/source/Shader.cpp
@@ -6,16 +6,13 @@
#include "Utils.hpp"
#include <imgui.h>
+#include <misc/cpp/imgui_stdlib.h>
#include <rapidjson/document.h>
-#include <rapidjson/filereadstream.h>
-#include <rapidjson/filewritestream.h>
-#include <rapidjson/writer.h>
#include <cassert>
#include <cstddef>
#include <cstdlib>
#include <utility>
-namespace fs = std::filesystem;
using namespace std::literals;
void ShaderMathVariable::ShowInfo() const {
@@ -70,8 +67,7 @@ ShaderVariable* ShaderInfo::FindVariable(const ShaderThingId& thing) {
return nullptr;
}
-Shader::Shader(std::string name)
- : mName{ name } {
+Shader::Shader() {
}
Shader::~Shader() {
@@ -304,14 +300,6 @@ Shader::ErrorCode Shader::InitFromSource(std::string_view source) {
#undef CATCH_ERROR
-void Shader::GetDesignatedMetadataPath(char* buffer, int bufferSize) {
- snprintf(buffer, bufferSize, "%s/Shaders/%s.json", AppConfig::assetDir.c_str(), mName.c_str());
-}
-
-fs::path Shader::GetDesignatedMetadataPath() {
- return AppConfig::assetDirPath / "Shaders" / fs::path(mName).replace_extension(".json");
-}
-
namespace ProjectBrussel_UNITY_ID {
bool QueryMathInfo(GLenum type, GLenum& scalarType, int& width, int& height) {
auto DoOutput = [&](GLenum scalarTypeIn, int widthIn, int heightIn) {
@@ -508,10 +496,6 @@ bool Shader::GatherInfoShaderIntrospection() {
return true;
}
-bool Shader::IsAnnoymous() const {
- return mName.empty();
-}
-
bool Shader::IsValid() const {
return mProgram != 0;
}
@@ -570,10 +554,70 @@ bool ReadShaderSamplerVariable(const rapidjson::Value& value, ShaderSamplerVaria
}
} // namespace ProjectBrussel_UNITY_ID
-bool Shader::SaveMetadataToFile(const fs::path& filePath) const {
+IresShader::IresShader()
+ : IresObject(KD_Shader) {
+ InvalidateInstance();
+}
+
+Shader* IresShader::GetInstance() const {
+ return mInstance.Get();
+}
+
+void IresShader::InvalidateInstance() {
+ if (mInstance != nullptr) {
+ mInstance->mIres = nullptr;
+ }
+ mInstance.Attach(new Shader());
+ mInstance->mIres = this;
+}
+
+void IresShader::ShowEditor(EditorInstance& editor) {
+ using namespace Tags;
+
+ IresObject::ShowEditor(editor);
+
+ if (ImGui::Button("Gather info")) {
+ mInstance->GatherInfoShaderIntrospection();
+ }
+
+ if (ImGui::InputText("Source file", &mSourceFile, ImGuiInputTextFlags_EnterReturnsTrue)) {
+ InvalidateInstance();
+ }
+ // In other cases, mSourceFile will be reverted to before edit
+
+ // TODO macros
+
+ ImGui::Separator();
+
+ auto& info = mInstance->GetInfo();
+ if (ImGui::CollapsingHeader("General")) {
+ ImGui::Text("OpenGL program ID: %u", mInstance->GetProgram());
+ }
+ if (ImGui::CollapsingHeader("Inputs")) {
+ for (auto& input : info.inputs) {
+ input.ShowInfo();
+ }
+ }
+ if (ImGui::CollapsingHeader("Outputs")) {
+ for (auto& output : info.outputs) {
+ output.ShowInfo();
+ }
+ }
+ if (ImGui::CollapsingHeader("Uniforms")) {
+ for (auto& uniform : info.uniforms) {
+ uniform->ShowInfo();
+ }
+ }
+}
+
+void IresShader::Write(IresWritingContext& ctx, rapidjson::Value& value, rapidjson::Document& root) const {
using namespace ProjectBrussel_UNITY_ID;
- rapidjson::Document root(rapidjson::kObjectType);
+ 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);
@@ -583,42 +627,52 @@ bool Shader::SaveMetadataToFile(const fs::path& filePath) const {
rvThings.PushBack(rvThing, root.GetAllocator());
}
- root.AddMember(rapidjson::StringRef(name), rvThings, root.GetAllocator());
+ value.AddMember(rapidjson::StringRef(name), rvThings, root.GetAllocator());
};
- SaveMathVars("Inputs", mInfo.inputs);
- SaveMathVars("Outputs", mInfo.outputs);
+ SaveMathVars("Inputs", shaderInfo.inputs);
+ SaveMathVars("Outputs", shaderInfo.outputs);
// TODO uniforms
+}
- auto file = Utils::OpenCstdioFile(filePath, Utils::WriteTruncate);
- if (!file) return false;
- DEFER { fclose(file); };
+void IresShader::Read(IresLoadingContext& ctx, const rapidjson::Value& value) {
+ using namespace ProjectBrussel_UNITY_ID;
- char writerBuffer[65536];
- rapidjson::FileWriteStream stream(file, writerBuffer, sizeof(writerBuffer));
- rapidjson::Writer<rapidjson::FileWriteStream> writer(stream);
- root.Accept(writer);
+ IresObject::Read(ctx, value);
- return true;
-}
+ auto rvSourceFile = rapidjson::GetProperty(value, rapidjson::kStringType, "SourceFile"sv);
+ if (!rvSourceFile) {
+ return;
+ } else {
+ this->mSourceFile = rapidjson::AsString(*rvSourceFile);
-bool Shader::LoadMetadataFromFile(const fs::path& filePath) {
- using namespace ProjectBrussel_UNITY_ID;
+ char shaderFilePath[256];
+ snprintf(shaderFilePath, sizeof(shaderFilePath), "%s/%s", AppConfig::assetDir.c_str(), rvSourceFile->GetString());
- mInfo = {};
+ auto shaderFile = Utils::OpenCstdioFile(shaderFilePath, Utils::Read);
+ if (!shaderFile) return;
+ DEFER { fclose(shaderFile); };
+
+ fseek(shaderFile, 0, SEEK_END);
+ auto shaderFileSize = ftell(shaderFile);
+ rewind(shaderFile);
- auto file = Utils::OpenCstdioFile(filePath, Utils::Read);
- if (!file) return false;
- DEFER { fclose(file); };
+ // Also add \0 ourselves
+ auto buffer = std::make_unique<char[]>(shaderFileSize + 1);
+ fread(buffer.get(), shaderFileSize, 1, shaderFile);
+ buffer[shaderFileSize] = '\0';
+ std::string_view source(buffer.get(), shaderFileSize);
- char readerBuffer[65536];
- rapidjson::FileReadStream stream(file, readerBuffer, sizeof(readerBuffer));
+ if (mInstance->InitFromSource(source) != Shader::EC_Success) {
+ return;
+ }
+ }
- rapidjson::Document root;
- root.ParseStream(stream);
+ auto& shaderInfo = mInstance->mInfo;
+ auto shaderProgram = mInstance->GetProgram();
auto LoadMathVars = [&](std::string_view name, ShaderThingId::Kind kind, std::vector<ShaderMathVariable>& vars) {
- auto rvThings = rapidjson::GetProperty(root, rapidjson::kArrayType, name);
+ auto rvThings = rapidjson::GetProperty(value, rapidjson::kArrayType, name);
if (!rvThings) return;
for (auto& rv : rvThings->GetArray()) {
@@ -626,15 +680,15 @@ bool Shader::LoadMetadataFromFile(const fs::path& filePath) {
ShaderMathVariable thing;
ReadShaderMathVariable(rv, thing);
- mInfo.things.try_emplace(thing.name, ShaderThingId{ kind, (int)vars.size() });
+ shaderInfo.things.try_emplace(thing.name, ShaderThingId{ kind, (int)vars.size() });
vars.push_back(std::move(thing));
}
};
- LoadMathVars("Inputs"sv, ShaderThingId::KD_Input, mInfo.inputs);
- LoadMathVars("Outputs"sv, ShaderThingId::KD_Output, mInfo.outputs);
+ LoadMathVars("Inputs"sv, ShaderThingId::KD_Input, shaderInfo.inputs);
+ LoadMathVars("Outputs"sv, ShaderThingId::KD_Output, shaderInfo.outputs);
- auto rvUniforms = rapidjson::GetProperty(root, rapidjson::kArrayType, "Uniforms"sv);
- if (!rvUniforms) return false;
+ auto rvUniforms = rapidjson::GetProperty(value, rapidjson::kArrayType, "Uniforms"sv);
+ if (!rvUniforms) return;
for (auto& rvUniform : rvUniforms->GetArray()) {
if (!rvUniform.IsObject()) continue;
@@ -665,68 +719,12 @@ bool Shader::LoadMetadataFromFile(const fs::path& filePath) {
return nullptr;
}();
if (uniform) {
- mInfo.things.try_emplace(uniform->name, ShaderThingId{ ShaderThingId::KD_Uniform, (int)mInfo.uniforms.size() });
- mInfo.uniforms.emplace_back(std::move(uniform));
- }
- }
-
- for (auto& uniform : mInfo.uniforms) {
- uniform->location = glGetUniformLocation(mProgram, uniform->name.c_str());
- }
-
- return true;
-}
-
-void ShaderManager::DiscoverShaders() {
- mShaders.clear();
-
- auto path = AppConfig::assetDirPath / "Shaders";
- if (!fs::exists(path)) {
- return;
- }
-
- for (auto& item : fs::directory_iterator(path)) {
- if (item.is_regular_file() && item.path().extension() == ".glsl") {
- auto shaderFile = Utils::OpenCstdioFile(item.path(), Utils::Read);
- if (!shaderFile) continue;
- DEFER { fclose(shaderFile); };
-
- fseek(shaderFile, 0, SEEK_END);
- auto shaderFileSize = ftell(shaderFile);
- rewind(shaderFile);
-
- // Also add \0 ourselves
- auto buffer = std::make_unique<char[]>(shaderFileSize + 1);
- fread(buffer.get(), shaderFileSize, 1, shaderFile);
- buffer[shaderFileSize] = '\0';
- std::string_view source(buffer.get(), shaderFileSize);
-
- RcPtr shader(new Shader(item.path().stem().string()));
- std::string_view shaderName(shader->GetName());
-
- // Load shader
- auto err = shader->InitFromSource(source);
- if (err != Shader::EC_Success) {
- continue;
- }
-
- // Load shader info if present
- fs::path infoPath(item.path());
- infoPath.replace_extension(".json");
- if (fs::exists(infoPath)) {
- shader->LoadMetadataFromFile(infoPath);
- }
-
- mShaders.try_emplace(shaderName, std::move(shader));
+ shaderInfo.things.try_emplace(uniform->name, ShaderThingId{ ShaderThingId::KD_Uniform, (int)shaderInfo.uniforms.size() });
+ shaderInfo.uniforms.emplace_back(std::move(uniform));
}
}
-}
-Shader* ShaderManager::FindShader(std::string_view name) {
- auto iter = mShaders.find(name);
- if (iter != mShaders.end()) {
- return iter->second.Get();
- } else {
- return nullptr;
+ for (auto& uniform : shaderInfo.uniforms) {
+ uniform->location = glGetUniformLocation(shaderProgram, uniform->name.c_str());
}
}