Advertisement
ChocoMan

Untitled

Apr 15th, 2014
184
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.45 KB | None | 0 0
  1. #include "model.h"
  2.  
  3.  
  4. Model::Model()
  5. {
  6.     m_VAO = 0;
  7.     ZERO_MEM(m_Buffers);
  8. }
  9.  
  10.  
  11. Model::~Model()
  12. {
  13.     Clear();
  14. }
  15.  
  16.  
  17. void Model::Clear()
  18. {
  19.     for (unsigned int i = 0; i < m_Textures.size(); i++)
  20.     {
  21.         SAFE_DELETE(m_Textures[i]);
  22.     }
  23.  
  24.     if (m_Buffers[0] != 0)
  25.         glDeleteBuffers(ARRAY_SIZE_IN_ELEMENTS(m_Buffers), m_Buffers);
  26.  
  27.     if (m_VAO != 0)
  28.     {
  29.         glDeleteVertexArrays(1, &m_VAO);
  30.         m_VAO = 0;
  31.     }
  32.        
  33. }
  34.  
  35.  
  36. bool Model::LoadMesh(const std::string& Filename)
  37. {
  38.     // Release the previously loaded mesh (if it exists)
  39.     Clear();
  40.  
  41.     glGenVertexArrays(1, &m_VAO);
  42.     glBindVertexArray(m_VAO);
  43.     glGenBuffers(ARRAY_SIZE_IN_ELEMENTS(m_Buffers), m_Buffers);
  44.  
  45.     bool Ret = false;
  46.     Assimp::Importer Importer;
  47.  
  48.     const aiScene* pScene = Importer.ReadFile(Filename, aiProcess_Triangulate | aiProcess_GenSmoothNormals | aiProcess_FlipUVs);
  49.  
  50.     if (pScene)
  51.     {
  52.         Ret = InitFromScene(pScene, Filename);
  53.     }
  54.     else
  55.     {
  56.         printf("Error parsing '%s': '%s'\n", Filename, Importer.GetErrorString());
  57.     }
  58.  
  59.     if (!Ret)
  60.     {
  61.         std::cout << "***Problem within LoadMesh" << std::endl;
  62.     }
  63.     else
  64.         std::cout << "***LoadMesh clean" << std::endl;
  65.    
  66.     glBindVertexArray(0);
  67.  
  68.     return Ret;
  69. }
  70.  
  71.  
  72. bool Model::InitFromScene(const aiScene* pScene, const std::string& Filename)
  73. {
  74.     m_Entries.resize(pScene->mNumMeshes);
  75.     m_Textures.resize(pScene->mNumMaterials);
  76.  
  77.     std::vector<Vec3f> Positions;
  78.     std::vector<Vec3f> Normals;
  79.     std::vector<Vec2f> TexCoords;
  80.     std::vector<unsigned int> Indices;
  81.  
  82.     unsigned int NumVertices = 0;
  83.     unsigned int NumIndices = 0;
  84.  
  85.     // Initialize the meshes in the scene one by one
  86.     for (unsigned int i = 0; i < m_Entries.size(); i++)
  87.     {
  88.         m_Entries[i].MaterialIndex = pScene->mMeshes[i]->mMaterialIndex;
  89.         m_Entries[i].NumIndices = pScene->mMeshes[i]->mNumFaces * 3;
  90.         m_Entries[i].BaseVertex = NumVertices;
  91.         m_Entries[i].BaseIndex = NumIndices;
  92.  
  93.         NumVertices += pScene->mMeshes[i]->mNumVertices;
  94.         NumIndices += m_Entries[i].NumIndices;
  95.     }
  96.  
  97.     Positions.reserve(NumVertices);
  98.     Normals.reserve(NumVertices);
  99.     TexCoords.reserve(NumVertices);
  100.     Indices.reserve(NumIndices);
  101.  
  102.     for (unsigned int i = 0; i < m_Entries.size(); i++)
  103.     {
  104.         const aiMesh* paiMesh = pScene->mMeshes[i];
  105.         InitMesh(paiMesh, Positions, Normals, TexCoords, Indices);
  106.     }
  107.  
  108.     if (!InitMaterials(pScene, Filename))
  109.         return false;
  110.  
  111.    
  112.     glBindBuffer(GL_ARRAY_BUFFER, m_Buffers[POS_VB]);
  113.     glBufferData(GL_ARRAY_BUFFER, sizeof(Positions[0]) * Positions.size(), &Positions[0], GL_STATIC_DRAW);
  114.     glEnableVertexAttribArray(0);
  115.     glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
  116.  
  117.     glBindBuffer(GL_ARRAY_BUFFER, m_Buffers[TEXCOORD_VB]);
  118.     glBufferData(GL_ARRAY_BUFFER, sizeof(TexCoords[0]) * TexCoords.size(), &TexCoords[0], GL_STATIC_DRAW);
  119.     glEnableVertexAttribArray(1);
  120.     glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, 0);
  121.  
  122.     glBindBuffer(GL_ARRAY_BUFFER, m_Buffers[NORMAL_VB]);
  123.     glBufferData(GL_ARRAY_BUFFER, sizeof(Normals[0]) * Normals.size(), &Normals[0], GL_STATIC_DRAW);
  124.     glEnableVertexAttribArray(2);
  125.     glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 0, 0);
  126.  
  127.     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_Buffers[INDEX_BUFFER]);
  128.     glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(Indices[0]) * Indices.size(), &Indices[0], GL_STATIC_DRAW);
  129.  
  130.     std::cout << "***GLCheckError: " << GLCheckError() << std::endl;
  131.     if (!GLCheckError())
  132.     {
  133.         std::cout << "***Problem within InitFromScene" << std::endl;
  134.     }
  135.     else
  136.         std::cout << "***InitFromScene clean***" << std::endl;
  137.  
  138.     return GLCheckError();
  139. }
  140.  
  141.  
  142. void Model::InitMesh(const aiMesh* paiMesh,
  143.     std::vector<Vec3f> &Positions,
  144.     std::vector<Vec3f> &Normals,
  145.     std::vector<Vec2f> &TexCoords,
  146.     std::vector<unsigned int> &Indices)
  147. {
  148.     const aiVector3D Zero3D(0.0f, 0.0f, 0.0f);
  149.  
  150.     for (unsigned int i = 0; i < paiMesh->mNumVertices; i++)
  151.     {
  152.         const aiVector3D* pPos = &(paiMesh->mVertices[i]);
  153.         const aiVector3D* pNormal = &(paiMesh->mNormals[i]);
  154.         const aiVector3D* pTexCoord = paiMesh->HasTextureCoords(0) ? &(paiMesh->mTextureCoords[0][i]) : &Zero3D;
  155.  
  156.         Positions.push_back(Vec3f(pPos->x, pPos->y, pPos->z));
  157.         Normals.push_back(Vec3f(pNormal->x, pNormal->y, pNormal->z));
  158.         TexCoords.push_back(Vec2f(pTexCoord->x, pTexCoord->y));
  159.     }
  160.  
  161.     for (unsigned int i = 0; i < paiMesh->mNumFaces; i++)
  162.     {
  163.         const aiFace& Face = paiMesh->mFaces[i];
  164.         assert(Face.mNumIndices == 3);
  165.         Indices.push_back(Face.mIndices[0]);
  166.         Indices.push_back(Face.mIndices[1]);
  167.         Indices.push_back(Face.mIndices[2]);
  168.     }
  169. }
  170.  
  171.  
  172. bool Model::InitMaterials(const aiScene* pScene, const std::string& Filename)
  173. {
  174.     std::string file = Filename;
  175.  
  176.     // Extract the directory part from the file name
  177.     std::string::size_type SlashIndex = file.find_last_of("/");
  178.     std::string Dir;
  179.  
  180.     if (SlashIndex == std::string::npos)
  181.         Dir = ".";
  182.     else if (SlashIndex == 0)
  183.         Dir = "/";
  184.     else
  185.         Dir = file.substr(0, SlashIndex);
  186.  
  187.     bool Ret = true;
  188.  
  189.     // Initialize the materials
  190.     for (unsigned int i = 0; i < pScene->mNumMaterials; i++)
  191.     {
  192.         const aiMaterial* pMaterial = pScene->mMaterials[i];
  193.  
  194.         m_Textures[i] = NULL;
  195.  
  196.         std::cout << file << " texture count: " << pMaterial->GetTextureCount(aiTextureType_DIFFUSE) << std::endl;
  197.  
  198.         if (pMaterial->GetTextureCount(aiTextureType_DIFFUSE) > 0)
  199.         {
  200.             aiString Path;
  201.  
  202.             if (pMaterial->GetTexture(aiTextureType_DIFFUSE, 0, &Path, NULL, NULL, NULL, NULL, NULL) == AI_SUCCESS)
  203.             {
  204.                 std::string FullPath = Dir + "/" + Path.data;
  205.                 m_Textures[i] = new MTexture(GL_TEXTURE_2D, FullPath.c_str());
  206.  
  207.                 if (!m_Textures[i]->Load())
  208.                 {
  209.                     printf("Error loading texture '%s'\n", FullPath.c_str());
  210.                     delete m_Textures[i];
  211.                     m_Textures[i] = NULL;
  212.                     Ret = false;
  213.                 }
  214.                 else
  215.                 {
  216.                     printf("Loaded texture '%s'\n", FullPath.c_str());
  217.                 }
  218.             }
  219.         }
  220.     }
  221.     std::cout << "\n--------------------------------------" << std::endl;
  222.     if (!Ret)
  223.     {
  224.         std::cout << "***Problem within InitMaterials" << std::endl;
  225.     }
  226.     else
  227.         std::cout << "***InitMaterials clean" << std::endl;
  228.  
  229.     return Ret;
  230. }
  231.  
  232.  
  233. void Model::Render()
  234. {
  235.     glBindVertexArray(m_VAO);
  236.  
  237.     for (unsigned int i = 0; i < m_Entries.size(); i++)
  238.     {
  239.         const unsigned int MaterialIndex = m_Entries[i].MaterialIndex;
  240.  
  241.         assert(MaterialIndex < m_Textures.size());
  242.  
  243.         if (m_Textures[MaterialIndex])
  244.             m_Textures[MaterialIndex]->Bind(GL_TEXTURE0);
  245.  
  246.         glDrawElementsBaseVertex(GL_TRIANGLES,
  247.                                 m_Entries[i].NumIndices,
  248.                                 GL_UNSIGNED_INT,
  249.                                 (void*) (sizeof(unsigned int) * m_Entries[i].BaseIndex),
  250.                                 m_Entries[i].BaseVertex);
  251.     }
  252.  
  253.     glBindVertexArray(0);
  254. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement