quick backup
[demo] / src / opengl / mesh-gl.cc
1 #include <GL/glew.h>
2 #include <gmath/gmath.h>
3
4 #include "mesh-gl.h"
5
6 MeshGL::MeshGL()
7 {
8         vao = 0;
9
10         vbo_vertices = 0;
11         vbo_normals = 0;
12         vbo_tex_coords = 0;
13         ibo = 0;
14
15         num_vertices = 0;
16         num_indices = 0;
17 }
18
19 MeshGL::MeshGL(const MeshGL &mesh)
20 {
21         indices = mesh.indices;
22         vertices = mesh.vertices;
23         normals = mesh.normals;
24         tex_coords = mesh.tex_coords;
25
26         vbo_vertices = 0;
27         vbo_normals = 0;
28         vbo_tex_coords = 0;
29         ibo = 0;
30         vao = 0;
31
32         /*
33          * if we set these to the actual
34          * vertices.size() and indices.size()
35          * update_vbo will have no effect
36          * */
37
38         num_vertices = 0;
39         num_indices = 0;
40 }
41
42 MeshGL &MeshGL::operator=(const MeshGL &mesh)
43 {
44         if(this == &mesh)
45                 return *this;
46
47         /* to avoid OpenGL leaks */
48         destroy_vbo();
49
50         /* what the copy constructor does */
51         indices = mesh.indices;
52         vertices = mesh.vertices;
53         normals = mesh.normals;
54         tex_coords = mesh.tex_coords;
55
56         return *this;
57 }
58
59 MeshGL::~MeshGL()
60 {
61         destroy_vbo();
62
63         vertices.clear();
64         normals.clear();
65 }
66
67 void MeshGL::draw() const
68 {
69         glBindVertexArray(vao);
70
71         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
72         glDrawElements(GL_TRIANGLES, num_indices, GL_UNSIGNED_SHORT, 0);
73
74         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
75         glBindVertexArray(0);
76 }
77
78 void MeshGL::update_vertex_data()
79 {
80         update_vbo();
81 }
82
83 void MeshGL::update_vbo()
84 {
85         if(vertices.empty()) {
86                 printf("empty vertices\n");
87                 return;
88         }
89
90         /* vao */
91         if(!vao)
92                 glGenVertexArrays(1, &vao);
93         glBindVertexArray(vao);
94
95         /* vertices */
96
97         if(!vbo_vertices)
98                 glGenBuffers(1, &vbo_vertices);
99         glBindBuffer(GL_ARRAY_BUFFER, vbo_vertices);
100         if(num_vertices != (int)vertices.size())
101                 glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(Vec3),
102                              &vertices[0], GL_STATIC_DRAW);
103         else
104                 glBufferSubData(GL_ARRAY_BUFFER, 0, vertices.size() * sizeof(Vec3),
105                                 &vertices[0]);
106         glVertexAttribPointer(MESH_VERTEX, 3, GL_FLOAT, GL_FALSE, sizeof(Vec3), 0);
107
108         /* normals */
109
110         if(!vbo_normals)
111                 glGenBuffers(1, &vbo_normals);
112         glBindBuffer(GL_ARRAY_BUFFER, vbo_normals);
113         if(num_vertices != (int)normals.size())
114                 glBufferData(GL_ARRAY_BUFFER, normals.size() * sizeof(Vec3),
115                              &normals[0], GL_STATIC_DRAW);
116         else
117                 glBufferSubData(GL_ARRAY_BUFFER, 0, normals.size() * sizeof(Vec3),
118                                 &normals[0]);
119         glVertexAttribPointer(MESH_NORMAL, 3, GL_FLOAT, GL_FALSE, sizeof(Vec3), 0);
120
121         /* texture coordinates */
122
123         if(!vbo_tex_coords)
124                 glGenBuffers(1, &vbo_tex_coords);
125         glBindBuffer(GL_ARRAY_BUFFER, vbo_tex_coords);
126         if(num_vertices != (int)tex_coords.size())
127                 glBufferData(GL_ARRAY_BUFFER, tex_coords.size() * sizeof(Vec2), &tex_coords[0], GL_STATIC_DRAW);
128         else
129                 glBufferSubData(GL_ARRAY_BUFFER, 0, tex_coords.size() * sizeof(Vec2), &tex_coords[0]);
130         glVertexAttribPointer(MESH_TEXTURE, 2, GL_FLOAT, GL_FALSE, sizeof(Vec2), 0);
131
132         num_vertices = vertices.size();
133
134         /* indices */
135
136         if(!ibo)
137                 glGenBuffers(1, &ibo);
138         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
139         if(num_indices != (int)indices.size())
140                 glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * 2,
141                              &indices[0], GL_STATIC_DRAW);
142         else
143                 glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, indices.size() * 2,
144                                 &indices[0]);
145
146         num_indices = indices.size();
147
148         glEnableVertexAttribArray(MESH_VERTEX);
149         glEnableVertexAttribArray(MESH_NORMAL);
150         glEnableVertexAttribArray(MESH_TEXTURE);
151
152         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
153         glBindBuffer(GL_ARRAY_BUFFER, 0);
154         glBindVertexArray(0);
155 }
156
157 void MeshGL::destroy_vbo()
158 {
159         if(vbo_vertices)
160                 glDeleteBuffers(1, &vbo_vertices);
161         if(vbo_normals)
162                 glDeleteBuffers(1, &vbo_normals);
163         if(vbo_tex_coords)
164                 glDeleteBuffers(1, &vbo_tex_coords);
165         if(ibo)
166                 if(vao)
167                         glDeleteVertexArrays(1, &vao);
168 }