Files |  Tutorials |  Articles |  Links |  Home |  Team |  Forum |  Wiki |  Impressum

Aktuelle Zeit: So Mai 19, 2024 05:47

Foren-Übersicht » Programmierung » OpenGL
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 29 Beiträge ]  Gehe zu Seite 1, 2  Nächste
Autor Nachricht
 Betreff des Beitrags: Color Picking Selection
BeitragVerfasst: Sa Mai 09, 2009 14:07 
Offline
DGL Member

Registriert: So Aug 20, 2006 23:19
Beiträge: 564
Hi, habe jetz eine Weile hier im Forum nach dieser Art des Selections gestöbert und angefangen, das bei mir mal umzusetzen.
Nur hackt es momentan am glReadPixels..

Ich zeichne zuerst meine Szene und dann im Klickevent lese ich ein paar Pixel aus:

Code:
  1.         FloatBuffer buffer = FloatBuffer.allocate(16);
  2.         getOwner().getGl().glReadPixels(e.getX(), e.getY(), 2, 2, GL.GL_RGBA, GL.GL_FLOAT, buffer);


Wenn ich damit auf ein grünes Quadrat klicke, bekomme ich immer nur Nullen als Inhalt des Buffers.. Irgendwie bin ich durch die Verwendung von readPixels noch nicht ganz durchgestiegen.. Danke schonmal :)

Edit: Crosspost auf http://www.java-forum.org/spiele-und-mu ... color.html


Zuletzt geändert von Shaddow am Sa Mai 09, 2009 19:57, insgesamt 3-mal geändert.

Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Mai 09, 2009 14:13 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Sep 23, 2002 19:27
Beiträge: 5812
Programmiersprache: C++
Der Ursprung des Koordinatensystems in OpenGL liegt unten links und nicht oben links wie bei Windows, also musst du deine Y-Koordinate von der Höhe des Viewports abziehen. Ansonsten sieht alles korrekt aus, ich persönlich lese jedoch immer nur einen Block von 1x1 Pixeln und auch als Byte ohne Alpha (braucht man für die Farbselektion nicht).

_________________
www.SaschaWillems.de | GitHub | Twitter | GPU Datenbanken (Vulkan, GL, GLES)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Mai 09, 2009 14:14 
Offline
DGL Member

Registriert: So Aug 20, 2006 23:19
Beiträge: 564
Das hatte ich auch schon mit dem Abzug der Höhe des Fensters getestet:
Code:
  1.  
  2.         FloatBuffer buffer = FloatBuffer.allocate(3);
  3.         getOwner().getGl().glReadPixels(e.getX(), getOwner().glWindow.getHeight() - e.getY(), 1, 1, GL.GL_RGB, GL.GL_FLOAT, buffer);
  4.        
  5.         for (int i = 0; i < buffer.limit(); i++)
  6.             System.out.println(buffer.get(i));
  7.  

Gibt mir 3 Nullen aus..


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Mai 09, 2009 14:23 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Sep 23, 2002 19:27
Beiträge: 5812
Programmiersprache: C++
So siehts bei mir in Delphi aus, evtl. verweist du falsch auf deinen Puffer, k.a. da ich selbst kaum Java kann :
Code:
  1. glReadPixels(MousePos.x, viewport[3]-MousePos.y, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, @Pixel[0]);

Zur Sicherheit solltest auch angeben aus welchem Puffer du lesen willst :
Code:
  1. glReadBuffer(GL_BACK);

_________________
www.SaschaWillems.de | GitHub | Twitter | GPU Datenbanken (Vulkan, GL, GLES)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Mai 09, 2009 14:36 
Offline
DGL Member

Registriert: So Aug 20, 2006 23:19
Beiträge: 564
Bringt auch alles nichts
Hab ich viellecht vorher schon einen Fehler gemacht? Also soweit, dass ich damit jetzt schon Colors fürs Selecten Picken will, bin ich ja noch gar nicht. Im grunde soll das nur mal ein Test sein, ob ich ueberhaupt die Farbe eines Pixels rausbekomm. Also müsste diese Methode mir doch Farbe angeben, wenn ich auf ein Gründes Quadrat klick oder?


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Mai 09, 2009 14:45 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Sep 23, 2002 19:27
Beiträge: 5812
Programmiersprache: C++
Lösche mal deine Szene mit ner anderen Farbe als Schwarz und mach nen ReadPixels und schau nach ob dort immer noch 0 drinne steht oder jetzt die Löschfarbe, damit kannst du zumindest ermitteln ob dein Problem beim ReadPixels oder wo anders liegt. Ansonsten sieht dein Code in Ordnung aus, probiers aber mal wie ich mit Bytes anstatt Floats und schau nochmal.

