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 :

Picking openGL api32


Sujet :

OpenGL

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    18
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 18
    Par défaut Picking openGL api32
    Bonjour,

    J'essaie de faire une sorte de paint 3D, avec 4 viewports, pour mon projet de première année, mais je n'arrive pas à faire fonctionner le picking, après bien des recherches !
    J'utilise l'API WIN 32.
    http://www.casimages.com/img.php?i=0...0223443836.jpg
    Voici le 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
     
    void picking( t_objet* ptrDeb, POINT curseurSouris, int largeur, t_viewport viewportActif, t_objet* ptrdeb )
    {
        int nbObjets, hits,;
        double precision[2] = { 3, 3 };
        GLuint buffer[ 500 ];
        GLuint* ptr = buffer;
     
        /* Renversement de l'axe des ordonnées */
        curseurSouris.y = hauteur - curseurSouris.y;
     
        glSelectBuffer( 500, buffer );
     
        glRenderMode( GL_SELECT );
        glInitNames();
        glPushName(0);
     
        glMatrixMode( GL_PROJECTION );
        glPushMatrix();
        glLoadIdentity();
     
        gluPickMatrix( (GLdouble)curseurSouris.x, (GLdouble)curseurSouris.y,
                        precision[0], precision[1], viewportActif.viewport );
     
        glMultMatrixd( viewportActif.projection );
     
        glMatrixMode( GL_MODELVIEW );
     
        dessinerSceneSelect( ptrDeb, buffer );
     
        hits = glRenderMode( GL_RENDER );
     
    }
    Je garde les matrices de projection grâce à la fonction ci-dessous :

    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
    void dessin( t_viewport* viewport, t_objet* ptrDeb, int largeur, int hauteur )
    {
        float coef;
    
        glViewport( viewport->viewport[0], viewport->viewport[1], viewport->viewport[2], viewport->viewport[3] );
    
        glMatrixMode( GL_PROJECTION );
        glLoadIdentity();
    
        if( viewport->vueAssociee == VIEWPORT_INACTIF )
            return;
    
        if( viewport->vueAssociee != VUEDEPERSPECTIVE )
        {
            if( largeur > hauteur )
            {
                coef = (float)largeur/hauteur;
                glOrtho( viewport->fenetrage[0]*coef, viewport->fenetrage[1]*coef, viewport->fenetrage[2],
                         viewport->fenetrage[3], 0.1, 1000 );
            }
            else
            {
                coef = hauteur/(float)largeur;
                glOrtho( viewport->fenetrage[0], viewport->fenetrage[1], viewport->fenetrage[2]*coef,
                         viewport->fenetrage[3]*coef, 0.1, 1000 );
            }
        }
        else gluPerspective( 45, (float)largeur / hauteur, 0.1, 1000 );
        /* Sauvegarde des informations sur les vues */
        glGetDoublev( GL_PROJECTION_MATRIX, viewport->projection );
        glMatrixMode( GL_MODELVIEW );
        glLoadIdentity();
    
        if( viewport->vueAssociee == VUEDEFACE )
            gluLookAt( 0.0, 0.0, viewport->camera.z,
                       viewport->camera.cibleX, viewport->camera.cibleY, viewport->camera.cibleZ,
                       viewport->camera.angleX, viewport->camera.angleY, viewport->camera.angleZ );
        else if( viewport->vueAssociee == VUEDEDERRIERE )
            gluLookAt( 0.0, 0.0, -viewport->camera.z,
                       viewport->camera.cibleX, viewport->camera.cibleY, viewport->camera.cibleZ,
                       viewport->camera.angleX, viewport->camera.angleY, viewport->camera.angleZ );
        else if( viewport->vueAssociee == VUEDEDESSUS )
            gluLookAt( 0.0000001, viewport->camera.y, 0.0,//Beug sinon...
                       viewport->camera.cibleX, viewport->camera.cibleY, viewport->camera.cibleZ,
                       viewport->camera.angleX, viewport->camera.angleY, viewport->camera.angleZ );
        else if( viewport->vueAssociee == VUEDEPERSPECTIVE )
            gluLookAt( viewport->camera.x, viewport->camera.y, viewport->camera.z,
                       viewport->camera.cibleX, viewport->camera.cibleY, viewport->camera.cibleZ,
                       viewport->camera.angleX, viewport->camera.angleY, viewport->camera.angleZ );
    
        /* Sauvegarde des informations sur les vues */
        glGetDoublev( GL_MODELVIEW_MATRIX, viewport->modelview );
    
        axes();
        quadrillage();
        dessinerScene( ptrDeb );
    }
    Donc la matrice et le viewport sont toujours à jour.

    Ensuite je dessine tout les objets contenus dans ma liste chainée. Exemple avec un triangle :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
     
    void triangleSelect( t_objet* triangle, GLuint* buffer )
    {
        glColor3f( triangle->couleur[0], triangle->couleur[1], triangle->couleur[2] );
        glLoadName( triangle->id );
        glBegin( GL_TRIANGLES );
            glVertex3d( triangle->x[0], triangle->y[0], triangle->z[0] );
            glVertex3d( triangle->x[1], triangle->y[1], triangle->z[1] );
            glVertex3d( triangle->x[2], triangle->y[2], triangle->z[2] );
        glEnd();
    }
    Mais malheureusement, soit ça me génére hit = -1 quand je clique sur un objet, ce qui n'est déjà pas si mal , mais mais rien n'est exploitable dans le tableau buffer. Après quelques objets dessinés, hit devient bien égal à 1 quand je clique que un objet mais le tableau n'est toujours pas exploitable.
    Je ne sais plus quoi faire...

    Je fournis le code pour ceux que ça interesse. Merci d'avance ^^

  2. #2
    Membre Expert
    Avatar de Lung
    Profil pro
    Analyste-programmeur
    Inscrit en
    Mai 2002
    Messages
    2 704
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Analyste-programmeur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 2 704
    Par défaut
    Je me permet de profiter de ton post.
    Je suis en train d'essayer de faire à peu près la même chose avec ces mêmes fonctions OpenGL.

    Quand je clique, j'obtiens bien le bon nombre d'objets cliqués, j'ai bien la liste des objets dans le tableau, mais j'ai un problème avec la profondeur de ces objets qui est fantaisiste. Ce qui fait que je ne peux pas trouver l'objet qui est au premier plan.
    Voici 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
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    function TFormGL.ClicSouris(const nX, nY: Integer): Boolean;
    const
       TAILLE_SELECT_BUFFER = 32;
    var
       TabBufferSelection: Array[0..TAILLE_SELECT_BUFFER] of GLuint;
       TabViewport: Array[0..3] of GLuint;
       nNbObjets, nProfondeurMin, nObjetSelectionne : GLuint;
       i: Integer;
    begin
       Result := False;
       glGetIntegerv(GL_VIEWPORT, @TabViewport);
       glSelectBuffer(TAILLE_SELECT_BUFFER, @TabBufferSelection);  
     
       glMatrixMode(GL_PROJECTION);
       glPushMatrix;
          glLoadIdentity;     
     
           glRenderMode(GL_SELECT);
     
          glInitNames;
          glPushName(0);
    //      glLoadIdentity;      
     
          gluPickMatrix(nX, Integer(TabViewport[3]) - nY, 1, 1, @TabViewport);
     
          gluPerspective(45, TabViewport[2] / TabViewport[3], 0, 100);
     
          //.Ré-affichage de la scène (avec activation de la matrice de modélisation-visualisation).
          FormPaint(nil);
     
          nNbObjets := glRenderMode(GL_RENDER);
     
          glMatrixMode(GL_PROJECTION);  
       glPopMatrix;
       glMatrixMode(GL_MODELVIEW);
     
       //.Si clic sur au moins un objet.
       if nNbObjets > 0 then
       begin
          Result := True;    
     
          //.Premier objet.
          nProfondeurMin := TabBufferSelection[1];
          nObjetSelectionne := TabBufferSelection[3];
     
          //.Parcours des objets (à partir du deuxième).
          for i:=1 to Pred(nNbObjets) do
          begin
             //.Si profondeur inférieure.
             if(TabBufferSelection[(i * 4) + 1] < nProfondeurMin) then
    			begin
    				//.Sauvegarde de l'objet.
    				nProfondeurMin := TabBufferSelection[(i * 4) + 1];
    				nObjetSelectionne := TabBufferSelection[(i * 4) + 3];
    			end;
          end;
     
          //.Selon objet.
          case nObjetSelectionne of
             //.Clef.
             (Integer(eClef) * 100):
                begin
                   ShowMessage('clef');
                end;
     
             //.MédiPack.
             (Integer(eMediPack) * 100):
                begin
                   ShowMessage('MédiPack');
                end;
     
             //.Vision nocturne.
             (Integer(eVisionNocturne) * 100):
                begin
                   ShowMessage('Vision nocturne');
                end;
          else
             Result := False;
          end;
       end;
    end;
    L'urgent est fait, l'impossible est en cours, pour les miracles prévoir un délai. :bug: ___ "http://club.developpez.com/regles/#LIII-A"Écrivez dans un français correct !!

    C++Builder 5 - Delphi 6#2 Entreprise - Delphi 2007 Entreprise - Delphi 2010 Architecte - Delphi XE Entreprise - Delphi XE7 Entreprise - Delphi 10 Entreprise - Delphi 10.4.2 Entreprise - Delphi 11.3 Entreprise - Visual studio 2022
    OpenGL 2.1 - Oracle 10g - Paradox - Interbase (XE) - PostgreSQL (15.7)

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    18
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 18
    Par défaut
    Est-ce que tu utilises plusieurs viewports comme moi ?

  4. #4
    Membre Expert
    Avatar de Lung
    Profil pro
    Analyste-programmeur
    Inscrit en
    Mai 2002
    Messages
    2 704
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Analyste-programmeur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 2 704
    Par défaut
    Citation Envoyé par g0ku_0ne Voir le message
    Est-ce que tu utilises plusieurs viewports comme moi ?
    Non, un seul.
    Mais, tu penses que ça a de l'importance.
    L'urgent est fait, l'impossible est en cours, pour les miracles prévoir un délai. :bug: ___ "http://club.developpez.com/regles/#LIII-A"Écrivez dans un français correct !!

    C++Builder 5 - Delphi 6#2 Entreprise - Delphi 2007 Entreprise - Delphi 2010 Architecte - Delphi XE Entreprise - Delphi XE7 Entreprise - Delphi 10 Entreprise - Delphi 10.4.2 Entreprise - Delphi 11.3 Entreprise - Visual studio 2022
    OpenGL 2.1 - Oracle 10g - Paradox - Interbase (XE) - PostgreSQL (15.7)

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    18
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 18
    Par défaut
    Je pense oui, car a chaque fois, quand on récupère les dimensions du viewport je vois :
    gluPickMatrix(nX, Integer(TabViewport[3]) - nY, 1, 1, @TabViewport);
    Et moi ça ne marche pas si je fait ça

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    19
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 19
    Par défaut
    Je pense oui, car a chaque fois, quand on récupère les dimensions du viewport je vois :
    gluPickMatrix(nX, Integer(TabViewport[3]) - nY, 1, 1, @TabViewport);
    Et moi ça ne marche pas si je fait ça
    Dans ton code, tu utilises le y directement :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
       gluPickMatrix( (GLdouble)curseurSouris.x, (GLdouble)curseurSouris.y,
                        precision[0], precision[1], viewportActif.viewport );
    Maintenant, est ce que le callback de la souris te renvoi les coordonnees par rapport au viewport ou par rapport a la fenetre ? Dans le 2e cas, essaye qqch de ce type la :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    gluPickMatrix( (GLdouble)curseurSouris.x-viewportActif.viewport[0], viewportActif.viewport[3]-curseurSouris.y-viewportActif.viewport[1],
                        precision[0], precision[1], viewportActif.viewport );
    Je suis pas calé en openGL, donc je n'ai aucune certitude dans tout ce que je viens dire. J'espere que ca te mettra sur une piste.

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

Discussions similaires

  1. Qt picking openGL
    Par CliffeCSTL dans le forum OpenGL
    Réponses: 2
    Dernier message: 25/04/2012, 09h23
  2. Picking OpenGL C++
    Par lulafitt dans le forum OpenGL
    Réponses: 1
    Dernier message: 22/02/2011, 17h21
  3. Question à propos du picking OpenGL
    Par choko83 dans le forum OpenGL
    Réponses: 2
    Dernier message: 06/04/2009, 09h54
  4. Probleme de Picking OPENGL
    Par Tiéry dans le forum OpenGL
    Réponses: 2
    Dernier message: 19/11/2007, 13h41
  5. Probème Picking OpenGL
    Par johnalias110 dans le forum OpenGL
    Réponses: 3
    Dernier message: 02/05/2007, 10h02

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