summaryrefslogtreecommitdiff
path: root/lib/glArrays.h
blob: 787ea17ea7a94e0300bf44769a30d4123662d009 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
#pragma once

#include <algorithm> // IWYU pragma: keep
#include <array>
#include <cstddef>
#include <glad/gl.h>
#include <special_members.h>

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>;
template<size_t N> using glFrameBuffers = glArrays<N, &glGenFramebuffers, &glDeleteFramebuffers>;
using glFrameBuffer = glFrameBuffers<1>;
template<size_t N> using glRenderBuffers = glArrays<N, &glGenRenderbuffers, &glDeleteRenderbuffers>;
using glRenderBuffer = glRenderBuffers<1>;