]> git.localhorst.tv Git - blank.git/blob - src/model/model.cpp
implemented font redering
[blank.git] / src / model / model.cpp
1 #include "BlockModel.hpp"
2 #include "Model.hpp"
3 #include "OutlineModel.hpp"
4 #include "SpriteModel.hpp"
5
6 #include <iostream>
7
8
9 namespace blank {
10
11 Model::Model() noexcept
12 : va(0)
13 , handle{}
14 , count(0) {
15         glGenVertexArrays(1, &va);
16         glGenBuffers(ATTRIB_COUNT, handle);
17 }
18
19 Model::~Model() noexcept {
20         glDeleteBuffers(ATTRIB_COUNT, handle);
21         glDeleteVertexArrays(1, &va);
22 }
23
24 Model::Model(Model &&other) noexcept
25 : va(other.va)
26 , count(other.count) {
27         other.va = 0;
28         for (int i = 0; i < ATTRIB_COUNT; ++i) {
29                 handle[i] = other.handle[i];
30                 other.handle[i] = 0;
31         }
32 }
33
34 Model &Model::operator =(Model &&other) noexcept {
35         std::swap(va, other.va);
36         for (int i = 0; i < ATTRIB_COUNT; ++i) {
37                 std::swap(handle[i], other.handle[i]);
38         }
39         count = other.count;
40         return *this;
41 }
42
43 void Model::Update(const Buffer &buf) noexcept {
44         glBindVertexArray(va);
45         glBindBuffer(GL_ARRAY_BUFFER, handle[ATTRIB_VERTEX]);
46         glBufferData(GL_ARRAY_BUFFER, buf.vertices.size() * sizeof(glm::vec3), buf.vertices.data(), GL_STATIC_DRAW);
47         glEnableVertexAttribArray(ATTRIB_VERTEX);
48         glVertexAttribPointer(
49                 ATTRIB_VERTEX, // location (for shader)
50                 3,             // size
51                 GL_FLOAT,      // type
52                 GL_FALSE,      // normalized
53                 0,             // stride
54                 nullptr        // offset
55         );
56
57 #ifndef NDEBUG
58         if (buf.colors.size() < buf.vertices.size()) {
59                 std::cerr << "Model: not enough colors!" << std::endl;
60         }
61 #endif
62         glBindBuffer(GL_ARRAY_BUFFER, handle[ATTRIB_COLOR]);
63         glBufferData(GL_ARRAY_BUFFER, buf.colors.size() * sizeof(glm::vec3), buf.colors.data(), GL_STATIC_DRAW);
64         glEnableVertexAttribArray(ATTRIB_COLOR);
65         glVertexAttribPointer(
66                 ATTRIB_COLOR,  // location (for shader)
67                 3,             // size
68                 GL_FLOAT,      // type
69                 GL_FALSE,      // normalized
70                 0,             // stride
71                 nullptr        // offset
72         );
73
74 #ifndef NDEBUG
75         if (buf.normals.size() < buf.vertices.size()) {
76                 std::cerr << "Model: not enough normals!" << std::endl;
77         }
78 #endif
79         glBindBuffer(GL_ARRAY_BUFFER, handle[ATTRIB_NORMAL]);
80         glBufferData(GL_ARRAY_BUFFER, buf.normals.size() * sizeof(glm::vec3), buf.normals.data(), GL_STATIC_DRAW);
81         glEnableVertexAttribArray(ATTRIB_NORMAL);
82         glVertexAttribPointer(
83                 ATTRIB_NORMAL, // location (for shader)
84                 3,             // size
85                 GL_FLOAT,      // type
86                 GL_FALSE,      // normalized
87                 0,             // stride
88                 nullptr        // offset
89         );
90
91         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, handle[ATTRIB_INDEX]);
92         glBufferData(GL_ELEMENT_ARRAY_BUFFER, buf.indices.size() * sizeof(Index), buf.indices.data(), GL_STATIC_DRAW);
93         count = buf.indices.size();
94 }
95
96
97 void Model::Draw() const noexcept {
98         glBindVertexArray(va);
99         glDrawElements(
100                 GL_TRIANGLES,    // how
101                 count,           // count
102                 GL_UNSIGNED_INT, // type
103                 nullptr          // offset
104         );
105 }
106
107
108 BlockModel::BlockModel() noexcept
109 : va(0)
110 , handle{}
111 , count(0) {
112         glGenVertexArrays(1, &va);
113         glGenBuffers(ATTRIB_COUNT, handle);
114 }
115
116 BlockModel::~BlockModel() noexcept {
117         glDeleteBuffers(ATTRIB_COUNT, handle);
118         glDeleteVertexArrays(1, &va);
119 }
120
121 BlockModel::BlockModel(BlockModel &&other) noexcept
122 : va(other.va)
123 , count(other.count) {
124         other.va = 0;
125         for (int i = 0; i < ATTRIB_COUNT; ++i) {
126                 handle[i] = other.handle[i];
127                 other.handle[i] = 0;
128         }
129 }
130
131 BlockModel &BlockModel::operator =(BlockModel &&other) noexcept {
132         std::swap(va, other.va);
133         for (int i = 0; i < ATTRIB_COUNT; ++i) {
134                 std::swap(handle[i], other.handle[i]);
135         }
136         count = other.count;
137         return *this;
138 }
139
140 void BlockModel::Update(const Buffer &buf) noexcept {
141         glBindVertexArray(va);
142         glBindBuffer(GL_ARRAY_BUFFER, handle[ATTRIB_VERTEX]);
143         glBufferData(GL_ARRAY_BUFFER, buf.vertices.size() * sizeof(glm::vec3), buf.vertices.data(), GL_STATIC_DRAW);
144         glEnableVertexAttribArray(ATTRIB_VERTEX);
145         glVertexAttribPointer(
146                 ATTRIB_VERTEX, // location (for shader)
147                 3,             // size
148                 GL_FLOAT,      // type
149                 GL_FALSE,      // normalized
150                 0,             // stride
151                 nullptr        // offset
152         );
153
154 #ifndef NDEBUG
155         if (buf.colors.size() < buf.vertices.size()) {
156                 std::cerr << "BlockModel: not enough colors!" << std::endl;
157         }
158 #endif
159         glBindBuffer(GL_ARRAY_BUFFER, handle[ATTRIB_COLOR]);
160         glBufferData(GL_ARRAY_BUFFER, buf.colors.size() * sizeof(glm::vec3), buf.colors.data(), GL_STATIC_DRAW);
161         glEnableVertexAttribArray(ATTRIB_COLOR);
162         glVertexAttribPointer(
163                 ATTRIB_COLOR,  // location (for shader)
164                 3,             // size
165                 GL_FLOAT,      // type
166                 GL_FALSE,      // normalized
167                 0,             // stride
168                 nullptr        // offset
169         );
170
171 #ifndef NDEBUG
172         if (buf.lights.size() < buf.vertices.size()) {
173                 std::cerr << "BlockModel: not enough lights!" << std::endl;
174         }
175 #endif
176         glBindBuffer(GL_ARRAY_BUFFER, handle[ATTRIB_LIGHT]);
177         glBufferData(GL_ARRAY_BUFFER, buf.lights.size() * sizeof(float), buf.lights.data(), GL_STATIC_DRAW);
178         glEnableVertexAttribArray(ATTRIB_LIGHT);
179         glVertexAttribPointer(
180                 ATTRIB_LIGHT, // location (for shader)
181                 1,            // size
182                 GL_FLOAT,     // type
183                 GL_FALSE,     // normalized
184                 0,            // stride
185                 nullptr       // offset
186         );
187
188         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, handle[ATTRIB_INDEX]);
189         glBufferData(GL_ELEMENT_ARRAY_BUFFER, buf.indices.size() * sizeof(Index), buf.indices.data(), GL_STATIC_DRAW);
190         count = buf.indices.size();
191 }
192
193
194 void BlockModel::Draw() const noexcept {
195         glBindVertexArray(va);
196         glDrawElements(
197                 GL_TRIANGLES,    // how
198                 count,           // count
199                 GL_UNSIGNED_INT, // type
200                 nullptr          // offset
201         );
202 }
203
204 OutlineModel::OutlineModel() noexcept
205 : vertices()
206 , colors()
207 , indices()
208 , va(0)
209 , handle{}
210 , dirty(false) {
211         glGenVertexArrays(1, &va);
212         glGenBuffers(ATTRIB_COUNT, handle);
213 }
214
215 OutlineModel::~OutlineModel() noexcept {
216         glDeleteBuffers(ATTRIB_COUNT, handle);
217         glDeleteVertexArrays(1, &va);
218 }
219
220
221 void OutlineModel::Clear() noexcept {
222         vertices.clear();
223         colors.clear();
224         indices.clear();
225         Invalidate();
226 }
227
228 void OutlineModel::Reserve(int v, int i) {
229         vertices.reserve(v);
230         colors.reserve(v);
231         indices.reserve(i);
232 }
233
234
235 void OutlineModel::Update() noexcept {
236         glBindBuffer(GL_ARRAY_BUFFER, handle[ATTRIB_VERTEX]);
237         glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(glm::vec3), vertices.data(), GL_STATIC_DRAW);
238         glEnableVertexAttribArray(ATTRIB_VERTEX);
239         glVertexAttribPointer(
240                 ATTRIB_VERTEX, // location (for shader)
241                 3,             // size
242                 GL_FLOAT,      // type
243                 GL_FALSE,      // normalized
244                 0,             // stride
245                 nullptr        // offset
246         );
247
248 #ifndef NDEBUG
249         if (colors.size() < vertices.size()) {
250                 std::cerr << "OutlineModel: not enough colors!" << std::endl;
251                 colors.resize(vertices.size(), { 1, 0, 1 });
252         }
253 #endif
254         glBindBuffer(GL_ARRAY_BUFFER, handle[ATTRIB_COLOR]);
255         glBufferData(GL_ARRAY_BUFFER, colors.size() * sizeof(glm::vec3), colors.data(), GL_STATIC_DRAW);
256         glEnableVertexAttribArray(ATTRIB_COLOR);
257         glVertexAttribPointer(
258                 ATTRIB_COLOR,  // location (for shader)
259                 3,             // size
260                 GL_FLOAT,      // type
261                 GL_FALSE,      // normalized
262                 0,             // stride
263                 nullptr        // offset
264         );
265
266         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, handle[ATTRIB_INDEX]);
267         glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(Index), indices.data(), GL_STATIC_DRAW);
268
269         dirty = false;
270 }
271
272
273 void OutlineModel::Draw() noexcept {
274         glBindVertexArray(va);
275
276         if (dirty) {
277                 Update();
278         }
279
280         glEnable(GL_LINE_SMOOTH);
281         glLineWidth(2.0f);
282
283         glDrawElements(
284                 GL_LINES,          // how
285                 indices.size(),    // count
286                 GL_UNSIGNED_SHORT, // type
287                 nullptr            // offset
288         );
289 }
290
291
292 SpriteModel::SpriteModel() noexcept
293 : vertices()
294 , coords()
295 , indices()
296 , va(0)
297 , handle{}
298 , dirty(false) {
299         glGenVertexArrays(1, &va);
300         glGenBuffers(ATTRIB_COUNT, handle);
301 }
302
303 SpriteModel::~SpriteModel() noexcept {
304         glDeleteBuffers(ATTRIB_COUNT, handle);
305         glDeleteVertexArrays(1, &va);
306 }
307
308
309 void SpriteModel::Clear() noexcept {
310         vertices.clear();
311         coords.clear();
312         indices.clear();
313         Invalidate();
314 }
315
316 void SpriteModel::Reserve(int v, int i) {
317         vertices.reserve(v);
318         coords.reserve(v);
319         indices.reserve(i);
320 }
321
322
323 void SpriteModel::LoadRect(
324         float w, float h,
325         const glm::vec2 &pivot,
326         const glm::vec2 &tex_begin,
327         const glm::vec2 &tex_end
328 ) {
329         Clear();
330         Reserve(4, 6);
331
332         vertices.emplace_back( -pivot.x,  -pivot.y, 0.0f);
333         vertices.emplace_back(w-pivot.x,  -pivot.y, 0.0f);
334         vertices.emplace_back( -pivot.x, h-pivot.y, 0.0f);
335         vertices.emplace_back(w-pivot.x, h-pivot.y, 0.0f);
336
337         coords.emplace_back(tex_begin.x, tex_begin.y);
338         coords.emplace_back(tex_end.x,   tex_begin.y);
339         coords.emplace_back(tex_begin.x, tex_end.y);
340         coords.emplace_back(tex_end.x,   tex_end.y);
341
342         indices.assign({ 0, 2, 1, 1, 2, 3 });
343
344         Invalidate();
345 }
346
347
348 void SpriteModel::Update() noexcept {
349         glBindBuffer(GL_ARRAY_BUFFER, handle[ATTRIB_VERTEX]);
350         glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(Position), vertices.data(), GL_STATIC_DRAW);
351         glEnableVertexAttribArray(ATTRIB_VERTEX);
352         glVertexAttribPointer(
353                 ATTRIB_VERTEX, // location (for shader)
354                 3,             // size
355                 GL_FLOAT,      // type
356                 GL_FALSE,      // normalized
357                 0,             // stride
358                 nullptr        // offset
359         );
360
361 #ifndef NDEBUG
362         if (coords.size() < vertices.size()) {
363                 std::cerr << "SpriteModel: not enough coords!" << std::endl;
364                 coords.resize(vertices.size(), { 1, 1 });
365         }
366 #endif
367         glBindBuffer(GL_ARRAY_BUFFER, handle[ATTRIB_TEXCOORD]);
368         glBufferData(GL_ARRAY_BUFFER, coords.size() * sizeof(TexCoord), coords.data(), GL_STATIC_DRAW);
369         glEnableVertexAttribArray(ATTRIB_TEXCOORD);
370         glVertexAttribPointer(
371                 ATTRIB_TEXCOORD, // location (for shader)
372                 2,               // size
373                 GL_FLOAT,        // type
374                 GL_FALSE,        // normalized
375                 0,               // stride
376                 nullptr          // offset
377         );
378
379         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, handle[ATTRIB_INDEX]);
380         glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(Index), indices.data(), GL_STATIC_DRAW);
381
382         dirty = false;
383 }
384
385
386 void SpriteModel::Draw() noexcept {
387         glBindVertexArray(va);
388
389         if (dirty) {
390                 Update();
391         }
392
393         glDrawElements(
394                 GL_TRIANGLES,      // how
395                 indices.size(),    // count
396                 GL_UNSIGNED_SHORT, // type
397                 nullptr            // offset
398         );
399 }
400
401 }