rev |
line source |
nuclear@2
|
1 #include "mesh.h"
|
nuclear@2
|
2 #include "opengl.h"
|
nuclear@2
|
3
|
nuclear@2
|
4 Mesh::Mesh()
|
nuclear@2
|
5 {
|
nuclear@2
|
6 nverts = nfaces = 0;
|
nuclear@2
|
7 for(int i=0; i<NUM_MESH_ATTR; i++) {
|
nuclear@2
|
8 vbo[i] = 0;
|
nuclear@2
|
9 }
|
nuclear@2
|
10 ibo = 0;
|
nuclear@2
|
11 tang_loc = -1;
|
nuclear@2
|
12 }
|
nuclear@2
|
13
|
nuclear@2
|
14 Mesh::~Mesh()
|
nuclear@2
|
15 {
|
nuclear@2
|
16 destroy();
|
nuclear@2
|
17 }
|
nuclear@2
|
18
|
nuclear@2
|
19 bool Mesh::create(const aiScene *scn, aiMesh *aim)
|
nuclear@2
|
20 {
|
nuclear@2
|
21 if(vbo[MESH_ATTR_VERTEX]) {
|
nuclear@2
|
22 destroy();
|
nuclear@2
|
23 }
|
nuclear@2
|
24
|
nuclear@2
|
25 nverts = aim->mNumVertices;
|
nuclear@2
|
26 nfaces = aim->mNumFaces;
|
nuclear@2
|
27
|
nuclear@2
|
28 glGenBuffers(1, vbo + MESH_ATTR_VERTEX);
|
nuclear@2
|
29 glBindBuffer(GL_ARRAY_BUFFER, vbo[MESH_ATTR_VERTEX]);
|
nuclear@2
|
30 glBufferData(GL_ARRAY_BUFFER, nverts * sizeof *aim->mVertices, aim->mVertices, GL_STATIC_DRAW);
|
nuclear@2
|
31
|
nuclear@2
|
32 if(aim->mNormals) {
|
nuclear@2
|
33 glGenBuffers(1, vbo + MESH_ATTR_NORMAL);
|
nuclear@2
|
34 glBindBuffer(GL_ARRAY_BUFFER, vbo[MESH_ATTR_NORMAL]);
|
nuclear@2
|
35 glBufferData(GL_ARRAY_BUFFER, nverts * sizeof *aim->mNormals, aim->mNormals, GL_STATIC_DRAW);
|
nuclear@2
|
36 }
|
nuclear@2
|
37 if(aim->mTangents) {
|
nuclear@2
|
38 glGenBuffers(1, vbo + MESH_ATTR_TANGENT);
|
nuclear@2
|
39 glBindBuffer(GL_ARRAY_BUFFER, vbo[MESH_ATTR_TANGENT]);
|
nuclear@2
|
40 glBufferData(GL_ARRAY_BUFFER, nverts * sizeof *aim->mTangents, aim->mTangents, GL_STATIC_DRAW);
|
nuclear@2
|
41 }
|
nuclear@2
|
42 if(aim->mTextureCoords[0]) {
|
nuclear@2
|
43 glGenBuffers(1, vbo + MESH_ATTR_TEXCOORD);
|
nuclear@2
|
44 glBindBuffer(GL_ARRAY_BUFFER, vbo[MESH_ATTR_TEXCOORD]);
|
nuclear@2
|
45 glBufferData(GL_ARRAY_BUFFER, nverts * sizeof *aim->mTextureCoords[0], aim->mTextureCoords[0], GL_STATIC_DRAW);
|
nuclear@2
|
46 }
|
nuclear@2
|
47
|
nuclear@2
|
48 glGenBuffers(1, &ibo);
|
nuclear@2
|
49 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
|
nuclear@2
|
50 glBufferData(GL_ELEMENT_ARRAY_BUFFER, nfaces * 3 * sizeof *aim->mFaces[0].mIndices, 0, GL_STATIC_DRAW);
|
nuclear@2
|
51
|
nuclear@2
|
52 /* map the buffer and fill it up */
|
nuclear@2
|
53 unsigned int *iptr = (unsigned int*)glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY);
|
nuclear@2
|
54
|
nuclear@2
|
55 for(int i=0; i<nfaces; i++) {
|
nuclear@2
|
56 for(int j=0; j<3; j++) {
|
nuclear@2
|
57 *iptr++ = aim->mFaces[i].mIndices[j];
|
nuclear@2
|
58 }
|
nuclear@2
|
59 }
|
nuclear@2
|
60 glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
|
nuclear@2
|
61 return true;
|
nuclear@2
|
62 }
|
nuclear@2
|
63
|
nuclear@2
|
64 void Mesh::destroy()
|
nuclear@2
|
65 {
|
nuclear@2
|
66 for(int i=0; i<NUM_MESH_ATTR; i++) {
|
nuclear@2
|
67 if(vbo[i]) {
|
nuclear@2
|
68 glDeleteBuffers(1, vbo + i);
|
nuclear@2
|
69 vbo[i] = 0;
|
nuclear@2
|
70 }
|
nuclear@2
|
71 }
|
nuclear@2
|
72 glDeleteBuffers(1, &ibo);
|
nuclear@2
|
73 ibo = 0;
|
nuclear@2
|
74
|
nuclear@2
|
75 nverts = nfaces = 0;
|
nuclear@2
|
76 tang_loc = -1;
|
nuclear@2
|
77 }
|
nuclear@2
|
78
|
nuclear@2
|
79 void Mesh::set_attrib_location(int attr, int loc)
|
nuclear@2
|
80 {
|
nuclear@2
|
81 if(attr == MESH_ATTR_TANGENT) {
|
nuclear@2
|
82 tang_loc = loc;
|
nuclear@2
|
83 }
|
nuclear@2
|
84 }
|
nuclear@2
|
85
|
nuclear@2
|
86 int Mesh::get_attrib_location(int attr) const
|
nuclear@2
|
87 {
|
nuclear@2
|
88 return tang_loc;
|
nuclear@2
|
89 }
|
nuclear@2
|
90
|
nuclear@2
|
91 void Mesh::draw() const
|
nuclear@2
|
92 {
|
nuclear@2
|
93 glBindBuffer(GL_ARRAY_BUFFER, vbo[MESH_ATTR_VERTEX]);
|
nuclear@2
|
94 glVertexPointer(3, GL_FLOAT, 0, 0);
|
nuclear@2
|
95 glEnableClientState(GL_VERTEX_ARRAY);
|
nuclear@2
|
96
|
nuclear@2
|
97 if(vbo[MESH_ATTR_NORMAL]) {
|
nuclear@2
|
98 glBindBuffer(GL_ARRAY_BUFFER, vbo[MESH_ATTR_NORMAL]);
|
nuclear@2
|
99 glNormalPointer(GL_FLOAT, 0, 0);
|
nuclear@2
|
100 glEnableClientState(GL_NORMAL_ARRAY);
|
nuclear@2
|
101 }
|
nuclear@2
|
102 if(vbo[MESH_ATTR_TANGENT] && tang_loc >= 0) {
|
nuclear@2
|
103 glBindBuffer(GL_ARRAY_BUFFER, vbo[MESH_ATTR_TANGENT]);
|
nuclear@2
|
104 glVertexAttribPointer(tang_loc, 3, GL_FLOAT, GL_FALSE, 0, 0);
|
nuclear@2
|
105 glEnableVertexAttribArray(tang_loc);
|
nuclear@2
|
106 }
|
nuclear@2
|
107 if(vbo[MESH_ATTR_TEXCOORD]) {
|
nuclear@2
|
108 glBindBuffer(GL_ARRAY_BUFFER, vbo[MESH_ATTR_TEXCOORD]);
|
nuclear@2
|
109 glTexCoordPointer(3, GL_FLOAT, 0, 0);
|
nuclear@2
|
110 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
nuclear@2
|
111 }
|
nuclear@2
|
112
|
nuclear@2
|
113 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
|
nuclear@2
|
114 glDrawElements(GL_TRIANGLES, nfaces * 3, GL_UNSIGNED_INT, 0);
|
nuclear@2
|
115
|
nuclear@2
|
116 glDisableClientState(GL_VERTEX_ARRAY);
|
nuclear@2
|
117 glDisableClientState(GL_NORMAL_ARRAY);
|
nuclear@2
|
118 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
nuclear@2
|
119 if(tang_loc >= 0) {
|
nuclear@2
|
120 glDisableVertexAttribArray(tang_loc);
|
nuclear@2
|
121 }
|
nuclear@2
|
122 }
|