sgltk 0.6
Simple OpenGL Tool Kit
Loading...
Searching...
No Matches
mesh.cpp
1#include "mesh.h"
2
3using namespace sgltk;
4
5Mesh::Mesh() {
6 tf_mode = GL_NONE;
7 model_matrix = glm::mat4(1.0);
8 shader = nullptr;
9 num_uv = 0;
10 num_col = 0;
11 num_vertices = 0;
12 index_type = 0;
13 glGenVertexArrays(1, &vao);
14
15 view_matrix = nullptr;
16 projection_matrix = nullptr;
17
18 bounding_box = { glm::vec3(0, 0, 0), glm::vec3(0, 0, 0) };
19
20 model_matrix_name = "model_matrix";
21 view_matrix_name = "view_matrix";
22 projection_matrix_name = "proj_matrix";
23 model_view_matrix_name = "model_view_matrix";
24 view_proj_matrix_name = "view_proj_matrix";
25 model_view_projection_matrix_name = "model_view_proj_matrix";
26 normal_matrix_name = "normal_matrix";
27
28 ambient_color_name = "color_ambient";
29 diffuse_color_name = "color_diffuse";
30 specular_color_name = "color_specular";
31 shininess_name = "shininess";
32 shininess_strength_name = "shininess_strength";
33
34 shininess = 0.0;
36 color_ambient = glm::vec4(0, 0, 0, 1);
37 color_diffuse = glm::vec4(0, 0, 0, 1);
38 color_specular = glm::vec4(0, 0, 0, 1);
39}
40
41Mesh::~Mesh() {
42 glDeleteVertexArrays(1, &vao);
43}
44
46 this->shader = shader;
47}
48
49bool Mesh::setup_camera(glm::mat4 *view_matrix,
50 glm::mat4 *projection_matrix) {
51 if(!view_matrix || !projection_matrix)
52 return false;
53
54 this->view_matrix = view_matrix;
55 this->projection_matrix = projection_matrix;
56 return true;
57}
58
60 if(!camera)
61 return false;
62
63 this->view_matrix = &camera->view_matrix;
64 this->projection_matrix = &camera->projection_matrix;
65 return true;
66}
67
68void Mesh::set_model_matrix_name(const std::string& name) {
69
70 if(name.length() > 0)
71 model_matrix_name = name;
72 else
73 model_matrix_name = "model_matrix";
74}
75
76void Mesh::set_view_matrix_name(const std::string& name) {
77
78 if(name.length() > 0)
79 view_matrix_name = name;
80 else
81 view_matrix_name = "view_matrix";
82}
83
84void Mesh::set_projection_matrix_name(const std::string& name) {
85
86 if(name.length() > 0)
88 else
89 projection_matrix_name = "proj_matrix";
90}
91
92void Mesh::set_model_view_matrix_name(const std::string& name) {
93
94 if(name.length() > 0)
96 else
97 model_view_matrix_name = "model_view_matrix";
98}
99
100void Mesh::set_view_proj_matrix_name(const std::string& name) {
101
102 if(name.length() > 0)
104 else
105 view_proj_matrix_name = "view_proj_matrix";
106}
107
108void Mesh::set_model_view_proj_name(const std::string& name) {
109
110 if(name.length() > 0)
112 else
113 model_view_projection_matrix_name = "model_view_proj_matrix";
114}
115
116void Mesh::set_normal_matrix_name(const std::string& name) {
117
118 if(name.length() > 0)
119 normal_matrix_name = name;
120 else
121 normal_matrix_name = "normal_matrix";
122}
123
124void Mesh::set_ambient_color_name(const std::string& name) {
125 if(name.length() > 0)
126 ambient_color_name = name;
127 else
128 ambient_color_name = "color_ambient";
129}
130
131void Mesh::set_diffuse_color_name(const std::string& name) {
132 if(name.length() > 0)
133 diffuse_color_name = name;
134 else
135 diffuse_color_name = "color_diffuse";
136}
137
138void Mesh::set_specular_color_name(const std::string& name) {
139 if(name.length() > 0)
140 specular_color_name = name;
141 else
142 specular_color_name = "color_specular";
143}
144
145void Mesh::set_shininess_name(const std::string& name) {
146 if(name.length() > 0)
147 shininess_name = name;
148 else
149 shininess_name = "shininess";
150}
151
152void Mesh::set_shininess_strength_name(const std::string& name) {
153 if(name.length() > 0)
155 else
156 shininess_strength_name = "shininess_strength";
157}
158
159void Mesh::attach_texture(const std::string& name,
160 const Texture& texture,
161 unsigned int index) {
162
163 textures.push_back({name, texture, index});
164}
165
167 tf_mode = mode;
168}
169
170void Mesh::attach_buffer(const Buffer *buffer,
171 GLuint target,
172 unsigned int index) {
173
174 attached_buffers.push_back(const_cast<Buffer*>(buffer));
175 attached_buffers_targets.push_back(target);
176 attached_buffers_indices.push_back(index);
177}
178
179int Mesh::set_vertex_attribute(const std::string& attrib_name,
180 unsigned int buffer_index,
181 GLint number_elements,
182 GLenum type,
183 GLsizei stride,
184 const GLvoid *pointer,
185 unsigned int divisor) {
186
187 if(!shader) {
188 return -1;
189 }
190
191 int loc = shader->get_attribute_location(attrib_name);
192 if(loc < 0) {
193 return -2;
194 }
195
196 return set_vertex_attribute(loc, buffer_index, number_elements, type,
197 stride, pointer, divisor);
198}
199
200int Mesh::set_vertex_attribute(int attrib_location,
201 unsigned int buffer_index,
202 GLint number_elements,
203 GLenum type,
204 GLsizei stride,
205 const GLvoid *pointer,
206 unsigned int divisor) {
207
208 if(attrib_location < 0) {
209 return -2;
210 }
211
212 if(buffer_index >= vbo.size()) {
213 return -3;
214 }
215
216 glBindVertexArray(vao);
217 vbo[buffer_index]->bind();
218
219 glEnableVertexAttribArray(attrib_location);
220 switch(type) {
221 case GL_BYTE:
222 case GL_UNSIGNED_BYTE:
223 case GL_SHORT:
224 case GL_UNSIGNED_SHORT:
225 case GL_INT:
226 case GL_UNSIGNED_INT:
227 glVertexAttribIPointer(attrib_location, number_elements,
228 type, stride, (void *)pointer);
229 break;
230 case GL_DOUBLE:
231 glVertexAttribLPointer(attrib_location, number_elements,
232 type, stride, (void *)pointer);
233 break;
234 default:
235 glVertexAttribPointer(attrib_location, number_elements,
236 type, GL_FALSE, stride,
237 (void*)pointer);
238 break;
239 }
240
241 glVertexAttribDivisor(attrib_location, divisor);
242 glBindVertexArray(0);
243 return 0;
244}
245
246int Mesh::set_buffer_vertex_attribute(const std::string& attrib_name,
247 sgltk::Buffer *buffer,
248 GLint number_elements,
249 GLenum type,
250 GLsizei stride,
251 const GLvoid *pointer,
252 unsigned int divisor) {
253
254 if(!shader) {
255 return -1;
256 }
257
258 int loc = shader->get_attribute_location(attrib_name);
259 if(loc < 0) {
260 return -2;
261 }
262
263 return set_buffer_vertex_attribute(loc, buffer, number_elements, type,
264 stride, pointer, divisor);
265}
266
267int Mesh::set_buffer_vertex_attribute(int attrib_location,
268 sgltk::Buffer *buffer,
269 GLint number_elements,
270 GLenum type,
271 GLsizei stride,
272 const GLvoid *pointer,
273 unsigned int divisor) {
274
275 if(attrib_location < 0) {
276 return -2;
277 }
278
279 glBindVertexArray(vao);
280 buffer->bind();
281
282 glEnableVertexAttribArray(attrib_location);
283 switch(type) {
284 case GL_BYTE:
285 case GL_UNSIGNED_BYTE:
286 case GL_SHORT:
287 case GL_UNSIGNED_SHORT:
288 case GL_INT:
289 case GL_UNSIGNED_INT:
290 glVertexAttribIPointer(attrib_location, number_elements,
291 type, stride, (void *)pointer);
292 break;
293 case GL_DOUBLE:
294 glVertexAttribLPointer(attrib_location, number_elements,
295 type, stride, (void *)pointer);
296 break;
297 default:
298 glVertexAttribPointer(attrib_location, number_elements,
299 type, GL_FALSE, stride,
300 (void*)pointer);
301 break;
302 }
303
304 glVertexAttribDivisor(attrib_location, divisor);
305 glBindVertexArray(0);
306 return 0;
307}
308
309void Mesh::material_uniform() {
315
316 int texture_loc;
317 int num_textures = 0;
318 for(const auto& tex : textures) {
319 texture_loc = shader->get_uniform_location(std::get<0>(tex));
320 if(texture_loc >= 0) {
321 shader->set_uniform(texture_loc + std::get<2>(tex), num_textures);
322 const_cast<Texture&>(std::get<1>(tex)).bind(num_textures++);
323 }
324 }
325 for(const auto& tex : auto_textures) {
326 texture_loc = shader->get_uniform_location(std::get<0>(tex));
327 if(texture_loc >= 0) {
328 shader->set_uniform(texture_loc + std::get<2>(tex), num_textures);
329 const_cast<Texture&>(std::get<1>(tex)).bind(num_textures++);
330 }
331 }
332}
333
334void Mesh::draw(GLenum mode) {
335 draw(mode, 0, nullptr);
336}
337
338void Mesh::draw(GLenum mode, const glm::mat4 *model_matrix) {
339 draw(mode, 0, model_matrix);
340}
341
342void Mesh::draw(GLenum mode,
343 unsigned int index_buffer,
344 const glm::mat4 *model_matrix = nullptr) {
345
346 if(!shader) {
347 App::error_string.push_back("Error: No shader specified");
348 return;
349 }
350
351 glm::mat4 M;
352 glm::mat4 MV;
353 glm::mat4 MVP;
354 glm::mat4 VP;
355 glm::mat3 NM;
356 if(model_matrix)
357 M = *model_matrix;
358 else
359 M = this->model_matrix;
360 shader->set_uniform(model_matrix_name, false, M);
361
362 NM = glm::transpose(glm::inverse(glm::mat3(M)));
363 shader->set_uniform(normal_matrix_name, false, NM);
364
365 if(view_matrix) {
366 MV = (*view_matrix) * M;
367 shader->set_uniform(view_matrix_name, false, *view_matrix);
368 shader->set_uniform(model_view_matrix_name, false, MV);
369 }
370 if(projection_matrix) {
371 if(view_matrix) {
372 MVP = (*projection_matrix) * MV;
373 VP = (*projection_matrix) * (*view_matrix);
374 shader->set_uniform(view_proj_matrix_name, false, VP);
375 } else {
376 MVP = (*projection_matrix) * M;
377 }
378 shader->set_uniform(projection_matrix_name, false,
379 *projection_matrix);
381 false, MVP);
382 }
383
384 material_uniform();
385
386 for(unsigned int i = 0; i < attached_buffers.size(); i++) {
387 attached_buffers[i]->bind(attached_buffers_targets[i],
388 attached_buffers_indices[i]);
389 }
390
391 glBindVertexArray(vao);
392 ibo[index_buffer]->bind();
393 if(shader->transform_feedback) {
394 GLenum primitive_type = tf_mode;
395 if(primitive_type == GL_NONE) {
396 switch(mode) {
397 case GL_POINTS:
398 primitive_type = GL_POINTS;
399 break;
400 case GL_LINES:
401 case GL_LINE_LOOP:
402 case GL_LINE_STRIP:
403 case GL_LINES_ADJACENCY:
404 case GL_LINE_STRIP_ADJACENCY:
405 primitive_type = GL_LINES;
406 break;
407 case GL_TRIANGLES:
408 case GL_TRIANGLE_STRIP:
409 case GL_TRIANGLE_FAN:
410 case GL_TRIANGLES_ADJACENCY:
411 case GL_TRIANGLE_STRIP_ADJACENCY:
412 primitive_type = GL_TRIANGLES;
413 break;
414 default:
415 break;
416 }
417 }
418 glBeginTransformFeedback(primitive_type);
419 }
420 glDrawElements(mode, ibo[index_buffer]->num_elements,
421 index_type, (void*)0);
422 if(shader->transform_feedback) {
423 glEndTransformFeedback();
424 }
425 ibo[index_buffer]->unbind();
426 glBindVertexArray(0);
427
428 for(unsigned int i = 0; i < attached_buffers.size(); i++) {
429 attached_buffers[i]->unbind();
430 }
431}
432
433void Mesh::draw_instanced(GLenum mode, unsigned int num_instances) {
434 draw_instanced(mode, 0, num_instances);
435}
436
437void Mesh::draw_instanced(GLenum mode, unsigned int index_buffer,
438 unsigned int num_instances) {
439
440 if(!shader) {
441 App::error_string.push_back("Error: No shader specified");
442 return;
443 }
444
445 glm::mat4 VP = (*projection_matrix) * (*view_matrix);
446
447 shader->set_uniform(view_matrix_name, false, *view_matrix);
448 shader->set_uniform(projection_matrix_name, false, *projection_matrix);
449 shader->set_uniform(view_proj_matrix_name, false, VP);
450
451 material_uniform();
452
453 for(unsigned int i = 0; i < attached_buffers.size(); i++) {
454 attached_buffers[i]->bind(attached_buffers_targets[i],
455 attached_buffers_indices[i]);
456 }
457
458 glBindVertexArray(vao);
459 ibo[index_buffer]->bind();
460 if(shader->transform_feedback) {
461 GLenum primitive_type = tf_mode;
462 if(primitive_type == GL_NONE) {
463 switch(mode) {
464 case GL_POINTS:
465 primitive_type = GL_POINTS;
466 break;
467 case GL_LINES:
468 case GL_LINE_LOOP:
469 case GL_LINE_STRIP:
470 case GL_LINES_ADJACENCY:
471 case GL_LINE_STRIP_ADJACENCY:
472 primitive_type = GL_LINES;
473 break;
474 case GL_TRIANGLES:
475 case GL_TRIANGLE_STRIP:
476 case GL_TRIANGLE_FAN:
477 case GL_TRIANGLES_ADJACENCY:
478 case GL_TRIANGLE_STRIP_ADJACENCY:
479 primitive_type = GL_TRIANGLES;
480 break;
481 default:
482 break;
483 }
484 }
485 glBeginTransformFeedback(primitive_type);
486 }
487 glDrawElementsInstanced(mode, ibo[index_buffer]->num_elements,
488 index_type, (void*)0, num_instances);
489 if(shader->transform_feedback) {
490 glEndTransformFeedback();
491 }
492 ibo[index_buffer]->unbind();
493 glBindVertexArray(0);
494
495 for(unsigned int i = 0; i < attached_buffers.size(); i++) {
496 attached_buffers[i]->unbind();
497 }
498}
static std::vector< std::string > error_string
A list of all error strings.
Definition app.h:151
Manages buffer objects.
Definition buffer.h:12
void bind()
Binds the buffer object to the target it was previously bound to or GL_ARRAY_BUFFER if the buffer has...
Definition buffer.h:48
Manages cameras.
Definition camera.h:12
glm::mat4 view_matrix
The view matrix.
Definition camera.h:17
glm::mat4 projection_matrix
The perspective projection matrix.
Definition camera.h:21
void set_projection_matrix_name(const std::string &name)
Sets the name of the projection matrix in the shader.
Definition mesh.cpp:84
int set_buffer_vertex_attribute(const std::string &attrib_name, sgltk::Buffer *buffer, GLint number_elements, GLenum type, GLsizei stride, const GLvoid *pointer, unsigned int divisor=0)
Sets pointers to vertex attributes.
Definition mesh.cpp:246
void attach_buffer(const sgltk::Buffer *buffer, GLuint target, unsigned int index=0)
Attaches a buffer that is automatically bound before each draw call.
Definition mesh.cpp:170
glm::vec4 color_diffuse
The diffuse color component of the material.
Definition mesh.h:246
std::string model_view_projection_matrix_name
The name of the model-view-projection matrix in the shader.
Definition mesh.h:213
std::string view_proj_matrix_name
The name of the view-projection matrix in the shader.
Definition mesh.h:209
std::vector< std::tuple< std::string, const Texture &, unsigned int > > textures
Attached user textures.
Definition mesh.h:258
std::string ambient_color_name
The name of the ambient materiel component.
Definition mesh.h:172
std::string diffuse_color_name
The name of the diffuse materiel component.
Definition mesh.h:176
void set_shininess_name(const std::string &name)
Sets the name of the shininess of the material in the shader.
Definition mesh.cpp:145
void set_model_view_matrix_name(const std::string &name)
Sets the name of the model-view matrix in the shader.
Definition mesh.cpp:92
void set_normal_matrix_name(const std::string &name)
Sets the name of the normal matrix in the shader.
Definition mesh.cpp:116
std::string projection_matrix_name
The name of the projection matrix in the shader.
Definition mesh.h:201
std::vector< std::tuple< std::string, const Texture &, unsigned int > > auto_textures
Attached textures.
Definition mesh.h:254
void attach_texture(const std::string &name, const sgltk::Texture &texture, unsigned int index=0)
Attaches a texture to the mesh.
Definition mesh.cpp:159
void draw_instanced(GLenum mode, unsigned int num_instances)
Renders the mesh multiple times.
Definition mesh.cpp:433
void draw(GLenum mode)
Renders the mesh using the first index buffer.
Definition mesh.cpp:334
void set_ambient_color_name(const std::string &name)
Sets the name of the ambient color in the shader.
Definition mesh.cpp:124
std::string model_matrix_name
The name of the model matrix in the shader.
Definition mesh.h:193
void set_model_matrix_name(const std::string &name)
Sets the name of the model matrix in the shader.
Definition mesh.cpp:68
std::vector< glm::vec3 > bounding_box
The bounding box.
Definition mesh.h:226
std::string shininess_strength_name
The name of the specular exponent.
Definition mesh.h:188
void set_diffuse_color_name(const std::string &name)
Sets the name of the diffuse color in the shader.
Definition mesh.cpp:131
std::string normal_matrix_name
The name of the normal matrix in the shader.
Definition mesh.h:217
unsigned int num_col
Number of vertex colors.
Definition mesh.h:164
void set_shininess_strength_name(const std::string &name)
Sets the name of the shininess strength of the material in the shader.
Definition mesh.cpp:152
void setup_shader(Shader *shader)
Specifies the shader to use to render the mesh.
Definition mesh.cpp:45
std::string model_view_matrix_name
The name of the model-view matrix in the shader.
Definition mesh.h:205
Shader * shader
The shader being used to draw the mesh.
Definition mesh.h:222
float shininess_strength
The strength of the shininess of the material.
Definition mesh.h:238
glm::vec4 color_ambient
The ambient color component of the material.
Definition mesh.h:242
void set_specular_color_name(const std::string &name)
Sets the name of the specular color in the shader.
Definition mesh.cpp:138
void set_model_view_proj_name(const std::string &name)
Sets the name of the model-view-projection matrix in the shader.
Definition mesh.cpp:108
std::string view_matrix_name
The name of the view matrix in the shader.
Definition mesh.h:197
std::string shininess_name
The name of the specular factor.
Definition mesh.h:184
bool setup_camera(glm::mat4 *view_matrix, glm::mat4 *projection_matrix)
Sets up the view and projection matrices that will be used by the mesh.
Definition mesh.cpp:49
glm::vec4 color_specular
The specular color component of the material.
Definition mesh.h:250
unsigned int num_vertices
Number of vertices.
Definition mesh.h:168
void set_transform_feedback_mode(GLenum mode)
Sets the output type for transform feedback operations.
Definition mesh.cpp:166
glm::mat4 model_matrix
The model matrix.
Definition mesh.h:230
int set_vertex_attribute(const std::string &attrib_name, unsigned int buffer_index, GLint number_elements, GLenum type, GLsizei stride, const GLvoid *pointer, unsigned int divisor=0)
Sets pointers to vertex attributes.
Definition mesh.cpp:179
unsigned int num_uv
Number of texture coordinates.
Definition mesh.h:160
std::string specular_color_name
The name of the specular materiel component.
Definition mesh.h:180
void set_view_proj_matrix_name(const std::string &name)
Sets the name of the view-projection matrix in the shader.
Definition mesh.cpp:100
float shininess
The shininess of the material.
Definition mesh.h:234
void set_view_matrix_name(const std::string &name)
Sets the name of the view matrix in the shader.
Definition mesh.cpp:76
Manager shaders.
Definition shader.h:12
void set_uniform(int location, T v0)
Sets the uniform.
int get_uniform_location(const std::string &name)
Returns the location of a uniform variable.
Definition shader.cpp:199
Manages textures.
Definition texture.h:13