]> git.localhorst.tv Git - blank.git/blob - src/model.cpp
4e75674256d59a25e05fbbe042b89dee5b0ef86b
[blank.git] / src / model.cpp
1 #include "model.hpp"
2
3 #include <iostream>
4
5
6 namespace blank {
7
8 Model::Model() noexcept
9 : va(0)
10 , handle{}
11 , count(0) {
12         glGenVertexArrays(1, &va);
13         glGenBuffers(ATTRIB_COUNT, handle);
14 }
15
16 Model::~Model() noexcept {
17         glDeleteBuffers(ATTRIB_COUNT, handle);
18         glDeleteVertexArrays(1, &va);
19 }
20
21 Model::Model(Model &&other) noexcept
22 : va(other.va)
23 , count(other.count) {
24         other.va = 0;
25         for (int i = 0; i < ATTRIB_COUNT; ++i) {
26                 handle[i] = other.handle[i];
27                 other.handle[i] = 0;
28         }
29 }
30
31 Model &Model::operator =(Model &&other) noexcept {
32         std::swap(va, other.va);
33         for (int i = 0; i < ATTRIB_COUNT; ++i) {
34                 std::swap(handle[i], other.handle[i]);
35         }
36         count = other.count;
37         return *this;
38 }
39
40 void Model::Update(const Buffer &buf) noexcept {
41         glBindVertexArray(va);
42         glBindBuffer(GL_ARRAY_BUFFER, handle[ATTRIB_VERTEX]);
43         glBufferData(GL_ARRAY_BUFFER, buf.vertices.size() * sizeof(glm::vec3), buf.vertices.data(), GL_STATIC_DRAW);
44         glEnableVertexAttribArray(ATTRIB_VERTEX);
45         glVertexAttribPointer(
46                 ATTRIB_VERTEX, // location (for shader)
47                 3,             // size
48                 GL_FLOAT,      // type
49                 GL_FALSE,      // normalized
50                 0,             // stride
51                 nullptr        // offset
52         );
53
54 #ifndef NDEBUG
55         if (buf.colors.size() < buf.vertices.size()) {
56                 std::cerr << "Model: not enough colors!" << std::endl;
57         }
58 #endif
59         glBindBuffer(GL_ARRAY_BUFFER, handle[ATTRIB_COLOR]);
60         glBufferData(GL_ARRAY_BUFFER, buf.colors.size() * sizeof(glm::vec3), buf.colors.data(), GL_STATIC_DRAW);
61         glEnableVertexAttribArray(ATTRIB_COLOR);
62         glVertexAttribPointer(
63                 ATTRIB_COLOR,  // location (for shader)
64                 3,             // size
65                 GL_FLOAT,      // type
66                 GL_FALSE,      // normalized
67                 0,             // stride
68                 nullptr        // offset
69         );
70
71 #ifndef NDEBUG
72         if (buf.normals.size() < buf.vertices.size()) {
73                 std::cerr << "Model: not enough normals!" << std::endl;
74         }
75 #endif
76         glBindBuffer(GL_ARRAY_BUFFER, handle[ATTRIB_NORMAL]);
77         glBufferData(GL_ARRAY_BUFFER, buf.normals.size() * sizeof(glm::vec3), buf.normals.data(), GL_STATIC_DRAW);
78         glEnableVertexAttribArray(ATTRIB_NORMAL);
79         glVertexAttribPointer(
80                 ATTRIB_NORMAL, // location (for shader)
81                 3,             // size
82                 GL_FLOAT,      // type
83                 GL_FALSE,      // normalized
84                 0,             // stride
85                 nullptr        // offset
86         );
87
88         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, handle[ATTRIB_INDEX]);
89         glBufferData(GL_ELEMENT_ARRAY_BUFFER, buf.indices.size() * sizeof(Index), buf.indices.data(), GL_STATIC_DRAW);
90         count = buf.indices.size();
91 }
92
93
94 void Model::Draw() const noexcept {
95         glBindVertexArray(va);
96         glDrawElements(
97                 GL_TRIANGLES,    // how
98                 count,           // count
99                 GL_UNSIGNED_INT, // type
100                 nullptr          // offset
101         );
102 }
103
104
105 BlockModel::BlockModel() noexcept
106 : va(0)
107 , handle{}
108 , count(0) {
109         glGenVertexArrays(1, &va);
110         glGenBuffers(ATTRIB_COUNT, handle);
111 }
112
113 BlockModel::~BlockModel() noexcept {
114         glDeleteBuffers(ATTRIB_COUNT, handle);
115         glDeleteVertexArrays(1, &va);
116 }
117
118 BlockModel::BlockModel(BlockModel &&other) noexcept
119 : va(other.va)
120 , count(other.count) {
121         other.va = 0;
122         for (int i = 0; i < ATTRIB_COUNT; ++i) {
123                 handle[i] = other.handle[i];
124                 other.handle[i] = 0;
125         }
126 }
127
128 BlockModel &BlockModel::operator =(BlockModel &&other) noexcept {
129         std::swap(va, other.va);
130         for (int i = 0; i < ATTRIB_COUNT; ++i) {
131                 std::swap(handle[i], other.handle[i]);
132         }
133         count = other.count;
134         return *this;
135 }
136
137 void BlockModel::Update(const Buffer &buf) noexcept {
138         glBindVertexArray(va);
139         glBindBuffer(GL_ARRAY_BUFFER, handle[ATTRIB_VERTEX]);
140         glBufferData(GL_ARRAY_BUFFER, buf.vertices.size() * sizeof(glm::vec3), buf.vertices.data(), GL_STATIC_DRAW);
141         glEnableVertexAttribArray(ATTRIB_VERTEX);
142         glVertexAttribPointer(
143                 ATTRIB_VERTEX, // location (for shader)
144                 3,             // size
145                 GL_FLOAT,      // type
146                 GL_FALSE,      // normalized
147                 0,             // stride
148                 nullptr        // offset
149         );
150
151 #ifndef NDEBUG
152         if (buf.colors.size() < buf.vertices.size()) {
153                 std::cerr << "BlockModel: not enough colors!" << std::endl;
154         }
155 #endif
156         glBindBuffer(GL_ARRAY_BUFFER, handle[ATTRIB_COLOR]);
157         glBufferData(GL_ARRAY_BUFFER, buf.colors.size() * sizeof(glm::vec3), buf.colors.data(), GL_STATIC_DRAW);
158         glEnableVertexAttribArray(ATTRIB_COLOR);
159         glVertexAttribPointer(
160                 ATTRIB_COLOR,  // location (for shader)
161                 3,             // size
162                 GL_FLOAT,      // type
163                 GL_FALSE,      // normalized
164                 0,             // stride
165                 nullptr        // offset
166         );
167
168 #ifndef NDEBUG
169         if (buf.lights.size() < buf.vertices.size()) {
170                 std::cerr << "BlockModel: not enough lights!" << std::endl;
171         }
172 #endif
173         glBindBuffer(GL_ARRAY_BUFFER, handle[ATTRIB_LIGHT]);
174         glBufferData(GL_ARRAY_BUFFER, buf.lights.size() * sizeof(float), buf.lights.data(), GL_STATIC_DRAW);
175         glEnableVertexAttribArray(ATTRIB_LIGHT);
176         glVertexAttribPointer(
177                 ATTRIB_LIGHT, // location (for shader)
178                 1,            // size
179                 GL_FLOAT,     // type
180                 GL_FALSE,     // normalized
181                 0,            // stride
182                 nullptr       // offset
183         );
184
185         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, handle[ATTRIB_INDEX]);
186         glBufferData(GL_ELEMENT_ARRAY_BUFFER, buf.indices.size() * sizeof(Index), buf.indices.data(), GL_STATIC_DRAW);
187         count = buf.indices.size();
188 }
189
190
191 void BlockModel::Draw() const noexcept {
192         glBindVertexArray(va);
193         glDrawElements(
194                 GL_TRIANGLES,    // how
195                 count,           // count
196                 GL_UNSIGNED_INT, // type
197                 nullptr          // offset
198         );
199 }
200
201 OutlineModel::OutlineModel() noexcept
202 : vertices()
203 , colors()
204 , indices()
205 , va(0)
206 , handle{}
207 , dirty(false) {
208         glGenVertexArrays(1, &va);
209         glGenBuffers(ATTRIB_COUNT, handle);
210 }
211
212 OutlineModel::~OutlineModel() noexcept {
213         glDeleteBuffers(ATTRIB_COUNT, handle);
214         glDeleteVertexArrays(1, &va);
215 }
216
217
218 void OutlineModel::Clear() noexcept {
219         vertices.clear();
220         colors.clear();
221         indices.clear();
222         Invalidate();
223 }
224
225 void OutlineModel::Reserve(int v, int i) {
226         vertices.reserve(v);
227         colors.reserve(v);
228         indices.reserve(i);
229 }
230
231
232 void OutlineModel::Update() noexcept {
233         glBindBuffer(GL_ARRAY_BUFFER, handle[ATTRIB_VERTEX]);
234         glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(glm::vec3), vertices.data(), GL_STATIC_DRAW);
235         glEnableVertexAttribArray(ATTRIB_VERTEX);
236         glVertexAttribPointer(
237                 ATTRIB_VERTEX, // location (for shader)
238                 3,             // size
239                 GL_FLOAT,      // type
240                 GL_FALSE,      // normalized
241                 0,             // stride
242                 nullptr        // offset
243         );
244
245 #ifndef NDEBUG
246         if (colors.size() < vertices.size()) {
247                 std::cerr << "OutlineModel: not enough colors!" << std::endl;
248                 colors.resize(vertices.size(), { 1, 0, 1 });
249         }
250 #endif
251         glBindBuffer(GL_ARRAY_BUFFER, handle[ATTRIB_COLOR]);
252         glBufferData(GL_ARRAY_BUFFER, colors.size() * sizeof(glm::vec3), colors.data(), GL_STATIC_DRAW);
253         glEnableVertexAttribArray(ATTRIB_COLOR);
254         glVertexAttribPointer(
255                 ATTRIB_COLOR,  // location (for shader)
256                 3,             // size
257                 GL_FLOAT,      // type
258                 GL_FALSE,      // normalized
259                 0,             // stride
260                 nullptr        // offset
261         );
262
263         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, handle[ATTRIB_INDEX]);
264         glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(Index), indices.data(), GL_STATIC_DRAW);
265
266         dirty = false;
267 }
268
269
270 void OutlineModel::Draw() noexcept {
271         glBindVertexArray(va);
272
273         if (dirty) {
274                 Update();
275         }
276
277         glEnable(GL_LINE_SMOOTH);
278         glLineWidth(2.0f);
279
280         glDrawElements(
281                 GL_LINES,          // how
282                 indices.size(),    // count
283                 GL_UNSIGNED_SHORT, // type
284                 nullptr            // offset
285         );
286 }
287
288 }