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 :

Imagerie médicale - fuite de mémoire - affichage de plusieurs textures


Sujet :

OpenGL

  1. #1
    Membre habitué
    Inscrit en
    Mars 2008
    Messages
    13
    Détails du profil
    Informations forums :
    Inscription : Mars 2008
    Messages : 13
    Par défaut Imagerie médicale - fuite de mémoire - affichage de plusieurs textures
    Bonjour à tous, voilà j'ai un pti soucis je vous donne rapidement le contexte. Je suis étudiant et je dois réaliser un projet pour un hôpital concernant un logiciel d'imagerie médicale.

    Je ne suis pas responsable du choix des librairies et les deux librairies choisies ont donc été WxWidget couplé à de l'OPENGL.

    Je vous explique mes soucis plus concrètement maintenant. Pour afficher les images, je génère des cubes et je leur applique la texture que j'ai chargé au préalable. Mon problème.... mon code affiche et rafraîchis très bien jusqu'à 30 images... mais j'en ai plus de 80 à afficher... au delà... freeze de Linux... impossible à récupérer. Voilà mon code :

    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
    63
    64
     
    void GL_Window::drawPixels(Traitement *don)
    {
     
    	SetCurrent();				// On définit le Canvas comme le Canvas current
     
    	glMatrixMode(GL_MODELVIEW);
     
    	// Point de vue
    	gluLookAt(0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0,0.0);
     
    	// Initialisation, couleur de fond ...
    	glClearColor(0.0, 0.0, 0.0, 0.0);	// On efface la couleur actuelle
     
    	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);  //Efface le frame buffer et le Z-buffer 
     
    	glRotatef(180.0f, 180.0f, 0.0f, 0.0f);	// On effectue un flip horizontal du repère
     
    	glEnable(GL_DEPTH_TEST);		// On active les options de profondeurs
    	glDepthFunc(GL_LESS);			// pour les pixels
     
    	glPixelStorei(GL_UNPACK_ALIGNMENT, 1);	// On modifie le mode de stockage des pixels
     
    	// On build une texture2D
    	GLuint m_Textures_num = -1; 
    	glGenTextures(1,&m_Textures_num);
    	glBindTexture(GL_TEXTURE_2D,m_Textures_num);
     
    	//gluBuild2DMipmaps(GL_TEXTURE_2D, 3, 128, 128, GL_RGB, GL_UNSIGNED_BYTE, RGBA);
    	glTexImage2D(GL_TEXTURE_2D,0, GL_RGB, 128, 128, 0, GL_RGB, GL_UNSIGNED_BYTE, RGBA);
    	//delete image;
     	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
    	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
     	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    	glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
    // 	glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND);
    	glEnable(GL_TEXTURE_2D);		// Activation des Textures2D
    // 	glShadeModel(GL_SMOOTH);			// Mode d'application
     
     
    	// On dessine le carré et on lui plaque la texture
    	GLfloat minX=-1.0,maxX=1.0f;
    	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    	glEnable(GL_COLOR_MATERIAL);
     
    	glBegin(GL_QUADS);
    	glTexCoord2f(0.0f, 0.0f);
    	glVertex2f(minX, minX); //glVertex3f(-0.20, -0.1, 0.0);
    	glTexCoord2f(0.0f, 1.0f);
    	glVertex2f(minX, maxX); //glVertex3f(-0.2, 0.1, 0.0);
    	glTexCoord2f(1.0f, 1.0f);
    	glVertex2f(maxX, maxX); //glVertex3f(0.0, 0.2, 0.0);
    	glTexCoord2f(1.0f, 0.0f);
    	glVertex2f(maxX, minX); //glVertex3f(0.0, -0.1, 0.0);
     
     	glEnd();
     
     
     	SwapBuffers();				// On affiche le buffer
    	// Libération des textures
    	cout << "Libération de la texture " << numero <<endl;
    	glDeleteTextures(1,&m_Textures_num);
    }
    Donc en plus de ne pas afficher plus de 30 images, mon programme subit de graves fuites de mémoires. Qqun voit le trou ? Le pointeur RGBA ne peut être supprimé puisqu'il pointe sur la structure de l'image et qu'au refresh, j'ai encore besoin de ce pointeur.

    Je précise que je dessine dans un wxCanvas... mais est-ce la peine ?

    Merci pour vos réponses... là perso, je craque... je ne vois ni la fuite de mémoire ni pourquoi il n'affiche pas plus de 30 images !

  2. #2
    Membre éprouvé Avatar de Harooold
    Homme Profil pro
    Ingénieur 3D temps réel
    Inscrit en
    Mars 2008
    Messages
    136
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur 3D temps réel
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2008
    Messages : 136
    Par défaut
    Je ne vois qu'un truc de bizarre, enfin, pour moi bizarre est ce que je ne comprend pas :p

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    Je n'en vois pas vraiment l'utilité, essaie de le commenter :p

    Un autre petit truc qui pourrait bien être ta "fuite"

    quand tu fais glSwapBuffer, ça change de frame buffer actif.
    Pour que l'affichage soit fluide, normalement tu travailles avec 2 frame buffers, pendant qu opengl est en train de dessiner dans l'un, l'autre est affiché à l'écran. glSwapBuffer intervertis les deux.

    Sauf qu'il me semble que toutes les opérations opengl que tu fais sont prises en compte sur le buffer actif.
    Là tu crées une texture pour un frame buffer, tu switch et tu détruis la textures, mais comme tu as changé de frame buffer actif, la texture n'est pas détruite, et donc tu accumule petit à petit les textures.

    Ce n'est qu'un hypothèse mais essaie juste de mettre le glDeleteTexture avant le glSwapBuffer

  3. #3
    Membre habitué
    Inscrit en
    Mars 2008
    Messages
    13
    Détails du profil
    Informations forums :
    Inscription : Mars 2008
    Messages : 13
    Par défaut
    Tout d'abord merci Harooold pour ta réponse si rapide.

    Bon alors j'ai fait comme tu m'as dis, j'ai mis le glDeleteTextures avant de Swapper. Le petit test avec affiche de 20 images fonctionne mais le fait de recharger et décharger la vue m'indique qu'il y a toujours des fuites de mémoire puisque le programme ne perd que très peu de poids concernant la mémoire (vu à l'aide de la commande ps sous Linux)
    Le test à 40 image freeze toujours le PC ! Grrr !

    Je me suis aperçu que mon programme n'était pas clair si on avait pas l'architecture des objets. Voilà donc une petite architecture rapide :

    -> MyFrame : wxScrolledWindow
    -> Contient un vector<GL_Window* : wxGLCanvas>
    Dans le constructeur de MyFrame, on initialise chaque GL_Window du vecteur avec une adresse vers sa texture et ensuite on lui demande de faire un drawPixels (méthode précédemment jointe)

    J'suis toujours preneur de méthode plus adaptée pour faire ça ou de correction sur mon code. Si quelqu'un a encore des idées et comprend pourquoi ça bug je suis preneur à 100%.

    Merci merci merci merci merciii d'avance !

    Ps : Je me suis laissé pensé que ma carte graphique avait une limite de textures affichables ? Svp... dites moi que c'est pas possible !

  4. #4
    Membre éprouvé Avatar de Harooold
    Homme Profil pro
    Ingénieur 3D temps réel
    Inscrit en
    Mars 2008
    Messages
    136
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur 3D temps réel
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2008
    Messages : 136
    Par défaut
    Hm, je me suis jamais servi de wgwidgetruc, si le problème vient de là je ne pourrais pas t'aider

    Par contre qu'est ce que tu cherches à réaliser exactement ?
    Apriori tu aurais tout plein de fenêtres avec un contexte opengl avec dans chacune d'elle un quad sur lequel tu plaques une texture c'est ça ?

    Si c'est le cas il vaudrait mieux te débrouiller avec un seul contexte opengl, qui accederait à la carte graphique tout seul à la place d'en avoir 50 qui demandent des trucs à ta carte en même temps.

    Bref, explique en détails ce que tu cherches à réaliser

  5. #5
    Membre habitué
    Inscrit en
    Mars 2008
    Messages
    13
    Détails du profil
    Informations forums :
    Inscription : Mars 2008
    Messages : 13
    Par défaut
    Merci pour ton suivis Harooold.
    Voilà je te joint un lien vers une capture d'écran de mon projet. Ici

    Pourquoi donc est-ce que je me casse la tête à gérer ça dans des contextes opengl différents ? La question est posée...

    Réponse : Parce que chaque élément est indépendant. En faite je dois pouvoir faire tourner les objets, les redimmensionner, les faire bouger sans que ça n'influe sur les autres. Donc pas d'interférences... donc pas le même contexte openGL. Ca marche très bien pour une 20aine de contextes.. mais à 40 ça gèle vraiment tout le PC ! Un enfer je te dis...

    J'espère te relire très bientôt et que ton message commencera par : "Joe, j'ai une solution à ton problème..."

    Merci aussi à tous les volontaires pour me débugger..

  6. #6
    Membre très actif

    Profil pro
    Étudiant
    Inscrit en
    Décembre 2004
    Messages
    499
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2004
    Messages : 499
    Par défaut
    salut je vois pas bien le rapport entre pouvoir déplacer les 80 objets et avoir besoin de 80 contextes opengl

    tu peux très bien mettre les 80 dans le même contexte

  7. #7
    Membre habitué
    Inscrit en
    Mars 2008
    Messages
    13
    Détails du profil
    Informations forums :
    Inscription : Mars 2008
    Messages : 13
    Par défaut
    salut acx01b,

    Bah en faite comme tu le vois sur l'image, comme chaque contexte est indépendant aucune image ne peut rentrer dans l'autre même si on décide de déplacer les objets, tout est bien carré.
    Je trouvais la solution propre et puis en plus de tout, je trouvais ça pratique parce quand je double clic sur une image, je peux récupérer le numéro de texture.... ce qui va me servir pour superposer les textures "double cliquer" et colorer les textures. Je suis pas sorti de l'auberge moi ...

    L'inconvénient avec un contexte général est que même si au départ je place bien les objets, rien ne peut empêcher que ça devienne un bazar pas possible puisqu'il doit être possible de les déplacer pour zoomer sur certaines parties...

    Si tu as une idée avec un contexte général, je suis preneur bien évidement...

    Merci de ton intérêt au sujet...

  8. #8
    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,

    pas sûr de t'apporter "LA" solution, mais plusieurs trucs m'interpellent:

    - Tu initialises des états OpenGL, comme le blending) à chaque frame. Ca n'est pas nécéssaire, tu peux le faire une fois (par contexte / fenêtre OpenGL) lors de l#initialisation et ca suffit si tu n'as pas besoin de les changer.
    - De même pour les textures. Tu les recharges à chaque frame, alors qu'il te suffit de les charger une fois au départ, puis juste de de les "binder" à chaque frame.

    Pour résumer, crée une variable GLuint m_texID pour chacun de tes contextes (par exemple une variable de classe, si chaque contexte / fenetre est modélisé dans une classe), et met ce code dans une fonction Init que tu n'appelles qu'une fois pour chaque contexte, avant de commencer les boucles 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
     
     
    // Etats OpenGL
    //------------------
    glEnable(GL_DEPTH_TEST);		// On active les options de profondeurs
    glDepthFunc(GL_LESS);			// pour les pixels
     
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);	// On modifie le mode de stockage des pixels
     
    glEnable(GL_TEXTURE_2D);		// Activation des Textures2D
     
    // Textures
    //-----------
    // On build une texture2D
    glGenTextures(1,&m_texID);
    glBindTexture(GL_TEXTURE_2D,m_texID);
     
    glTexImage2D(GL_TEXTURE_2D,0, GL_RGB, 128, 128, 0, GL_RGB, GL_UNSIGNED_BYTE, RGBA);
     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
    ensuite, au début de ta fonction Draw, tu appelles simplement
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    glBindTexture(GL_TEXTURE_2D,m_texID);
    pour indiquer à OpenGL de charger la texture m_texID, qu'il a déjà configurée une fois (et UNE seulement, d'où l'avantage).

    Je ne suis pas sûr du lien avec les fuites de mémoire, mais d'un point de vue performances c'est beaucoup plus efficace.

    - Autre remarque: tu as écris
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    glRotatef(180.0f, 180.0f, 0.0f, 0.0f);
    si tu veux faire une rotation de 180° autour de X, il faudrait plutôt
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    glRotatef(180.0f, 1.0f, 0.0f, 0.0f);
    Je ne suis pas sûr de ce que fait OpenGL avec ton 2eme argument à 180.0f, il est probable qu'il le limite à 1.0 mais c'est sans garantie

    - Enfin tu utilises
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    glEnable(GL_COLOR_MATERIAL)
    mais tu ne définis aucune couleur pour tes vertex, avec glColor3f par exemple. Là encore, pas sûr de comment OpenGL se débrouille avec ca....

    Voilà, en espérant que ca t'aidera....

  9. #9
    Rédacteur
    Avatar de bafman
    Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    2 574
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Novembre 2003
    Messages : 2 574
    Par défaut
    dans l'ordre des truc a faire (et qui ont déjà été dit, je ne fait qu'appuyer les propos précédents) :

    - ne PAS recharger la texture à chaque frame... une fois après l'initialisation du contexte suffit largement
    - utiliser un seul contexte openGL. si tu veut ne pas avoir de débordement, utilise des viewport différent, mais toujours le même contexte. Utiliser des contextes différent, c'est à faire quand on a plusieurs fenêtres séparé, ce qui n'est pas ton cas ici.
    En plus, c'est ce qu'il y a de pire au niveau perf pour le driver...
    * Il est infiniment plus simple de faire rapidement un code qui marche que de faire un code rapide qui marche
    * pour faciliter les recherches, n'oubliez pas de voter pour les réponses pertinentes
    Mes articles

  10. #10
    Membre très actif

    Profil pro
    Étudiant
    Inscrit en
    Décembre 2004
    Messages
    499
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2004
    Messages : 499
    Par défaut
    salut

    je n'avais pas pensé au viewport

    en effet utilises un viewport différent pour chaque image (glViewport)

    pour avoir le numéros de la texture (de la zone) tu numérotes tes zones de 0 à 79

    tu les mets par exemple sur 8 lignes, 10 colonnes

    et le numéro de la zone cliquée sera (y * 8 / h) * 10 + (x * 10 / w)
    où x,y sont les coordonnées du pixel cliqué
    w,h les dimensions de l'écran

  11. #11
    Membre Expert
    Avatar de Ti-R
    Homme Profil pro
    Ingénieur R&D
    Inscrit en
    Avril 2003
    Messages
    1 683
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2003
    Messages : 1 683
    Par défaut
    Un autre truc "bizarre", l'image RGBA est chargée comme RGB

    Code Bazzooka : Sélectionner tout - Visualiser dans une fenêtre à part
    glTexImage2D(GL_TEXTURE_2D,0, GL_RGB, 128, 128, 0, GL_RGB, GL_UNSIGNED_BYTE, RGBA);

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    glTexImage2D(GL_TEXTURE_2D, 0, 4, 128, 128, 0, GL_RGBA, GL_UNSIGNED_BYTE, RGBA);
    Sinon les fuites mémoires doivent venir d'ailleurs....

  12. #12
    Membre éprouvé Avatar de Harooold
    Homme Profil pro
    Ingénieur 3D temps réel
    Inscrit en
    Mars 2008
    Messages
    136
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur 3D temps réel
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2008
    Messages : 136
    Par défaut
    Bref, en gros, la solution la plus adaptée et propre serait bien d'avoir un seul contexte opengl et utiliser glViewport pour isoler chaque image.

    En gros ça donnera :

    - 1 fonction d'initialisation d'opengl
    - 1 classe "Element" ( ou le nom que tu veux ) du style

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    class Element
    {
        public :
           Element();
           void render();
     
        private :
           GLuint texId;
           GLuint x, y, width, height;
    }
    Où chaque instance d'élement représente une partie de la fenêtre opengl dans laquelle tu vas afficher ton quad et ta texture identifiée par le texId de cette instance.
    (x,y,width,height) sont les paramètres du viewport.

    Tu crées donc à l'initialisation autant d'instance Element que tu veux, pour chaque Element tu crées la texture associée avec glTexImage2D et tu generes les coordonées du viewport associé.

    - Ton appli aura donc un vecteur (<vector>) d'Element ( qu'on va appeller elements ), ta fonction d'affichage donnera ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    void display()
    {
        glClear( ... )
        glLoadIdentity()
     
        int elements_count = elements.size()
        for( int i = 0 ; i < elements_count ; i++ )
            elements[i]->render();
     
       SwapBuffers
    }
    et la fonction render d'un element :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    void Element::render()
    {
        glViewport(x, y, width, height)
     
        glBindTexture(GL_TEXTURE_2D, texId)
     
        // dessin du quad texturé
     
    }
    Après, quand tu voudras faire bouger un element, tu regardes simplement les coordonées de la souris sur la fenêtre pour en déduire dans quel viewport elle est et donc quel est l element selectionné.
    Et tu appliqueras les transformations sur l Element selectionné en ajoutant des trucs dans la classe et les modifiant en fonction des entrées utilisateur.

    Puis tu pourras mettre facilement une texture en plein écran en jouant avec les viewport également :p

    Bref, je vois la structure comme ça, ce n'est pas spécialement compliqué et je ne vois pas trop pourquoi il y aurait de problèmes de mémoire dans ce cas là, si ce n'est ta carte graphique qui n'a pas assez de RAM video pour stocker tout les objets textures crées... m'enfin, si ce n'est pas une antiquité, il doit y avoir de la marge

  13. #13
    Membre habitué
    Inscrit en
    Mars 2008
    Messages
    13
    Détails du profil
    Informations forums :
    Inscription : Mars 2008
    Messages : 13
    Par défaut
    Wow wow wow... Merci à tous pour vos réponses. Je m'aperçois bien que mon appli est pas ce qu'il y a de plus performant et est truffée d'erreurs de débutant... que je suis en OpenGL.

    Juste une petite précision sur un glRotatef que ShevchenKik avait relevé. En faite quand j'affiche mes textures, elles sont à l'envers, et j'ai découvert que
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    glRotatef(180.0f, 180.0f, 0.0f, 0.0f);
    que j'utilise permettait de faire un flip horizontal... par hasard bien évidement. C'était juste la transformation dont j'avais besoin (parce qu'imaginez que le doc se trompe entre le haut et le bas... ça le fait pas de s'en aperçevoir au moment du charcutage !).

    Encore une petite autre pour Ti-R : En faite c'est juste mon nom de variable qui est mal foutu. J'aurai du utiliser RGB au lieu de RGBA mais à l'époque, j'espérai tellement récupérer le canal Alpha..... bref je rêve bien sûr, pour superposer mes 2 textures je vait devoir utiliser le multitexturage... Je sens que j'ai pas fini de rire.

    Harooold, acx01b, bafman et les autres, merci beaucoup pour vos conseils. Je me met dès ce soir à cette mutation de code avec :
    - les glViewport
    - l'initialisation de toutes les textures en une fois et un bind pour chacune d'elle
    et je vous tiens au courant de mes avancées.

    Aller tant que j'y suis, j'ose... Je sais que pour récupérer les coordonnées de ma souris j'utilisais des évènements liés aux fenêtres de wxWidget. Est-ce que cela sera encore valable dans mon glViewport ? Et est-ce qu'en cliquant dans un glViewport, je pourrai récupérer l'objet associé à ce glViewport et décidé de ne redessiner que lui ?

    Merci encore à tous et bonne fin d'après-midi...

  14. #14
    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
    Comme disait Haroold dans son dernier post, il va te falloir, dans la fonction de gestion de la souris de wxWidget, effectuer un peu de calcul pour savoir dans quel "viewport" se trouve ton curseur.

    Une fois que tu l'as détecté tu ne mets à jour que ce dernier. Ca peut cependant poser problème si, en manipulant un viewport, tu fais sortir de ton curseur de ce viewport (par exemple si tu utilises click gauche + mouvement souris pour faire tourner ton modele 3D). Il faudra donc que tu fasses gaffe à ca:
    - Soit les interactions avec un viewport sont limitées aux mouvements de souris "au dessus" de ce dernier, ce qui est un peu limité
    - soit tu dis par exemple:
    1)click gauche = selectionne le viewport actif
    2) maintenir enfoncé + bouger = fait tourner ton modele (c'est un exemple, bien sûr tu définis toi mêmes ce que tu veux faire), même si tu "sors" du viewport
    3) relâcher le boutton déselectionne le viewport "actif"

  15. #15
    Membre habitué
    Inscrit en
    Mars 2008
    Messages
    13
    Détails du profil
    Informations forums :
    Inscription : Mars 2008
    Messages : 13
    Par défaut
    Merci ShevchenKik, je vois exactement quels seront mes soucis et comment les résoudre grâce à ton explication. Tant que j'y suis je profite... Vu que l'application n'a pas une taille fixe mais est reSizable comment déterminé à quel glViewport appartient un point (coordonnées de la souris au premier clic). Vu que la taille de la fenêtre est modifiable, le nombre de glViewport par ligne l'est aussi... donc rien de fixe.
    Est-ce qu'une technique du style :
    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
     
    for(int j = 0; j < nombreViewPortParColonne; j++)
    {
        if(event.GetY() >= j*SizeOfGlViewPort )
        {
            for(int i = 0;i < nombreViewPortParLigne;i++)
            {
                if(event.GetX() >= i*SizeOfGlViewPort )
                {
                // Alors j'ai le bon numéro de glViewPort, il est en (i, j)
                // Redessine ce glViewPort
                }
             }
        }
    }
    C'est en pseudo-code... mais est-ce que la logique y est ? En supposant que event.GetX() récupère la coordonnée X du clic et que le glViewPort est carré.

    Merci de votre suivis...

  16. #16
    Membre habitué
    Inscrit en
    Mars 2008
    Messages
    13
    Détails du profil
    Informations forums :
    Inscription : Mars 2008
    Messages : 13
    Par défaut
    Bonjour à tous, c'est encore moi...

    Bon alors mon projet a plutôt pas mal avancer, mais je me retrouve aujourd'hui avec un nouveau soucis concernant mes textures. Tout d'abord je voulais vous annoncer que l'utilisation des glViewport avait parfaitement fonctionner. Je vous remercie donc pour votre aide...

    Aujourd'hui j'essaie de modéliser les coupes en tranches de mes images médicales. Je récupère donc les bons pixels puisque j'arrive à les dessiner grâce à la fonction glDrawPixels mais impossible de binder ces textures sur mes petits cubes...

    Voilà un bout de monde code spécialement changé pour les tests. Il n'est pas optimal mais ne fonctionne déjà pas tel quel...

    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
    63
    64
    65
    66
    67
    68
     
    	// On remplit le tableau de valeur pour la vue de cote
    	cout << "Vue de cote" << endl;
    	int cmpH=this->GetSize().GetHeight()-cote-marge;
    	glEnable(GL_SCISSOR_TEST);
    	glScissor(0, cmpH, hauteur,nbImage);
    	glViewport(0, cmpH, hauteur,nbImage);
     
    	for(int z = 0 ; z < nbImage ; z++) {
    		for(int y = 0 ; y < hauteur ; y++) {
    			vueCote[y + z * hauteur] = don->imageSequin[0]->valeurs[(z * largeur * hauteur) + y * largeur + currentX]; 
    		}
    	}
     
             // ICI CA MARCHE
    	glDrawPixels(hauteur,nbImage , GL_RGB, GL_UNSIGNED_BYTE, don->imageSequin[0]->keepRGB(vueCote,nbImage ,hauteur));
    	SwapBuffers();
    	sleep(1);
     
    	// On recolorie tout en noir
    	glScissor(0,0,s.GetWidth()+marge, s.GetHeight()+marge);
    	glViewport(0,0,s.GetWidth()+marge, s.GetHeight()+marge);
    	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);  //Efface le frame buffer et le Z-buffer
    	SwapBuffers();
     
            // On réduit la zone de dessin
    	glScissor(0, cmpH, hauteur,nbImage);
    	glViewport(0, cmpH, hauteur,nbImage);
     
     
    	// On build une texture2D
    	GLuint m_Textures_numi = -1; 
    	glGenTextures(1,&m_Textures_numi);
    	glBindTexture(GL_TEXTURE_2D,m_Textures_numi);
     
    	glTexImage2D(GL_TEXTURE_2D,0, GL_RGB, hauteur,nbImage, 0, GL_RGB, GL_UNSIGNED_BYTE, don->imageSequin[0]->keepRGB(vueCote, nbImage,hauteur));
    // 	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
    // 	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
    // 	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    // 	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    // 	glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
    	glEnable(GL_TEXTURE_2D);		// Activation des Textures2D
    	glShadeModel(GL_SMOOTH);		// Mode d'application	
     
     
    		// On dessine le carré et on lui plaque la texture
    		GLfloat minX=-1.0,maxX=1.0f;
    		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    		glEnable(GL_COLOR_MATERIAL);
     
    		glBegin(GL_QUADS);
    		glTexCoord2f(0.0f, 0.0f);
    		glVertex2f(minX, minX); //glVertex3f(-0.20, -0.1, 0.0);
    		glTexCoord2f(0.0f, 1.0f);
    		glVertex2f(minX, maxX); //glVertex3f(-0.2, 0.1, 0.0);
    		glTexCoord2f(1.0f, 1.0f);
    		glVertex2f(maxX, maxX); //glVertex3f(0.0, 0.2, 0.0);
    		glTexCoord2f(1.0f, 0.0f);
    		glVertex2f(maxX, minX); //glVertex3f(0.0, -0.1, 0.0);
    		//delete(RGBA);
    		glEnd();
     
    // 		cmpL+=(cote+marge);
                    // ICI RIEN A FAIRE J'OBTIENS UN CARRE BLANC DE LA BONNE TAILLE MAIS BLANC !
    		cout << "PRE-TEMPO" <<endl;
    		SwapBuffers();
    		sleep(2);
    		cout << "TEMPO" <<endl;
    Quelqu'un aurait une idée ?
    Merci d'avance pour vos réponses...

  17. #17
    Membre habitué
    Inscrit en
    Mars 2008
    Messages
    13
    Détails du profil
    Informations forums :
    Inscription : Mars 2008
    Messages : 13
    Par défaut
    Je viens de décommenter mes paramètres pour les textures et les images carrés s'affichent correctement. Les autres ne fonctionnent pas...
    Est-ce que mes paramètres de textures ne sont pas bons si je mappe ça sur des surfaces carrée ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
    	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
    	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    	glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
     
    	glEnable(GL_TEXTURE_2D);		// Activation des Textures2D
    	glShadeModel(GL_SMOOTH);		// Mode d'application

Discussions similaires

  1. affichage sans fuite de mémoire
    Par kris1 dans le forum GTK+ avec C & C++
    Réponses: 1
    Dernier message: 27/11/2007, 18h21
  2. Réponses: 2
    Dernier message: 09/10/2004, 11h35
  3. [DirectDraw7] Affichage de plusieurs image bmp
    Par SteelBox dans le forum DirectX
    Réponses: 3
    Dernier message: 24/04/2004, 19h00
  4. Problème de mémoire Affichage images
    Par Repti dans le forum C++Builder
    Réponses: 6
    Dernier message: 29/03/2004, 20h06
  5. Réponses: 8
    Dernier message: 17/10/2002, 12h52

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