rev |
line source |
nuclear@3
|
1 #include <stdio.h>
|
nuclear@3
|
2 #include <string.h>
|
nuclear@3
|
3 #include <GL/glew.h>
|
nuclear@3
|
4 #include "mesh.h"
|
nuclear@3
|
5
|
nuclear@3
|
6 #define ALL_VALID 0xffffffff
|
nuclear@3
|
7
|
nuclear@3
|
8 Mesh::Mesh()
|
nuclear@3
|
9 {
|
nuclear@3
|
10 buf_valid = ALL_VALID;
|
nuclear@3
|
11
|
nuclear@3
|
12 for(int i=0; i<vcount; i++) {
|
nuclear@3
|
13 attr[i] = 0;
|
nuclear@3
|
14 attr_size[i] = 0;
|
nuclear@3
|
15 buf_valid &= ~(1 << i);
|
nuclear@3
|
16 }
|
nuclear@3
|
17 vcount = 0;
|
nuclear@3
|
18 glGenBuffers(NUM_MESH_ATTRIBS, vbo);
|
nuclear@3
|
19 }
|
nuclear@3
|
20
|
nuclear@3
|
21 Mesh::~Mesh()
|
nuclear@3
|
22 {
|
nuclear@3
|
23 for(int i=0; i<vcount; i++) {
|
nuclear@3
|
24 delete [] attr[i];
|
nuclear@3
|
25 }
|
nuclear@3
|
26 glDeleteBuffers(NUM_MESH_ATTRIBS, vbo);
|
nuclear@3
|
27 }
|
nuclear@3
|
28
|
nuclear@3
|
29 float *Mesh::set_attrib(int aidx, int count, int elemsz, float *data)
|
nuclear@3
|
30 {
|
nuclear@3
|
31 if(attr[aidx]) {
|
nuclear@3
|
32 delete [] attr[aidx];
|
nuclear@3
|
33 }
|
nuclear@3
|
34 attr[aidx] = new float[count * elemsz];
|
nuclear@3
|
35 attr_size[aidx] = elemsz;
|
nuclear@3
|
36 buf_valid &= ~(1 << aidx);
|
nuclear@3
|
37 return attr[aidx];
|
nuclear@3
|
38 }
|
nuclear@3
|
39
|
nuclear@3
|
40 float *Mesh::get_attrib(int aidx)
|
nuclear@3
|
41 {
|
nuclear@3
|
42 buf_valid &= ~(1 << aidx);
|
nuclear@3
|
43 return attr[aidx];
|
nuclear@3
|
44 }
|
nuclear@3
|
45
|
nuclear@3
|
46 const float *Mesh::get_attrib(int aidx) const
|
nuclear@3
|
47 {
|
nuclear@3
|
48 return attr[aidx];
|
nuclear@3
|
49 }
|
nuclear@3
|
50
|
nuclear@3
|
51 void Mesh::draw() const
|
nuclear@3
|
52 {
|
nuclear@3
|
53 update_buffers();
|
nuclear@3
|
54
|
nuclear@3
|
55 if(!vbo[MESH_ATTR_VERTEX]) {
|
nuclear@3
|
56 fprintf(stderr, "trying to render without a vertex buffer\n");
|
nuclear@3
|
57 return;
|
nuclear@3
|
58 }
|
nuclear@3
|
59
|
nuclear@3
|
60 glBindBuffer(GL_ARRAY_BUFFER, vbo[MESH_ATTR_VERTEX]);
|
nuclear@3
|
61 glEnableClientState(GL_VERTEX_ARRAY);
|
nuclear@3
|
62 glVertexPointer(attr_size[MESH_ATTR_VERTEX], GL_FLOAT, 0, 0);
|
nuclear@3
|
63
|
nuclear@3
|
64 if(vbo[MESH_ATTR_NORMAL]) {
|
nuclear@3
|
65 glBindBuffer(GL_ARRAY_BUFFER, vbo[MESH_ATTR_NORMAL]);
|
nuclear@3
|
66 glEnableClientState(GL_NORMAL_ARRAY);
|
nuclear@3
|
67 glNormalPointer(GL_FLOAT, 0, 0);
|
nuclear@3
|
68 }
|
nuclear@3
|
69 if(vbo[MESH_ATTR_TEXCOORD]) {
|
nuclear@3
|
70 glBindBuffer(GL_ARRAY_BUFFER, vbo[MESH_ATTR_TEXCOORD]);
|
nuclear@3
|
71 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
nuclear@3
|
72 glTexCoordPointer(attr_size[MESH_ATTR_TEXCOORD], GL_FLOAT, 0, 0);
|
nuclear@3
|
73 }
|
nuclear@3
|
74 glBindBuffer(GL_ARRAY_BUFFER, 0);
|
nuclear@3
|
75
|
nuclear@3
|
76 glDrawArrays(GL_TRIANGLES, 0, vcount);
|
nuclear@3
|
77
|
nuclear@3
|
78 glDisableClientState(GL_VERTEX_ARRAY);
|
nuclear@3
|
79 if(vbo[MESH_ATTR_NORMAL]) {
|
nuclear@3
|
80 glDisableClientState(GL_NORMAL_ARRAY);
|
nuclear@3
|
81 }
|
nuclear@3
|
82 if(vbo[MESH_ATTR_TEXCOORD]) {
|
nuclear@3
|
83 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
nuclear@3
|
84 }
|
nuclear@3
|
85 }
|
nuclear@3
|
86
|
nuclear@3
|
87 void Mesh::update_buffers() const
|
nuclear@3
|
88 {
|
nuclear@3
|
89 if(buf_valid == ALL_VALID) {
|
nuclear@3
|
90 return;
|
nuclear@3
|
91 }
|
nuclear@3
|
92
|
nuclear@3
|
93 for(int i=0; i<NUM_MESH_ATTRIBS; i++) {
|
nuclear@3
|
94 if((buf_valid & (1 << i)) == 0) {
|
nuclear@3
|
95 glBindBuffer(GL_ARRAY_BUFFER, vbo[i]);
|
nuclear@3
|
96 glBufferData(GL_ARRAY_BUFFER, vcount * attr_size[i] * sizeof(float),
|
nuclear@3
|
97 attr[i], GL_STATIC_DRAW);
|
nuclear@3
|
98 buf_valid |= 1 << i;
|
nuclear@3
|
99 }
|
nuclear@3
|
100 }
|
nuclear@3
|
101 }
|