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 :

Problème de "Picking"


Sujet :

OpenGL

Vue hybride

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

    Informations forums :
    Inscription : Septembre 2006
    Messages : 31
    Par défaut Problème de "Picking"
    Salut à tous,

    Je me suis bien avancé dans mon programme mais j'arrive à un bug que je n'arrive pas à regler. J'y est travailler pendant toute la journée et j'ai rien trouver. Alors je me suis dit que je viendrais consulter les superbe membres du forum devellopez .

    Alors le problème est que j'essaye de faire une detection de sélection avec la souris. Mais on dirait que c'est le if qui ne fonctionne pas, je trouve sa très étrange. Alors voila mon code :

    Main.cpp
    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
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
     
    #include <GL/glut.h>
    #include <iostream>
    #include <stdlib.h>
    #include "render.h"
     
    RenderRR *g_Render = NULL;
     
    const int LARGEUR_FENETRE = 800;
    const int HAUTEUR_FENETRE = 600;
    int g_mx=0, g_my=0;
    int g_w, g_h;
     
    #define BUFFERSIZE 1024
    #define CARREROUGE 1
    #define TRIANGLEBLEU 2
     
     
    GLuint selectBuf[BUFFERSIZE];
    GLint hits;
    int cursorX, cursorY;
    int renderScene;
     
    //fonctions ci-dessous servent pour afficher le texte
    void reshape(GLint w, GLint h) 
    {
      g_w = w;
      g_h = h;
     
      glViewport(0, 0, g_w, g_h);
      glMatrixMode(GL_PROJECTION);
      glLoadIdentity();
      gluPerspective(65.0, (float)g_w / g_h, 1, 1000);
      glMatrixMode(GL_MODELVIEW);
    }
     
    void mousestate(int button, int state, int mousex, int mousey)
    {
     
    	if (button == GLUT_LEFT_BUTTON)
    	{
    		if (state == GLUT_DOWN)
    		{
    			cursorX = mousex;
    			cursorY = mousey;
    			void startPicking();
    		}
    	}
    }
     
    void startPicking(int cursorX, int cursorY)
    {
    GLint viewport[4];
    	float ratio;
     
    	glSelectBuffer(BUFFERSIZE,selectBuf);
     
    	glGetIntegerv(GL_VIEWPORT,viewport);
     
    	glRenderMode(GL_SELECT);
     
    	glInitNames();
     
    	glMatrixMode(GL_PROJECTION);
    	glPushMatrix();
    	glLoadIdentity();
     
    	gluPickMatrix(cursorX,viewport[3]-cursorY,5,5,viewport);
    	ratio = (viewport[2]+0.0) / viewport[3];
    	gluPerspective(45,ratio,0.1,1000);
    	glMatrixMode(GL_MODELVIEW);
    }
     
    void processHits2 (GLint hits, GLuint buffer[], int sw)
    {
    	if(hits = 1)
    	{
    		renderScene=TRIANGLEBLEU;
    	}
    	else if(hits=2)
    	{
    		renderScene=CARREROUGE;
    	}   
    }
     
    void stopPicking() {
     
    	glMatrixMode(GL_PROJECTION);
    	glPopMatrix();
    	glMatrixMode(GL_MODELVIEW);
    	glFlush();
    	hits = glRenderMode(GL_RENDER);
    	if (hits != 0){
    		processHits2(hits,selectBuf,0);
    	}
    }
     
     
    void mousemotion(int x, int y)
    {
        g_mx = x;
        g_my = y;
        glutPostRedisplay();
    }
     
    //fonctions ci-dessous servent pour afficher le texte
    void Graphique_SetOrthographicProjection() 
    {
        //Sauvegarde de la matrice MODELVIEW
        glMatrixMode(GL_MODELVIEW);
        glPushMatrix();
     
        // Passer dans le mode projection
        glMatrixMode(GL_PROJECTION);
        //Sauvegarde de la matrice PROJECTION    
        glPushMatrix();
        glLoadIdentity();
     
        // Mettre en place une perspective orthogonale
        gluOrtho2D(0,g_w, g_h, 0);
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
    }
     
    void Graphique_ResetPerspectiveProjection() 
    {
        glMatrixMode(GL_PROJECTION);
        //On remet la matrice de PROJECTION
        glPopMatrix();
     
        glMatrixMode(GL_MODELVIEW);
        //On remet la matrice de MODELVIEW 
        glPopMatrix();
    }
     
    void dessine_souris()
    {
    	Graphique_SetOrthographicProjection();
    	glTranslatef(g_mx, g_my, 0.0f);
    	g_Render->Cursor();
    	Graphique_ResetPerspectiveProjection();
    }
     
     
     
    void display()
    {
     
    	// Enleve la couleur
        glClear(GL_COLOR_BUFFER_BIT);
        glLoadIdentity();
     
    	Graphique_SetOrthographicProjection();
    	g_Render->Menu(renderScene,LARGEUR_FENETRE,HAUTEUR_FENETRE);
    	Graphique_ResetPerspectiveProjection();
     
    	//Rendu de la souris
        dessine_souris();
     
    	glutSwapBuffers();
     
    }
     
    int main(int argc, char **argv)
    {
        glutInit(&argc,argv);
        glutInitWindowSize (LARGEUR_FENETRE,HAUTEUR_FENETRE);
        glutInitDisplayMode ( GLUT_RGB | GLUT_DOUBLE);
        glutCreateWindow ("Jeux");
     
    	glutSetCursor(GLUT_CURSOR_NONE);
        glutDisplayFunc(display);
    	glutMouseFunc(mousestate);
        glutMotionFunc(mousemotion);
        glutPassiveMotionFunc(mousemotion);
        glutReshapeFunc(reshape);
     
        glutMainLoop();
     
    	return(0);
    }
    Render.cpp
    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
     
    #include <gl/glut.h>
    #include <gl/glu.h>
    #include <math.h>
    #include "Render.h"
     
    #define CARRE 1
    #define TRIANGLE 2
     
    RenderRR::RenderRR()
    {
    }
     
    RenderRR::~RenderRR()
    {
    }
     
    void RenderRR::Cursor()
    {
       // Couleur Verte
        glColor3f(0.0f, 0.5f, 0.0f);
     
        // Dessine les deux triangle formant la souris
        glBegin(GL_TRIANGLES);
            glVertex3d(0.0f, -0.0f, 0.0f);
            glVertex3d(0.0f, -8.0f, 0.0f);
            glVertex3d(-12.0f, -20.0f, 0.0f);
    	glEnd();
     
    	glBegin(GL_TRIANGLES);
            glVertex3d(8.0f, -8.0f, 0.0f);
            glVertex3d(0.0f, -8.0f, 0.0f);
            glVertex3d(-12.0f, -20.0f, 0.0f);
        glEnd();
     
    }
     
    void RenderRR::Menu(int render, int largeurf, int hauteurf)
    {
     
    	if(render = 0)
    	{
    	glPushName(CARRE);
    	glTranslatef(largeurf/2-50, hauteurf/2-50, 0.0f);
     
    	// Couleur Rouge
    	glColor3f(1.0f, 0.0f, 0.0f);
    	//Dessine un carré
     
    	glBegin(GL_QUADS);
    		glVertex3d(0.0f, 0.0f, 0.0f);
    		glVertex3d(100.0f, 0.0f, 0.0f);
    		glVertex3d(100.0f, 100.0f, 0.0f);
    		glVertex3d(0.0f, 100.0f, 0.0f);
    	glEnd();
    	glPopName();
     
    	}
    	else if(render = 1)
    	{
    	glPushName(TRIANGLE);	
    	glTranslatef(largeurf/2-50, hauteurf/2+50, 0.0f);
     
    	// Couleur Bleu
    	glColor3f(0.0f, 0.0f, 1.0f);
     
    	// Dessine un triangle
     
    	glBegin(GL_TRIANGLES);
    		glVertex3d(0.0f, 0.0f, 0.0f);
    		glVertex3d(100.0f, 0.0f, 0.0f);
    		glVertex3d(50.0f, -100.0f, 0.0f);
    	glEnd();
    	glPopName();
     
    	}
    }

    Alors si jamais quelqu'un trouve l'erreur ou la solution, je vais être extrêmement content. Merci.

    Maxetime

  2. #2
    Expert confirmé

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Par défaut
    Ton programme a des erreurs graves :
    Render.cpp: In member function 'void RenderRR::Menu(int, int, int)':
    Render.cpp:40: warning: suggest parentheses around assignment used as truth value
    Render.cpp:58: warning: suggest parentheses around assignment used as truth value

    Main.cpp: In function 'void processHits2(GLint, GLuint*, int)':
    Main.cpp:75: warning: suggest parentheses around assignment used as truth value
    Main.cpp:79: warning: suggest parentheses around assignment used as truth value
    Main.cpp: At global scope:
    Main.cpp:73: warning: unused parameter 'buffer'
    Main.cpp:73: warning: unused parameter 'sw'
    Ensuite, tu as ceci dans ton code :
    à la place de l'appel startPicking;[/b]... Ce n'est pas la même chose. Si tu fais une recherche dans le forum, on a déjà parlé du picking quelque part et on avait fait une version qui marchait.

    Tu pourras t'en inspirer...

    Jc

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    31
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 31
    Par défaut
    Salut,

    Je ne sais pas avec quel compilateur vous travailler, mais moi je travail avec visual c++ 6.0 et il me donne aucune erreure, de plus le code fonction bien je peut partir l'application.

    Le problème c'est avec la variable renderScene elle ne change jamais de valeur même si je la change manuellement juste avant il me donne toujours une valeur de 1 puisque dans le "If (renderScene == 1)" de mon fichier "Render.cpp" il donne toujours un rendu de la scène qui a la valeur 1.

    Maxetime

  4. #4
    Expert confirmé

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Par défaut
    Citation Envoyé par maxetime
    Salut,

    Je ne sais pas avec quel compilateur vous travailler, mais moi je travail avec visual c++ 6.0 et il me donne aucune erreure, de plus le code fonction bien je peut partir l'application.
    Je compile avec les options -Wall -Wextra -O2

    Le problème c'est avec la variable renderScene elle ne change jamais de valeur même si je la change manuellement juste avant il me donne toujours une valeur de 1 puisque dans le "If (renderScene == 1)" de mon fichier "Render.cpp" il donne toujours un rendu de la scène qui a la valeur 1.

    Maxetime
    N'est pas intéressant de voir que dans ton code tu as un seul '=' (c'est un des warnings que je t'ai donné) et dans ton texte tu en as 2...

    Vu qu'en info, rien n'est laissé au hasard, je me demande lequel des deux est la bonne solution ?

    Par contre, cela ne veut pas dire que ton code marchera, c'est juste déjà très mal parti !

    Corrige les erreurs et regarde si cela fonctionne,

    Jc

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    31
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 31
    Par défaut
    Salut,

    Vive les petites erreures d'inattention qui nous font chercher pendant plusieurs jours .

    Bon comme de fait maintenant sa marche pour le if, il y a seulement pour le picking que je vais devoir chercher parce que je crois que mon processhits ne fonctionne pas correctement. Je cherche à comprendre comment gerer les hits, car je veux seulement faire que lorsque je clique sur le triangle bleu la scène se change pour afficher le carré rouge.

    Si quelqu'un peu m'expliquer le picking ou me referer a de bonne explication sa serait sympa en attendant je cherche toujours et j'améliore mon code en même temps. (Ajout de nouvelle chose)

    Merci encore,

    Maxetime

  6. #6
    Expert confirmé

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Par défaut
    J'avais déjà dis qu'on avait discuté du picking avant :

    Citation Envoyé par fearyourself
    Si tu fais une recherche dans le forum, on a déjà parlé du picking quelque part et on avait fait une version qui marchait.

    Tu pourras t'en inspirer...
    As-tu cherché au moins ?

    J'ai fait une recherche sur picking et c'était dans les premiers...

    http://www.developpez.net/forums/sho...d.php?t=199003

    Jc

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    31
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 31
    Par défaut
    oui, j'avais fait une recherche et j'avais trouver ce post, mais je ne comprend pas très bien pour quoi il y a un pointeur et une boucle, je voudrais savoir si c'est possible de seulement tester si tel objet à ressu un hit.

    C'est seulement pour sa que j'ai reecrit ici en demandant des explication sur le picking, désolé j'aurais du préciser.

    Maxetime

    [edit]

    Je vit au Québec alors nous avons 6h de décalage et donc c'est pour sa que je ne peux pas toujours répondre aussi vite.

    [/edit]

  8. #8
    Expert confirmé

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Par défaut
    Citation Envoyé par maxetime
    oui, j'avais fait une recherche et j'avais trouver ce post, mais je ne comprend pas très bien pour quoi il y a un pointeur et une boucle, je voudrais savoir si c'est possible de seulement tester si tel objet à ressu un hit.

    C'est seulement pour sa que j'ai reecrit ici en demandant des explication sur le picking, désolé j'aurais du préciser.

    Maxetime
    Il faut gérer la boucle car il se peut que plusieurs éléments soit touchés par le même click. En fait, une fois que le picking a été fait, nous avons un tableau des éléments séléctionnés. Il faudra donc après les parcourir et choisir celui qui nous intéresse...

    Je croyais que le code fait dans l'autre fil était assez clair, qu'est-ce que tu ne comprends pas ?

    [edit]

    Je vit au Québec alors nous avons 6h de décalage et donc c'est pour sa que je ne peux pas toujours répondre aussi vite.

    [/edit]
    C'est pas grave ca

    Jc

  9. #9
    Membre averti
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    31
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 31
    Par défaut
    Salut,

    Je me suis documenter un peu plus sur le picking, sur ce forum ainsi qu'avec NeHe, et je pensais avoir compris mais il semble qu'il y ait toujours quelque chose que je fait mal. Je vais vous mettre mon code et j'espère que vous trouverez pourquoi cela ne fonctionne pas.

    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
     
    ////////////////////////////////
    ///////     Picking    /////////
    ////////////////////////////////
     
    void startPicking(int cursorX, int cursorY)
    {
    	// The Size Of The Viewport. [0] Is <x>, [1] Is <y>, [2] Is <length>, [3] Is <width>
    	GLint	viewport[4];
     
    	// This Sets The Array <viewport> To The Size And Location Of The Screen Relative To The Window
    	glGetIntegerv(GL_VIEWPORT, viewport);
     
    	glSelectBuffer(BUFFERSIZE,selectBuf);
     
    	glRenderMode(GL_SELECT);
     
    	glInitNames();
    	glPushName(0);
     
    	glMatrixMode(GL_PROJECTION);
    	glPushMatrix();
    	glLoadIdentity();
     
    	gluPickMatrix(cursorX,viewport[3]-cursorY,1.0f,1.0f,viewport);
    	gluPerspective(45.0f, (GLfloat) (viewport[2]-viewport[0])/(GLfloat) (viewport[3]-viewport[1]), 0.1f, 100.0f);
    	glMatrixMode(GL_MODELVIEW);
     
    	g_Render->Menu(renderScene,LARGEUR_FENETRE,HAUTEUR_FENETRE);
     
    	glMatrixMode(GL_PROJECTION);				// Select The Projection Matrix
    	glPopMatrix();								// Pop The Projection Matrix
    	glMatrixMode(GL_MODELVIEW);					// Select The Modelview Matrix
    	hits=glRenderMode(GL_RENDER);				// Switch To Render Mode, Find Out How Many
     
    	if (hits != 0)
    		{ 
    			processHits2(hits,selectBuf);
    		}
    }		
     
    void processHits2 (GLint hits, GLuint buffer[])
    {
     	int	choose = buffer[3];					// Nom de l'objet
    	int	mindepth = buffer[1];				// Distance Minimal
    	int	maxdepth = buffer[2];				// Distance Maximal
     
    	for (int loop = 1; loop < hits; loop++)				// Loop Through All The Detected Hits
    	{
    		// Cacule quel objet du clique est le plus proche 
    		if (buffer[loop*4+1] < GLuint(mindepth))
    		{
    			choose = buffer[loop*4+3];			// Choisit l'objet le plus proche
    			mindepth = buffer[loop*4+1];		// Distance Minimal
    			maxdepth = buffer[loop*4+2];		// Distance Maximal
    		}       
    	}
     
    	if (choose == 0)
    	{
    		renderScene=!renderScene;
    	}
    	if(choose == 1)
    	{
    		renderScene=!renderScene;
    	}
     
    }
    Et voici la fonction de rendu
    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
     
    void RenderRR::Menu(int render, int largeurf, int hauteurf)
    {
     
    	if(render == 0)
    	{
    	glLoadName(CARRE);
    	glTranslatef(largeurf/2-50, hauteurf/2-50, 0.0f);
     
    	// Couleur Rouge
    	glColor3f(1.0f, 0.0f, 0.0f);
    	//Dessine un carré
     
    	glBegin(GL_QUADS);
    		glVertex3d(0.0f, 0.0f, 0.0f);
    		glVertex3d(100.0f, 0.0f, 0.0f);
    		glVertex3d(100.0f, 100.0f, 0.0f);
    		glVertex3d(0.0f, 100.0f, 0.0f);
    	glEnd();
    	}
    	else if(render == 1)
    	{
    	glLoadName(TRIANGLE);;	
    	glTranslatef(largeurf/2-50, hauteurf/2+50, 0.0f);
     
    	// Couleur Bleu
    	glColor3f(0.0f, 0.0f, 1.0f);
     
    	// Dessine un triangle
     
    	glBegin(GL_TRIANGLES);
    		glVertex3d(0.0f, 0.0f, 0.0f);
    		glVertex3d(100.0f, 0.0f, 0.0f);
    		glVertex3d(50.0f, -100.0f, 0.0f);
    	glEnd();
     
    	}
    }
    Voila, si vous avez besoin de d'autre partie n'hésitez pas à me les demander.

    Maxetime

Discussions similaires

  1. [Wamp] Problème d'insertion avec quote d'un formulaire
    Par cyberdevelopment dans le forum EDI, CMS, Outils, Scripts et API
    Réponses: 1
    Dernier message: 20/08/2006, 18h55
  2. [SQL-Server] Problèmes de guillemets et quotes dans un INSERT
    Par gregb34 dans le forum PHP & Base de données
    Réponses: 2
    Dernier message: 05/05/2006, 09h40

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