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