]> git.lizzy.rs Git - dragonblocks3d.git/blob - src/dragonblocks/mesh.cpp
a37ac3a4d6827d7e4d0dfa1649c036e92f90811f
[dragonblocks3d.git] / src / dragonblocks / mesh.cpp
1 #include <glm/gtc/matrix_transform.hpp>
2 #include <glm/gtc/constants.hpp>
3 #include "gldebug.hpp"
4 #include "mesh.hpp"
5 #include "scene.hpp"
6 #include "shader_program.hpp"
7
8 using namespace std;
9 using namespace glm;
10 using namespace dragonblocks;
11
12 double Mesh::Effect::grow_time = 0.5;   // s
13 double Mesh::Effect::flyin_time = 0.5;  // s
14 double Mesh::Effect::flyin_offset = 20; // m
15 double Mesh::Effect::rotate_speed = 1;  // turns/s
16
17 mat4 Mesh::Effect::getModelMatrix(double dtime, vec3 pos, vec3 size, vec3 rotation_axis, float rotation_angle, void *extra_data)
18 {
19         mat4 trans = mat4(1.0);
20
21         if (type == Mesh::Effect::Type::NONE)
22                 goto finish;
23
24         if (expires) {
25                 time_left -= dtime;
26                 if (time_left < 0) {
27                         type = Mesh::Effect::Type::NONE;
28                         if (on_finish) {
29                                 (*on_finish)(extra_data);
30                         }
31                         goto finish;
32                 }
33         }       
34
35         switch (type) {
36                 case Mesh::Effect::Type::FLYIN:
37                 pos.y -= Mesh::Effect::flyin_offset * time_left / Mesh::Effect::flyin_time;
38                 break;
39                 
40                 case Mesh::Effect::Type::GROW:
41                 size *= 1 - time_left / Mesh::Effect::grow_time;
42                 break;
43                 
44                 case Mesh::Effect::Type::ROTATE:
45                 rotation_angle += glfwGetTime() * Mesh::Effect::rotate_speed * pi<float>() * 2;
46         }
47
48         finish:
49         
50         trans = translate(trans, pos);
51         trans = rotate(trans, rotation_angle, rotation_axis);
52         trans = scale(trans, size);
53         
54         return trans;
55 }
56
57 Mesh::Effect::Effect(Mesh::Effect::Type t, void (*callback)(void *))
58 {
59         type = t;
60         on_finish = callback;
61         switch(type) {
62                 case Mesh::Effect::Type::FLYIN:
63                 expires = true;
64                 time_left = Mesh::Effect::flyin_time;
65                 break;
66                 
67                 case Mesh::Effect::Type::GROW:
68                 expires = true;
69                 time_left = Mesh::Effect::grow_time;
70                 break;
71                 
72                 case Mesh::Effect::Type::ROTATE:
73                 expires = false;
74         }
75 }
76
77 void Mesh::configureVertexObjects(const GLvoid *vertices, GLsizeiptr vertices_size)
78 {
79         glGenVertexArrays(1, &VAO); CHECKERR
80         glGenBuffers(1, &VBO); CHECKERR
81         
82         glBindVertexArray(VAO); CHECKERR
83         glBindBuffer(GL_ARRAY_BUFFER, VBO); CHECKERR
84         
85         glBufferData(GL_ARRAY_BUFFER, vertices_size, vertices, GL_STATIC_DRAW); CHECKERR
86         
87         GLsizei stride = 5 * sizeof(GLfloat); CHECKERR
88         
89         glVertexAttribPointer(0, 3, GL_FLOAT, false, stride, (GLvoid *)(0 * sizeof(GLfloat))); CHECKERR
90         glEnableVertexAttribArray(0); CHECKERR
91         glVertexAttribPointer(1, 2, GL_FLOAT, false, stride, (GLvoid *)(3 * sizeof(GLfloat))); CHECKERR
92         glEnableVertexAttribArray(1); CHECKERR
93         
94         glBindBuffer(GL_ARRAY_BUFFER, 0); CHECKERR
95         glBindVertexArray(0); CHECKERR
96 }
97
98 void Mesh::render(double dtime, ShaderProgram *shader_program)
99 {
100         shader_program->use(); CHECKERR
101         
102         mat4 model_matrix = effect.getModelMatrix(dtime, pos, size, rotation_axis, rotation_angle, extra_data); CHECKERR
103         
104         shader_program->set("model", model_matrix); CHECKERR
105         
106         glBindVertexArray(VAO); CHECKERR
107         for (int i = 0; i < textures.size(); i++) {
108                 textures[i].bind(); CHECKERR
109                 glDrawArrays(GL_TRIANGLES, i * vertices_per_texture, vertices_per_texture); CHECKERR
110         }
111         glBindVertexArray(0); CHECKERR
112         glBindTexture(GL_TEXTURE_2D, 0); CHECKERR
113 }
114
115 void Mesh::addToScene()
116 {
117         scene->add(this);
118 }
119
120 void Mesh::removeFromScene()
121 {
122         scene->remove(this);
123 }
124
125 Mesh::Mesh(Scene *s): pos(0.0), size(1.0), rotation_axis(0.0, 1.0, 0.0), scene(s)
126 {
127 }