_________________
www.SaschaWillems.de | GitHub | Twitter | GPU Datenbanken (Vulkan, GL, GLES)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Mai 09, 2009 14:50 
Offline
DGL Member

Registriert: So Aug 20, 2006 23:19
Beiträge: 564
Clearcolor auf (1,0,0,1) gibt immernoch (0,0,0)

... Eigenartig^^


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Mai 09, 2009 15:05 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Sep 23, 2002 19:27
Beiträge: 5812
Programmiersprache: C++
Richtiger Puffer (mal testweise GL_FRONT probieren)? Richtiger Verweis auf den Pixelpuffer? Auf OpenGL-Fehler überpprüft? Wann wird glReadPixels aufgerufen? Koordination innerhalb des Viewports?

_________________
www.SaschaWillems.de | GitHub | Twitter | GPU Datenbanken (Vulkan, GL, GLES)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Mai 09, 2009 15:18 
Offline
DGL Member

Registriert: So Aug 20, 2006 23:19
Beiträge: 564
Puffer sowohl Front als auch Back getestet
Verweis auf Buffer: so würd ich ihn initalisieren, aber ob das so richtig ist, weiss ich nicht
Aufruf von Readpixels: während des klickereignisses. Szene ist bereits gezeichnet
Koordinaten im Viewport: Viewport ist das komplette Fenster, also ja

OpenglFehler?:GL_INVALID_OPERATION
ich weiss allerdings nicht, woher der kommt.
Laut Wiki:
Zitat:
GL_INVALID_OPERATION wird generiert wenn format GL_COLOR_INDEX ist und der Farbpuffer RGBA Werte enthält.
GL_INVALID_OPERATION wird generiert wenn format GL_STENCIL_INDEX ist und kein Schablonen-(/Stencil-)Puffer existiert.
GL_INVALID_OPERATION wird generiert wenn format GL_DEPTH_COMPONENT ist und kein Tiefenpuffer existiert.
GL_INVALID_OPERATION wird generiert wenn glReadPixels innerhalb eines glBegin-glEnd Blocks aufgerufen wird.


die ersten drei entfallen. und zwischen begin und end wirds auch nicht aufgerufen


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Mai 09, 2009 15:38 
Offline
DGL Member

Registriert: So Aug 20, 2006 23:19
Beiträge: 564
Okay ich habs. Wahrscheinlich lag der Fehler tatsächlich daran, dass ReadPixels während Begin und End aufgerufen wurde und ich habe es nihct gleich mitbekommen, weil die AWTEventQueue ein paralleler Thread zum OGLThread ist. Ich habe also beim Event lediglich eine "Notiz" hinterlassen, dass geklickt wurde und diesen Klick dann im OGLThread dann mit Readpixels verarbeiten lassen. Und siehe da, ich bekomme zahlen :D


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Mai 09, 2009 15:41 
Offline
Forenkatze
Benutzeravatar

Registriert: Mi Okt 22, 2003 18:30
Beiträge: 1945
Wohnort: Närnberch
Programmiersprache: Scala, Java, C*
Ich hab mit OpenGL unter Java zwar kaum Erfahrungen - für Swing und Konsorten gilt aber: Wenn du eine GUI hast, dann lass die ganze Anwendung im AWTEventQueue-Thread laufen. Es sei denn, sie ist speziell auf Multithreading ausgelegt, was ich jetzt mal nicht bei dir annehme ;)

Für sowas gibt's ja SwingUtilities.invokeLater (...);
Oder werf mal einen Blick in das "neue" concurrency-package. Da sind tolle Sachen für diese Probleme drin, könnten vielleicht nützlich sein ;)

