Bonjour à vous tous, et oui, c'est encore moi, et j'ai encore un problème.
Je pensais me servir comme il faut de la lib Assimp, mais en fait non ^^

Mon problème est que les coordonnées de textures (normales je ne sais pas) sont mauvaises, mais pas les vertex, ce n'est pas un problème de (1 - y)



Vous voyez, c'est pas très beau.

Voici mon code, j’espère qu'il est assez commenté.

Je résonne par "un tableau / mesh", c'est pour ça qu'il y a beaucoup de vector.

Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
class Model
{
    public :
        Model(void);
        Model(string const &filePath);
        Model(Model const &model);
        Model &operator=(Model const &model);
 
        void load(string const &filePath);
 
        void draw(ModelViewStackMatrix const &projModelview);
 
        bool isInit(void) const {return m_IsInit;}
 
        void drop(void);
 
        ~Model(void);
 
    private :
        bool m_IsInit;
 
        // Chaque mesh possède son propre VBO indicé
        vector<VBO> m_Vbo;
        vector<VBO> m_Ibo;
 
        unsigned m_NMesh; // Nombre de Mesh
        vector<unsigned> m_NVertices; // Nombres de sommets
 
        // Contient la taille des différentes données par VBO
        vector<unsigned> m_SizeVertex;
        vector<unsigned> m_SizeNormal;
        vector<unsigned> m_SizeCoordTexture;
        vector<unsigned> m_SizeIndex;
 
        // Contient l'index du material par VBO
        vector<unsigned> m_IndexMaterial;
 
        vector<bool> m_UseNormal;  // Est ce que le mesh utilise des normals?
        vector<bool> m_UseTexture; // Est ce que le mesh utilise une texture?
 
        string m_FilePath; // Chemin du fichier
 
        const aiScene *m_Scene; // Ce qui permet de gérer la scène
 
        // Map : Key : index du matériel, Value : Texture / Color
        map<unsigned, Texture> m_Texture;
 
        map<unsigned, vec4> m_ColorDiffuse; // Couleur diffuse
        map<unsigned, vec4> m_ColorAmbient; // Couleur ambiante
 
        /*********************************************************************/
        string m_GetDir(string const &str); // Récupère le dossier du fichier
        void m_LoadAllColorTexture(void); // Récupère toutes les textures
        void m_GetData(void); // Récupère les IBO, VBO
 
        // Le i ici permet de savoir à quel mesh on se trouve
        void m_GetIbo(aiMesh const *mesh, int const &i); // Recupère les IBO
        void m_GetVbo(aiMesh const *mesh, int const &i); // Récupère les VBO
 
        static Assimp::Importer importer;
        static Shader shader;
};
Voilà tout d'abord la fonction load

Elle crée les shaders, ouvre le fichier, appelle les fonctions servant à construire le modèle

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
void Model::load(string const &filePath)
{
    // Première chose, si il n'est pas créer, on créer le shader
    if(shader.isInit() == false)
        shader.load("Shaders/Model.vert", "Shaders/Model.frag");
 
    m_Scene = importer.ReadFile(filePath, aiProcessPreset_TargetRealtime_MaxQuality);
 
    if(m_Scene == NULL)
        return;
 
    m_FilePath = filePath;
 
    m_LoadAllColorTexture();
 
    m_GetData();
 
    m_IsInit = true;
}
Ainsi que la fonction loadAllColorTexture.
Elle permet de récupérer chaque texture, et les couleurs diffuse et ambiante si il y a pour chaque mesh

Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
string Model::m_GetDir(string const &str)
{
    string res = str;
    // Supprime la partie situé après le dernier '/'
    res.erase(res.begin() + res.find_last_of('/') + 1, res.end());
    return res;
}
 
void Model::m_LoadAllColorTexture(void)
{
    for(unsigned i = 0; i != m_Scene->mNumMaterials; ++i)
    {
        aiReturn texFound = AI_SUCCESS;
        aiString pathTex; // pathTexture
 
        // On récupère le nom de la texture.
        texFound = m_Scene->mMaterials[i]->GetTexture(aiTextureType_DIFFUSE,
                                                          0, &pathTex);
        /* Le m_GetDir permet de retrouver l'adresse complète du dossier
            où se trouve le fichier 3D */
 
        if(texFound == AI_SUCCESS) // On ajoute la texture si elle existe
            m_Texture[i] = Texture(m_GetDir(m_FilePath) + pathTex.data);
 
        // On récupère notre couleur diffuse
        aiColor4D c;
        if(aiGetMaterialColor(m_Scene->mMaterials[i], AI_MATKEY_COLOR_DIFFUSE, &c) == AI_SUCCESS)
            m_ColorDiffuse[i] = vec4(c.r, c.g, c.b, c.a);
 
        // On récupère notre couleur ambiente
        if(aiGetMaterialColor(m_Scene->mMaterials[i], AI_MATKEY_COLOR_AMBIENT, &c) == AI_SUCCESS)
            m_ColorAmbient[i] = vec4(c.r, c.g, c.b, c.a);
    }
}
Maintenant, la fonction getData

