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