Registriert: Di Okt 13, 2009 17:25 Beiträge: 365
Programmiersprache: C++
Es wird grundsätzlich erstmal immer nur in den Backbuffer gezeichnet. Erst wenn du SwapBuffers aufrufst, wird der Inhalt des Backbuffers auf den sichtbaren FrontBuffer übertragen. Du kannst also erstmal deinen Selektionskram rendern, dann ggf. den Backbuffer leeren (glClear) und nachdem du dann das, was der Benutzer sehen soll, gezeichnet hast kannst du SwapBuffers aufrufen.
edit: Okay vergiss, was ich hier geschrieben habe. Wie sich durch Coolcat herausgestellt hat, bist du nicht der einzige mit Unwissen.
Zuletzt geändert von mrtrain am Mi Aug 31, 2011 19:43, insgesamt 2-mal geändert.
Und wie sage ich dem Ganzen, dass die Objekte in dieser zusätzlich übergebenen Farbe nicht gezeichnet werden sollen, sonden nur in einem zweiten Buffer (?) landen sollen?
Welchen Buffer meinst du jetzt? Framebuffer? VBO? Geht es dir darum nicht in den Framebuffer zu rendern weil der User dein Color-Picking ja nicht zu Gesicht bekommen soll? => Dafür gibt es FramebufferObjects (FBO). Es ist übrigens eine gute Idee das FBO dann nur z.B. 3x3 Pixel groß zu machen, schließlich willst du ja nur den Pixel unter dem Cursor und nicht den kompletten Bildschirm. Es ist allerdings nicht ganz trivial die Matrizen entsprechend anzupassen. Ich habe das aber hier irgendwo in einem anderen Thread erklärt. (Edit: hier )
@mrtrain: In WebGL gibt es kein SwapBuffers, das geht irgendwie automatisch und keiner weiß wie Ich vermute aber das Swapbuffers einfach immer dann aufgerufen wird, wenn das Programm wieder im Idle-Zustand ist, also der Browser die Kontrolle hat.
Registriert: Do Mai 20, 2010 10:54 Beiträge: 10
Programmiersprache: C/C++
Wenn du lediglich überprüfen möchtest, ob ein Objekt mit der Maus selektiert wurde, kannst du auch den umgekehrten Weg einschlagen und für den Objektmittelpunkt einfach die Bildschirmkoordinaten berechnen.
Und wie sage ich dem Ganzen, dass die Objekte in dieser zusätzlich übergebenen Farbe nicht gezeichnet werden sollen, sonden nur in einem zweiten Buffer (?) landen sollen?
Welchen Buffer meinst du jetzt? Framebuffer? VBO? Geht es dir darum nicht in den Framebuffer zu rendern weil der User dein Color-Picking ja nicht zu Gesicht bekommen soll? => Dafür gibt es FramebufferObjects (FBO).
Ja genau, ich will nicht, dass man die bunten Farben des Pickings sehen soll. Mal sehen, was ich aus diesen Buffern machen kann. Muss ich denn nun jedes VBO umstellen auf FBO ?
AlexMaRu hat geschrieben:
Wenn du lediglich überprüfen möchtest, ob ein Objekt mit der Maus selektiert wurde, kannst du auch den umgekehrten Weg einschlagen und für den Objektmittelpunkt einfach die Bildschirmkoordinaten berechnen.
Im Prinzip geht es darum, ja. Meine Idee war die Bildschirmkoordinaten der aktuellen Mausposition in Objektkoordinaten umzuwandeln und anschließend anhand dieser überprüfen, ob das Objekt getroffen wurde. Mittlerweile funktioniert das mit dem invertieren der Viewing-Pipeline-Matrix, d.h. mir liegen die ursprünglichen Objektkoordinaten vor. Doch ein Problem habe ich noch: eine Rotation verändert alle Werte, sodass bei einem erneuten Klick auf die Szene vollkommen falsche Werte zurückgeliefert werden.
Danke für den Link, ich werde es auf jeden Fall mal ausprobieren!
Öh, wie meinen? VBOs haben mit FBOs jetzt erstmal wenig zu tun, aber gesehen davon das es beides BufferObjekte sind also Speicherbereiche mit irgendwelchen Daten drin. Wenn sobald ein FBO gebunden ist beziehen sich alle Render-Aufrufe auf diesen FBO. Texturen und VBOs kannst du ganz normal nutzen. Sobald du wieder den FBO mit der ID "0" bindest, renderst du wieder in den normalen Framebuffer. Ein FBO ändert einfach nur das Ziel wo du hin renderst.
VBOs haben mit FBOs jetzt erstmal wenig zu tun, aber gesehen davon das es beides BufferObjekte sind also Speicherbereiche mit irgendwelchen Daten drin. Wenn sobald ein FBO gebunden ist beziehen sich alle Render-Aufrufe auf diesen FBO. Texturen und VBOs kannst du ganz normal nutzen. Sobald du wieder den FBO mit der ID "0" bindest, renderst du wieder in den normalen Framebuffer. Ein FBO ändert einfach nur das Ziel wo du hin renderst.
Aah jetzt habe ich es verstanden Habe nun ein Framebuffer-Objekt in webgl erstellt und kann ihn benutzen. Komischerweise gibt es auch hier wieder Unterschiede zu opengl es2.0, wie zB.: Man stellt nicht mit ID "0" um, sondern mit "null"..woher man das auch immer wissen sollte... Die Frage jetzt: wie geht es weiter? So wie ich es bisher verstanden habe, muss ich alle meine in den normalen Framebuffer gerenderten Objekte nochmals mit den draw-Aufrufen und den neuen Farben in den selbst erstellten FBO rendern. Wenn dem so ist, dann wird die Szene stets zweifach gezeichnet; ein Geschwindigkeitskiller?
Und noch etwas. Ich wollte überprüfen, ob der FBO korrekt erstellt wurde, was durch checkFramebufferStatus möglich ist.
Code:
var check=gl.checkFramebufferStatus(gl.FRAMEBUFFER); alert(check)
Der ausgegebene Wert ist 36053. Was kann ich damit anfangen?
Man stellt nicht mit ID "0" um, sondern mit "null"..woher man das auch immer wissen sollte...
In WebGL sind sämtliche OpenGL-Objekte wie Texturen, Shader, VBOs und auch FBOs auch wirkliche JavaScript-Objekte. Es handelt sich also um echte Pointer und nicht nur um virtuelle IDs. Entsprechend muss man auch den Null-Pointer benutzen.
Zitat:
Wenn dem so ist, dann wird die Szene stets zweifach gezeichnet; ein Geschwindigkeitskiller?
Richtig, die Szene wird zweifach gezeichnet, ABER... 1. Die Grafikkarte ist in der Geometrieverarbeitung verdammt schnell. Was Zeit kostet sind aufwendige Shader oder große Datenmengen die hin und her geschoben werden, z.B. Texturen. 2. JavaScript ist dagegen verdammt langsam. Ich würde mal vermuten wenn alle notwendigen Daten bereits auf der Grafikkarte sind ist die Karte locker 100mal schneller als die JavaScript-Anwendung. Hängt natürlich auch von der Hardware, Browser, usw. ab. 3. Du renderst ja hoffentlich nicht die komplette Szene sondern nur den sichtbaren Teil unter Verwendung eines effizienten Tests, z.B. irgendeine Baumstruktur (QuadTree, etc). 4. Du kannst die Größe des FBO auf 3x3 Pixel reduzieren, den dich interessiert ja nur der Farbwert unter dem Cursor. Deine Sichtbarkeitsberechnung vor dem rendern solltest du an diese reduzierte Größe anpassen. Dazu habe ich hier irgendwo nen Link gepostet.
Zitat:
Der ausgegebene Wert ist 36053. Was kann ich damit anfangen?
Versuch mal das gegen diese Konstanten zu vergleichen:
Wenn dem so ist, dann wird die Szene stets zweifach gezeichnet
Naja, eigentlich muss man die Szene nur dann zweifach zeichnen, wenn man wissen will, was gerade unter der Maus liegt (*1). Wenn das zB auf Click reagieren soll, dann muss nur doppelt gezeichnet werden, wenn geklickt wurde. Wenn es immer auf die Mausposition reagieren soll, dann wird die Szene wirklich immer zweimal gezeichnet (*2)
(*1): Oder halt sonst wo. Jedenfalls wenn man wissen will, was auf einem bestimmten Pixel ist
(*2): Oder auch nur zB bei jedem zweiten Mal. Je nachdem, wie schnell es reagieren soll
3. Du renderst ja hoffentlich nicht die komplette Szene sondern nur den sichtbaren Teil unter Verwendung eines effizienten Tests, z.B. irgendeine Baumstruktur (QuadTree, etc).
Oh das hört sich spannend an. Abr worauf genau ist das bezogen? Ich dachte mit clipping lasse ich alle nicht sichtbaren Teile der Szene weg..
Zitat:
4. Du kannst die Größe des FBO auf 3x3 Pixel reduzieren, den dich interessiert ja nur der Farbwert unter dem Cursor. Deine Sichtbarkeitsberechnung vor dem rendern solltest du an diese reduzierte Größe anpassen. Dazu habe ich hier irgendwo nen Link gepostet.
Danke auch für diesen Tipp! Ich lade lieber erstmal den ganzen FBO mit dessen Inhalt. Wenn alles so funktioniert, wie ich möchte, kümmere ich mich um solche eher kompliziert umzusetzenden Verbesserungen
----------
Ich bin gerade dabei jedem VBO eine eindeutige Farbe zu verleihen. Doch scheinbar habe ich nur sehr wenige Farben zur Auswahl, weil sich die Werte bei readPixels fast nie verändern, wenn ich die Farbe im VBO nur leicht verändere:
[0.0, 0.0, 1/255] wird mit readPixels zu [0,0,0] [0.0, 0.0, 1/150] wird mit readPixels zu [0,0,0] ... //bleibt immer bei [0,0,0] [0.0, 0.0, 1/10] wird mit readPixels zu [0,0,2] [0.0, 0.0, 1/9] wird mit readPixels zu [0,0,3]
Wenn sich tatsächlich erst etwas bei einer Kommanachstelle ändert, habe ich ja nur 1000 Farben zur Auswahl. Ich brauche aber viel mehr Was läuft hier falsch?
Registriert: Fr Jan 04, 2008 21:29 Beiträge: 419 Wohnort: Lübeck
müsste 1/255 nicht korrekter als 1.0/255.0 geschrieben werden? Ist es nicht so, dass die Operatoren anhand der schreibweise erkennen, für welchen Datentyp sie ausgewertet werden sollen? Zumindest bei C++ bin ich mir da sicher.
Edit: Außerdem wäre es wohl praktischer sich eine Konstante zu halten alla "ColorStep = 1.0/255.0" und dann beim festlegen der Farbe diese Konstante mit den gewünschten R-, G-, B-Werten zu multiplizieren. Also ColorStep*R, ColorStep*G, ColorStep*B
Oh das hört sich spannend an. Abr worauf genau ist das bezogen? Ich dachte mit clipping lasse ich alle nicht sichtbaren Teile der Szene weg..
Ich bin mir nicht sicher ob wir hier das selbe meinen, aber Clipping findet auf der Grafikkarte statt. Diese stellt fest ob ein Dreieck im Sichtbereich liegt und schneidet es ggf. zurecht oder überspringt es. Es werden nur vollständig sichtbare Dreiecke gerendert. Clipping findet aber erst nach dem Vertexshader bzw. Geometryshader statt. Was ich aber jetzt meint war ein Frustum-Culling auf Objektebene. D.h. für jedes größere Objekt wird vor dem rendern kurz getestet ob dessen BoundingBox den Sichtbereich berührt. Diese BoundingBoxen kann man dann wieder in größeren BoundingBoxen zusammenfassen, diese dann nochmal, und so weiter. Am Ende kann man durch den Test weniger BoundingBoxen zehntausende Dreiecke vom rendern ausschließen. Das ist eine Standard-Technik die eigentlich jeder beim normalen rendern benutzt. Sollte massenhaft Tutorials dazu geben. Stichworte wären z.B. QuadTree oder Octtree.
Was ich nun eigentlich sagen wollte: Diese Frustum-Culling kann man leicht so flexibel implementieren, dass du den selben Code auch beim Color-Picking benutzen kannst.
Zitat:
Was läuft hier falsch?
Das sieht mir nach Datenmüll aus, vermutlich liest du mit readpixels nicht aus dem FBO. Jedenfalls solltest du volle 32bit zur Verfügung haben, bzw. 24bit wenn der Buffer kein Alpha hat. Du kannst erst dann mit readpixels lesen wenn du den FBO deaktiviert hast, also NULL als FBO gebunden hast. Liegt es vielleicht daran? Des weiteren erinnere ich mich dunkel daran das es unter WebGL bei readpixels Probleme gab, ich weiß aber nicht mehr welche => Google.
Was ich aber jetzt meint war ein Frustum-Culling auf Objektebene. D.h. für jedes größere Objekt wird vor dem rendern kurz getestet ob dessen BoundingBox den Sichtbereich berührt. Diese BoundingBoxen kann man dann wieder in größeren BoundingBoxen zusammenfassen, diese dann nochmal, und so weiter. Am Ende kann man durch den Test weniger BoundingBoxen zehntausende Dreiecke vom rendern ausschließen. Das ist eine Standard-Technik die eigentlich jeder beim normalen rendern benutzt. Sollte massenhaft Tutorials dazu geben. Stichworte wären z.B. QuadTree oder Octtree.
Was ich nun eigentlich sagen wollte: Diese Frustum-Culling kann man leicht so flexibel implementieren, dass du den selben Code auch beim Color-Picking benutzen kannst.
Alles klar, danke. Werde es mir bei Bedarf genauer anschauen.
Zitat:
Das sieht mir nach Datenmüll aus, vermutlich liest du mit readpixels nicht aus dem FBO. ... Du kannst erst dann mit readpixels lesen wenn du den FBO deaktiviert hast, also NULL als FBO gebunden hast. Liegt es vielleicht daran?
Auch wenn ich den FBO deaktiviere, bringt es keine Veränderungen mit sich. Der Effekt bleibt der selbe, die Werte bleiben auch dieselben:
Code:
gl.bindFramebuffer(gl.FRAMEBUFFER,null); //gl.bindFramebuffer(gl.FRAMEBUFFER,fbo); var pix = gl.readPixels(xclick, canvas.height-yclick, 1, 1, gl.RGB,gl.UNSIGNED_BYTE); if (!pix) { //wegen readPixels-Probleme; siehe http://asalga.wordpress.com/2010/07/14/compensating-for-webgl-readpix pix = new WebGLUnsignedByteArray(4); gl.readPixels(xclick,canvas.height-(yclick), 1, 1, gl.RGB, gl.UNSIGNED_BYTE, pix); }
Zitat:
Des weiteren erinnere ich mich dunkel daran das es unter WebGL bei readpixels Probleme gab, ich weiß aber nicht mehr welche => Google.
Ich denke, dass es ein Plattform- und Browserübergreifendes Problem gab/gibt. Sollte aber mit der if-Abfrage abgehandelt sein.
Zitat:
Jedenfalls solltest du volle 32bit zur Verfügung haben, bzw. 24bit wenn der Buffer kein Alpha hat.
Komischerweise habe ich sie zur Verfügung. Nur das Problem ist derzeit, dass man den Wertebereich [0.0 - 1.0] entsprechend anpassen muss. In den oberen Bereichen (nahe der 1.0), nimmt der entsprechende RGB-Wert sprunghaft zu/ab: z.B.: 0.996 -> 253 0.992 -> 251 0.988 -> 249 Nimmt aber nicht immer um 2 ab. In den unteren Bereichen kommt es wie gesagt zu kaum einer Veränderung der RGB-Zahl.
Bei 0.5 würde man ja 127 erwarten. Ich bekomme 64.
Du kannst erst dann mit readpixels lesen wenn du den FBO deaktiviert hast, also NULL als FBO gebunden hast.
Sorry, meine Aussage war Unsinn. Wenn du die Textur hinter dem FBO als normale Textur benutzen willst musst du einen anderen FBO binden. (bzw. den speziellen FBO "null".)
glReadPixels liest aber aus dem aktiven Framebuffer, nicht aus der Textur, daher muss dein FBO sogar gebunden sein. Trotzdem, das ganze reicht stark nach nicht initialisierten Werten. Machst du ein glClear vor dem rendern in den FBO? Ggf. ist der Z-Buffer nicht initialisiert. Auch den Colorbuffer solltest du auf eine konstante Farbe setzen.
... das ganze reicht stark nach nicht initialisierten Werten. Machst du ein glClear vor dem rendern in den FBO? Ggf. ist der Z-Buffer nicht initialisiert. Auch den Colorbuffer solltest du auf eine konstante Farbe setzen.
Einiges von dem hier aufgeführten hatte ich tatsächlich vergessen. Letztlich aber lag die falsche RGB-Umwandlung an einem ambienten Licht, das noch aktiviert war, als die Werte in den FBO geschrieben wurde. Danke nochmals für eure Hilfe, es funzt jetzt alles einigermaßen!
Zwei Dinge oder Fragen wären da noch: 1.Im DGL FBO Tutorial wird eine Textur erstellt und dem FBO hinzugefügt, um "Um Farbinformationen in das Framebufferobjekt schreiben zu können". Muss das immer so gemacht werden, damit man Farben in einem FBO schreiben kann? Warum denn eine Textur? Ich dachte die wären nur dazu da, um Objekten in Opengl eine Rastergrafik auf geeignete Weise zuzuweisen..
2. Das picking ist derzeit etwas unpräzise, da ich ein wenig neben dem Objekt klicken muss, um es getroffen zu haben. Je weiter ich rauszoome, desto größer der Fehler, was dazu führt, dass ich in einem noch größeren Abstand neben das Objekt klicken muss. Hat jemand eine Vermutung, woran es liegen könnte?
Mitglieder in diesem Forum: 0 Mitglieder und 13 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.