IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

OpenGL Discussion :

Vertex-Array: crash à la destruction de la liste d'indices


Sujet :

OpenGL

  1. #1
    Membre chevronné
    Inscrit en
    Février 2008
    Messages
    413
    Détails du profil
    Informations personnelles :
    Âge : 45

    Informations forums :
    Inscription : Février 2008
    Messages : 413
    Par défaut Vertex-Array: crash à la destruction de la liste d'indices
    Bonjour,

    j'implémente en ce moment les vertex Arrays pour accélérer un peu mon rendu.

    J'ai pour l'instant deux versions:
    A) une créant un array à afficher avec glDrawArrays: dans ce tableau, certains vertex sont répétés
    B) une où j'utilise glDrawElements: dans ce cas, les vertex ne sont pas répétés dans le tableau, mais dans la liste d'indices qui lui est associée

    Dans les deux cas, ca marche, tout s'affiche comme il faut.

    En revanche, quand je quitte mon programme, ca plante au moment d'effacer ma liste d'indices (donc seulement dans le cas B), le A) n'ayant pas d'indices).

    C'est bizarre, OpenGL garde-t-il un lien vers cette liste? Ca me surprendrait, d'autant plus que les tableaux de vertex, eux, s'effacent sans problème....

  2. #2
    Membre chevronné
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    366
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 366
    Par défaut
    ne tenterais tu pas de detruire les listes apres destruction du context OpnGL ?

  3. #3
    Membre chevronné
    Inscrit en
    Février 2008
    Messages
    413
    Détails du profil
    Informations personnelles :
    Âge : 45

    Informations forums :
    Inscription : Février 2008
    Messages : 413
    Par défaut
    Je détruis tout ca dans mes destructeurs, donc à priori après la destruction du contexte OpenGL.

    Dans tous les cas il s'agit d'un tableau de GLushort dans mon code c++, ca ne devrait donc rien avoir à faire avec OpenGL (ce n'est pas comme si j'effacais des display lists). Je viens d'essayer de supprimer le tableau avant la destruction du contexte OpenGL mais ca ne change rien.

    Comme dit, ca marche sans problème pour le tableau de vertex donc je suis un peu perdu là....

  4. #4
    Membre chevronné
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    366
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 366
    Par défaut
    je pensais que tu tentais de detruire une ressource OpenGL (un handle type GL(u)int sur un vertex buffer) apres destruction du context lui meme.

    Si tu as un crash au moment du delete sur un buffer memoire CPU c'est autre chose ...


    Dans ce cas, si tu as un bout de code minimaliste , ca nous aidera a t aider

  5. #5
    Membre chevronné
    Inscrit en
    Février 2008
    Messages
    413
    Détails du profil
    Informations personnelles :
    Âge : 45

    Informations forums :
    Inscription : Février 2008
    Messages : 413
    Par défaut
    Salut,

    oui comme dit à priori c'est plus un probleme de c++ que d'opengl, mais vu que je suis quand même a peu près sûr de faire les choses correctement avec mon code c++ je ne sais plus trop....

    Bref, un peu de code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    class BGLVertexArray
    {
    private:
    	.....
            .....
    	// 1D sorted array parameters
    	short		m_1DArray_Size;			// Size of the 1D sorted or indexed array 
    	short		m_1DArray_nbIndices;	// Number of indices for the 1D indexed array
    	short		m_1DArray_Type;			// Type (sorted or indexed) of the 1D array
    	BGLVertex*	m_1DArray_Data;			// Sorted 1D Array 		
    	GLushort*	m_1DArray_Indices;		// Indices of the indexed 1D array
    Mon constructeur, qui ne fait rien à part initialiser les variables:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    BGLVertexArray::BGLVertexArray()
    {
    	....
            ....
    	m_1DArray_Data			= NULL;
    	m_1DArray_Indices		= NULL;
            ....
    }
    La création des deux tableau se fait dans une autre méthode, extraits:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    void BGLVertexArray::Create1DIndexedArray()
    {
            ....
    	m_1DArray_Indices	= new GLushort[m_1DArray_nbIndices];
    	m_1DArray_Data		= new BGLVertex[m_1DArray_Size];
           .....
           //Remplissage des tableaux
           ....
    }
    Ensuite, avant de créer ma display list, j'appelle:
    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
     
    void BGLVertexArray::LoadArrays(BOOL useVertexAttribs, GLint attribLocation)
    {
    	glEnableClientState(GL_VERTEX_ARRAY);
    	glVertexPointer(3, GL_DOUBLE, sizeof(BGLVertex), &m_1DArray_Data[0].Pos[0]);
     
    	glEnableClientState(GL_NORMAL_ARRAY);	
    	glNormalPointer(GL_DOUBLE, sizeof(BGLVertex), &m_1DArray_Data[0].Norm[0]);	
     
    	glClientActiveTexture(GL_TEXTURE1); 
    	glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    	glTexCoordPointer(2, GL_DOUBLE, sizeof(BGLVertex), &m_1DArray_Data[0].TexCoords[0]);	
     
    	m_attribLoc = attribLocation;
    	if(useVertexAttribs)
    	{
    		glEnableVertexAttribArray(m_attribLoc);
    		glVertexAttribPointer(m_attribLoc, 3, GL_DOUBLE, false, sizeof(BGLVertex), &m_1DArray_Data[0].CNorm[0]);
    	}
    }
    Et pour dessiner:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    void BGLVertexArray::Draw()
    {
    	switch(m_1DArray_Type)
    	{
    		case SORTED_ARRAY:
    			glDrawArrays(GL_TRIANGLE_STRIP, 0, m_1DArray_Size);
    			break;
     
    		case INDEXED_ARRAY:
    			glDrawElements(GL_TRIANGLE_STRIP, m_1DArray_nbIndices, GL_UNSIGNED_SHORT, m_1DArray_Indices);
    			break;
    	}
    }
    Dans le cas qui pose problème, j'utilise INDEXED_ARRAY

    Jusque là tout va bien, dans les deux cas ca s'affiche correctement, donc les tableaux sont bien créés et leur contenu est valide

    par contre quand le destructeur est appelé, ca plante à la destruction de la liste d'indices (mais, je le rappelle, pas de problème pour détruire la liste des vertex)

    Destructeur:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    BGLVertexArray::~BGLVertexArray()
    {
    	if(m_1DArray_Data)	  delete[] m_1DArray_Data;
            if(m_1DArray_Indices) delete[] m_1DArray_Indices; // Et là ca plante....
    }
    Voilà, ca fait pas mal de code d'un coup, désolé, mais ca ne devrait pas être trop compliqué à comprendre... Bref, si quelqu'un a une idée elle est plus que la bienvenue, merci d'avance!

  6. #6
    Membre Expert
    Avatar de shenron666
    Homme Profil pro
    avancé
    Inscrit en
    Avril 2005
    Messages
    2 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : avancé

    Informations forums :
    Inscription : Avril 2005
    Messages : 2 580
    Par défaut
    les raisons qui me viennent à l'esprit sont :
    - tu libères un pointeur invalide
    - tu libères un pointeur alors qu'une partie de ton code utilise les données qu'il stocke

    assures toi qu'OpenGL n'est pas en train d'utiliser ton tableau au moment où tu le libères
    il faut savoir qu'un appel à glDrawElements est asynchrone
    tu balances le pointeur au driver qui te rend la main aussitot et les données pointées sont transférées en tache de fond, ce qui peux faire planter si tu libères le pointeur alors qu'il est en train de transférer
    Tutoriels OpenGL
    Je ne répondrai à aucune question en MP
    - Si c'est simple tu dis que c'est compliqué et tu le fait
    - Si c'est compliqué tu dis que c'est simple et tu le sous-traite ou le fait faire par un stagiaire.

  7. #7
    Membre chevronné
    Inscrit en
    Février 2008
    Messages
    413
    Détails du profil
    Informations personnelles :
    Âge : 45

    Informations forums :
    Inscription : Février 2008
    Messages : 413
    Par défaut
    Merci pour tes réponses Shenron666,

    Je ne pense pas que ca vienne d'un pointeur invalide, je vais vérifier ca encore mais il n'y pas de raison (d'autant plus que je teste le pointeur avant d'effacer la mémoire).

    Par contre le coup du glDrawElements asynchrone ca pourrait bien être ca. Comment puis-je m'assurer que le transfert est terminé?
    J'ai essayé un glFinish ou un glFlush avant de détruire mon pointeur mais rien n'y fait

    En fait, je n'utilise glDrawElements que lors de la création de ma display list. Puisque par après je peux appeler la DL et l'afficher sans problème, le transfert a été effectué avec succès non? Il ne va pas le refaire à chaque frame, vu que c'est dans une DL, si?

  8. #8
    Membre Expert
    Avatar de shenron666
    Homme Profil pro
    avancé
    Inscrit en
    Avril 2005
    Messages
    2 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : avancé

    Informations forums :
    Inscription : Avril 2005
    Messages : 2 580
    Par défaut
    attention, dans la displaylist tu mémorises des instructions
    donc un glDrawArrays ou un glDrawElements dans une DL reste un glDrawArrays ou un glDrawElements, les vertices ne sont pas "envoyées" dans la DL
    je ne sait pas si je me fait bien comprendre
    Tutoriels OpenGL
    Je ne répondrai à aucune question en MP
    - Si c'est simple tu dis que c'est compliqué et tu le fait
    - Si c'est compliqué tu dis que c'est simple et tu le sous-traite ou le fait faire par un stagiaire.

  9. #9
    Membre chevronné
    Inscrit en
    Février 2008
    Messages
    413
    Détails du profil
    Informations personnelles :
    Âge : 45

    Informations forums :
    Inscription : Février 2008
    Messages : 413
    Par défaut
    Je comprends ce que tu veux dire...mais je ne suis pas sûr d'être d'accord:

    Pour moi une DL permet de compiler les valeurs passées et de les enregistrer. Par exemple si les données des vertex sont dans un tableau, OpenGL sauvegardera dans la DL les valeurs du tableau pour ne pas avoir, lors du rendu, à le parcourir pour les en extraire.

    Avec un vertex Array je ne sais pas exactement comment ca se passe, par contre. Mais je viens de faire un test en effacant ma liste de vertex juste après la création de la DL, et ca ne pose aucun problème pour afficher la DL par la suite. Les données sont donc bien compilées et sauvegardées. Par contre ca plante invariablement quand j'efface la liste d'indices, que ca soit juste après la création de la DL ou plus tard lors de la fermeture du programme....

  10. #10
    Membre Expert
    Avatar de shenron666
    Homme Profil pro
    avancé
    Inscrit en
    Avril 2005
    Messages
    2 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : avancé

    Informations forums :
    Inscription : Avril 2005
    Messages : 2 580
    Par défaut
    Citation Envoyé par ShevchenKik Voir le message
    Pour moi une DL permet de compiler les valeurs passées et de les enregistrer. Par exemple si les données des vertex sont dans un tableau, OpenGL sauvegardera dans la DL les valeurs du tableau pour ne pas avoir, lors du rendu, à le parcourir pour les en extraire.
    si tu parles d'un boucle for et des glVertex à répétition, ce n'est pas la même chose entre mémoriser un glDrawElements avec envoi d'un pointeur et N glVertex3f(x,y,z)
    tu transmet des commandes glVertex avec des coordonnées dans le second cas

    Citation Envoyé par ShevchenKik Voir le message
    Avec un vertex Array je ne sais pas exactement comment ca se passe, par contre. Mais je viens de faire un test en effacant ma liste de vertex juste après la création de la DL, et ca ne pose aucun problème pour afficher la DL par la suite. Les données sont donc bien compilées et sauvegardées.
    tu utilises combien de vertex array ?
    parceque pour changer de vertex array, tu dois appeler glVertexPointer
    et si tu as libéré ton pointeur...
    glVertexPointer transmet les vertices à la carte
    tant que tu n'en change pas ça marche
    mais libères ton tableau d'indices avant d'appeler glDrawElements via la DL
    je serai étonné que ça ne plante pas

    Citation Envoyé par ShevchenKik Voir le message
    Par contre ca plante invariablement quand j'efface la liste d'indices, que ca soit juste après la création de la DL ou plus tard lors de la fermeture du programme....
    faut peut-etre chercher ailleurs alors
    c'est forcément une utilisation d'une zone mémoire invalide

    edit : retrace bien ce que fait ton programme après que tu ais appelé le destructeur de ta classe, ça t'aidera peut-etre à trouver la source du problème
    Tutoriels OpenGL
    Je ne répondrai à aucune question en MP
    - Si c'est simple tu dis que c'est compliqué et tu le fait
    - Si c'est compliqué tu dis que c'est simple et tu le sous-traite ou le fait faire par un stagiaire.

  11. #11
    Membre chevronné
    Inscrit en
    Février 2008
    Messages
    413
    Détails du profil
    Informations personnelles :
    Âge : 45

    Informations forums :
    Inscription : Février 2008
    Messages : 413
    Par défaut
    Merci pour ton aide shenron666,

    comme tu le suggerais a la fin de ton post, ca n'a finalement rien à voir avec OpenGL, c'etait une bourde en c++...

    Le problème est que je ne reservais pas assez de place lors de la création de mon tableau (il me manquait 2 indices).
    Après, lors du remplissage je remplissais "2 cases trop loin", sans que ca ne me génère une erreur (?). Par contre à la destruction ca plantait.

    Voilà, problème rêglé! Désolé de vous avoir tenu la jambe pour un probleme qui ne venait pas d'OpenGL.

    tu utilises combien de vertex array ?
    parceque pour changer de vertex array, tu dois appeler glVertexPointer
    et si tu as libéré ton pointeur...glVertexPointer transmet les vertices à la carte
    tant que tu n'en change pas ça marche
    mais libères ton tableau d'indices avant d'appeler glDrawElements via la DL
    je serai étonné que ça ne plante pas
    Pour l'instant un seul. Bien sûr, si je l'efface avant la CREATION de la DL, ca plante quand glDrawElements est appelé.

    Par contre, effacer les tableaux juste après la création de la DL ne pose aucun probleme par la suite, lors de l'APPEL de la DL.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Vertex Array dans Display List ?
    Par GruZloR dans le forum OpenGL
    Réponses: 3
    Dernier message: 29/03/2006, 12h55
  2. Vertex Array & Listes d'Affichage ...
    Par yagero dans le forum OpenGL
    Réponses: 3
    Dernier message: 18/09/2005, 18h32
  3. Multitexturing Vertex Array et Display List
    Par Wyatt dans le forum OpenGL
    Réponses: 1
    Dernier message: 04/05/2005, 15h07
  4. vertex array
    Par Jbx 2.0b dans le forum OpenGL
    Réponses: 2
    Dernier message: 12/07/2004, 11h37
  5. Performance des vertex array
    Par Mathieu.J dans le forum OpenGL
    Réponses: 13
    Dernier message: 25/06/2004, 10h47

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo