aboutsummaryrefslogtreecommitdiff
path: root/src/brussel.engine
diff options
context:
space:
mode:
authorrtk0c <[email protected]>2024-04-27 10:06:05 -0700
committerrtk0c <[email protected]>2025-08-16 11:34:45 -0700
commitc1b01f66de039a34914387abe21ac52e7e00347a (patch)
treeef5d9d370a5c1956a27f5da06b839133913169e9 /src/brussel.engine
parent9b2387dfe702bbadbdfde03fad8ba20daec127f8 (diff)
Commit misc work from a while ago
Diffstat (limited to 'src/brussel.engine')
-rw-r--r--src/brussel.engine/Material.cpp37
-rw-r--r--src/brussel.engine/Shader.cpp140
-rw-r--r--src/brussel.engine/Shader.hpp6
-rw-r--r--src/brussel.engine/Shader_p.hpp16
4 files changed, 94 insertions, 105 deletions
diff --git a/src/brussel.engine/Material.cpp b/src/brussel.engine/Material.cpp
index 4443ae5..21edd4d 100644
--- a/src/brussel.engine/Material.cpp
+++ b/src/brussel.engine/Material.cpp
@@ -230,35 +230,36 @@ void Material::SetShader(Shader* shader) {
mBoundTextures.clear();
for (int i = 0; i < info.uniforms.size(); ++i) {
auto& decl = info.uniforms[i];
- switch (decl->kind) {
- case ShaderVariable::KD_Math: {
- auto& mathDecl = static_cast<ShaderMathVariable&>(*decl);
+ switch (decl.index()) {
+ case ShaderInfo::kKindMath: {
+ auto& mathDecl = std::get<ShaderMathVariable>(decl);
if (mathDecl.width == 1) {
if (mathDecl.height == 1) {
// Scalar
auto& scalar = mBoundScalars.emplace_back();
- scalar.location = decl->location;
+ scalar.location = mathDecl.location;
scalar.infoUniformIndex = i;
} else {
// Vector
auto& vec = mBoundVectors.emplace_back();
- vec.location = decl->location;
+ vec.location = mathDecl.location;
vec.infoUniformIndex = i;
vec.actualLength = mathDecl.height;
}
} else {
// Matrix
auto& mat = mBoundMatrices.emplace_back();
- mat.location = decl->location;
+ mat.location = mathDecl.location;
mat.infoUniformIndex = i;
mat.actualWidth = mathDecl.width;
mat.actualHeight = mathDecl.height;
}
} break;
- case ShaderVariable::KD_Sampler: {
+ case ShaderInfo::kKindSampler: {
+ auto& samplerDecl = std::get<ShaderSamplerVariable>(decl);
auto& uniform = mBoundTextures.emplace_back();
- uniform.location = decl->location;
+ uniform.location = samplerDecl.location;
uniform.infoUniformIndex = i;
} break;
}
@@ -363,7 +364,7 @@ void IresMaterial::ShowEditor(IEditor& editor) {
auto shaderIres = shader->GetIres();
for (auto& field : mInstance->mBoundScalars) {
- auto& decl = static_cast<ShaderMathVariable&>(*shaderInfo.uniforms[field.infoUniformIndex]);
+ auto& decl = std::get<ShaderMathVariable>(shaderInfo.uniforms[field.infoUniformIndex]);
decl.ShowInfo();
ImGui::Indent();
@@ -377,7 +378,7 @@ void IresMaterial::ShowEditor(IEditor& editor) {
ImGui::Unindent();
}
for (auto& field : mInstance->mBoundVectors) {
- auto& decl = static_cast<ShaderMathVariable&>(*shaderInfo.uniforms[field.infoUniformIndex]);
+ auto& decl = std::get<ShaderMathVariable>(shaderInfo.uniforms[field.infoUniformIndex]);
decl.ShowInfo();
ImGui::Indent();
@@ -394,13 +395,13 @@ void IresMaterial::ShowEditor(IEditor& editor) {
ImGui::Unindent();
}
for (auto& field : mInstance->mBoundMatrices) {
- auto& decl = static_cast<ShaderMathVariable&>(*shaderInfo.uniforms[field.infoUniformIndex]);
+ auto& decl = std::get<ShaderMathVariable>(shaderInfo.uniforms[field.infoUniformIndex]);
decl.ShowInfo();
// TODO
}
for (auto& field : mInstance->mBoundTextures) {
- auto& decl = static_cast<ShaderSamplerVariable&>(*shaderInfo.uniforms[field.infoUniformIndex]);
+ auto& decl = std::get<ShaderSamplerVariable>(shaderInfo.uniforms[field.infoUniformIndex]);
decl.ShowInfo();
// TODO
@@ -423,7 +424,7 @@ void IresMaterial::Write(IresWritingContext& ctx, rapidjson::Value& value, rapid
rapidjson::Value fields(rapidjson::kArrayType);
for (auto& scalar : mInstance->mBoundScalars) {
rapidjson::Value rvField(rapidjson::kObjectType);
- rvField.AddMember("Name", shaderInfo.uniforms[scalar.infoUniformIndex]->name, root.GetAllocator());
+ rvField.AddMember("Name", std::visit([](auto&& v) { return v.name; }, shaderInfo.uniforms[scalar.infoUniformIndex]), root.GetAllocator());
rvField.AddMember("Type", "Scalar", root.GetAllocator());
switch (scalar.actualType) {
case GL_FLOAT: rvField.AddMember("Value", scalar.floatValue, root.GetAllocator()); break;
@@ -434,14 +435,14 @@ void IresMaterial::Write(IresWritingContext& ctx, rapidjson::Value& value, rapid
}
for (auto& vector : mInstance->mBoundVectors) {
rapidjson::Value rvField(rapidjson::kObjectType);
- rvField.AddMember("Name", shaderInfo.uniforms[vector.infoUniformIndex]->name, root.GetAllocator());
+ rvField.AddMember("Name", std::visit([](auto&& v) { return v.name; }, shaderInfo.uniforms[vector.infoUniformIndex]), root.GetAllocator());
rvField.AddMember("Type", "Vector", root.GetAllocator());
rvField.AddMember("Value", MakeVectorJson(vector, root).Move(), root.GetAllocator());
fields.PushBack(rvField, root.GetAllocator());
}
for (auto& matrix : mInstance->mBoundMatrices) {
rapidjson::Value rvField(rapidjson::kObjectType);
- rvField.AddMember("Name", shaderInfo.uniforms[matrix.infoUniformIndex]->name, root.GetAllocator());
+ rvField.AddMember("Name", std::visit([](auto&& v) { return v.name; }, shaderInfo.uniforms[matrix.infoUniformIndex]), root.GetAllocator());
rvField.AddMember("Type", "Matrix", root.GetAllocator());
rvField.AddMember("Value", MakeMatrixJson(matrix, root).Move(), root.GetAllocator());
fields.PushBack(rvField, root.GetAllocator());
@@ -492,7 +493,7 @@ void IresMaterial::Read(IresLoadingContext& ctx, const rapidjson::Value& value)
Material::ScalarUniform uniform;
if (rvName) {
TryFindShaderId(shader, rapidjson::AsStringView(*rvName), uniform.infoUniformIndex);
- uniform.location = shaderInfo.uniforms[uniform.infoUniformIndex]->location;
+ uniform.location = std::visit([](auto&& v) { return v.location; }, shaderInfo.uniforms[uniform.infoUniformIndex]);
}
if (rvValue->IsFloat()) {
uniform.actualType = GL_FLOAT;
@@ -509,14 +510,14 @@ void IresMaterial::Read(IresLoadingContext& ctx, const rapidjson::Value& value)
auto uniform = ReadVectorFromJson(*rvValue);
if (rvName) {
TryFindShaderId(shader, rapidjson::AsStringView(*rvName), uniform.infoUniformIndex);
- uniform.location = shaderInfo.uniforms[uniform.infoUniformIndex]->location;
+ uniform.location = std::visit([](auto&& v) { return v.location; }, shaderInfo.uniforms[uniform.infoUniformIndex]);
}
mInstance->mBoundVectors.push_back(std::move(uniform));
} else if (type == "Matrix"sv) {
auto uniform = ReadMatrixFromjson(*rvValue);
if (rvName) {
TryFindShaderId(shader, rapidjson::AsStringView(*rvName), uniform.infoUniformIndex);
- uniform.location = shaderInfo.uniforms[uniform.infoUniformIndex]->location;
+ uniform.location = std::visit([](auto&& v) { return v.location; }, shaderInfo.uniforms[uniform.infoUniformIndex]);
}
mInstance->mBoundMatrices.push_back(uniform);
} else if (type == "Texture"sv) {
diff --git a/src/brussel.engine/Shader.cpp b/src/brussel.engine/Shader.cpp
index 9bf2e0e..d795188 100644
--- a/src/brussel.engine/Shader.cpp
+++ b/src/brussel.engine/Shader.cpp
@@ -1,4 +1,5 @@
#include "Shader.hpp"
+#include "Shader_p.hpp"
#include "AppConfig.hpp"
@@ -19,20 +20,23 @@
using namespace std::literals;
void ShaderMathVariable::ShowInfo() const {
+ auto semantic = Metadata::EnumToString(this->semantic);
+ auto scalarType = Tags::GLTypeToString(this->scalarType);
ImGui::BulletText("Location: %d\nName: %s\nSemantic: %.*s\nType: %.*s %dx%d",
location,
name.c_str(),
- PRINTF_STRING_VIEW(Metadata::EnumToString(semantic)),
- PRINTF_STRING_VIEW(Tags::GLTypeToString(scalarType)),
+ PRINTF_STRING_VIEW(semantic),
+ PRINTF_STRING_VIEW(scalarType),
width,
height);
}
void ShaderSamplerVariable::ShowInfo() const {
+ auto semantic = Metadata::EnumToString(this->semantic);
ImGui::BulletText("Location: %d\nName: %s\nSemantic: %.*s\nType: Sampler",
location,
name.c_str(),
- PRINTF_STRING_VIEW(Metadata::EnumToString(semantic)));
+ PRINTF_STRING_VIEW(semantic));
}
namespace ProjectBrussel_UNITY_ID {
@@ -66,12 +70,12 @@ void InitAutoFills(Shader& shader) {
}
} // namespace ProjectBrussel_UNITY_ID
-GLuint ShaderInfo::FindInputLocation(Tags::VertexElementSemantic semantic) {
+GLuint ShaderInfo::FindInputLocation(Tags::VertexElementSemantic semantic) const {
using namespace ProjectBrussel_UNITY_ID;
return FindLocation(inputs, semantic);
}
-GLuint ShaderInfo::FindOutputLocation(Tags::VertexElementSemantic semantic) {
+GLuint ShaderInfo::FindOutputLocation(Tags::VertexElementSemantic semantic) const {
using namespace ProjectBrussel_UNITY_ID;
return FindLocation(outputs, semantic);
}
@@ -85,31 +89,35 @@ Shader::~Shader() {
namespace ProjectBrussel_UNITY_ID {
// Grabs section [begin, end)
-Shader::ErrorCode CreateShader(GLuint& out, const char* src, int beginIdx, int endIdx, GLenum type) {
- out = glCreateShader(type);
+Shader::ErrorCode CreateShader(OGLShader& out, const char* src, int beginIdx, int endIdx, GLenum type) {
+ GLuint shader = glCreateShader(type);
const GLchar* begin = &src[beginIdx];
const GLint len = endIdx - beginIdx;
- glShaderSource(out, 1, &begin, &len);
+ glShaderSource(shader, 1, &begin, &len);
- glCompileShader(out);
+ glCompileShader(shader);
GLint compileStatus;
- glGetShaderiv(out, GL_COMPILE_STATUS, &compileStatus);
+ glGetShaderiv(shader, GL_COMPILE_STATUS, &compileStatus);
if (compileStatus == GL_FALSE) {
GLint len;
- glGetShaderiv(out, GL_INFO_LOG_LENGTH, &len);
+ glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &len);
std::string log(len, '\0');
- glGetShaderInfoLog(out, len, nullptr, log.data());
+ glGetShaderInfoLog(shader, len, nullptr, log.data());
- return Shader ::EC_CompilationFailed;
+ std::fprintf(stderr, "Error compiling shader: %s", log.c_str());
+
+ glDeleteShader(shader);
+ return Shader::EC_CompilationFailed;
}
+ out = shader;
return Shader::EC_Success;
}
-Shader::ErrorCode CreateShader(GLuint& out, std::string_view str, GLenum type) {
- return CreateShader(out, str.data(), 0, str.size(), type);
+Shader::ErrorCode CreateShader(OGLShader& out, std::string_view str, GLenum type) {
+ return CreateShader(out, str.data(), 0, static_cast<int>(str.size()), type);
}
Shader::ErrorCode LinkShaderProgram(GLuint program) {
@@ -144,58 +152,41 @@ Shader::ErrorCode Shader::InitFromSources(const ShaderSources& sources) {
return EC_AlreadyInitialized;
}
- GLuint program = glCreateProgram();
- ScopeGuard sg = [&]() { glDeleteProgram(program); };
+ OGLShaderProgram program(glCreateProgram());
- GLuint vertex = 0;
- DEFER {
- glDeleteShader(vertex);
- };
+ OGLShader vertex;
if (!sources.vertex.empty()) {
CATCH_ERROR(CreateShader(vertex, sources.vertex, GL_VERTEX_SHADER));
- glAttachShader(program, vertex);
+ glAttachShader(program.get(), vertex.get());
}
- GLuint geometry = 0;
- DEFER {
- glDeleteShader(geometry);
- };
+ OGLShader geometry;
if (!sources.geometry.empty()) {
CATCH_ERROR(CreateShader(geometry, sources.geometry, GL_GEOMETRY_SHADER));
- glAttachShader(program, geometry);
+ glAttachShader(program.get(), geometry.get());
}
- GLuint tessControl = 0;
- DEFER {
- glDeleteShader(tessControl);
- };
+ OGLShader tessControl;
if (!sources.tessControl.empty()) {
CATCH_ERROR(CreateShader(tessControl, sources.tessControl, GL_TESS_CONTROL_SHADER));
- glAttachShader(program, tessControl);
+ glAttachShader(program.get(), tessControl.get());
}
- GLuint tessEval = 0;
- DEFER {
- glDeleteShader(tessEval);
- };
+ OGLShader tessEval;
if (!sources.tessEval.empty()) {
CATCH_ERROR(CreateShader(tessEval, sources.tessEval, GL_TESS_EVALUATION_SHADER));
- glAttachShader(program, tessEval);
+ glAttachShader(program.get(), tessEval.get());
}
- GLuint fragment = 0;
- DEFER {
- glDeleteShader(fragment);
- };
+ OGLShader fragment;
if (!sources.fragment.empty()) {
CATCH_ERROR(CreateShader(fragment, sources.fragment, GL_FRAGMENT_SHADER));
- glAttachShader(program, fragment);
+ glAttachShader(program.get(), fragment.get());
}
- CATCH_ERROR(LinkShaderProgram(program));
+ CATCH_ERROR(LinkShaderProgram(program.get()));
- sg.Dismiss();
- mProgram = program;
+ mProgram = program.release();
InitAutoFills(*this);
@@ -205,30 +196,11 @@ Shader::ErrorCode Shader::InitFromSources(const ShaderSources& sources) {
Shader::ErrorCode Shader::InitFromSource(std::string_view source) {
using namespace ProjectBrussel_UNITY_ID;
- GLuint vertex = 0;
- DEFER {
- glDeleteShader(vertex);
- };
-
- GLuint geometry = 0;
- DEFER {
- glDeleteShader(geometry);
- };
-
- GLuint tessControl = 0;
- DEFER {
- glDeleteShader(tessControl);
- };
-
- GLuint tessEval = 0;
- DEFER {
- glDeleteShader(tessEval);
- };
-
- GLuint fragment = 0;
- DEFER {
- glDeleteShader(fragment);
- };
+ OGLShader vertex;
+ OGLShader geometry;
+ OGLShader tessControl;
+ OGLShader tessEval;
+ OGLShader fragment;
int prevBegin = -1; // Excluding #type marker
int prevEnd = -1; // [begin, end)
@@ -240,15 +212,15 @@ Shader::ErrorCode Shader::InitFromSource(std::string_view source) {
return EC_Success;
}
- if (prevShaderVariant == "vertex" && !vertex) {
+ if (prevShaderVariant == "vertex" && vertex.get() == 0) {
CATCH_ERROR(CreateShader(vertex, source.data(), prevBegin, prevEnd, GL_VERTEX_SHADER));
- } else if (prevShaderVariant == "geometry" && !geometry) {
+ } else if (prevShaderVariant == "geometry" && geometry.get() == 0) {
CATCH_ERROR(CreateShader(geometry, source.data(), prevBegin, prevEnd, GL_GEOMETRY_SHADER));
- } else if (prevShaderVariant == "tessellation_control" && !tessControl) {
+ } else if (prevShaderVariant == "tessellation_control" && tessControl.get() == 0) {
CATCH_ERROR(CreateShader(tessControl, source.data(), prevBegin, prevEnd, GL_TESS_CONTROL_SHADER));
- } else if (prevShaderVariant == "tessellation_evaluation" && !tessEval) {
+ } else if (prevShaderVariant == "tessellation_evaluation" && tessEval.get() == 0) {
CATCH_ERROR(CreateShader(tessEval, source.data(), prevBegin, prevEnd, GL_TESS_EVALUATION_SHADER));
- } else if (prevShaderVariant == "fragment" && !fragment) {
+ } else if (prevShaderVariant == "fragment" && fragment.get() == 0) {
CATCH_ERROR(CreateShader(fragment, source.data(), prevBegin, prevEnd, GL_FRAGMENT_SHADER));
} else {
return EC_InvalidShaderVariant;
@@ -312,19 +284,17 @@ Shader::ErrorCode Shader::InitFromSource(std::string_view source) {
prevEnd = static_cast<int>(source.size());
CATCH_ERROR(CommitSection());
- GLuint program = glCreateProgram();
- ScopeGuard sg = [&]() { glDeleteProgram(program); };
+ OGLShaderProgram program(glCreateProgram());
- if (vertex) glAttachShader(program, vertex);
- if (geometry) glAttachShader(program, geometry);
- if (tessControl) glAttachShader(program, tessControl);
- if (tessEval) glAttachShader(program, tessEval);
- if (fragment) glAttachShader(program, fragment);
+ if (vertex) glAttachShader(program.get(), vertex.get());
+ if (geometry) glAttachShader(program.get(), geometry.get());
+ if (tessControl) glAttachShader(program.get(), tessControl.get());
+ if (tessEval) glAttachShader(program.get(), tessEval.get());
+ if (fragment) glAttachShader(program.get(), fragment.get());
- CATCH_ERROR(LinkShaderProgram(program));
+ CATCH_ERROR(LinkShaderProgram(program.get()));
- sg.Dismiss();
- mProgram = program;
+ mProgram = program.release();
InitAutoFills(*this);
@@ -610,7 +580,7 @@ void IresShader::Write(IresWritingContext& ctx, rapidjson::Value& value, rapidjs
using namespace ProjectBrussel_UNITY_ID;
IresObject::Write(ctx, value, root);
- json_dto::json_output_t out( value, root.GetAllocator() );
+ json_dto::json_output_t out(value, root.GetAllocator());
out << mInstance->mInfo;
}
diff --git a/src/brussel.engine/Shader.hpp b/src/brussel.engine/Shader.hpp
index cb980cd..14480cd 100644
--- a/src/brussel.engine/Shader.hpp
+++ b/src/brussel.engine/Shader.hpp
@@ -75,10 +75,12 @@ struct ShaderInfo {
std::vector<ShaderMathVariable> inputs;
std::vector<ShaderMathVariable> outputs;
std::vector<std::variant<ShaderMathVariable, ShaderSamplerVariable>> uniforms;
+ static constexpr int kKindMath = 0;
+ static constexpr int kKindSampler = 1;
// Find the first variable with the matching semantic
- GLuint FindInputLocation(Tags::VertexElementSemantic semantic);
- GLuint FindOutputLocation(Tags::VertexElementSemantic semantic);
+ GLuint FindInputLocation(Tags::VertexElementSemantic semantic) const;
+ GLuint FindOutputLocation(Tags::VertexElementSemantic semantic) const;
template <typename TJsonIo>
void json_io(TJsonIo& io) {
diff --git a/src/brussel.engine/Shader_p.hpp b/src/brussel.engine/Shader_p.hpp
new file mode 100644
index 0000000..81a6603
--- /dev/null
+++ b/src/brussel.engine/Shader_p.hpp
@@ -0,0 +1,16 @@
+#pragma once
+
+#include "ScopedResource.hpp"
+
+#include <glad/glad.h>
+
+struct OGLShaderDeleter {
+ static void DeleteObject(GLuint id) { glDeleteShader(id); }
+};
+
+struct OGLShaderProgramDeleter {
+ static void DeleteObject(GLuint id) { glDeleteProgram(id); }
+};
+
+using OGLShader = ScopedResource<GLuint, OGLShaderDeleter, 0>;
+using OGLShaderProgram = ScopedResource<GLuint, OGLShaderProgramDeleter, 0>;