diff options
author | Jon Bergli Heier <snakebite@jvnv.net> | 2011-07-01 17:20:53 +0200 |
---|---|---|
committer | Jon Bergli Heier <snakebite@jvnv.net> | 2011-07-02 18:10:14 +0200 |
commit | 75a90df8bf7f38e746e021c23248e1607931132c (patch) | |
tree | df2b4f48d5157f775c719192484188a2b0b8a04a /model.cpp | |
parent | 90d570822f85f70c31f80789ad6791cebd904468 (diff) |
Import and render tree models.
Trees are loaded from the new trees.blend using assimp. Tree objects are
then received from the server and rendered on the given terrain
locations.
Each chunk now holds a list of objects and coordinates, which can be
used to easily add other models as well.
Also moded the GLSL fog code to its own shader which can be linked in
different programs.
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 |