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