Partage
  • Partager sur Facebook
  • Partager sur Twitter

Affichage partiel sous OpenGL

    12 février 2019 à 22:23:55

    Bonjour à tous,

    Suivant quelques tutoriels ça et là sur le web, je me fais un peu la main sur OpenGL. J'ai réalisé un tout petit module me permettant de charger des fichiers *.obj, mais je pense que ce chargeur nécessite quelques modifications.

    Voici ce que me donne l'un des modèles que je peux charger :

    On voit ici que seuls certains polygones apparaissent. Lorsque je souhaite charger des modèles plus simples (tétraèdres, cubes etc...) tout se déroule bien. Mais dès qu'il s'agit de modèles plus complets, j'ai ce type de résultats (voire rien du tout).

    Pour des raisons pratiques, je ne pourrais montrer ici que la partie "loader" du code qui selon moi est la partie à modifier :

    void Mesh::load(const GLchar* path)
    {
    
    	std::ifstream file(path, std::ios::in);
    	std::string line;
    
    	if(!file)
    	{
    		std::cout << "ERROR : failed to load mesh file !" << std::endl;
    		exit(0);
    	}
    
    	while(getline(file, line))
    	{
    		if (line.substr(0,2) == "v ")
            {
    			std::istringstream s(line.substr(2));
                glm::vec3 vp;
                s >> vp.x >> vp.y >> vp.z;
                m_vertex.push_back(vp);
            }
            else if (line.substr(0,3) == "vt ")
    		{
    			std::istringstream s(line.substr(3));
                glm::vec2 vt;
                s >> vt.x >> vt.y;
                m_texture.push_back(vt);
    		}
            else if (line.substr(0,3) == "vn ")
    		{
    			std::istringstream s(line.substr(3));
                glm::vec3 vn;
                s >> vn.x >> vn.y >> vn.z;
                m_normal.push_back(vn);
    		}
    		else if(line.substr(0,2) == "f ")
    		{
    			std::istringstream s(line.substr(2));
                unsigned short v, t, n;
                v = t = n = 0;
    			for(int i = 0; i < 3; i++)
    			{
    				s >> v; s.seekg(1, std::ios::cur);
    				s >> t; s.seekg(1, std::ios::cur);
    				s >> n;
    
    				m_vertexIndex.push_back(v-1);
    				m_textureIndex.push_back(t-1);
    				m_normalIndex.push_back(n-1);
    			}
    		}
    	};
    
    	file.close();
    }


    Le côté "indexage" du modèle est réalisé directement par OpenGL grâce à l'EBO :

    void Mesh::initialiseEBO()
    {
    	glGenBuffers(1, &m_ebo);
    	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ebo);
    		glBufferData(GL_ELEMENT_ARRAY_BUFFER, m_vertexIndex.size() * sizeof(GLfloat), &m_vertexIndex[0], GL_STATIC_DRAW);
    	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
    }


    Si quelqu'un, via les informations fournies, est capable de m'indiquer les éléments à améliorer, j'en serais ravi !

    Si vous avez besoin de plus d'infos, n'hésitez pas à me demander, je tâcherais de fournir le code nécessaire.

    Merci d'avance !

    -
    Edité par BioKore 12 février 2019 à 22:24:20

    • Partager sur Facebook
    • Partager sur Twitter
      13 février 2019 à 0:08:48

      Salut !

      Es-tu sûr que les faces sont bien des triangles ?
      Dans le format OBJ, tu peux avoir des triangles ou des quads (3 ou 4 indices pour la balise "f")

      • Partager sur Facebook
      • Partager sur Twitter

      Si vous ne trouvez plus rien, cherchez autre chose.

        13 février 2019 à 19:00:40

        Très bien vu ! Il n'y a effectivement que des quads dans le *.obj ! D'ailleurs, hier, juste après avoir poster ce message, je me suis aperçu que le modèle suivant s'affichait correctement :

        Donc oui. Je ferais plus attention à ça par la suite !

        Je profiterais de ce post d'ailleurs, pour savoir s'il était vraiment nécessaire, dans le cas d'un projet pédagogique, de récupérer les "submeshes". Par exemple, dans le modèle affiché juste au dessus, l'objet principal est découpé en plusieurs séries de v/vt/vn/f entrecoupés de "g" (sur wikipedia j'ai vu qu'il s'agissait de groupes). J'imagine que cela est particulièrement utile pour la gestion des textures non ?

        Car du coup, je me demande si au lieu de charger tout le fichier comme un bourrin (visiblement ça marche quand même), je ne devrais pas récupérer un array de submeshes pour en faire des subobmodels qui au final générerons mon modèle. Par modèle, j'entends Mesh + Texture + Matériau. Donc par exemple, pour une voiture, je pourrais avoir 5 submodels (4 roues + une caisse) qui contiennent chacun leurs textures et matériaux, et enfin agglomérer le tout pour former le modèle "voiture".

        Je sais que le plus simple serait d'utiliser une bibliothèque toute prête pour le chargement des fichiers, mais à mon avis, il est tout de même important que je fasse moi même un module de chargement minimal mais assez clair afin de mieux comprendre comment tout s'emboite.

        • Partager sur Facebook
        • Partager sur Twitter
          13 février 2019 à 19:17:36

          De mon côté, j'utilise Assimp, pour charger les modèles, parce que le format OBJ est une poubelle, chacun fait plus ou moins à sa sauce.

          Après, dans mon parser OBJ, je ne changeais de submesh que lorsque je rencontrais une instruction "usemtl"

          • Partager sur Facebook
          • Partager sur Twitter

          Si vous ne trouvez plus rien, cherchez autre chose.

            13 février 2019 à 20:03:44

            Et du coup, comment ça se passe quand tu as des textures différentes ? ces informations sont contenues dans le mtl aussi ? Sur le modèle de mon précédent post, le dossier ne contient qu'un  seul fichier mtl mais plusieurs fichiers textures. Je vais me renseigner un peu plus sur ces formats....
            • Partager sur Facebook
            • Partager sur Twitter
              13 février 2019 à 20:12:41

              Ben les textures peuvent être utilisées à différents effets : couleur diffuse, couleur spéculaire, couleur émissive, normales, ... Et ce rien que pour le format OBJ.

              • Partager sur Facebook
              • Partager sur Twitter

              Si vous ne trouvez plus rien, cherchez autre chose.

                17 février 2019 à 10:38:18

                Ce qui saute aux yeux dans le premier screenshot (la main), c'est que tu as un triangle sur deux d'affiché :)

                Visiblement tu ne gères pas l'éclairage, mais on pourrait penser que les normales des triangles pas vu sont juste à l'envers, autrement dit tu as dessiné le triangles dans le mauvais sens.

                J'ai déjà eu ce soucis avec les triangles-strip que je gérais mal.

                • Partager sur Facebook
                • Partager sur Twitter

                Recueil de code C et C++  http://fvirtman.free.fr/recueil/index.html

                  17 février 2019 à 12:46:21

                  Too late, too late :D
                  • Partager sur Facebook
                  • Partager sur Twitter

                  Si vous ne trouvez plus rien, cherchez autre chose.

                  Affichage partiel sous OpenGL

                  × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                  × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                  • Editeur
                  • Markdown