aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/brussel.common/PodVector.hpp104
-rw-r--r--src/brussel.common/RcPtr.hpp2
-rw-r--r--src/brussel.common/ScopedResource.hpp54
-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
7 files changed, 208 insertions, 151 deletions
diff --git a/src/brussel.common/PodVector.hpp b/src/brussel.common/PodVector.hpp
index bd92e7d..b6ab1d6 100644
--- a/src/brussel.common/PodVector.hpp
+++ b/src/brussel.common/PodVector.hpp
@@ -26,20 +26,20 @@ public:
mData = nullptr;
}
- PodVector(const PodVector<T>& src) {
+ PodVector(const PodVector& src) {
mSize = mCapacity = 0;
mData = nullptr;
operator=(src);
}
- PodVector<T>& operator=(const PodVector<T>& src) {
+ PodVector& operator=(const PodVector& src) {
clear();
resize(src.mSize);
- std::memcpy(mData, src.mData, (size_t)mSize * sizeof(T));
+ std::memcpy(mData, src.mData, static_cast<size_t>(mSize) * sizeof(T));
return *this;
}
- PodVector(PodVector&& src) {
+ PodVector(PodVector&& src) noexcept {
mSize = src.mSize;
mCapacity = src.mCapacity;
mData = src.mData;
@@ -48,7 +48,7 @@ public:
src.mData = nullptr;
}
- PodVector& operator=(PodVector&& src) {
+ PodVector& operator=(PodVector&& src) noexcept {
if (this != &src) {
std::free(mData);
@@ -66,18 +66,18 @@ public:
std::free(mData);
}
- bool empty() const { return mSize == 0; }
- int size() const { return mSize; }
- int size_in_bytes() const { return mSize * (int)sizeof(T); }
- int max_size() const { return 0x7FFFFFFF / (int)sizeof(T); }
- int capacity() const { return mCapacity; }
+ [[nodiscard]] bool empty() const { return mSize == 0; }
+ [[nodiscard]] int size() const { return mSize; }
+ [[nodiscard]] int size_in_bytes() const { return mSize * static_cast<int>(sizeof(T)); }
+ [[nodiscard]] static int max_size() { return std::numeric_limits<int>::max() / static_cast<int>(sizeof(T)); }
+ [[nodiscard]] int capacity() const { return mCapacity; }
- T& operator[](int i) {
+ [[nodiscard]] T& operator[](int i) {
assert(i >= 0 && i < mSize);
return mData[i];
}
- const T& operator[](int i) const {
+ [[nodiscard]] const T& operator[](int i) const {
assert(i >= 0 && i < mSize);
return mData[i];
}
@@ -90,24 +90,24 @@ public:
}
}
- T* begin() { return mData; }
- const T* begin() const { return mData; }
- T* end() { return mData + mSize; }
- const T* end() const { return mData + mSize; }
+ [[nodiscard]] T* begin() { return mData; }
+ [[nodiscard]] const T* begin() const { return mData; }
+ [[nodiscard]] T* end() { return mData + mSize; }
+ [[nodiscard]] const T* end() const { return mData + mSize; }
- T* data() { return mData; }
+ [[nodiscard]] T* data() { return mData; }
- T& front() {
+ [[nodiscard]] T& front() {
assert(mSize > 0);
return mData[0];
}
- const T& front() const {
+ [[nodiscard]] const T& front() const {
assert(mSize > 0);
return mData[0];
}
- T& back() {
+ [[nodiscard]] T& back() {
assert(mSize > 0);
return mData[mSize - 1];
}
@@ -117,16 +117,16 @@ public:
return mData[mSize - 1];
}
- void swap(PodVector<T>& rhs) {
+ friend void swap(PodVector& lhs, PodVector& rhs) noexcept {
int rhs_size = rhs.mSize;
- rhs.mSize = mSize;
- mSize = rhs_size;
+ rhs.mSize = lhs.mSize;
+ lhs.mSize = rhs_size;
int rhs_cap = rhs.mCapacity;
- rhs.mCapacity = mCapacity;
- mCapacity = rhs_cap;
+ rhs.mCapacity = lhs.mCapacity;
+ lhs.mCapacity = rhs_cap;
T* rhs_mDataTmp = rhs.mData;
- rhs.mData = mData;
- mData = rhs_mDataTmp;
+ rhs.mData = lhs.mData;
+ lhs.mData = rhs_mDataTmp;
}
int grow_capacity(int sz) const {
@@ -165,9 +165,9 @@ public:
/// Resize a vector to a smaller mSize, guaranteed not to cause a reallocation
void reserve(int newCapacity) {
if (newCapacity <= mCapacity) return;
- auto tmp = (T*)std::malloc((size_t)newCapacity * sizeof(T));
+ auto tmp = static_cast<T*>(std::malloc(static_cast<size_t>(newCapacity) * sizeof(T)));
if (mData) {
- std::memcpy(tmp, mData, (size_t)mSize * sizeof(T));
+ std::memcpy(tmp, mData, static_cast<size_t>(mSize) * sizeof(T));
std::free(mData);
}
mData = tmp;
@@ -201,7 +201,10 @@ public:
T* erase(const T* it) {
assert(it >= mData && it < mData + mSize);
const ptrdiff_t off = it - mData;
- std::memmove(mData + off, mData + off + 1, ((size_t)mSize - (size_t)off - 1) * sizeof(T));
+ std::memmove(
+ mData + off,
+ mData + off + 1,
+ (static_cast<size_t>(mSize) - static_cast<size_t>(off) - 1) * sizeof(T));
mSize--;
return mData + off;
}
@@ -210,15 +213,22 @@ public:
assert(it >= mData && it < mData + mSize && it_last > it && it_last <= mData + mSize);
const ptrdiff_t count = it_last - it;
const ptrdiff_t off = it - mData;
- std::memmove(mData + off, mData + off + count, ((size_t)mSize - (size_t)off - count) * sizeof(T));
- mSize -= (int)count;
+ std::memmove(
+ mData + off,
+ mData + off + count,
+ (static_cast<size_t>(mSize) - static_cast<size_t>(off) - count) * sizeof(T));
+ mSize -= static_cast<int>(count);
return mData + off;
}
T* erase_unsorted(const T* it) {
assert(it >= mData && it < mData + mSize);
const ptrdiff_t off = it - mData;
- if (it < mData + mSize - 1) std::memcpy(mData + off, mData + mSize - 1, sizeof(T));
+ if (it < mData + mSize - 1)
+ std::memcpy(
+ mData + off,
+ mData + mSize - 1,
+ sizeof(T));
mSize--;
return mData + off;
}
@@ -227,13 +237,17 @@ public:
assert(it >= mData && it <= mData + mSize);
const ptrdiff_t off = it - mData;
if (mSize == mCapacity) reserve(grow_capacity(mSize + 1));
- if (off < (int)mSize) std::memmove(mData + off + 1, mData + off, ((size_t)mSize - (size_t)off) * sizeof(T));
+ if (off < mSize)
+ std::memmove(
+ mData + off + 1,
+ mData + off,
+ (static_cast<size_t>(mSize) - static_cast<size_t>(off)) * sizeof(T));
std::memcpy(&mData[off], &v, sizeof(v));
mSize++;
return mData + off;
}
- bool contains(const T& v) const {
+ [[nodiscard]] bool contains(const T& v) const {
const T* data = mData;
const T* dataEnd = mData + mSize;
while (data < dataEnd) {
@@ -242,7 +256,7 @@ public:
return false;
}
- T* find(const T& v) {
+ [[nodiscard]] T* find(const T& v) {
T* data = mData;
const T* dataEnd = mData + mSize;
while (data < dataEnd)
@@ -253,14 +267,14 @@ public:
return data;
}
- const T* find(const T& v) const {
+ [[nodiscard]] const T* find(const T& v) const {
const T* data = mData;
const T* dataEnd = mData + mSize;
- while (data < dataEnd)
+ while (data < dataEnd) {
if (*data == v)
break;
- else
- ++data;
+ ++data;
+ }
return data;
}
@@ -285,13 +299,13 @@ public:
int index_from_ptr(const T* it) const {
assert(it >= mData && it < mData + mSize);
const ptrdiff_t off = it - mData;
- return (int)off;
+ return off;
}
// Custom utility functions
- std::span<T> as_span() { return { mData, (size_t)mSize }; }
- std::span<uint8_t> as_data_span() { return { (uint8_t*)mData, (size_t)mSize * sizeof(T) }; }
- std::span<const T> as_span() const { return { mData, (size_t)mSize }; }
- std::span<const uint8_t> as_data_span() const { return { (uint8_t*)mData, (size_t)mSize * sizeof(T) }; }
+ [[nodiscard]] std::span<T> as_span() { return { mData, static_cast<size_t>(mSize) }; }
+ [[nodiscard]] std::span<uint8_t> as_data_span() { return { static_cast<uint8_t*>(mData), static_cast<size_t>(mSize) * sizeof(T) }; }
+ [[nodiscard]] std::span<const T> as_span() const { return { mData, static_cast<size_t>(mSize) }; }
+ [[nodiscard]] std::span<const uint8_t> as_data_span() const { return { static_cast<uint8_t*>(mData), static_cast<size_t>(mSize) * sizeof(T) }; }
};
diff --git a/src/brussel.common/RcPtr.hpp b/src/brussel.common/RcPtr.hpp
index e3e420e..72a9b86 100644
--- a/src/brussel.common/RcPtr.hpp
+++ b/src/brussel.common/RcPtr.hpp
@@ -98,7 +98,7 @@ public:
template <typename TThat>
bool operator==(const RcPtr<TThat>& ptr) const {
- return mPtr == ptr.Get();
+ return mPtr == ptr.get();
}
T* Get() const {
diff --git a/src/brussel.common/ScopedResource.hpp b/src/brussel.common/ScopedResource.hpp
new file mode 100644
index 0000000..b4098eb
--- /dev/null
+++ b/src/brussel.common/ScopedResource.hpp
@@ -0,0 +1,54 @@
+#pragma once
+
+#include <type_traits>
+
+/// std::unique_ptr, but for non-pointer resources
+template <typename T, typename TDeleter, T kNullValue = T()>
+ requires std::is_trivial_v<T> && std::equality_comparable<T>
+class ScopedResource {
+private:
+ T mValue;
+
+public:
+ ScopedResource()
+ : mValue{ kNullValue } {}
+ explicit ScopedResource(T t)
+ : mValue{ std::move(t) } {}
+
+ ScopedResource(const ScopedResource& that) = delete;
+ ScopedResource& operator=(const ScopedResource& that) = delete;
+
+ ScopedResource(ScopedResource&& that) noexcept
+ : mValue(that.mValue) {}
+ ScopedResource& operator=(ScopedResource&& that) noexcept {
+ if (this == &that)
+ return *this;
+ TDeleter::DeleteObject(mValue);
+ mValue = that.mValue;
+ that.mValue = kNullValue;
+ return *this;
+ }
+
+ ScopedResource& operator=(T newValue) {
+ TDeleter::DeleteObject(mValue);
+ mValue = newValue;
+ return *this;
+ }
+
+ ~ScopedResource() {
+ TDeleter::DeleteObject(mValue);
+ }
+
+ explicit operator bool() const {
+ return mValue != kNullValue;
+ }
+
+ const T& get() const { return mValue; }
+ T& get() { return mValue; }
+
+ T release() {
+ T tmp = mValue;
+ mValue = kNullValue;
+ return tmp;
+ }
+};
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>;