4 #include <glm/gtc/matrix_transform.hpp>
5 #include <glm/gtc/constants.hpp>
9 #include "shader_program.hpp"
13 using namespace dragonblocks;
15 double Mesh::Effect::grow_time = 0.25; // s
16 double Mesh::Effect::flyin_time = 0.4; // s
17 double Mesh::Effect::flyin_offset = 20; // m
18 double Mesh::Effect::rotate_speed = 1; // turns/s
20 mat4 Mesh::Effect::getModelMatrix(double dtime, vec3 pos, vec3 size, vec3 rotation_axis, float rotation_angle)
22 mat4 trans = mat4(1.0);
24 if (type == Mesh::Effect::Type::NONE)
30 type = Mesh::Effect::Type::NONE;
32 (*on_finish)(extra_data);
39 case Mesh::Effect::Type::FLYIN:
40 pos.y -= Mesh::Effect::flyin_offset * time_left / Mesh::Effect::flyin_time;
43 case Mesh::Effect::Type::GROW:
44 size *= 1 - time_left / Mesh::Effect::grow_time;
47 case Mesh::Effect::Type::ROTATE:
48 rotation_angle += glfwGetTime() * Mesh::Effect::rotate_speed * pi<float>() * 2;
53 trans = translate(trans, pos);
54 trans = rotate(trans, rotation_angle, rotation_axis);
55 trans = scale(trans, size);
60 Mesh::Effect::Effect(Mesh::Effect::Type t, void (*o)(void *), void *e) : type(t), on_finish(o), extra_data(e)
63 case Mesh::Effect::Type::FLYIN:
65 time_left = Mesh::Effect::flyin_time;
68 case Mesh::Effect::Type::GROW:
70 time_left = Mesh::Effect::grow_time;
73 case Mesh::Effect::Type::ROTATE:
78 void Mesh::vertexConfig(const GLvoid *v, GLsizei s)
80 if (vertices_changed || configured)
81 throw runtime_error("Attempt to configure Mesh that is already configured");
83 memcpy(vertices, v, s);
85 vertices_changed = true;
88 void Mesh::render(double dtime, ShaderProgram *shader_program)
90 if (vertices_changed) {
97 shader_program->use(); CHECKERR
99 mat4 model_matrix = effect.getModelMatrix(dtime, pos, size, rotation_axis, rotation_angle); CHECKERR
101 shader_program->set("model", model_matrix); CHECKERR
103 glBindVertexArray(VAO); CHECKERR
104 for (int i = 0; i < textures.size(); i++) {
105 textures[i].bind(); CHECKERR
106 glDrawArrays(GL_TRIANGLES, i * vertices_per_texture, vertices_per_texture); CHECKERR
108 glBindVertexArray(0); CHECKERR
109 glBindTexture(GL_TEXTURE_2D, 0); CHECKERR
117 rotation_axis = vec3(0.0, 1.0, 0.0);
118 vertices_per_texture = 0;
122 glDeleteVertexArrays(1, &VAO); CHECKERR
125 glDeleteBuffers(1, &VAO); CHECKERR
127 vertices_changed = false;
135 void Mesh::addToScene()
140 void Mesh::removeFromScene()
145 Mesh::Mesh(Scene *s): scene(s)
150 void Mesh::runVertexConfig()
152 if (! vertices || vertices_size == 0)
153 throw runtime_error("Invalid Mesh configuration");
155 glGenVertexArrays(1, &VAO); CHECKERR
156 glGenBuffers(1, &VBO); CHECKERR
158 glBindVertexArray(VAO); CHECKERR
159 glBindBuffer(GL_ARRAY_BUFFER, VBO); CHECKERR
161 glBufferData(GL_ARRAY_BUFFER, vertices_size, vertices, GL_STATIC_DRAW); CHECKERR
163 GLsizei stride = 5 * sizeof(GLfloat); CHECKERR
165 glVertexAttribPointer(0, 3, GL_FLOAT, false, stride, (GLvoid *)(0 * sizeof(GLfloat))); CHECKERR
166 glEnableVertexAttribArray(0); CHECKERR
167 glVertexAttribPointer(1, 2, GL_FLOAT, false, stride, (GLvoid *)(3 * sizeof(GLfloat))); CHECKERR
168 glEnableVertexAttribArray(1); CHECKERR
170 glBindBuffer(GL_ARRAY_BUFFER, 0); CHECKERR
171 glBindVertexArray(0); CHECKERR
175 vertices_changed = false;