_________________
"Für kein Tier wird so viel gearbeitet wie für die Katz'."


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Mai 09, 2009 17:29 
Offline
DGL Member

Registriert: So Aug 20, 2006 23:19
Beiträge: 564
Also bisher wüsste ich nicht, dass man den OGL Thread irgendwie in den AWt reinbekommt, aber muss ich mal nachforschen^^

Ich hab noch eine Frage zu dieser Colorpick methode:
Wie ist genau die vorgehensweise?

Ich habe es folgendermaßen verstanden:
Ich rendere meine Objecte mit zufaelligen Farben. Danach überzeichne ich sie normal wie ich sie haben will und beim Pick kommt dann die richtige Farbe raus. Klingt n bisschen komisch...

Irgendwie habe ich da ein paar Lücken drin.
Wird da irgendetwas mittels Backfaceculling weggemacht? Etwa das gefärbte Object? Hab das in irgendeinem Thread gelesen..
Und dann: bekomme ich die "unique" farbe überhaupt noch heraus, wenn ich a) mit der richtigen drüber zeichne oder sie b) wegculle?

Oder ist es vielmehr so, dass ich immer nur das zeichne, was ich wirklich sehen will und beim onclick zeichne ich einmal das ganze in unique farbe und hole die richtige farbe heraus?

^^

Danke schonmal für die erklärung


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Mai 09, 2009 18:47 
Offline
Guitar Hero
Benutzeravatar

Registriert: Do Sep 25, 2003 15:56
Beiträge: 7804
Wohnort: Sachsen - ERZ / C
Programmiersprache: Java (, Pascal)
Wenn du klickst, renderst du deine Szene neu.
Du schaltest alles aus was du nicht brauchst (Texture, Licht, Blending), du solltest vielleicht sogar noch eine Schablone erzeugen, welche nur den Bereich rund um den Curser beschreibbar läßt. Du solltest Flat-Shading einschalten (glShadeModel).
Alle Objekte bekommen von dir eine Farbe. Diese Farbe musst du natürlich irgendwo speichern, damit du später wieder weißt was du überhaupt getroffen hast.

Du zeichnest dann die Szene einmal. Ließt die Farbe aus und berechnest was getroffen wurde.
Vor dem nächsten Zeichnen machst du alle Änderungen wieder rückgängig. (Licht wieder an, Texturen wieder an, etc.)

Einen Algorithmus zum erzeugen der Farben für deine Objekte kann primitiv sein. z.B. fängst du bei (1,0,0) (Bytewerte) and und zählst nach oben bis (255,0,0). Dann gehts weiter bei (255,1,0) usw.
Auch wenn du die Farben nicht auseinander halten kannst, sind die Werte für den Rechner deutlich unterschiedlich.

_________________
Blog: kevin-fleischer.de und fbaingermany.com


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Mai 09, 2009 19:03 
Offline
DGL Member

Registriert: So Aug 20, 2006 23:19
Beiträge: 564
Ich bekomms einfach nicht hin ^^ Also hier mla ein bissel Quellcode:

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.
Code:
  1.     public void mousePressed(MouseEvent e)
  2.     {
  3.         getOwner().setInSelectiveMode(true);
  4.         point = e.getPoint();      
  5.     }      
  6.  


Nächster Rendervorgang, statt wie normal die Szene,wird diesmal eine Methode aufgerufen, die die selektierbaren Objekte zeichnen soll:
Code:
  1. [Cameraanpassungen etc...]
  2.         try
  3.         {
  4.             glSceneManager.getCurScene().update(currentTime);
  5.            
  6.             if (inSelectiveMode)
  7.                 glSelectionManager.renderSelectables(gl, glu);
  8.             else
  9.                 glSceneManager.getCurScene().draw(gl, glu);
  10.         }
  11.         catch(SceneFailureException sfe)
  12.         {
  13.             sfe.printStackTrace();
  14.         }      



Alles ausschalten, Objekte werden gezeichnet. Muss nun der Swapbuffers forciert werden?
Code:
  1.         gl.glDisable(GL.GL_TEXTURE_2D);
  2.         gl.glDisable(GL.GL_LIGHTING);
  3.         gl.glDisable(GL.GL_BLEND);
  4.         gl.glShadeModel(GL.GL_FLAT);
  5.        
  6.         for(Iterator<ISelectable> i = colors.values().iterator(); i.hasNext();)
  7.         {
  8.             i.next().renderByColor(gl, glu);
  9.         }
  10.  
  11.         getOwner().arg0.swapBuffers();
  12.  
  13.  


