skybox working
[demo] / src / opengl / mesh-gl.cc
1 #include <GL/glew.h>
2 #include <GL/gl.h>
3 #include <gmath/gmath.h>
4
5 #include "mesh-gl.h"
6
7 MeshGL::MeshGL()
8 {
9         vao = 0;
10
11         vbo_vertices = 0;
12         vbo_normals = 0;
13         vbo_tex_coords = 0;
14         ibo = 0;
15
16         num_vertices = 0;
17         num_indices = 0;
18 }
19
20 MeshGL::MeshGL(const MeshGL &mesh)
21 {
22         indices = mesh.indices;
23         vertices = mesh.vertices;
24         normals = mesh.normals;
25         tex_coords = mesh.tex_coords;
26
27         vbo_vertices = 0;
28         vbo_normals = 0;
29         vbo_tex_coords = 0;
30         ibo = 0;
31         vao = 0;
32
33         /*
34          * if we set these to the actual
35          * vertices.size() and indices.size()
36          * update_vbo will have no effect
37          * */
38
39         num_vertices = 0;
40         num_indices = 0;
41 }
42
43 MeshGL &MeshGL::operator=(const MeshGL &mesh)
44 {
45         if(this == &mesh)
46                 return *this;
47
48         /* to avoid OpenGL leaks */
49         destroy_vbo();
50
51         /* what the copy constructor does */
52         indices = mesh.indices;
53         vertices = mesh.vertices;
54         normals = mesh.normals;
55         tex_coords = mesh.tex_coords;
56
57         return *this;
58 }
59
60 MeshGL::~MeshGL()
61 {
62         destroy_vbo();
63
64         vertices.clear();
65         normals.clear();
66 }
67
68 void MeshGL::draw() const
69 {
70         glBindVertexArray(vao);
71
72         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
73         glDrawElements(GL_TRIANGLES, num_indices, GL_UNSIGNED_SHORT, 0);
74
75         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
76         glBindVertexArray(0);
77 }
78
79 void MeshGL::update_vertex_data()
80 {
81         update_vbo();
82 }
83
84 void MeshGL::update_vbo()
85 {
86         if(vertices.empty()) {
87                 printf("empty vertices\n");
88                 return;
89         }
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         num_vertices = vertices.size();
134
135         /* indices */
136
137         if(!ibo)
138                 glGenBuffers(1, &ibo);
139         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
140         if(num_indices != (int)indices.size())
141                 glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * 2,
142                              &indices[0], GL_STATIC_DRAW);
143         else
144                 glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, indices.size() * 2,
145                                 &indices[0]);
146
147         num_indices = indices.size();
148
149         glEnableVertexAttribArray(MESH_VERTEX);
150         glEnableVertexAttribArray(MESH_NORMAL);
151         glEnableVertexAttribArray(MESH_TEXTURE);
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 }