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