Pour chaque mesh, cette fonction récupère un IBO, un VBO, et l'index du matériel utilisé par ce mesh

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void Model::m_GetData(void)
{
    m_NMesh = m_Scene->mNumMeshes;
 
    VBO vbo;
 
    // Pour chaque mesh
    for(unsigned i = 0; i < m_NMesh; ++i)
    {
        aiMesh *mesh = m_Scene->mMeshes[i];
 
        m_GetIbo(mesh, i);
        m_GetVbo(mesh, i);
 
        //L'index du materiel afin de pouvoir afficher la bonne texture
        m_IndexMaterial.push_back(mesh->mMaterialIndex);
    }
}
La fonction getIbo
Cette fonction récupère les indices de toutes les faces et les met dans un IBO
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
void Model::m_GetIbo(aiMesh const *mesh, int const &i)
{
    VBO ibo;
 
    // On multiplie par 3 car 3 sommets dans une face (triangle)
    m_NVertices.push_back(mesh->mNumFaces * 3); // Nombre de sommets
 
    unsigned *index = new unsigned[m_NVertices[i]]; // donnée de l'IBO
 
    // Multiplication par sizeof unsigned pour avoir le nombre de byte
    m_SizeIndex.push_back(m_NVertices[i] * sizeof(unsigned));
 
    // Pour chaque face
    for(unsigned t = 0; t < mesh->mNumFaces; ++t)
    {
        // On récupère la face.
        aiFace *faceActu = &mesh->mFaces[t];
 
        // On copie les indices de la face dans notre tableau d'index
        // Toujours une multiplication par trois car 3 indices = une face
        memcpy(&index[t * 3], faceActu->mIndices, 3 * sizeof(unsigned));
    }
 
    // On crée l'IBO
    ibo.allocate(m_SizeIndex[i], INDEX_BUFFER, NEVER_MODIFY);
    ibo.sendData(index, m_SizeIndex[i], 0);
 
    m_Ibo.push_back(ibo); // Copie de l'ibo
 
    // Libère de la mémoire
    ibo.drop();
    delete[] index;
}
La fonction getVbo
Elle récupère le nombre de sommet, ajuste en conséquence la taille des normales, coordonnée de texture et des vertex et les envoie dans le VBO
en ajustant les offset

Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
void Model::m_GetVbo(aiMesh const *mesh, int const &i)
{
    VBO vbo;
 
    // On récupère les tailles des différentes composantes
    m_SizeVertex.push_back(mesh->mNumVertices * 3 * sizeof(float));
 
    // Si il y a des normales
    if(mesh->HasNormals())
    {
        m_SizeNormal.push_back(mesh->mNumVertices * 3 * sizeof(float));
        m_UseNormal.push_back(true);
    }
 
    else
    {
        m_SizeNormal.push_back(0);
        m_UseNormal.push_back(false);
    }
 
    // Si il y a une texture
    if(mesh->HasTextureCoords(0))
    {
        // 2 coordonnée pour une coordonnée de texture
        m_SizeCoordTexture.push_back(mesh->mNumVertices * 2 * sizeof(float));
        m_UseTexture.push_back(true);
    }
 
    else
    {
        m_SizeCoordTexture.push_back(0);
        m_UseTexture.push_back(false);
    }
 
    // Maintenant que l'on a toutes les tailles, on créer le VBO
    vbo.allocate(m_SizeVertex[i] + m_SizeNormal[i] +
                 m_SizeCoordTexture[i],
                 ARRAY_BUFFER, NEVER_MODIFY);
 
    // On envoie les données une par une en utilisant l'offset
    vbo.sendData(mesh->mVertices, m_SizeVertex[i],
                 0); // vertex
 
    vbo.sendData(mesh->mNormals, m_SizeNormal[i],
                 m_SizeVertex[i]); // normal
 
    vbo.sendData(mesh->mTextureCoords[0], m_SizeCoordTexture[i],
                 m_SizeVertex[i] + m_SizeNormal[i]); // coordTexture
 
    m_Vbo.push_back(vbo); // On copie notre vbo
    vbo.drop(); // On le supprime
}
Et enfin, même si je pense que ce n'est pas le plus important, la fonction d'affichage

Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
void Model::draw(ModelViewStackMatrix const &mat)
{
    shader.use(true);
 
    // Pour chaque mesh
    for(unsigned i = 0; i < m_NMesh; ++i)
    {
        m_Vbo[i].use(true);
        m_Ibo[i].use(true);
            shader.sendVar("in_Vertex", 3,
                            BUFFER_OFFSET(0));
 
            if(m_UseNormal[i])
            {
                shader.sendVar("in_Normal", 3,
                                BUFFER_OFFSET(m_SizeVertex[i]));
            }
 
            if(m_UseTexture[i])
            {
                shader.sendVar("in_TexCoord", 2,
                                BUFFER_OFFSET(m_SizeVertex[i] +
                                              m_SizeNormal[i]));
            }
 
            // Si il y a utilisation de texture, on recupère l'index du matériel
            if(m_UseTexture[i])
                m_Texture[m_IndexMaterial[i]].use();
            else // Sinon, on désactive la texture
                Texture::noUse();
 
            shader.sendInt("useTex", m_UseTexture[i] ? 1 : 0);
            shader.sendVec4("colorDiffuse", m_ColorDiffuse[m_IndexMaterial[i]]);
            shader.sendVec4("colorAmbient", m_ColorAmbient[m_IndexMaterial[i]]);
 
            shader.sendMatrix4("projectionModelView", mat.getMatrix());
            glDrawElements(GL_TRIANGLES, m_NVertices[i], GL_UNSIGNED_INT, 0);
    }
 
    shader.use(false);
}
Voilà, merci de votre aide, et désolé pour la taille du code que je viens de vous envoyer(mais ça pourra éventuellement servir à quelqu'un d'autre '-' )...

EDIT : Trouver l'erreur en lisant mieux la documentation, pour les coordonnées de texture, c'est un vecteur3D aussi, pas un vecteur2D, donc c'est normal que ça ne marchait pas ^^ Désolé du dérangement.