# JOGL Selection By Color



## Shaddow (9. Mai 2009)

Hi Leute,
ich versuch grad bei mir eine Selektion zu implementieren. Ich weiß zwar, dass es eine OGL eigene Selektion gibt, aber die soll ja ziemlich unperformant sein und prinzipiell gefällt mir die Lösung über die Farben auch besser. 

Ich weise also jedem Selektierbaren Item eine einzigartige Farbe zu, zeichne beim Mausklick die Szene einmal in den Selektionsfarben, lese per Readpixels die Farbe im Klickbereihc aus und schließe auf dads angeklickte Item zurück. Soviel zur Theorie.. 

Sobald der Mouseklick erfolgt, wird der Modus des Renderers auf Selection gesetzt. Beim nächsten Rendern wird, die Selectionsfläche gezeichnet. Punkt wird schonmal gemerkt.

```
public void mousePressed(MouseEvent e) 
	{
		getOwner().setInSelectiveMode(true);
		point = e.getPoint();		
	}
```

Nächster Rendervorgang, statt wie normal die Szene,wird diesmal eine Methode aufgerufen, die die selektierbaren Objekte zeichnen soll:

```
[Cameraanpassungen etc...]
        try
        {
        	glSceneManager.getCurScene().update(currentTime);
        	
        	if (inSelectiveMode)
        		glSelectionManager.renderSelectables(gl, glu);
        	else
        		glSceneManager.getCurScene().draw(gl, glu);
        }
        catch(SceneFailureException sfe)
        {
        	sfe.printStackTrace();
        }
```


Alles ausschalten, Objekte werden gezeichnet. Muss nun der Swapbuffers forciert werden?

```
gl.glDisable(GL.GL_TEXTURE_2D);
		gl.glDisable(GL.GL_LIGHTING);
		gl.glDisable(GL.GL_BLEND);
		gl.glShadeModel(GL.GL_FLAT);
		
		for(Iterator<ISelectable> i = colors.values().iterator(); i.hasNext();)
		{
			i.next().renderByColor(gl, glu);
		}

		getOwner().arg0.swapBuffers();
```

Auslesen der geklickten Fläche incl Check, auf welche Farben er zutrifft-

```
ByteBuffer buffer = ByteBuffer.allocate(3);
			getOwner().getGl().glReadBuffer(GL.GL_FRONT);		
			getOwner().getGl().glReadPixels((int)point.getX(), getOwner().glWindow.getHeight() - (int)point.getY(), 1, 1, GL.GL_RGB, GL.GL_UNSIGNED_BYTE, buffer);
					
			int[] intbuffer = new int[4];
			
			for (int i = 0; i <buffer.limit(); i++)
			{
				if(buffer.get(i)<0)
					intbuffer[i] = 256+buffer.get(i);
				else
					intbuffer[i] = buffer.get(i);
			}
				
			System.out.println("--------");	
			GLColor tmp = new GLColor(intbuffer[0],intbuffer[1],intbuffer[2],0);
			if (colors.equals(tmp))
				System.out.println("JO");
			
			for(Iterator<ISelectable> i = colors.values().iterator(); i.hasNext();)
			{
				
				ISelectable s = i.next();
				System.out.println(s.getUniqueColor().toByteArray()[0]+" "+
						s.getUniqueColor().toByteArray()[1]+" "+
						s.getUniqueColor().toByteArray()[2]+" "+
						s.getUniqueColor().toByteArray()[3]);
				
				if (s.getUniqueColor().compareTo(tmp)==1)
				{	if(curFocus!=null)
					curFocus.looseFocus();
					s.gainFocus();
					curFocus = s;
				System.out.println("JO");break;}
			}
			System.out.println("--------");
			System.out.println(intbuffer[0]+" "+intbuffer[1]+" "+intbuffer[2]);
			
			getOwner().setInSelectiveMode(false);
			getOwner().getGl().glShadeModel(GL.GL_SMOOTH);
```

Ich habe das ganze mit dem Swapbuffers und ohne getestet. Das Resultat ist imemr das selbe: Die getroffene Farbe ist imemr die, mit der die Objekte eigentlich gezeichnet werden, aber nicht die Farbe, die ich ihnen zugewiesen habe..

Als beispielszene habe ich 4 Quadrate, die alle kunterbunte Uniquefarben haben, und in der richtigen Szene grün sind.
Wenn ich das ganze teste, kommt der folgende Output:

228 238 186 0 // die vier bunten farben, die mein Selectionmanager sich gemerkt hat
195 210 212 0
128 232 230 0
131 171 253 0
--------
72 90 52 0 // die eine farbe im Klickbereich, die eine der vier oberen seien müsste, aber die ist, mit der die Szene wirklich gezeichnet wird

Obwohl ich also kurz vor dem Farbcheck die Szene in selektionsfarben zeichne, bleibt die Farbe bei dem Check zurück, die eigentlich gezeichnet wird..
Hat da jemand eine Idee? 


Anmerkung: Crosspost auf DGL :: Thema anzeigen - Color Picking Selection


----------



## Spacerat (11. Mai 2009)

Tja... Selection by Color ist mir zwar nicht geläufig, aber Picking in JOGL sagt mir was. Deshalb möchte ich trotz deiner Bedenken doch mal auf das GL Interne Verfahren hinweisen, was letztendlich doch nicht so unperformant ist wie man sagt. Dieses habe ich zwar so noch nicht durchgearbeitet, aber zumindest schon mal angesehen und ein Wenig mit dem Picking-Verfahren experimentiert. Funktionierte prächtig.


----------



## Evil-Devil (13. Mai 2009)

Zeichne deine Colormap doch einfach in den Backbuffer und lies dann auch von dort aus. Dann sparst du dir das Swap Buffers und dürftest dein Problem mit den "Echtfarben" auch gelöst haben.


----------



## Shaddow (13. Mai 2009)

Evil-Devil hat gesagt.:


> Zeichne deine Colormap doch einfach in den Backbuffer und lies dann auch von dort aus. Dann sparst du dir das Swap Buffers und dürftest dein Problem mit den "Echtfarben" auch gelöst haben.



Genau das mach ich ^^
Der Fehler lag in einem aktivierten Depthbuffer, von dessen Aktivität ich aber unglücklicherweise nichts wusste ^^ Er hat sich beim Debuggen auch ganz geschickt deaktiviert (soll heissen, ich war so dumm und hab ihn immer ausgemacht, als ich schauen wollte, ob er an ist)... However, er ist aus, und alles funkioniert prächtig


----------

