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