From 47a43fecb108065487348015ea9b1a3f0a4d4639 Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Sat, 20 Mar 2021 15:31:13 -0500 Subject: [PATCH] [nostalgia/core/userland] Cleanup shader cleanup with unique_ptr-like GLobject type --- src/nostalgia/core/userland/gfx_opengl.cpp | 6 +-- src/nostalgia/core/userland/glutils.cpp | 29 +++++------- src/nostalgia/core/userland/glutils.hpp | 51 +++++++++++++++++++++- 3 files changed, 64 insertions(+), 22 deletions(-) diff --git a/src/nostalgia/core/userland/gfx_opengl.cpp b/src/nostalgia/core/userland/gfx_opengl.cpp index 1b3588e6..6cc0a123 100644 --- a/src/nostalgia/core/userland/gfx_opengl.cpp +++ b/src/nostalgia/core/userland/gfx_opengl.cpp @@ -38,7 +38,7 @@ struct Background: public Bufferset { }; struct GlImplData { - GLuint bgShader = 0; + Program bgShader; int64_t prevFpsCheckTime = 0; uint64_t draws = 0; std::array backgrounds; @@ -191,7 +191,7 @@ static void drawBackgrounds(GlImplData *id) { ox::Error init(Context *ctx) { const auto id = new GlImplData; ctx->setRendererData(id); - oxReturnError(buildShaderProgram(bgvshad, bgfshad).get(&id->bgShader)); + oxReturnError(buildShaderProgram(bgvshad, bgfshad).moveTo(&id->bgShader)); for (auto &bg : id->backgrounds) { initBackgroundBufferset(ctx, id->bgShader, &bg); } @@ -200,8 +200,6 @@ ox::Error init(Context *ctx) { ox::Error shutdown(Context *ctx) { const auto id = ctx->rendererData(); - glDeleteProgram(id->bgShader); - id->bgShader = 0; for (auto &bg : id->backgrounds) { destroy(bg); } diff --git a/src/nostalgia/core/userland/glutils.cpp b/src/nostalgia/core/userland/glutils.cpp index 71635be0..134c5b91 100644 --- a/src/nostalgia/core/userland/glutils.cpp +++ b/src/nostalgia/core/userland/glutils.cpp @@ -15,8 +15,11 @@ namespace nostalgia::core::renderer { +template struct GLobject; +template struct GLobject; + [[nodiscard]] -static ox::Result buildShader(GLuint shaderType, const GLchar *src, const char *shaderName) { +static ox::Result buildShader(GLuint shaderType, const GLchar *src, const char *shaderName) { const auto shader = glCreateShader(shaderType); glShaderSource(shader, 1, &src, nullptr); glCompileShader(shader); @@ -29,26 +32,18 @@ static ox::Result buildShader(GLuint shaderType, const GLchar *src, cons glDeleteShader(shader); return OxError(1, "shader compile error"); } - return shader; + return Shader(shader); } [[nodiscard]] -ox::Result buildShaderProgram(const GLchar *vert, const GLchar *frag) { - ox::Result out; +ox::Result buildShaderProgram(const GLchar *vert, const GLchar *frag) { oxRequire(vs, buildShader(GL_VERTEX_SHADER, vert, "vshad")); - auto [fs, fserr] = buildShader(GL_FRAGMENT_SHADER, frag, "fshad"); - if (!fserr) { - auto prgm = glCreateProgram(); - glAttachShader(prgm, vs); - glAttachShader(prgm, fs); - glLinkProgram(prgm); - out = prgm; - } else { - out = fserr; - } - glDeleteShader(fs); - glDeleteShader(vs); - return out; + oxRequire(fs, buildShader(GL_FRAGMENT_SHADER, frag, "fshad")); + Program prgm(glCreateProgram()); + glAttachShader(prgm, vs); + glAttachShader(prgm, fs); + glLinkProgram(prgm); + return ox::move(prgm); } void destroy(const Bufferset &bufferset) { diff --git a/src/nostalgia/core/userland/glutils.hpp b/src/nostalgia/core/userland/glutils.hpp index 49eaefd7..f5320eb3 100644 --- a/src/nostalgia/core/userland/glutils.hpp +++ b/src/nostalgia/core/userland/glutils.hpp @@ -15,9 +15,58 @@ #endif #include +#include namespace nostalgia::core::renderer { +template +struct GLobject { + + GLuint id = 0; + + constexpr GLobject() = default; + + explicit constexpr GLobject(GLuint id) { + this->id = id; + } + + constexpr GLobject(GLobject &&o) { + id = o.id; + o.id = 0; + } + + ~GLobject() { + oxDebugf("Deleting {}", id); + del(id); + } + + GLobject &operator=(GLobject &&o) { + id = o.id; + o.id = 0; + return *this; + } + + constexpr GLuint release() noexcept { + auto out = id; + id = 0; + return out; + } + + constexpr operator GLuint&() noexcept { + return id; + } + + constexpr operator const GLuint&() const noexcept { + return id; + } + +}; + +extern template struct GLobject; +extern template struct GLobject; +using Shader = GLobject; +using Program = GLobject; + struct Texture { GLuint texId = 0; @@ -43,7 +92,7 @@ struct Bufferset { }; [[nodiscard]] -ox::Result buildShaderProgram(const GLchar *vert, const GLchar *frag); +ox::Result buildShaderProgram(const GLchar *vert, const GLchar *frag); void destroy(const Bufferset &bufferset);