1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
|
#include "model.h"
#include <iostream>
#include <stdexcept>
namespace models {
Mesh::Mesh(const aiScene *scene, const aiMesh *mesh, std::map<std::string, GLuint>& scene_textures) {
aiMaterial *mat = scene->mMaterials[mesh->mMaterialIndex];
unsigned int texture_count = mat->GetTextureCount(aiTextureType_DIFFUSE);
for(unsigned int j = 0; j < texture_count; j++) {
aiString ai_path;
if(mat->GetTexture(aiTextureType_DIFFUSE, j, &ai_path) == AI_SUCCESS) {
std::string path(ai_path.data, ai_path.length);
GLuint tex = scene_textures[path];
textures.push_back(tex);
}
}
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
vertices = 0;
for(unsigned int i = 0; i < mesh->mNumFaces; i++)
vertices += mesh->mFaces[i].mNumIndices;
glBufferData(GL_ARRAY_BUFFER, vertices*3*2*3 * sizeof(float), NULL, GL_STATIC_DRAW);
float *buffer = (float*)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
unsigned int index = 0;
for(unsigned int i = 0; i < mesh->mNumFaces; i++) {
aiFace *face = &mesh->mFaces[i];
for(unsigned int j = 0; j < face->mNumIndices; j++) {
aiVector3D *texcoord = &mesh->mTextureCoords[0][face->mIndices[j]];
aiVector3D *vertex = &mesh->mVertices[face->mIndices[j]];
aiVector3D *normal = &mesh->mNormals[face->mIndices[j]];
buffer[index++] = vertex->x;
buffer[index++] = vertex->y;
buffer[index++] = vertex->z;
buffer[index++] = texcoord->x;
buffer[index++] = 2 - texcoord->y;
buffer[index++] = normal->x;
buffer[index++] = normal->y;
buffer[index++] = normal->z;
}
}
glUnmapBuffer(GL_ARRAY_BUFFER);
}
Mesh::~Mesh() {
glDeleteBuffers(1, &vbo);
}
void Mesh::render() {
GLenum tex_i = GL_TEXTURE0;
for(std::vector<GLuint>::iterator it = textures.begin(); it != textures.end(); it++) {
glActiveTexture(tex_i++);
glBindTexture(GL_TEXTURE_2D, *it);
}
glActiveTexture(GL_TEXTURE0);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glPushClientAttrib(GL_CLIENT_ALL_ATTRIB_BITS);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glVertexPointer(3, GL_FLOAT, 8*sizeof(float), NULL);
glTexCoordPointer(2, GL_FLOAT, 8*sizeof(float), (const GLvoid*)(sizeof(float)*3));
glNormalPointer(GL_FLOAT, 8*sizeof(float), (const GLvoid*)(sizeof(float)*5));
glDrawArrays(GL_TRIANGLES, 0, vertices);
glPopClientAttrib();
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
Tree::Tree(const aiScene *scene, std::map<std::string, GLuint>& scene_textures) {
trunk = new Mesh(scene, scene->mMeshes[22], scene_textures);
leaves = new Mesh(scene, scene->mMeshes[3], scene_textures);
}
Tree::~Tree() {
delete trunk;
delete leaves;
}
void Tree::render() {
trunk->render();
glTranslatef(0.786, 2.845, 5.1);
leaves->render();
}
/* ModelManager */
ModelManager *ModelManager::model_mgr = NULL;
void ModelManager::add_model(const std::string name, Model::p model) {
models.insert(std::pair<const std::string, Model::p>(name, model));
}
Model::p ModelManager::get_model(const std::string name) {
std::map<const std::string, Model::p>::iterator it = models.find(name);
if(it != models.end())
return it->second;
return Model::p();
}
ModelManager& ModelManager::get_instance() {
if(!model_mgr)
model_mgr = new ModelManager();
return *model_mgr;
}
} // namespace models
|