Auslesen der geklickten Fläche incl Check, auf welche Farben er zutrifft-
Code:
  1.             ByteBuffer buffer = ByteBuffer.allocate(3);
  2.             getOwner().getGl().glReadBuffer(GL.GL_FRONT);      
  3.             getOwner().getGl().glReadPixels((int)point.getX(), getOwner().glWindow.getHeight() - (int)point.getY(), 1, 1, GL.GL_RGB, GL.GL_UNSIGNED_BYTE, buffer);
  4.                    
  5.             int[] intbuffer = new int[4];
  6.            
  7.             for (int i = 0; i <buffer.limit(); i++)
  8.             {
  9.                 if(buffer.get(i)<0)
  10.                     intbuffer[i] = 256+buffer.get(i);
  11.                 else
  12.                     intbuffer[i] = buffer.get(i);
  13.             }
  14.                
  15.             System.out.println("--------");
  16.             GLColor tmp = new GLColor(intbuffer[0],intbuffer[1],intbuffer[2],0);
  17.             if (colors.equals(tmp))
  18.                 System.out.println("JO");
  19.            
  20.             for(Iterator<ISelectable> i = colors.values().iterator(); i.hasNext();)
  21.             {
  22.                
  23.                 ISelectable s = i.next();
  24.                 System.out.println(s.getUniqueColor().toByteArray()[0]+" "+
  25.                         s.getUniqueColor().toByteArray()[1]+" "+
  26.                         s.getUniqueColor().toByteArray()[2]+" "+
  27.                         s.getUniqueColor().toByteArray()[3]);
  28.                
  29.                 if (s.getUniqueColor().compareTo(tmp)==1)
  30.                 {   if(curFocus!=null)
  31.                     curFocus.looseFocus();
  32.                     s.gainFocus();
  33.                     curFocus = s;
  34.                 System.out.println("JO");break;}
  35.             }
  36.             System.out.println("--------");
  37.             System.out.println(intbuffer[0]+" "+intbuffer[1]+" "+intbuffer[2]);
  38.            
  39.             getOwner().setInSelectiveMode(false);
  40.             getOwner().getGl().glShadeModel(GL.GL_SMOOTH);
  41.  


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


Hat da jemand eine Idee? :)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Mai 09, 2009 22:28 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Sep 23, 2002 19:27
Beiträge: 5812
Programmiersprache: C++
Wenn du aus dem hinteren Puffer liest ist ein Swapbuffers natürlich überflüssig. Ansonsten liefert dir Readpixels genau dass was man auif dem Bildschirm sieht, also lass dir mal rendern was während der Selektion gezeichnet wird (evtl. überschreibst du irgendwo die Einstellungen für die Selektion).

Und als kleiner Tipp : Für die Farbselektion sollte man auf keinen Fall die RGB-Werte in 1er Schritten durchgehen, denn spätestens wenn jemand das Programm mit aktiviertem AA laufen lässt bekommt man an den Rändern mit Sicherheit leicht andere Farbwerte als die des Hauptobjektes und dann kann ein Hochzählen mit 1 zu falscher Auswahl führen. Hier muss man halt ein passendes Delta finden.

_________________
www.SaschaWillems.de | GitHub | Twitter | GPU Datenbanken (Vulkan, GL, GLES)


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 29 Beiträge ]  Gehe zu Seite 1, 2  Nächste
Foren-Übersicht » Programmierung » OpenGL


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 10 Gäste


Du darfst keine neuen Themen in diesem Forum erstellen.
Du darfst keine Antworten zu Themen in diesem Forum erstellen.
Du darfst deine Beiträge in diesem Forum nicht ändern.
Du darfst deine Beiträge in diesem Forum nicht löschen.
Du darfst keine Dateianhänge in diesem Forum erstellen.

Suche nach:
Gehe zu:  
cron
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.064s | 14 Queries | GZIP : On ]