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

3D Java Discussion :

problème picking jogl


Sujet :

3D Java

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    21
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 21
    Par défaut problème picking jogl
    Bonjour, alors voilà depuis quelques jours je m'acharne sur le picking en jogl, par exemple j'ai un cube, et quand je clique sur une facette elle change de couleur. Jusque là ça marche nickel, mais dès que mon objet dépasse 128 facettes, pouf, marche plus, quand je clique sur les facettes d'après, ben ça prend en compte que la 128ème facette :/
    Je pense que ça doit venir de mon Buffer, mais j'ai l'impression que je sais pas comment changer sa taille vu que quand j'essaie de le faire ça change rien :/
    Voilà les bouts de codes qui concernent le picking :

    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
    case SELECT:
    	int buffsize = 512;
    	double x = (double) mouse_x, y = (double) mouse_y;
    	int[] viewPort = new int[4];
    	IntBuffer selectBuffer1 = BufferUtils.createIntBuffer(buffsize);
        	int hits = 0;
    	gl.glGetIntegerv(GL.GL_VIEWPORT, viewPort,0);
    	gl.glSelectBuffer(buffsize, selectBuffer1);
    	gl.glRenderMode(GL.GL_SELECT);
    	gl.glInitNames();
    	gl.glMatrixMode(GL.GL_PROJECTION);
       	gl.glPushMatrix();
    		gl.glLoadIdentity();
    		glu.gluPickMatrix(x, (double) viewPort[3] - y, 1.0d, 1.0d, viewPort,0);
     
    		gl.glViewport(0, 0, canvas.getWidth(), canvas.getHeight());
    		gl.glMatrixMode(GL.GL_PROJECTION);
    		glu.gluPerspective(45.0f, h, 0.1f, 100000.0f);
     
    		if(disp_facette)
    		{
    			gl.glColor3d(0.2,0.4,0.6);
    			for(int m = 0;m<all_facettes.size();m++)
    			{
    				Facette face = (Facette)all_facettes.get(m);
    				gl.glMaterialfv(GL.GL_FRONT_AND_BACK,GL.GL_AMBIENT,face.get_ambient(),0);
    				gl.glMaterialfv(GL.GL_FRONT_AND_BACK,GL.GL_DIFFUSE,face.get_diffuse(),0);
    				gl.glMaterialfv(GL.GL_FRONT_AND_BACK,GL.GL_SPECULAR,face.get_speculaire(),0);
    				gl.glMaterialf(GL.GL_FRONT_AND_BACK,GL.GL_SHININESS, 0.0f);
    				gl.glPushName(m);
    				gl.glBegin(GL.GL_POLYGON);
    					gl.glNormal3d(face.get_normale()[0],face.get_normale()[1],face.get_normale()[2]);
    					for(int j = 0; j<face.get_sommets().size();j++)
    					{
    						Sommets_facette sommet = face.get_sommet(j);
    						gl.glVertex3d(sommet.get_x(), sommet.get_y(), sommet.get_z());
    					}
    				gl.glEnd();
    			}
    	gl.glPopMatrix();
    	gl.glFlush();
    	hits = gl.glRenderMode(GL.GL_RENDER);
    	processHits(hits, selectBuffer1);
    	cmd = UPDATE;
    	break;
    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
    public void processHits(int hits, IntBuffer buffer)
    {
    	if (hits == 0) return; // no hits to process
    	int selectedNameID = 0; // dummy initial values 
    	float smallestZ = -1.0f; 
    	boolean isFirstLoop = true; 
    	int offset = 0; /* iterate through the hit records, saving the smallest z value and the name ID associated with it */ 
    	for (int i=0; i < hits; i++) 
    	{ 
    		int numNames = buffer.get(offset); 
    		offset++; // minZ and maxZ are taken from the Z buffer 
    		float minZ = (float)buffer.get(offset)/0x7fffffff;
    		offset++; // store the smallest z value 
    		if (isFirstLoop)
    		{ 
    			smallestZ = minZ; 
    			isFirstLoop = false; 
    		} 
    		else 
    		{ 
    			if (minZ < smallestZ)
    				smallestZ = minZ; 
    		} 
    		float maxZ = (float)buffer.get(offset)/0x7fffffff; 
    		offset++; 
    		int nameID;
    		for (int j=0; j < numNames; j++)
    		{ 
    			nameID = buffer.get(offset); 
    			if (j == (numNames-1)) 
    			{ // if the last one (the top element on the stack) 
    				if (smallestZ == minZ) // is this the smallest min z?
    					selectedNameID = nameID; // then store it's name ID 
    			}
    			offset++;
    		}
    	}
    	System.out.println("Picked the " + (selectedNameID));
     
    	Facette face = (Facette)all_facettes.get(selectedNameID);
    	if(face.picked())
    		face.remove_picking(); //remet la couleur d'origine de la facette
    	else
    		face.set_picking(); //met la facette en vert
     
    	all_facettes.set(selectedNameID, face);
    }
    Si vous avez des questions n'hésitez pas (si vous avez des réponses hésitez encore moins :p)

  2. #2
    Membre éclairé

    Profil pro
    Inscrit en
    Avril 2007
    Messages
    17
    Détails du profil
    Informations personnelles :
    Âge : 53
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Avril 2007
    Messages : 17
    Par défaut Taille du buffer
    Bonjour,
    ton problème vient souvent de la taille de ton buffer. Augmente le et cela devra mieux marcher.

    Par contre, je ne connais pas de moyen efficace pour en déterminer la taille à part la méthode empirique

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    21
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 21
    Par défaut
    Ben comme je l'ai dit dans mon premier message, quand j'essaie de changer la taille du buffer, ça change rien, j'ai essayé par exemple en mettant buffsize à plus de 48000 (en passant par pas mal de multiple de puissance de 2), pareil, il s'arrête à la 128ème facette. Et quand j'affiche la taille max de mon IntBuffer avec la méthode limit, il me renvoit la valeur de buffsize, donc à prioris, ça a bien changé la taille. Donc soit je m'y prends mal, soit c'est pas ça qui pose problème :/

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    21
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 21
    Par défaut
    Bon ben pour ceux qui auraient le même problème, voilà la solution, suffit de remplacer le glPushName par glLoadName, et de faire un glPushName(-1) avant les glLoadName, comme j'ai fait là :

    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
    case SELECT:
    	int buffsize = 512;
    	double x = (double) mouse_x, y = (double) mouse_y;
    	int[] viewPort = new int[4];
    	IntBuffer selectBuffer1 = BufferUtils.createIntBuffer(buffsize);
    	int hits = 0;
    	gl.glGetIntegerv(GL.GL_VIEWPORT, viewPort,0);
    	gl.glSelectBuffer(buffsize, selectBuffer1);
    	gl.glRenderMode(GL.GL_SELECT);
    	gl.glInitNames();
    	gl.glMatrixMode(GL.GL_PROJECTION);
    	gl.glPushMatrix();
    		gl.glLoadIdentity();
    		glu.gluPickMatrix(x, (double) viewPort[3] - y, 1.0d, 1.0d, viewPort,0);
    	    	gl.glViewport(0, 0, canvas.getWidth(), canvas.getHeight());
    	    	gl.glMatrixMode(GL.GL_PROJECTION);
    	    	glu.gluPerspective(45.0f, h, 0.1f, 100000.0f);
     
    		if(disp_facette)
    		{
    			gl.glColor3d(0.2,0.4,0.6);
     
    			gl.glPushName(-1);
    			for(int m = 0;m<all_facettes.size();m++)
    			{
    				Facette face = (Facette)all_facettes.get(m);														
    				gl.glMaterialfv(GL.GL_FRONT_AND_BACK,GL.GL_AMBIENT,face.get_ambient(),0);		    									gl.glMaterialfv(GL.GL_FRONT_AND_BACK,GL.GL_DIFFUSE,face.get_diffuse(),0);		    									gl.glMaterialfv(GL.GL_FRONT_AND_BACK,GL.GL_SPECULAR,face.get_speculaire(),0);
    				gl.glMaterialf(GL.GL_FRONT_AND_BACK,GL.GL_SHININESS, 0.0f);
     
    				gl.glLoadName(m);
    				gl.glBegin(GL.GL_POLYGON);
    					gl.glNormal3d(face.get_normale()[0],face.get_normale()[1],face.get_normale()[2]);
    					for(int j = 0; j<face.get_sommets().size();j++)
    					{
    						Sommets_facette sommet = face.get_sommet(j);
    						gl.glVertex3d(sommet.get_x(), sommet.get_y(), sommet.get_z());
    					}
    				gl.glEnd();
    			}
    		}
    		gl.glMatrixMode(GL.GL_PROJECTION);
    	gl.glPopMatrix();
    	gl.glFlush();
    	hits = gl.glRenderMode(GL.GL_RENDER);
    	selectBuffer1.rewind();
    	processHits(hits, selectBuffer1);
    	cmd = UPDATE;
     
    	break;

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    80
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 80
    Par défaut petites precisions
    Oui, en fait pour ceux que ça intéresse, la raison à ça est que OpenGL possède une pile de noms (NameStack) de taille limitée.

    Le fait d'enchainer les glPushName() fait vite déborder la pile, et il ne tient plus compte des nouveaux Push.

    Il existe une fonction glGetIntegerv(GL_MAX_NAME_STACK_DEPTH, * int) permet de savoir la profondeur de cette pile. (qui varie d'une CG a l'autre)

    En ce qui concerne ta solution :

    Le glLoadName() remplace la valeur de haut de pile par celle que tu donne en argument. tu ne fait donc plus sauter la pile.

    Tu aurai egalement pu faire un glPopName() a la fin de chaque primitive (qui retire la valeur en sommet de pile) ça marche également.
    C'est le meme principe que les glPushMatrix() / glPopMatrix(). Mais l'effet n'étant pas visuel avec les noms, l'oubli de glPopName() passe souvent inaperçu.

    En espérant que ces petites explications aiderons d'autres gens.

    HopeLeaves

  6. #6
    Invité
    Invité(e)
    Par défaut
    Bonjour

    Les deux lignes suivantes sont fausses :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    float minZ = (float)buffer.get(offset)/0x7fffffff;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    float maxZ = (float)buffer.get(offset)/0x7fffffff;
    J'explique pourquoi et je donne la solution ici :
    http://jogamp.762907.n3.nabble.com/b...3p1446213.html

    Ca vous évitera de galérer des heures à vous demander pourquoi la valeur minimale de profondeur est parfois supérieure à la valeur maximale de profondeur ce qui est absurde quand on se réfère à la documentation d'OpenGL.

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

Discussions similaires

  1. Problème installation Jogl
    Par deape dans le forum 3D
    Réponses: 4
    Dernier message: 03/02/2012, 17h48
  2. [JAVA3D] Problème Picking
    Par juliens9 dans le forum 3D
    Réponses: 6
    Dernier message: 18/10/2007, 17h37
  3. Problème de "Picking"
    Par maxetime dans le forum OpenGL
    Réponses: 10
    Dernier message: 29/09/2006, 13h36
  4. problème de picking (C++)
    Par khayyam90 dans le forum OpenGL
    Réponses: 5
    Dernier message: 14/08/2005, 14h56
  5. [Debutant Java JOGL] problème glVertexPointer()
    Par Stef784ever dans le forum OpenGL
    Réponses: 2
    Dernier message: 21/04/2004, 17h43

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