summaryrefslogtreecommitdiff
path: root/model.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'model.cpp')
-rw-r--r--model.cpp104
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