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