first git commit: scene, object, mesh, texture, shader, material etc
[demo] / src / opengl / mesh-gl.cc
1 #include <GL/glew.h>
2
3 #include "mesh-gl.h"
4
5 MeshGL::MeshGL()
6 {
7         which_mask = 0;
8
9         vao = 0;
10
11         vbo_vertices = 0;
12         vbo_normals = 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
25         vbo_vertices = 0;
26         vbo_normals = 0;
27         ibo = 0;
28
29         /*
30          * if we set these to the actual
31          * vertices.size() and indices.size()
32          * update_vbo will have no effect
33          * */
34
35         num_vertices = 0;
36         num_indices = 0;
37 }
38
39 MeshGL &MeshGL::operator=(const MeshGL &mesh)
40 {
41         if(this == &mesh)
42                 return *this;
43
44         /* to avoid OpenGL leaks */
45         destroy_vbo();
46
47         /* what the copy constructor does */
48         indices = mesh.indices;
49         vertices = mesh.vertices;
50         normals = mesh.normals;
51
52         return *this;
53 }
54
55 MeshGL::~MeshGL()
56 {
57         destroy_vbo();
58
59         vertices.clear();
60         normals.clear();
61 }
62
63 /*
64 void MeshGL::draw() const
65 {
66         // save the previously bound vao, vbo just in case
67         int curr_vao;
68         int curr_vbo;
69         glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &curr_vao);
70         glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &curr_vbo);
71
72         glBindVertexArray(vao);
73
74         glBindBuffer(GL_ARRAY_BUFFER, vbo_vertices);
75         glVertexPointer(3, GL_FLOAT, 0, 0);
76         glBindBuffer(GL_ARRAY_BUFFER, vbo_normals);
77         glNormalPointer(GL_FLOAT, 0, 0);
78         glBindBuffer(GL_ARRAY_BUFFER, 0);
79
80         glEnableClientState(GL_VERTEX_ARRAY);
81         glEnableClientState(GL_NORMAL_ARRAY);
82         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
83         glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_SHORT, 0);
84         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
85         glDisableClientState(GL_VERTEX_ARRAY);
86         glDisableClientState(GL_NORMAL_ARRAY);
87
88         // return to previous state
89         glBindBuffer(GL_ARRAY_BUFFER, curr_vbo);
90         glBindVertexArray(curr_vao);
91 }
92 */
93
94 void MeshGL::update_vertex_data()
95 {
96         update_vbo();
97 }
98
99 void MeshGL::update_vbo()
100 {
101         // save the previously bound vao, vbo just in case
102         int curr_vao;
103         int curr_vbo;
104         glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &curr_vao);
105         glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &curr_vbo);
106
107         if(!vao)
108                 glGenVertexArrays(1, &vao);
109
110         glBindVertexArray(vao);
111
112         if(which_mask & MESH_NORMAL) {
113                 if(!vbo_normals) {
114                         glGenBuffers(1, &vbo_normals);
115                 }
116                 glBindBuffer(GL_ARRAY_BUFFER, vbo_normals);
117                 if(num_vertices != (int)normals.size()) {
118                         glBufferData(GL_ARRAY_BUFFER, normals.size() * 3 * sizeof(float),
119                                      &normals[0], GL_STREAM_DRAW);
120                 }
121                 else {
122                         glBufferSubData(GL_ARRAY_BUFFER, 0, normals.size() * 3 * sizeof(float),
123                                         &normals[0]);
124                 }
125         }
126
127         if(which_mask & MESH_VERTEX) {
128                 if(!vbo_vertices) {
129                         glGenBuffers(1, &vbo_vertices);
130                 }
131                 glBindBuffer(GL_ARRAY_BUFFER, vbo_vertices);
132                 if(num_vertices != (int)vertices.size()) {
133                         glBufferData(GL_ARRAY_BUFFER, vertices.size() * 3 * sizeof(float),
134                                      &vertices[0], GL_STREAM_DRAW);
135                 }
136                 else {
137                         glBufferSubData(GL_ARRAY_BUFFER, 0, vertices.size() * 3 * sizeof(float),
138                                         &vertices[0]);
139                 }
140                 num_vertices = vertices.size();
141         }
142
143         if(which_mask & MESH_INDEX) {
144                 if(!ibo) {
145                         glGenBuffers(1, &ibo);
146                 }
147                 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
148                 if(num_indices != (int)indices.size()) {
149                         glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * 2,
150                                      &indices[0], GL_STATIC_DRAW);
151                 }
152                 else {
153                         glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, indices.size() * 2,
154                                         &indices[0]);
155                 }
156                 num_indices = indices.size();
157         }
158
159         /* bind previously bound vbo */
160         glBindBuffer(GL_ARRAY_BUFFER, curr_vbo);
161         glBindVertexArray(curr_vao);
162 }
163
164 void MeshGL::destroy_vbo()
165 {
166         if(vbo_vertices)
167                 glDeleteBuffers(1, &vbo_vertices);
168         if(vbo_normals)
169                 glDeleteBuffers(1, &vbo_normals);
170         if(ibo)
171                 glDeleteBuffers(1, &ibo);
172         if(vao)
173                 glDeleteVertexArrays(1, &vao);
174 }