diff options
Diffstat (limited to 'model.cpp')
-rw-r--r-- | model.cpp | 104 |
1 files changed, 104 insertions, 0 deletions
diff --git a/model.cpp b/model.cpp new file mode 100644 index 0000000..67e4561 --- /dev/null +++ b/model.cpp @@ -0,0 +1,104 @@ +#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(); +} + +} // namespace models |