Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "model.h"
- Model::Model()
- {
- m_VAO = 0;
- ZERO_MEM(m_Buffers);
- }
- Model::~Model()
- {
- Clear();
- }
- void Model::Clear()
- {
- for (unsigned int i = 0; i < m_Textures.size(); i++)
- {
- SAFE_DELETE(m_Textures[i]);
- }
- if (m_Buffers[0] != 0)
- glDeleteBuffers(ARRAY_SIZE_IN_ELEMENTS(m_Buffers), m_Buffers);
- if (m_VAO != 0)
- {
- glDeleteVertexArrays(1, &m_VAO);
- m_VAO = 0;
- }
- }
- bool Model::LoadMesh(const std::string& Filename)
- {
- // Release the previously loaded mesh (if it exists)
- Clear();
- glGenVertexArrays(1, &m_VAO);
- glBindVertexArray(m_VAO);
- glGenBuffers(ARRAY_SIZE_IN_ELEMENTS(m_Buffers), m_Buffers);
- bool Ret = false;
- Assimp::Importer Importer;
- const aiScene* pScene = Importer.ReadFile(Filename, aiProcess_Triangulate | aiProcess_GenSmoothNormals | aiProcess_FlipUVs);
- if (pScene)
- {
- Ret = InitFromScene(pScene, Filename);
- }
- else
- {
- printf("Error parsing '%s': '%s'\n", Filename, Importer.GetErrorString());
- }
- if (!Ret)
- {
- std::cout << "***Problem within LoadMesh" << std::endl;
- }
- else
- std::cout << "***LoadMesh clean" << std::endl;
- glBindVertexArray(0);
- return Ret;
- }
- bool Model::InitFromScene(const aiScene* pScene, const std::string& Filename)
- {
- m_Entries.resize(pScene->mNumMeshes);
- m_Textures.resize(pScene->mNumMaterials);
- std::vector<Vec3f> Positions;
- std::vector<Vec3f> Normals;
- std::vector<Vec2f> TexCoords;
- std::vector<unsigned int> Indices;
- unsigned int NumVertices = 0;
- unsigned int NumIndices = 0;
- // Initialize the meshes in the scene one by one
- for (unsigned int i = 0; i < m_Entries.size(); i++)
- {
- m_Entries[i].MaterialIndex = pScene->mMeshes[i]->mMaterialIndex;
- m_Entries[i].NumIndices = pScene->mMeshes[i]->mNumFaces * 3;
- m_Entries[i].BaseVertex = NumVertices;
- m_Entries[i].BaseIndex = NumIndices;
- NumVertices += pScene->mMeshes[i]->mNumVertices;
- NumIndices += m_Entries[i].NumIndices;
- }
- Positions.reserve(NumVertices);
- Normals.reserve(NumVertices);
- TexCoords.reserve(NumVertices);
- Indices.reserve(NumIndices);
- for (unsigned int i = 0; i < m_Entries.size(); i++)
- {
- const aiMesh* paiMesh = pScene->mMeshes[i];
- InitMesh(paiMesh, Positions, Normals, TexCoords, Indices);
- }
- if (!InitMaterials(pScene, Filename))
- return false;
- glBindBuffer(GL_ARRAY_BUFFER, m_Buffers[POS_VB]);
- glBufferData(GL_ARRAY_BUFFER, sizeof(Positions[0]) * Positions.size(), &Positions[0], GL_STATIC_DRAW);
- glEnableVertexAttribArray(0);
- glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
- glBindBuffer(GL_ARRAY_BUFFER, m_Buffers[TEXCOORD_VB]);
- glBufferData(GL_ARRAY_BUFFER, sizeof(TexCoords[0]) * TexCoords.size(), &TexCoords[0], GL_STATIC_DRAW);
- glEnableVertexAttribArray(1);
- glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, 0);
- glBindBuffer(GL_ARRAY_BUFFER, m_Buffers[NORMAL_VB]);
- glBufferData(GL_ARRAY_BUFFER, sizeof(Normals[0]) * Normals.size(), &Normals[0], GL_STATIC_DRAW);
- glEnableVertexAttribArray(2);
- glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 0, 0);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_Buffers[INDEX_BUFFER]);
- glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(Indices[0]) * Indices.size(), &Indices[0], GL_STATIC_DRAW);
- std::cout << "***GLCheckError: " << GLCheckError() << std::endl;
- if (!GLCheckError())
- {
- std::cout << "***Problem within InitFromScene" << std::endl;
- }
- else
- std::cout << "***InitFromScene clean***" << std::endl;
- return GLCheckError();
- }
- void Model::InitMesh(const aiMesh* paiMesh,
- std::vector<Vec3f> &Positions,
- std::vector<Vec3f> &Normals,
- std::vector<Vec2f> &TexCoords,
- std::vector<unsigned int> &Indices)
- {
- const aiVector3D Zero3D(0.0f, 0.0f, 0.0f);
- for (unsigned int i = 0; i < paiMesh->mNumVertices; i++)
- {
- const aiVector3D* pPos = &(paiMesh->mVertices[i]);
- const aiVector3D* pNormal = &(paiMesh->mNormals[i]);
- const aiVector3D* pTexCoord = paiMesh->HasTextureCoords(0) ? &(paiMesh->mTextureCoords[0][i]) : &Zero3D;
- Positions.push_back(Vec3f(pPos->x, pPos->y, pPos->z));
- Normals.push_back(Vec3f(pNormal->x, pNormal->y, pNormal->z));
- TexCoords.push_back(Vec2f(pTexCoord->x, pTexCoord->y));
- }
- for (unsigned int i = 0; i < paiMesh->mNumFaces; i++)
- {
- const aiFace& Face = paiMesh->mFaces[i];
- assert(Face.mNumIndices == 3);
- Indices.push_back(Face.mIndices[0]);
- Indices.push_back(Face.mIndices[1]);
- Indices.push_back(Face.mIndices[2]);
- }
- }
- bool Model::InitMaterials(const aiScene* pScene, const std::string& Filename)
- {
- std::string file = Filename;
- // Extract the directory part from the file name
- std::string::size_type SlashIndex = file.find_last_of("/");
- std::string Dir;
- if (SlashIndex == std::string::npos)
- Dir = ".";
- else if (SlashIndex == 0)
- Dir = "/";
- else
- Dir = file.substr(0, SlashIndex);
- bool Ret = true;
- // Initialize the materials
- for (unsigned int i = 0; i < pScene->mNumMaterials; i++)
- {
- const aiMaterial* pMaterial = pScene->mMaterials[i];
- m_Textures[i] = NULL;
- std::cout << file << " texture count: " << pMaterial->GetTextureCount(aiTextureType_DIFFUSE) << std::endl;
- if (pMaterial->GetTextureCount(aiTextureType_DIFFUSE) > 0)
- {
- aiString Path;
- if (pMaterial->GetTexture(aiTextureType_DIFFUSE, 0, &Path, NULL, NULL, NULL, NULL, NULL) == AI_SUCCESS)
- {
- std::string FullPath = Dir + "/" + Path.data;
- m_Textures[i] = new MTexture(GL_TEXTURE_2D, FullPath.c_str());
- if (!m_Textures[i]->Load())
- {
- printf("Error loading texture '%s'\n", FullPath.c_str());
- delete m_Textures[i];
- m_Textures[i] = NULL;
- Ret = false;
- }
- else
- {
- printf("Loaded texture '%s'\n", FullPath.c_str());
- }
- }
- }
- }
- std::cout << "\n--------------------------------------" << std::endl;
- if (!Ret)
- {
- std::cout << "***Problem within InitMaterials" << std::endl;
- }
- else
- std::cout << "***InitMaterials clean" << std::endl;
- return Ret;
- }
- void Model::Render()
- {
- glBindVertexArray(m_VAO);
- for (unsigned int i = 0; i < m_Entries.size(); i++)
- {
- const unsigned int MaterialIndex = m_Entries[i].MaterialIndex;
- assert(MaterialIndex < m_Textures.size());
- if (m_Textures[MaterialIndex])
- m_Textures[MaterialIndex]->Bind(GL_TEXTURE0);
- glDrawElementsBaseVertex(GL_TRIANGLES,
- m_Entries[i].NumIndices,
- GL_UNSIGNED_INT,
- (void*) (sizeof(unsigned int) * m_Entries[i].BaseIndex),
- m_Entries[i].BaseVertex);
- }
- glBindVertexArray(0);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement