Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #pragma once
- #include <stdio.h>
- #include <string>
- #include <fstream>
- #include <sstream>
- #include <iostream>
- #include <map>
- #include <vector>
- #include <GL/glew.h>
- #include <glm/glm.hpp>
- #include <glm/gtc/matrix_transform.hpp>
- #include <SOIL/SOIL.h>
- #include <assimp/Importer.hpp>
- #include <assimp/scene.h>
- #include <assimp/postprocess.h>
- #include "TextureLoader.hpp"
- #include "Mesh.h"
- using namespace std;
- class Model
- {
- public:
- /* Functions */
- Model( GLchar *path )
- {
- this->loadModel( path );
- }
- void Draw( Shader shader )
- {
- for ( GLuint i = 0; i < this->meshes.size( ); i++ )
- {
- this->meshes[i].Draw( shader );
- }
- }
- private:
- /* Model Data */
- vector<Mesh> meshes;
- string directory;
- vector<Texture> textures_loaded;
- /* Functions */
- void loadModel( string path )
- {
- Assimp::Importer importer;
- const aiScene *scene = importer.ReadFile( path, aiProcess_Triangulate | aiProcess_FlipUVs );
- if( !scene || scene->mFlags == AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode ) // if is Not Zero
- {
- cout << "Model could not be loaded!\n " << importer.GetErrorString( ) << endl;
- return;
- }
- this->directory = path.substr( 0, path.find_last_of( '/' ) );
- this->processNode( scene->mRootNode, scene );
- }
- void processNode( aiNode* node, const aiScene* scene )
- {
- for ( GLuint i = 0; i < node->mNumMeshes; i++ )
- {
- aiMesh* mesh = scene->mMeshes[node->mMeshes[i]];
- this->meshes.push_back( this->processMesh( mesh, scene ) );
- }
- for ( GLuint i = 0; i < node->mNumChildren; i++ )
- {
- this->processNode( node->mChildren[i], scene );
- }
- }
- Mesh processMesh( aiMesh *mesh, const aiScene *scene )
- {
- vector<Vertex> vertices;
- vector<GLuint> indices;
- vector<Texture> textures;
- for ( GLuint i = 0; i < mesh->mNumVertices; i++ )
- {
- Vertex vertex;
- // Positions
- vertex.Position.x = mesh->mVertices[i].x;
- vertex.Position.y = mesh->mVertices[i].y;
- vertex.Position.z = mesh->mVertices[i].z;
- // Normals
- vertex.Normal.x = mesh->mNormals[i].x;
- vertex.Normal.y = mesh->mNormals[i].y;
- vertex.Normal.z = mesh->mNormals[i].z;
- // Texture Coordinates
- if( mesh->mTextureCoords[0] )
- {
- vertex.TexCoords.x = mesh->mTextureCoords[0][i].x;
- vertex.TexCoords.y = mesh->mTextureCoords[0][i].y;
- }
- else
- {
- vertex.TexCoords = glm::vec2( 0.0f, 0.0f );
- }
- vertices.push_back( vertex );
- }
- for ( GLuint i = 0; i < mesh->mNumFaces; i++ )
- {
- aiFace face = mesh->mFaces[i];
- for ( GLuint j = 0; j < face.mNumIndices; j++ )
- {
- indices.push_back( face.mIndices[j] );
- }
- }
- // Process materials
- if( mesh->mMaterialIndex >= 0 )
- {
- aiMaterial* material = scene->mMaterials[mesh->mMaterialIndex];
- // 1. Diffuse maps
- vector<Texture> diffuseMaps = this->loadMaterialTextures( material, aiTextureType_DIFFUSE, "texture_diffuse" );
- textures.insert( textures.end( ), diffuseMaps.begin( ), diffuseMaps.end( ) );
- // 2. Specular maps
- vector<Texture> specularMaps = this->loadMaterialTextures( material, aiTextureType_SPECULAR, "texture_specular" );
- textures.insert( textures.end( ), specularMaps.begin( ), specularMaps.end( ) );
- }
- return Mesh( vertices, indices, textures );
- }
- vector<Texture> loadMaterialTextures( aiMaterial *mat, aiTextureType type, string typeName )
- {
- vector<Texture> textures;
- for ( GLuint i = 0; i < mat->GetTextureCount( type ); i++ )
- {
- aiString str;
- mat->GetTexture( type, i, &str );
- GLboolean skip = false;
- for ( GLuint j = 0; j < textures_loaded.size( ); j++ )
- {
- if( textures_loaded[j].path == str )
- {
- textures.push_back( textures_loaded[j] );
- skip = true;
- break;
- }
- }
- if( !skip )
- {
- Texture texture;
- texture.id = TextureLoader::loadTextureFromFile( str.C_Str( ), this->directory );
- texture.type = typeName;
- texture.path = str;
- textures.push_back( texture );
- this->textures_loaded.push_back( texture );
- }
- }
- return textures;
- }
- };
Add Comment
Please, Sign In to add comment