]> git.localhorst.tv Git - blank.git/blob - src/model.cpp
08b29242b1b185a90c60d54ec59e3b58b2fa4edf
[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         for (int i = 0; i < ATTRIB_COUNT; ++i) {
37                 std::swap(handle[i], other.handle[i]);
38         }
39         dirty = other.dirty;
40         return *this;
41 }
42
43
44 void Model::Clear() {
45         vertices.clear();
46         colors.clear();
47         normals.clear();
48         Invalidate();
49 }
50
51 void Model::Reserve(int s) {
52         vertices.reserve(s);
53         colors.reserve(s);
54         normals.reserve(s);
55 }
56
57
58 void Model::Update() {
59         glBindBuffer(GL_ARRAY_BUFFER, handle[ATTRIB_VERTEX]);
60         glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(glm::vec3), vertices.data(), GL_STATIC_DRAW);
61
62 #ifndef NDEBUG
63         if (colors.size() < vertices.size()) {
64                 std::cerr << "Model: not enough colors!" << std::endl;
65                 colors.resize(vertices.size(), { 1, 0, 1 });
66         }
67 #endif
68         glBindBuffer(GL_ARRAY_BUFFER, handle[ATTRIB_COLOR]);
69         glBufferData(GL_ARRAY_BUFFER, colors.size() * sizeof(glm::vec3), colors.data(), GL_STATIC_DRAW);
70
71 #ifndef NDEBUG
72         if (normals.size() < vertices.size()) {
73                 std::cerr << "Model: not enough normals!" << std::endl;
74                 normals.resize(vertices.size(), { 0, 1, 0 });
75         }
76 #endif
77         glBindBuffer(GL_ARRAY_BUFFER, handle[ATTRIB_NORMAL]);
78         glBufferData(GL_ARRAY_BUFFER, normals.size() * sizeof(glm::vec3), normals.data(), GL_STATIC_DRAW);
79
80         dirty = false;
81 }
82
83
84 void Model::Draw() {
85         if (dirty) {
86                 Update();
87         }
88
89         glEnableVertexAttribArray(ATTRIB_VERTEX);
90         glBindBuffer(GL_ARRAY_BUFFER, handle[ATTRIB_VERTEX]);
91         glVertexAttribPointer(
92                 ATTRIB_VERTEX, // location (for shader)
93                 3,             // size
94                 GL_FLOAT,      // type
95                 GL_FALSE,      // normalized
96                 0,             // stride
97                 nullptr        // offset
98         );
99
100         glEnableVertexAttribArray(ATTRIB_COLOR);
101         glBindBuffer(GL_ARRAY_BUFFER, handle[ATTRIB_COLOR]);
102         glVertexAttribPointer(
103                 ATTRIB_COLOR,  // location (for shader)
104                 3,             // size
105                 GL_FLOAT,      // type
106                 GL_FALSE,      // normalized
107                 0,             // stride
108                 nullptr        // offset
109         );
110
111         glEnableVertexAttribArray(ATTRIB_NORMAL);
112         glBindBuffer(GL_ARRAY_BUFFER, handle[ATTRIB_NORMAL]);
113         glVertexAttribPointer(
114                 ATTRIB_NORMAL, // location (for shader)
115                 3,             // size
116                 GL_FLOAT,      // type
117                 GL_FALSE,      // normalized
118                 0,             // stride
119                 nullptr        // offset
120         );
121
122         glDrawArrays(
123                 GL_TRIANGLES,   // how
124                 0,              // start
125                 vertices.size() // len
126         );
127
128         glDisableVertexAttribArray(ATTRIB_NORMAL);
129         glDisableVertexAttribArray(ATTRIB_COLOR);
130         glDisableVertexAttribArray(ATTRIB_VERTEX);
131 }
132
133
134 OutlineModel::OutlineModel()
135 : vertices()
136 , colors()
137 , handle{}
138 , dirty(false) {
139         glGenBuffers(ATTRIB_COUNT, handle);
140 }
141
142 OutlineModel::~OutlineModel() {
143         glDeleteBuffers(ATTRIB_COUNT, handle);
144 }
145
146
147 void OutlineModel::Clear() {
148         vertices.clear();
149         colors.clear();
150         Invalidate();
151 }
152
153 void OutlineModel::Reserve(int s) {
154         vertices.reserve(s);
155         colors.reserve(s);
156 }
157
158
159 void OutlineModel::Update() {
160         glBindBuffer(GL_ARRAY_BUFFER, handle[ATTRIB_VERTEX]);
161         glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(glm::vec3), vertices.data(), GL_STATIC_DRAW);
162
163 #ifndef NDEBUG
164         if (colors.size() < vertices.size()) {
165                 std::cerr << "OutlineModel: not enough colors!" << std::endl;
166                 colors.resize(vertices.size(), { 1, 0, 1 });
167         }
168 #endif
169         glBindBuffer(GL_ARRAY_BUFFER, handle[ATTRIB_COLOR]);
170         glBufferData(GL_ARRAY_BUFFER, colors.size() * sizeof(glm::vec3), colors.data(), GL_STATIC_DRAW);
171
172         dirty = false;
173 }
174
175
176 void OutlineModel::Draw() {
177         if (dirty) {
178                 Update();
179         }
180
181         glEnableVertexAttribArray(ATTRIB_VERTEX);
182         glBindBuffer(GL_ARRAY_BUFFER, handle[ATTRIB_VERTEX]);
183         glVertexAttribPointer(
184                 ATTRIB_VERTEX, // location (for shader)
185                 3,             // size
186                 GL_FLOAT,      // type
187                 GL_FALSE,      // normalized
188                 0,             // stride
189                 nullptr        // offset
190         );
191
192         glEnableVertexAttribArray(ATTRIB_COLOR);
193         glBindBuffer(GL_ARRAY_BUFFER, handle[ATTRIB_COLOR]);
194         glVertexAttribPointer(
195                 ATTRIB_COLOR,  // location (for shader)
196                 3,             // size
197                 GL_FLOAT,      // type
198                 GL_FALSE,      // normalized
199                 0,             // stride
200                 nullptr        // offset
201         );
202
203         glEnable(GL_LINE_SMOOTH);
204         glLineWidth(2.0f);
205
206         glDrawArrays(
207                 GL_LINES,       // how
208                 0,              // start
209                 vertices.size() // len
210         );
211
212         glDisableVertexAttribArray(ATTRIB_COLOR);
213         glDisableVertexAttribArray(ATTRIB_VERTEX);
214 }
215
216 }