Problem mit glReadPixels()
-
Hallo
Ich hab ein Problem mit oben genannter Funktion. Und zwar möchte ich beim klicken auf ein OpenGL-Fenster die Bildschirmkoordinaten in Koordinaten meines Objektraumes umwandeln. Ich nutze dazu die glReadPixels() wie folgt:
Zuerst die Übergabe der Koordinaten an die Umwandlungsfunktion:
void COpenGLControl::OnLButtonDown(UINT nFlags, CPoint point) { // get the point in world coordinates sVertex world_point = WinPosTo3DPos( point.x, point.y ); CWnd::OnLButtonDown(nFlags, point); }Und dann die eigentliche Funktion:
sVertex COpenGLControl::WinPosTo3DPos(float winX, float winY) { GLint viewport[4]; GLdouble modelMatrix[16]; GLdouble projMatrix[16]; GLdouble objX; GLdouble objY; GLdouble objZ; GLdouble winZ; glGetDoublev(GL_MODELVIEW_MATRIX, modelMatrix ); glGetDoublev(GL_PROJECTION_MATRIX, projMatrix ); glGetIntegerv(GL_VIEWPORT, viewport ); float winY_new = viewport[3] - winY; // In OpenGL steigt Y von unten (0) nach oben // Auslesen des Tiefenpuffers an der Position (X/Y_new) glReadPixels(winX, winY_new, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &winZ ); // Errechnen des Punktes welcher mit den beiden Matrizen multipliziert (X/Y_new/Z) ergibt: gluUnProject( (GLdouble)winX, (GLdouble)winY_new, winZ, modelMatrix, projMatrix, viewport, &objX, &objY, &objZ); sVertex point; point.pos.x = (float)objX; point.pos.y = (float)objY; point.pos.z = (float)objZ; return point; }Bei dieser Konfiguration von glReadPixels() kommt bei winZ ein völlig kryptischer Wert raus. Was muss ich machen, um den korrekten Wert zu erhalten? Ist es überhaupt möglich (Umwandlung von 2D in 3D müßte ja eigentlich eine Gerade ergeben...)
MfG
Neron
-
Ok, hab noch weiter dran gearbeitet und einiges mehr festgestellt.
Erstmal scheint es nicht an der Funktion glReadPixels() zu liegen, denn auch wenn ich für winZ konkrete Werte für gluUnProject() einsetze, kommt immer noch ziemlicher Murks raus.
Das Problem ist: Es scheint völlig egal, welche Werte für winX und winY eingehen. Also egal wo ich in meinem Fenster hinklicke, es kommt immer wieder derselbe Wert raus (winX und winY werden korrekt ermittelt). Ich bewege meine Kamera nämlich bei der Initialisierung um 100 Einheiten in negativer z-Richtung, der ermittelte Punkt ist dann (0, 0, 100). Ich habe ein paar Funktionen, um die Kameraposition weiter zu verändern. Wann immer ich das tue, ändert sich auch die Ausgabe der gluUnProject(). Der ermittelte Punkt stimmt stets mit dem Viewpoint überein. Woran kann das liegen? Wird vielleicht eine Matrix falsch ermittelt, oder der Viewport?
-
Hm, niemand der Ahnung hat?
Ich hab nu schon hunderte Beiträge gelesen und bin mir eigentlich sicher, dass ich die Funktionen richtig konfiguriert habe. Allerdings habe ich gelesene, das jemand Probleme hatte, weil er die Funktion außerhalb der Display Methode verwendet hat. Kann es daran liegen?
Bitte helft mir, ich weiß nicht weiter aber benötige diese Funktion wirklich dringend

-
Du scheinst da irgendwo einen Fehler zu haben. f'`8k
Bye, TGGC (\-/ returns)
-
Hm....soweit war ich auch schon.
Gedankenblitz: Kann es daran liegen, dass ich die Kamera bewege und nicht das Objekt? Aber dürfte ja eigentlich nicht sein oder?
-
Es scheint, als hätte ich's hinbekommen. Und zwar wird der Punkt korrekt berechnet, wenn ich statt
gluUnProject( (GLdouble)winX, (GLdouble)winY_new, (GLdouble)winZ, modelMatrix, projMatrix, viewport, &objX, &objY, &objZ);die Konfiguration
gluUnProject( (GLdouble)winX, (GLdouble)winY_new, 1, modelMatrix, projMatrix, viewport, &objX, &objY, &objZ);verwende. Ich raff's zwar nich ganz, aber die Gerade wird nun korrekt gezeichnet, allerdings bis ans Ende meines Ansichtsvolumens
-
Wie heißt es so schön? Back to the roots... Ich bin wieder bei meinem ursprünglichen Problem, nämlich der glReadPixels(). Es hat ein wenig gedauert, bis ich genau gerafft hab, wie die ganze Sache mit gluUnProject() funktioniert. Wenn ich also für winZ den Wert 1 übergebe spuckt er mir halt den Wert der zFar-Plane raus, hatte ich ja auch geschrieben.
Nu möchte ich aber nicht den z-Wert der zFar-Plane, sondern den z-Wert meines Objekts haben. Allerdings spuckt die Funktion glReadPixels() mir immer genau den Wert für winZ aus, den ich hineingebe. Also ein undefinierter Wert ergibt wieder einen undefinierten, 1 bleibt 1 usw... Und das für sämtliche x-y-Kombinationen. Woran kann das liegen? Kann es sein, dass nichts in den z-Buffer geschrieben wird? Das geht doch nicht oder?
Es wäre wirklich hilfreich, wenn sich mal jemand der etwas Ahnung hat, ein paar Gedanken machen könnte.
-
Hi !
Also ich hab zwar keine Ahnung warum dass mit glReadPixels nicht funktioniert, kann aber eventuell eine Alternative bieten:Mit dem Selectionbuffer kannst deine gezeichneten Objekte benennen, und bei Mausklick herausfinden welches Objekt ausgewählt wurde...
Über diesen Umweg kannst du dann sicherlich die z-Koordinate bestimmen, wenn du diese weiterhin benötigst.
-
Das Problem ist, ich habe nur 1 Objekt - nach deinem Vorschlag müßte ich dann wohl die 64000 Dreiecke des Objekts numerieren und auswählen, was aber n bissel heftig ist.
Muss ich glReadPixels() vielleicht vorher konfigurieren? Ich hab gelesen, dass es da einige Funktionen vorweg gibt, aber Beispiele zum Auslesen des z-Buffers hab ich stets ohne Vorkonfiguration gefunden.
-
Vllt. sowas?

glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LEQUAL);
-
Mach ich natürlich längst

-
Die Werte im z-Buffer sind immmer zwischen 0.0f und 1.0f. Und natürlich undefiniert falls dort nichts in den z-Buffer eingetragen wurde. Kommen wenigstens einigermassen sinnvolle werte (zwischen 0 und 1) für deine Objekte heraus? Dann könntest du mit gluUnproject diese Werte umrechnen.
Mit glDepthRange(near,far) kann man übrigens den oben genannten Intervall ändern
Hoffe das hilft !
-
megaweber schrieb:
Die Werte im z-Buffer sind immmer zwischen 0.0f und 1.0f.
Jo, das is mir soweit klar.
megaweber schrieb:
Und natürlich undefiniert falls dort nichts in den z-Buffer eingetragen wurde. Kommen wenigstens einigermassen sinnvolle werte (zwischen 0 und 1) für deine Objekte heraus?
Da liegt ja mein Problem - die Werte sind völlig unbrauchbar. Ich nutze ja wie beschrieben
glReadPixels(winX, winY_new, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &winZ );Aber winZ wird hierbei nicht verändert. Wenn ich
glReadPixels(winX, winY_new, 2, 2, GL_DEPTH_COMPONENT, GL_FLOAT, &winZ );einsetze, kommen wenigstens berechnete Werte raus, aber dieliegen zwischen 0.006 und 0.008 - also völlig sinlos.
megaweber schrieb:
Dann könntest du mit gluUnproject diese Werte umrechnen.
Scroll mal hoch im Beitrag, das is ja mein Ziel

megaweber schrieb:
Mit glDepthRange(near,far) kann man übrigens den oben genannten Intervall ändern
Auch das weiß ich, aber ich hab gelesen, dass wenn ich die Finger davon lass, standardmäßig Werte zwischen 0.0 und 1.0 rauskommen, wie du schon gesagt hast. So möcht ich's ja auch haben

Ich bin halt völlig ratlos, hab schon viele Leute gefragt und mehrere Foren konsultiert. Ich hab sämtliche Tiefenfunktionen, die benötigt werden aktiviert und auch sonstige Ratschläge beherzigt, aber ich komm einfach nicht auf vernünftige Werte

-
Warum sind deine ersten beiden Argumente von glReadPixel vom typ float?
Hab grad mal nachgeschaut und dein winx und winy sollten viewport koordinaten sein und somit vom typ int...
ansonsten weiss ich auch nich weiter ...
-
Wenn man nicht mehr weiter weiß, probiert man natürlich alles

Aber wie du dir sicher selbst gedacht hast, hat das wenig Einluß und durch den (Gldouble) cast ja noch viel weniger. Es kommt nach wie vor der gleiche Murks raus.Mir wurde gesagt
Kann sein, dass es an der OpenGL Bibliothek liegt (unter Windows also der Grafikkarten-Treiber)
Kann das möglich sein?