VertexArray.cpp
1// Copyright 2019 Arthur Sonzogni. All rights reserved.
2// Use of this source code is governed by the MIT license that can be found in
3// the LICENSE file.
4
5#include <smk/VertexArray.hpp>
6
7namespace smk {
8
9VertexArray::VertexArray() = default;
10
11void VertexArray::Allocate(int element_size, void* data) {
12 glGenVertexArrays(1, &vao_);
13 glBindVertexArray(vao_);
14
15 glGenBuffers(1, &vbo_);
16 glBindBuffer(GL_ARRAY_BUFFER, vbo_);
17
18 glBufferData(GL_ARRAY_BUFFER, GLsizeiptr(size_ * element_size), data,
19 GL_STATIC_DRAW);
20 glEnableVertexAttribArray(0);
21}
22
23VertexArray::~VertexArray() {
24 Release();
25}
26
27void VertexArray::Bind() const {
28 glBindVertexArray(vao_);
29}
30
31// NOLINTNEXTLINE
32void VertexArray::UnBind() const {
33 glBindVertexArray(0);
34}
35
36VertexArray::VertexArray(const VertexArray& other) {
37 this->operator=(other);
38}
39
40VertexArray::VertexArray(VertexArray&& other) noexcept {
41 this->operator=(std::move(other));
42}
43
44VertexArray& VertexArray::operator=(const VertexArray& other) {
45 if (&other == this) {
46 return *this;
47 }
48 Release();
49 if (!other.vbo_) {
50 return *this;
51 }
52
53 if (!other.ref_count_) {
54 other.ref_count_ = new int(1); // NOLINT
55 }
56
57 vbo_ = other.vbo_;
58 vao_ = other.vao_;
59 ref_count_ = other.ref_count_;
60 size_ = other.size_;
61
62 (*ref_count_)++;
63 return *this;
64}
65
66VertexArray& VertexArray::operator=(VertexArray&& other) noexcept {
67 std::swap(vbo_, other.vbo_);
68 std::swap(vao_, other.vao_);
69 std::swap(size_, other.size_);
70 std::swap(ref_count_, other.ref_count_);
71 return *this;
72}
73
74/// Constructor for a vector of 2D vertices.
75/// @param array A set of 2D triangles.
76VertexArray::VertexArray(const std::vector<Vertex2D>& array) {
77 size_ = array.size();
78 Allocate(sizeof(Vertex2D), (void*)array.data());
79 Vertex2D::Bind();
80}
81
82/// Constructor for a vector of 3D vertices.
83/// @param array A set of 3D triangles.
84VertexArray::VertexArray(const std::vector<Vertex3D>& array) {
85 size_ = array.size();
86 Allocate(sizeof(Vertex3D), (void*)array.data());
87 Vertex3D::Bind();
88}
89
90/// @brief The size of the GPU array.
91/// @return the number of vertices in the GPU array.
92size_t VertexArray::size() const {
93 return size_;
94}
95
96bool VertexArray::operator==(const smk::VertexArray& other) const {
97 return vbo_ == other.vbo_;
98}
99
100bool VertexArray::operator!=(const smk::VertexArray& other) const {
101 return vbo_ != other.vbo_;
102}
103
104void VertexArray::Release() {
105 // Nothing to do for the null VertexArray.
106 if (!vbo_) {
107 return;
108 }
109
110 // Transfert state to local.
111 GLuint vbo = 0;
112 GLuint vao = 0;
113 int* ref_count = nullptr;
114 std::swap(vbo, vbo_);
115 std::swap(vao, vao_);
116 std::swap(ref_count, ref_count_);
117
118 // Early return without releasing the resource if it is still hold by copy of
119 // this class.
120 if (ref_count) {
121 --(*ref_count);
122 if (*ref_count) {
123 return;
124 }
125 delete ref_count; // NOLINT
126 ref_count = nullptr;
127 }
128
129 // Release the OpenGL objects.
130 glDeleteBuffers(1, &vbo);
131 glDeleteVertexArrays(1, &vao);
132}
133
134} // namespace smk.
An array of smk::Vertex moved to the GPU memory. This represent a set of triangles to be drawn by the...
Definition: VertexArray.hpp:20
size_t size() const
The size of the GPU array.
Definition: VertexArray.cpp:92
The vertex structure suitable for a 2D shader.
Definition: Vertex.hpp:13
The vertex structure suitable for a 2D shader.
Definition: Vertex.hpp:21