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