summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gfx/models/mesh.cpp3
-rw-r--r--gfx/models/mesh.h3
-rw-r--r--gfx/models/texture.cpp10
-rw-r--r--gfx/models/texture.h10
-rw-r--r--lib/glArrays.cpp21
-rw-r--r--lib/glArrays.h76
-rw-r--r--lib/glBuffers.cpp13
-rw-r--r--lib/glBuffers.h64
-rw-r--r--lib/glVertexArrays.cpp13
-rw-r--r--lib/glVertexArrays.h64
-rw-r--r--test/Jamfile.jam1
-rw-r--r--test/test-lib.cpp50
-rw-r--r--ui/icon.cpp10
-rw-r--r--ui/icon.h10
-rw-r--r--ui/iconButton.cpp3
-rw-r--r--ui/iconButton.h3
-rw-r--r--ui/text.cpp3
-rw-r--r--ui/text.h3
18 files changed, 164 insertions, 196 deletions
diff --git a/gfx/models/mesh.cpp b/gfx/models/mesh.cpp
index 09c2872..f13e242 100644
--- a/gfx/models/mesh.cpp
+++ b/gfx/models/mesh.cpp
@@ -1,6 +1,5 @@
#include "mesh.h"
-#include "glBuffers.h"
-#include "glVertexArrays.h"
+#include "glArrays.h"
#include "vertex.hpp"
#include <cstddef>
diff --git a/gfx/models/mesh.h b/gfx/models/mesh.h
index 4e6cec8..9b74f48 100644
--- a/gfx/models/mesh.h
+++ b/gfx/models/mesh.h
@@ -2,8 +2,7 @@
#define MESH_INCLUDED_H
#include <GL/glew.h>
-#include <glBuffers.h>
-#include <glVertexArrays.h>
+#include <glArrays.h>
#include <memory>
#include <span>
diff --git a/gfx/models/texture.cpp b/gfx/models/texture.cpp
index cd275e8..612f0a0 100644
--- a/gfx/models/texture.cpp
+++ b/gfx/models/texture.cpp
@@ -1,4 +1,6 @@
#include "texture.h"
+#include "glArrays.h"
+#include <GL/glew.h>
#include <cache.h>
#include <gfx/image.h>
#include <resource.h>
@@ -6,11 +8,10 @@
Cache<Texture> Texture::cachedTexture;
-Texture::Texture(const std::filesystem::path & fileName) : m_texture {}
+Texture::Texture(const std::filesystem::path & fileName)
{
const Image tex {Resource::mapPath(fileName).c_str(), STBI_rgb_alpha};
- glGenTextures(1, &m_texture);
glBindTexture(GL_TEXTURE_2D, m_texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
@@ -22,11 +23,6 @@ Texture::Texture(const std::filesystem::path & fileName) : m_texture {}
GL_RGBA, GL_UNSIGNED_BYTE, tex.data.data());
}
-Texture::~Texture()
-{
- glDeleteTextures(1, &m_texture);
-}
-
void
Texture::Bind() const
{
diff --git a/gfx/models/texture.h b/gfx/models/texture.h
index 8bbba85..6dbe9af 100644
--- a/gfx/models/texture.h
+++ b/gfx/models/texture.h
@@ -1,9 +1,8 @@
#ifndef TEXTURE_H
#define TEXTURE_H
-#include <GL/glew.h>
#include <filesystem>
-#include <special_members.hpp>
+#include <glArrays.h>
template<typename Obj> class Cache;
@@ -11,17 +10,12 @@ class Texture {
public:
explicit Texture(const std::filesystem::path & fileName);
- virtual ~Texture();
-
- NO_COPY(Texture);
- NO_MOVE(Texture);
-
static Cache<Texture> cachedTexture;
void Bind() const;
private:
- GLuint m_texture;
+ glTexture m_texture;
};
#endif
diff --git a/lib/glArrays.cpp b/lib/glArrays.cpp
new file mode 100644
index 0000000..7c5b2ea
--- /dev/null
+++ b/lib/glArrays.cpp
@@ -0,0 +1,21 @@
+#include "glArrays.h"
+#include <type_traits>
+
+// Base
+static_assert(!std::is_default_constructible_v<glArraysBase<1>>);
+static_assert(!std::is_copy_constructible_v<glArraysBase<1>>);
+static_assert(!std::is_copy_assignable_v<glArraysBase<1>>);
+static_assert(std::is_nothrow_move_constructible_v<glArraysBase<1>>);
+static_assert(std::is_nothrow_move_assignable_v<glArraysBase<1>>);
+
+// Specialisations (glBuffer is an example of the typedef)
+static_assert(std::is_nothrow_default_constructible_v<glBuffer>);
+static_assert(!std::is_trivially_default_constructible_v<glBuffer>);
+static_assert(std::is_nothrow_destructible_v<glBuffer>);
+static_assert(!std::is_trivially_destructible_v<glBuffer>);
+static_assert(std::is_default_constructible_v<glBuffer>);
+static_assert(!std::is_copy_constructible_v<glBuffer>);
+static_assert(!std::is_copy_assignable_v<glBuffer>);
+static_assert(std::is_nothrow_move_constructible_v<glBuffer>);
+static_assert(std::is_nothrow_move_assignable_v<glBuffer>);
+static_assert(sizeof(glBuffer) == sizeof(GLuint));
diff --git a/lib/glArrays.h b/lib/glArrays.h
new file mode 100644
index 0000000..ed05eeb
--- /dev/null
+++ b/lib/glArrays.h
@@ -0,0 +1,76 @@
+#pragma once
+
+#include <GL/glew.h>
+#include <algorithm> // IWYU pragma: keep
+#include <array>
+#include <cstddef>
+#include <special_members.hpp>
+
+template<size_t N> class glArraysBase {
+ static_assert(N > 0);
+
+public:
+ ~glArraysBase() = default;
+ NO_COPY(glArraysBase);
+ CUSTOM_MOVE(glArraysBase);
+
+ // NOLINTNEXTLINE(hicpp-explicit-conversions)
+ inline operator GLuint() const
+ {
+ static_assert(N == 1, "Implicit cast only if N == 1");
+ return ids.front();
+ }
+
+ inline auto
+ operator[](size_t n) const
+ {
+ return ids[n];
+ }
+
+ constexpr static auto size {N};
+
+protected:
+ glArraysBase() noexcept = default;
+ std::array<GLuint, N> ids {};
+};
+
+template<size_t N> inline glArraysBase<N>::glArraysBase(glArraysBase<N> && src) noexcept : ids {src.ids}
+{
+ std::fill(src.ids.begin(), src.ids.end(), 0);
+}
+
+template<size_t N>
+inline glArraysBase<N> &
+glArraysBase<N>::operator=(glArraysBase<N> && src) noexcept
+{
+ ids = src.ids;
+ std::fill(src.ids.begin(), src.ids.end(), 0);
+ return *this;
+}
+
+template<size_t N, auto Gen, auto Del> class glArrays : public glArraysBase<N> {
+public:
+ using glArraysBase<N>::glArraysBase;
+ using glArraysBase<N>::operator=;
+
+ DEFAULT_MOVE_COPY(glArrays);
+
+ inline glArrays() noexcept
+ {
+ (*Gen)(N, this->ids.data());
+ }
+
+ inline ~glArrays() noexcept
+ {
+ if (this->ids.front()) {
+ (*Del)(N, this->ids.data());
+ }
+ }
+};
+
+template<size_t N> using glVertexArrays = glArrays<N, &glGenVertexArrays, &glDeleteVertexArrays>;
+using glVertexArray = glVertexArrays<1>;
+template<size_t N> using glBuffers = glArrays<N, &glGenBuffers, &glDeleteBuffers>;
+using glBuffer = glBuffers<1>;
+template<size_t N> using glTextures = glArrays<N, &glGenTextures, &glDeleteTextures>;
+using glTexture = glTextures<1>;
diff --git a/lib/glBuffers.cpp b/lib/glBuffers.cpp
deleted file mode 100644
index cb5ab2a..0000000
--- a/lib/glBuffers.cpp
+++ /dev/null
@@ -1,13 +0,0 @@
-#include "glBuffers.h"
-
-void
-glBuffersBase::gen(GLsizei n, GLuint * ids)
-{
- glGenBuffers(n, ids);
-}
-
-void
-glBuffersBase::del(GLsizei n, const GLuint * ids)
-{
- glDeleteBuffers(n, ids);
-}
diff --git a/lib/glBuffers.h b/lib/glBuffers.h
deleted file mode 100644
index e2c09df..0000000
--- a/lib/glBuffers.h
+++ /dev/null
@@ -1,64 +0,0 @@
-#ifndef GLBUFFERS_H
-#define GLBUFFERS_H
-
-#include <GL/glew.h>
-#include <algorithm> // IWYU pragma: keep
-#include <array>
-#include <cstddef>
-#include <special_members.hpp>
-
-class glBuffersBase {
-protected:
- static void gen(GLsizei, GLuint *);
- static void del(GLsizei, const GLuint *);
-};
-
-template<size_t N> class glBuffers : glBuffersBase {
-public:
- glBuffers()
- {
- gen(N, ids.data());
- }
-
- ~glBuffers()
- {
- del(N, ids.data());
- }
-
- NO_COPY(glBuffers);
- CUSTOM_MOVE(glBuffers);
-
- // NOLINTNEXTLINE(hicpp-explicit-conversions)
- operator GLuint() const
- {
- static_assert(N == 1, "Implicit cast only if N == 1");
- return ids.front();
- }
-
- auto
- operator[](size_t n) const
- {
- return ids[n];
- }
-
-private:
- std::array<GLuint, N> ids {};
-};
-
-template<size_t N> glBuffers<N>::glBuffers(glBuffers<N> && src) noexcept : ids {src.ids}
-{
- std::fill(src.ids.begin(), src.ids.end(), -1);
-}
-
-template<size_t N>
-glBuffers<N> &
-glBuffers<N>::operator=(glBuffers<N> && src) noexcept
-{
- ids = src.ids;
- std::fill(src.ids.begin(), src.ids.end(), -1);
- return *this;
-}
-
-using glBuffer = glBuffers<1>;
-
-#endif
diff --git a/lib/glVertexArrays.cpp b/lib/glVertexArrays.cpp
deleted file mode 100644
index 372b49b..0000000
--- a/lib/glVertexArrays.cpp
+++ /dev/null
@@ -1,13 +0,0 @@
-#include "glVertexArrays.h"
-
-void
-glVertexArraysBase::gen(GLsizei n, GLuint * ids)
-{
- glGenVertexArrays(n, ids);
-}
-
-void
-glVertexArraysBase::del(GLsizei n, const GLuint * ids)
-{
- glDeleteVertexArrays(n, ids);
-}
diff --git a/lib/glVertexArrays.h b/lib/glVertexArrays.h
deleted file mode 100644
index 803206a..0000000
--- a/lib/glVertexArrays.h
+++ /dev/null
@@ -1,64 +0,0 @@
-#ifndef GLVERTEXARRAYS_H
-#define GLVERTEXARRAYS_H
-
-#include <GL/glew.h>
-#include <algorithm> // IWYU pragma: keep
-#include <array>
-#include <cstddef>
-#include <special_members.hpp>
-
-class glVertexArraysBase {
-protected:
- static void gen(GLsizei, GLuint *);
- static void del(GLsizei, const GLuint *);
-};
-
-template<size_t N> class glVertexArrays : glVertexArraysBase {
-public:
- glVertexArrays()
- {
- gen(N, ids.data());
- }
-
- ~glVertexArrays()
- {
- del(N, ids.data());
- }
-
- NO_COPY(glVertexArrays);
- CUSTOM_MOVE(glVertexArrays);
-
- // NOLINTNEXTLINE(hicpp-explicit-conversions)
- operator GLuint() const
- {
- static_assert(N == 1, "Implicit cast only if N == 1");
- return ids.front();
- }
-
- auto
- operator[](size_t n) const
- {
- return ids[n];
- }
-
-private:
- std::array<GLuint, N> ids {};
-};
-
-template<size_t N> glVertexArrays<N>::glVertexArrays(glVertexArrays<N> && src) noexcept : ids {src.ids}
-{
- std::fill(src.ids.begin(), src.ids.end(), -1);
-}
-
-template<size_t N>
-glVertexArrays<N> &
-glVertexArrays<N>::operator=(glVertexArrays<N> && src) noexcept
-{
- ids = src.ids;
- std::fill(src.ids.begin(), src.ids.end(), -1);
- return *this;
-}
-
-using glVertexArray = glVertexArrays<1>;
-
-#endif
diff --git a/test/Jamfile.jam b/test/Jamfile.jam
index f8987d0..e487044 100644
--- a/test/Jamfile.jam
+++ b/test/Jamfile.jam
@@ -22,6 +22,7 @@ project : requirements
run test-collection.cpp ;
run test-obj.cpp ;
run test-maths.cpp ;
+run test-lib.cpp ;
run test-network.cpp ;
run test-persistence.cpp : -- : [ sequence.insertion-sort [ glob fixtures/json/*.json fixtures/json/bad/*.json ] ] ;
run test-text.cpp ;
diff --git a/test/test-lib.cpp b/test/test-lib.cpp
new file mode 100644
index 0000000..e464f2f
--- /dev/null
+++ b/test/test-lib.cpp
@@ -0,0 +1,50 @@
+#define BOOST_TEST_MODULE test_lib
+
+#include "test-helpers.hpp"
+#include <boost/test/data/test_case.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <GL/glew.h>
+#include <glArrays.h>
+#include <set>
+
+std::set<GLuint> active;
+void
+generator(GLsizei n, GLuint * out)
+{
+ static GLuint next {1};
+
+ while (n--) {
+ active.insert(next);
+ *out++ = next++;
+ }
+}
+
+void
+deleter(GLsizei n, GLuint * in)
+{
+ BOOST_CHECK(std::all_of(in, in + n, [](GLuint id) {
+ return active.erase(id) > 0;
+ }));
+}
+
+using TestArray = glArrays<5, &generator, &deleter>;
+
+BOOST_AUTO_TEST_CASE(generate_and_delete)
+{
+ {
+ TestArray a;
+ }
+ BOOST_CHECK(active.empty());
+}
+
+BOOST_AUTO_TEST_CASE(generate_move_and_delete)
+{
+ {
+ TestArray a;
+ BOOST_CHECK_EQUAL(TestArray::size, active.size());
+ TestArray b {std::move(a)};
+ BOOST_CHECK_EQUAL(TestArray::size, active.size());
+ }
+ BOOST_CHECK(active.empty());
+}
diff --git a/ui/icon.cpp b/ui/icon.cpp
index 371410a..657e953 100644
--- a/ui/icon.cpp
+++ b/ui/icon.cpp
@@ -1,4 +1,6 @@
#include "icon.h"
+#include "glArrays.h"
+#include <GL/glew.h>
#include <gfx/image.h>
#include <resource.h>
#include <stb/stb_image.h>
@@ -7,9 +9,8 @@ Icon::Icon(const std::filesystem::path & fileName) : Icon {Image {Resource::mapP
{
}
-Icon::Icon(const Image & tex) : size {tex.width, tex.height}, m_texture {}
+Icon::Icon(const Image & tex) : size {tex.width, tex.height}
{
- glGenTextures(1, &m_texture);
glBindTexture(GL_TEXTURE_2D, m_texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
@@ -21,11 +22,6 @@ Icon::Icon(const Image & tex) : size {tex.width, tex.height}, m_texture {}
GL_RGBA, GL_UNSIGNED_BYTE, tex.data.data());
}
-Icon::~Icon()
-{
- glDeleteTextures(1, &m_texture);
-}
-
void
Icon::Bind() const
{
diff --git a/ui/icon.h b/ui/icon.h
index cc6df87..2650218 100644
--- a/ui/icon.h
+++ b/ui/icon.h
@@ -1,10 +1,9 @@
#ifndef ICON_H
#define ICON_H
-#include <GL/glew.h>
#include <filesystem>
+#include <glArrays.h>
#include <glm/glm.hpp>
-#include <special_members.hpp>
class Image;
@@ -13,16 +12,11 @@ public:
explicit Icon(const std::filesystem::path & fileName);
explicit Icon(const Image & image);
- virtual ~Icon();
-
- NO_COPY(Icon);
- NO_MOVE(Icon);
-
void Bind() const;
const glm::vec2 size;
private:
- GLuint m_texture;
+ glTexture m_texture;
};
#endif
diff --git a/ui/iconButton.cpp b/ui/iconButton.cpp
index c97896f..f74b3fc 100644
--- a/ui/iconButton.cpp
+++ b/ui/iconButton.cpp
@@ -1,6 +1,5 @@
#include "iconButton.h"
-#include "glBuffers.h"
-#include "glVertexArrays.h"
+#include "glArrays.h"
#include "ui/icon.h"
#include "ui/uiComponent.h"
#include <GL/glew.h>
diff --git a/ui/iconButton.h b/ui/iconButton.h
index 76e3f1b..53ada74 100644
--- a/ui/iconButton.h
+++ b/ui/iconButton.h
@@ -3,8 +3,7 @@
#include "icon.h"
#include "uiComponent.h"
-#include <glBuffers.h>
-#include <glVertexArrays.h>
+#include <glArrays.h>
#include <glm/glm.hpp>
#include <string>
diff --git a/ui/text.cpp b/ui/text.cpp
index be696c3..2acfb7e 100644
--- a/ui/text.cpp
+++ b/ui/text.cpp
@@ -3,8 +3,7 @@
#include "gfx/gl/uiShader.h"
#include "uiComponent.h"
#include <array>
-#include <glBuffers.h>
-#include <glVertexArrays.h>
+#include <glArrays.h>
#include <glm/gtc/type_ptr.hpp>
#include <map>
#include <utility>
diff --git a/ui/text.h b/ui/text.h
index 81122de..cbe49de 100644
--- a/ui/text.h
+++ b/ui/text.h
@@ -2,8 +2,7 @@
#include "uiComponent.h"
#include <GL/glew.h>
-#include <glBuffers.h>
-#include <glVertexArrays.h>
+#include <glArrays.h>
#include <glm/glm.hpp>
#include <string_view>
#include <vector>