42c2af9251e9dac300fe228188abf6206b2a932a
[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         if(!vao)
70                 return;
71
72         glBindVertexArray(vao);
73
74         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
75         glDrawElements(GL_TRIANGLES, num_indices, GL_UNSIGNED_INT, 0);
76         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
77
78         glBindVertexArray(0);
79 }
80
81 void MeshGL::update_vertex_data()
82 {
83         update_vbo();
84 }
85
86 void MeshGL::update_vbo()
87 {
88         if(!num_vertices)
89                 return;
90
91         /* vao */
92         if(!vao)
93                 glGenVertexArrays(1, &vao);
94         glBindVertexArray(vao);
95
96         /* vertices */
97
98         if(!vbo_vertices)
99                 glGenBuffers(1, &vbo_vertices);
100         glBindBuffer(GL_ARRAY_BUFFER, vbo_vertices);
101         if(num_vertices != (int)vertices.size())
102                 glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(Vec3),
103                              &vertices[0], GL_STATIC_DRAW);
104         else
105                 glBufferSubData(GL_ARRAY_BUFFER, 0, vertices.size() * sizeof(Vec3),
106                                 &vertices[0]);
107         glVertexAttribPointer(MESH_VERTEX, 3, GL_FLOAT, GL_FALSE, sizeof(Vec3), 0);
108
109         /* normals */
110
111         if(!vbo_normals)
112                 glGenBuffers(1, &vbo_normals);
113         glBindBuffer(GL_ARRAY_BUFFER, vbo_normals);
114         if(num_vertices != (int)normals.size())
115                 glBufferData(GL_ARRAY_BUFFER, normals.size() * sizeof(Vec3),
116                              &normals[0], GL_STATIC_DRAW);
117         else
118                 glBufferSubData(GL_ARRAY_BUFFER, 0, normals.size() * sizeof(Vec3),
119                                 &normals[0]);
120         glVertexAttribPointer(MESH_NORMAL, 3, GL_FLOAT, GL_FALSE, sizeof(Vec3), 0);
121
122         /* texture coordinates */
123
124         if(!vbo_tex_coords)
125                 glGenBuffers(1, &vbo_tex_coords);
126         glBindBuffer(GL_ARRAY_BUFFER, vbo_tex_coords);
127         if(num_vertices != (int)tex_coords.size())
128                 glBufferData(GL_ARRAY_BUFFER, tex_coords.size() * sizeof(Vec2), &tex_coords[0], GL_STATIC_DRAW);
129         else
130                 glBufferSubData(GL_ARRAY_BUFFER, 0, tex_coords.size() * sizeof(Vec2), &tex_coords[0]);
131         glVertexAttribPointer(MESH_TEXTURE, 2, GL_FLOAT, GL_FALSE, sizeof(Vec2), 0);
132
133         /* indices */
134
135         if(!ibo)
136                 glGenBuffers(1, &ibo);
137         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
138         if(num_indices != (int)indices.size())
139                 glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * 2,
140                              &indices[0], GL_STATIC_DRAW);
141         else
142                 glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, indices.size() * 2,
143                                 &indices[0]);
144
145         num_indices = indices.size();
146         num_vertices = vertices.size();
147
148         glEnableVertexAttribArray(MESH_VERTEX);
149         glEnableVertexAttribArray(MESH_NORMAL);
150         glEnableVertexAttribArray(MESH_TEXTURE);
151
152
153         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
154         glBindBuffer(GL_ARRAY_BUFFER, 0);
155         glBindVertexArray(0);
156 }
157
158 void MeshGL::destroy_vbo()
159 {
160         if(vbo_vertices)
161                 glDeleteBuffers(1, &vbo_vertices);
162         if(vbo_normals)
163                 glDeleteBuffers(1, &vbo_normals);
164         if(vbo_tex_coords)
165                 glDeleteBuffers(1, &vbo_tex_coords);
166         if(ibo)
167                 if(vao)
168                         glDeleteVertexArrays(1, &vao);
169 }