Partage
  • Partager sur Facebook
  • Partager sur Twitter

Pointeur sur un unsigned int qui change de valeur.

La valeur du pointeur change toute seule.

Sujet résolu
    21 mars 2019 à 16:11:47

    Salut, je voudrais faire un pointeur sur des index, (j'utilise des EBOs pour afficher des sommets) et lorsque je supprime des sommets de particules je dois remettre à jour les indices du VBO de tout les sommets de la scène pour que les indices se suivent pour ne pas avoir de trou ce qui poserait problème à l'affichage car j'aurai des indices dans mon EBO qui pointent vers aucun sommet.

    Et pour pas devoir remettre à jour les index dans tout les tableaux de sommets de mes entités, j'utilise un pointeur sur une unsigned int pour tout les tableaux de sommets de mes entités.

    Problème : même si les pointeurs sur les index sont bien référencé lorsque je les ajoutes dans les tableaux de sommet de mes entités :


    virtual bool addEntity(Entity *entity) {
                    transformMatrices.push_back(&entity->getTransform());
                    for (unsigned int i = 0; i < entity->getNbFaces(); i++) {
                        VertexArray& va =  entity->getFace(i)->getVertexArray();
                        //va.transform(entity->getTransform());
                        for (unsigned int j = 0; j < va.getVertexCount(); j++) {
                            sceneVertices.append(va[j]);
                            sceneVertices.addIndex(va, nbSceneVertices);
                            sceneVertices.addTransformId(nbTransforms, nbSceneVertices);
                            nbSceneVertices++;
                        }
                    }
                    /*std::cout<<"type : "<<entity->getType()<<std::endl;
                    for (unsigned int i = 0; i < entity->getNbFaces(); i++) {
                        VertexArray& va =  entity->getFace(i)->getVertexArray();
                        for (unsigned int j = 0; j < va.getVertexCount(); j++) {
                            std::cout<<"added index : *"<<va.m_indexes[j]<<std::endl;
                        }
                    }*/
    
                    entity->getTransform().setTransformId(nbTransforms);
                    nbTransforms++;
                }

    sceneVertices est de type Vertexbuffer.

    void VertexBuffer::addIndex(VertexArray& va, unsigned int index) {
                m_indexes.push_back(index);
                va.addIndex(&m_indexes.back());
                if (!needToUpdateIndexBuffer)
                    needToUpdateIndexBuffer = true;
            }
    void VertexArray::addIndex(unsigned int* index) {
                m_indexes.push_back(index);
                //std::cout<<"va index : "<<index<<"size : "<<m_indexes.size()<<std::endl;
                if (!needToUpdateVBOBuffer)
                    needToUpdateVBOBuffer = true;
            }




    Lorsque je veux récupérer les entités visible de la scène, la valeur des index change toute seule (pourtant les adresses de mes unsigned int sont bonne) :


    vEntitiesByType.clear();
                        visibleEntities.clear();
                        visibleEntities.resize(Entity::getNbEntityTypes());
                        for (unsigned int i = 0; i < visibleEntities.size(); i++) {
                            visibleEntities[i].resize(Entity::getNbEntities(), nullptr);
                        }
                        int x = view.getPosition().x;
                        int y = view.getPosition().y;
                        int z = view.getPosition().z;
                        int endX = view.getPosition().x + view.getWidth() + 100;
                        int endY = view.getPosition().y + view.getHeight() + 100;
                        int endZ = view.getDepth() + 100;
                        physic::BoundingBox bx (x, y, z, endX-view.getPosition().x, endY-view.getPosition().y, endZ);
    
                        for (int i = x; i <= endX; i+=gridMap->getOffsetX()) {
                            for (int j = y; j <= endY; j+=gridMap->getOffsetY()) {
                                //for (int k = 0; k <= endZ; k+=gridMap->getOffsetZ()) {
                                    math::Vec3f point(i, j, 0);
                                    CellMap* cell = getGridCellAt(point);
                                    if (cell != nullptr) {
                                        for (unsigned int n = 0; n < cell->getNbEntitiesInside(); n++) {
                                           Entity* entity = cell->getEntityInside(n);   
                                           physic::BoundingBox& bounds = entity->getGlobalBounds();
                                           
                                           if (bx.intersects(bounds) && visibleEntities[entity->getRootTypeInt()][entity->getId()] != entity) {
    
                                               visibleEntities[entity->getRootTypeInt()][entity->getId()] = entity;
                                           }
                                          
                                        }
                                    }
                                //}
                            }


    Alors je ne sais pas ce qu'il a fumé le compilateur parce que la position des sommets et tout ça reste bonne lorsque j'ajoute les entités ici :

    bool Map::addEntity(Entity *entity) {
                EntityManager::addEntity(entity);
                if (entity->isAnimated()) {
                    if (static_cast<AnimatedEntity*>(entity)->getCurrentFrame() != nullptr) {
                        addEntity(static_cast<AnimatedEntity*>(entity)->getCurrentFrame());
                    } else {
                        gridMap->addEntity(entity);
                    }
                } else {
                    std::vector<Entity*> children = entity->getChildren();
                    for (unsigned int i = 0; i < children.size(); i++) {
                         addEntity(children[i]);
                    }
                }
                /*if (entity->getType() == "E_PONCTUAL_LIGHT") {
                        std::cout<<"ponctual light"<<std::endl;
                        sf:sleep(sf::seconds(1));
                }*/
                if (entity->isLeaf()) {
                    for (unsigned int j = 0; j < entity->getFaces().size(); j++) {
                         if (entity->getFaces()[j]->getMaterial().getTexture() != nullptr) {
                             increaseComptImg(entity->getFaces()[j]->getMaterial().getTexture());
                         }
                    }
                    gridMap->addEntity(entity);
                    for (unsigned int c = 0; c < frcm->getNbComponents(); c++) {
                        if(frcm->getRenderComponent(c) != nullptr) {
                            frcm->getRenderComponent(c)->loadShaders();
                        }
                    }
                }            
            }
       bool GridMap::addEntity (Entity *entity) {
                int x = entity->getGlobalBounds().getPosition().x;
                int y = entity->getGlobalBounds().getPosition().y;
                int endX = (x + entity->getGlobalBounds().getWidth());
                int endY = (y + entity->getGlobalBounds().getHeight());
                bool added = false;
                /*std::array<math::Vec2f, 4> pos;
                pos[0] = math::Vec2f(x, y);
                pos[1] = math::Vec2f(x, y + endY);
                pos[2] = math::Vec2f(x + endX, y + endY);
                pos[3] = math::Vec2f(x + endX, y);
    
                for (unsigned int i = 0; i < pos.size(); i++) {
                    if (!(containsEntity(entity, pos[i]))) {
                        CellMap *cm = getGridCellAt(pos[i]);
                        if (cm == nullptr) {
                            createCellMap(pos[i]);
                            cm = getGridCellAt(pos[i]);
                        }
                        added = true;
                        cm->addEntity(entity);
                    }
                }*/
                for (int i = x; i <= endX; i+= offsetX) {
                    for (int j = y; j <= endY; j+= offsetY)  {
                        math::Vec2f pos (i, j);
                        if (!(containsEntity(entity, pos))) {
                            CellMap *cm = getGridCellAt(pos);
                            if (cm == nullptr) {
                                createCellMap(pos);
                                cm = getGridCellAt(pos);
                            }
                            added = true;
                            cm->addEntity(entity);
                        }
                    }
                }
                return added;
            }
     void CellMap::addEntity (Entity *entity) {
                std::unique_ptr<Entity> ptr;
                ptr.reset(entity);
                entityInside.push_back(std::move(ptr));
            }


    Je vais renommer la classe Map en classe Scene parce que Map ça fait pensé à une classe du jeux et pas à une classe du moteur de jeux.

    Si vous voulez voir plus de code il est sur mon dépôt git : Ici


    PS : bon apparemment la valeur des deux premiers unsigned int change toute seule, même si les pointeurs sur les unsigned int pointent toujours vers la même adresse. Voici une image qui illustre le bug (ça semble être un bug du compilateur c++)

    -
    Edité par OmbreNoire 21 mars 2019 à 16:50:43

    • Partager sur Facebook
    • Partager sur Twitter
      21 mars 2019 à 16:27:47

      Lu'!

      Lorsque tu redimensionnes un vector, tu invalides potentiellement tout pointeur sur son contenu.

      • Partager sur Facebook
      • Partager sur Twitter
      Posez vos questions ou discutez informatique, sur le Discord NaN | Tuto : Preuve de programmes C
        21 mars 2019 à 16:52:19

        A mince, comment je peux faire alors pour que le contenu du pointeur reste valide, je dois utiliser un tableau dynamique car, je ne connais pas à l'avance la taille de mes éléments.
        • Partager sur Facebook
        • Partager sur Twitter
          21 mars 2019 à 16:57:27

          Enregistre un index plutôt qu'un pointeur.

          • Partager sur Facebook
          • Partager sur Twitter
          Posez vos questions ou discutez informatique, sur le Discord NaN | Tuto : Preuve de programmes C
            21 mars 2019 à 17:27:03

            Ok je vais faire cela merci.
            • Partager sur Facebook
            • Partager sur Twitter
              24 mars 2019 à 10:09:20

              Sinon, si tu veux éviter que tes pointeurs soient invalidés par le redimensionnement du vector, tu peux faire :

              vector.reserve(x)

              Après, ça ne marchera que si tu sais à l'avance le nombre d'éléments que contiendra ton vector et ça ne marchera plus si tu dépasses x nombres d'éléments dans ton vector.

              • Partager sur Facebook
              • Partager sur Twitter
                24 mars 2019 à 15:38:39

                A oui je comprend si je devais faire une classe moi même, que je redimensionnerais le tableau il faut faire une copie des éléments de l'ancien tableau, dans le nouveau et donc, les pointeurs ne sont plus valides.

                Je sais pas si il y a moyen de trouver une solution pour redimentionner un tableau sans le recopier, genre faire une allocation en ajoutant de la mémoire supplémentaire et ajouter les nouveaux élément à la fin. Ça serait plus performant ...

                • Partager sur Facebook
                • Partager sur Twitter
                  25 mars 2019 à 16:34:36

                  J'ai une idée, en fait mon std::vector (un VBO) contient des blocs de sommets et d'ids qui eux, sont de taille fixe, (ainsi lorsque je remet à jour les sommets d'une animation, je n'ai besoin que de remettre à jour les sommets de l'animation et pas tout le VBO avec glSubArray.)

                  Je pensais faire ceci : un std;;vector qui contient des tableaux à taille fixe et renvoyer des pointeurs sur les ids contenu dans le tabeau à taille fixe.

                  Et donc là normalement, même si je redimensionne le vecteur, les élément dans le tableau contiennent toujours la même adresse, la seule adresse qui change se sera l'adresse du tableau dans le std::vector.

                  Il faudrait que je teste ça, ça serait génial, je ne devrais plus modifier les id dans le VBO, et dans les Vertex array. (Et donc ça serait plus rapide et moi, j'ai vraiment besoin d'avoir quelque chose de performant, surtout pour faire du rendu en temps réel ou là il faut vraiment coder mais d'une manière heu comment dire, faut vraiment réfléchir quoi)

                  -
                  Edité par OmbreNoire 25 mars 2019 à 16:35:15

                  • Partager sur Facebook
                  • Partager sur Twitter
                    25 mars 2019 à 16:46:53

                    Nope. Si tu mets des tableaux dans ton vector, tu y mets des tableaux, pas des pointeurs vers les tableaux.

                    • Partager sur Facebook
                    • Partager sur Twitter
                    Posez vos questions ou discutez informatique, sur le Discord NaN | Tuto : Preuve de programmes C
                      28 mars 2019 à 21:15:42

                      "Je sais pas si il y a moyen de trouver une solution pour redimentionner un tableau sans le recopier, genre faire une allocation en ajoutant de la mémoire supplémentaire et ajouter les nouveaux élément à la fin."

                      Impossible car rien ne garantie qu'il y ait assez de memoire en contigu pour agrandir le tableau.


                      • Partager sur Facebook
                      • Partager sur Twitter

                      Pointeur sur un unsigned int qui change de valeur.

                      × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                      • Editeur
                      • Markdown