1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160
|
bool Modele::loadGlresources(const aiScene *scene)
{
m_scene = scene;
//adapte le tableau contenant les indices des VBO au nombre de mesh
m_info_rendu.resize(scene->mNumMeshes);
//on crée un VBO pour chaque mesh
for(unsigned int i = 0; i < scene->mNumMeshes; i++)
{
aiMesh* mesh = scene->mMeshes[i];
//structure recevant les indices, ....
g_resources infoMesh;
infoMesh.mesh = mesh;
// Gestion des matériaux
unsigned int numMaterial = mesh->mMaterialIndex;
if(scene->HasMaterials() && (numMaterial <= scene->mNumMaterials))
{
//gestion de la texture
//nom de la texture
aiString cheminTex;
if(AI_SUCCESS == material->GetTexture(aiTextureType_DIFFUSE, 0, &cheminTex))
{
//conversion aiString to std::string
std::string nomTex;
for(size_t k = 0; k < cheminTex.length; k++)
{
nomTex += cheminTex.data[k];
}
//construction du chemin absolu de l'image
QDir cheminAppli;
QString cheminImage = cheminAppli.absolutePath() + "/modeles/" + nomTex.c_str();
infoMesh.texture = m_RenduModele->loadTexture(cheminImage);
infoMesh.hasTexture = true;
}
else
infoMesh.hasTexture = false;
}
else
{
infoMesh.hasTexture = false;
//couleur par defaut
infoMesh.couleur = glm::vec4(1.0f, 0.0f, 0.0f, 1.0f);
}
// création du buffer pour les position, normals, texCoord
infoMesh.vertex_buffer = new QGLBuffer(QGLBuffer::VertexBuffer);
if(infoMesh.vertex_buffer->create())
{
infoMesh.vertex_buffer->bind();
infoMesh.vertex_buffer->setUsagePattern(QGLBuffer::DynamicDraw);
//tableau temporaire contenant les infos
info_vertex *attributes = (info_vertex *)malloc(mesh->mNumVertices * sizeof(info_vertex));
for(unsigned int j = 0; j < mesh->mNumVertices; j++)
{
attributes[j].position.x = mesh->mVertices[j].x;
attributes[j].position.y = mesh->mVertices[j].y;
attributes[j].position.z = mesh->mVertices[j].z;
attributes[j].position.w = 1.0f;
if(mesh->HasNormals())
{
attributes[j].normal.x = mesh->mNormals[j].x;
attributes[j].normal.y = mesh->mNormals[j].y;
attributes[j].normal.z = mesh->mNormals[j].z;
attributes[j].normal.w = 1.0f;
}
else
{
attributes[j].normal = glm::vec4(0.0f, 0.0f, 0.0f, 0.0f);
}
if(mesh->HasVertexColors(0))
{
infoMesh.hasColors = true;
attributes[j].couleur.r = mesh->mColors[0][j].r;
attributes[j].couleur.g = mesh->mColors[0][j].g;
attributes[j].couleur.b = mesh->mColors[0][j].b;
attributes[j].couleur.a = 1.0f;
}
else
{
attributes[j].couleur = glm::vec4(0.0f, 0.0f, 0.0f, 1.0f);
}
if(mesh->HasTextureCoords(0))
{
attributes[j].texCoord.x = mesh->mTextureCoords[0][j].x;
attributes[j].texCoord.y = mesh->mTextureCoords[0][j].y;
}
else
{
attributes[j].texCoord = glm::vec2(0.0, 0.0);
}
}
//on envoie les données au VBO
infoMesh.vertex_buffer->allocate(attributes, mesh->mNumVertices * sizeof(info_vertex));
GLsizei stride = sizeof(info_vertex);
infoMesh.in.position = m_RenduModele->m_program.attributeLocation("position");
m_RenduModele->m_program.setAttributeBuffer(infoMesh.in.position, GL_FLOAT, (int)offsetof(info_vertex, position), 4, stride);
infoMesh.in.normal = m_RenduModele->m_program.attributeLocation("normal");
m_RenduModele->m_program.setAttributeBuffer(infoMesh.in.normal, GL_FLOAT, (int)offsetof(info_vertex, normal), 4, stride);
infoMesh.in.texCoord = m_RenduModele->m_program.attributeLocation("texCoord");
m_RenduModele->m_program.setAttributeBuffer(infoMesh.in.texCoord, GL_FLOAT, (int)offsetof(info_vertex, texCoord), 2, stride);
infoMesh.in.couleur = m_RenduModele->m_program.attributeLocation("couleur");
m_RenduModele->m_program.setAttributeBuffer(infoMesh.in.couleur, GL_FLOAT, (int)offsetof(info_vertex, couleur), 4, stride);
infoMesh.vertex_buffer->release();
m_RenduModele->m_program.release();
free(attributes);
}
else
return false;
//Création des indices
infoMesh.element_buffer = new QGLBuffer(QGLBuffer::IndexBuffer);
if(infoMesh.element_buffer->create())
{
infoMesh.element_buffer->bind();
//tableau temporaire
element *indices = (element *)malloc(mesh->mNumFaces * 3 * sizeof(element));
//on parcourt les faces
unsigned int count = 0;
for(unsigned int p = 0; p < mesh->mNumFaces; p++)
{
indices[count].element = mesh->mFaces[p].mIndices[0];
indices[count + 1].element = mesh->mFaces[p].mIndices[1];
indices[count + 2].element = mesh->mFaces[p].mIndices[2];
count += 3;
}
//on charge les indices
infoMesh.element_buffer->allocate(indices, mesh->mNumFaces * 3 * sizeof(element));
infoMesh.count = mesh->mNumFaces * 3;
free(indices);
}
//on sauvegarde à l'indice du mesh
m_info_rendu[i] = infoMesh;
//on augmente le nombre de mesh
m_nbMesh++;
}
return true;
} |
Partager