OpenGL 1.0 Problem mit ColorPicker

  • Antworten:4
Marcel S.
  • Forum-Beiträge: 120

23.02.2012, 19:17:24 via Website

Hallo zusammen...

Ich habe hier ein kleines Problem, und hoffe das mir jemand von euch einen kleinen Denkanstoß geben kann :)

Also ich versuche hier per ColorPickerMethode die angeklickten Objekte in meiner Szene zu Identifizieren.
soweit Funktioniert das jetzt auch prima. Allerdings spuckt mir glReadPixels() nur die richtigen Werte aus
wenn die zu analysierende Farbe entweder voll oder gar nicht gezeichnet wird.

zur Veranschaulichung:
solche Farben, also Farben deren komponenten entweder 255 oder 0 sind, werden gepickt und korrekt zurückgegeben... die Werte entsprechen RGBA
1float[]{0f,0f,1f,0f}
2float[]{0f,1f,1f,0f}
3float[]{1f,1f,1f,0f}

bei solchen werten erhalte ich nicht nur die Falsche Farbe zurück.. sondern erhalte bei mehrfachem auswerten der selben Farbe auf dem Bildschirm auch noch unterschieliche Ergebnisse.
1float[]{0.1f,0.1f,0.1f,0f}
2float[]{0.2f,0.2f,0.2f,0f}
3float[]{0.3f,0.3f,0.3f,0f}

Jetzt dachte ich bereits an einen Umrechenfehler zwischen float und integer konnte allerdings keinen ausmachen und die unterschiedlichen Ergebnisse bei einem Klick auf einen gleichfarbigen pixel würde das auch nicht erklären.

Hier kurz die Methode mit der ich den Pixel auslese:
[code]
public ByteBuffer buffer = ByteBuffer.allocateDirect(4);
gl.glReadPixels(this.touchPoint.x, this.touchPoint.y, 1, 1, GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE,buffer);

for(int b = 0; b < 4; b+=1){
this.pickcolor[b] = (int)buffer.get(b)& 0xff; if (pickcolor[b]<0) pickcolor[b]+=256;
}
[/code]

Die X und Y Koordinaten des Pixels erhalte ich durch onTouch und die Koordinaten wurden bereits an das Ogl Koordinatensystem angepasst.
Ich hoffe mir kann jemand weiter helfen. Ich kann mir eigentlich nur Vorstellen das ich die Werte schon Falsch aus dem ByteBuffer hole allerdings
weis ich nicht wie ich das anders anstellen könnte.

Ausgewertet wird das ganze in der onDrawFrame(GL10 gl)

1. Zeichnen der Objekte mit einmaliger Farbe
2. Auswerten des ge-pickten Pixels
3. Echte Szene Zeichnen

Vielen dank für eure Mühe...

— geändert am 23.02.2012, 20:32:11

Antworten
reiti.net
  • Forum-Beiträge: 339

24.02.2012, 12:28:41 via Website

edit: maskierung sollte passen :-) *peinlich*

Auch bedenken, dass byte in java signed ist, weiß nicht genau wie das beim ByteBuffer gehandhabt wird, aber eventuell ist das ein problem

— geändert am 24.02.2012, 12:35:22

Antworten
Marcel S.
  • Forum-Beiträge: 120

24.02.2012, 14:39:33 via Website

Ich geb ja zu das ich nicht der Hero bin was die Bytes angeht :)

Wahrscheinlich hab ich hier ein völliges Verständnisproblem. :*)
Sollte das Byte nicht wenigstens immer gleich groß sein wenn es sich immer um die gleiche Farbe handelt.

Ich habe Beispielsweise ein Pixel das lediglich einen Rotanteil von 0.5f hat.
Lese ich dieses Pixel nun aus erhalte ich als Ergebnis mit der oben beschriebenen Methode mal 123 und mal 132.
Habe Ich allerdings ein Pixel mit einem Rotanteil von 1.0f erhalte ich immer genau die zu erwartenden 255 zurück.
Das gleiche passiert bei einem Farbanteil von 0.0 , in dem Fall erhalte ich auch immer 0.

Kannst du mir vielleicht einen Tipp geben was an der Maskierung nicht stimmt?

Antworten
reiti.net
  • Forum-Beiträge: 339

26.02.2012, 00:26:47 via Website

Maskierung war ein Denkfehler von mir, dat passt schon :-)

Ich muss jetzt auch zugeben, ich bin nicht der openGL Guru.

Gut, also zusammenfassend, du bekommst schon den richtigen Wert zurück, aber der variiert und ist nicht exakt.

Da fallen mir nun 2 Dinge ein:

1. openGL ist nicht 2D sondern arbeitet intern (nehm ich an) mit Texturen und diese werden eventuell mit dem Hintergrund interpoliert ..? Frage ist also geht der Colorpicker tatsächlich in den Pixel/Framebuffer oder auf die Textur

2. eventuelle Rundungsfehler? (RGB ist nicht float)

Antworten
Marcel S.
  • Forum-Beiträge: 120

26.02.2012, 10:04:13 via Website

Ich habe die Farben mit glColor4f(0.5f,0.5f,0.5f,1f) gezeichnet,
also den Farbwert als float angegeben. Wenn ich das Pixel nun auswerte erhalte ich allerdings "scheinbar" einen byteBuffer
mit int werten zurück. daher kam es wahrscheinlich durch Rundungsfehler zu unterschiedlichen werten.

Ich zeichne die Farben jetzt so, rot,grün,blau,alpha entsprechen einer ganzen zahl zwischen 0 und 255.
glColor4f(rot /255, grün / 255, blau / 255 , alpha / 255);

dadurch bekomme ich jetzt auch immer die selben werte zurück. allerdings sind diese immer noch Falsch.

Beispiel:
rot == 128;
grün,blau == 0;
alpha = 255;
glColor4f(rot / 255, grün, blau , alpha);

wenn ich das Pixel auswerte erhalte ich für die Farbkomponenten diese vier werte...
rot == -124
grün,blau == 0.
alpha = -1

Wieso wird aus 128 ein wert von -124 ????
Sollte das byte bei einem Überlauf nicht wenigstens den wert -128 haben???
Bei alpha funktioniert es, wie zu erwarten kommt -1 dabei raus, mit 256 addiert weil kleiner 0 habe ich meine 255.

Aber es kommt noch besser.
wenn ich eine Farbe verwende deren Farbanteile alle gleich sind.

z.B.
rot,grün,blau ==128
alpha == 255

clColor4f(rot / 255, grün / 255, blau / 255, alpha / 255);
dann erhalte ich beim auswerten...
rot= -124;
grün = -126;
blau = -124;
alpha = -1;

Die Abweichung vom tatsächlichen Wert ist für mich hier einfach nicht nach vollziehbar.
Das Ausmaß der Abweichung ist noch dazu variabel. Hier ein paar Beispielen.


Gezeichnete Farbe in RGB
10,10,10
zurück gegebene Farbe beim Picking
8,8,8

Gezeichnete Farbe in RGB
50,50,50
zurück gegebene Farbe beim Picking
49,49,49

Gezeichnete Farbe in RGB
128,128,128
zurück gegebene Farbe beim Picking
-124,-126-124

Gezeichnete Farbe in RGB
240,240,240
zurück gegebene Farbe beim Picking
-117,-117,-117


Ich bin mir sicher ich sehe einfach den Wald vor lauter Bäumen nicht :).
Ich bin euch für jeden Ratschlag dankbar. :)

— geändert am 26.02.2012, 10:16:32

Antworten