2014-11-05 7 views
7

Nach zwei Stunden googeln (here, here, here, here und here, und eine Tonne andere, die ich nicht zu finden bin gestört), dachte ich, Ich hatte endlich die Theorie gelernt, wie man 3D-Koordinaten in 2D-Koordinaten umwandelt. Aber es funktioniert nicht. Die Idee besteht darin, die 3D-Koordinaten eines Schiffes in 2D-Koordinaten auf dem Bildschirm zu übersetzen, um den Benutzernamen des Spielers, der dieses Schiff steuert, zu rendern.gluProject 3D-Konvertierung von Koordinaten in 2D nicht konvertieren Koordinaten Coordinate die 2D-Y richtig

Jedoch wird der Text in der falschen Stelle zu machen: enter image description here

Der Text ist "Test || || 2DXCoordinate 2DZCoordinate".

Hier ist meine getScreenCoords() - Die konvertiert die 3D-Koordinaten in 2D.

public static int[] getScreenCoords(double x, double y, double z) { 
    FloatBuffer screenCoords = BufferUtils.createFloatBuffer(4); 
    IntBuffer viewport = BufferUtils.createIntBuffer(16); 
    FloatBuffer modelView = BufferUtils.createFloatBuffer(16); 
    FloatBuffer projection = BufferUtils.createFloatBuffer(16); 
    GL11.glGetFloat(GL11.GL_MODELVIEW_MATRIX, modelView); 
    GL11.glGetFloat(GL11.GL_PROJECTION_MATRIX, projection); 
    GL11.glGetInteger(GL11.GL_VIEWPORT, viewport); 
    boolean result = GLU.gluProject((float) x, (float) y, (float) z, modelView, projection, viewport, screenCoords); 
    if (result) { 
     return new int[] { (int) screenCoords.get(0), (int) screenCoords.get(1) }; 
    } 
    return null; 
} 

screenCoords.get (0) gibt eine perfekte X-Koordinate zurück. ScreenCoords.get (1) wird jedoch höher oder niedriger, je nachdem, wie weit ich vom Schiff entfernt bin. Nach vielen Stunden Debugging, habe ich es verengt, um diese Zeile nicht mehr korrekt ist:

GLU.gluProject((float) x, (float) y, (float) z, modelView, projection, viewport, screenCoords); 

Aber ich habe keine Ahnung, was falsch ist. Die X-Koordinate des Schiffes ist in Ordnung .... Warum nicht das Y?

Laut BDL Antwort, ich liefern die "falsche Matrix" zu gluProject(). Aber ich sehe nicht, wie das möglich ist, da ich die Methode direkt nach dem Rendern meines Schiffes anrufe (was offensichtlich in welcher Matrix auch immer das Schiff zeichnet).

Ich kann einfach nicht ergründen, was falsch ist.

Hinweis: Die Antwort von BDL ist vollkommen ausreichend, außer dass nicht erklärt wird, warum die Y-Koordinaten falsch sind.

Hinweis: Diese Frage war früher viel länger und viel vager. Ich habe meine eingegrenzte Frage nach stundenlangem Debugging gepostet.

+0

1. setzen Sie Ihre GL_MODELVIEW-Matrix irgendwo in Ihrem Code? Für mich sieht es so aus, als wäre es eine Identitätsmatrix. 2. Enthält orthographicProjectionMatrix die perspektivische Projektion, die Sie verwenden, um Ihr Schiff zu rendern? – BDL

+0

@BDL orthographicProjectionMatrix enthält die Projektion, die ich verwende, um den Text zu rendern. Nicht das Schiff. – Joehot200

+0

Im zweiten von Ihnen geposteten Codeblock laden Sie orthographicProjectionMatrix in Ihre Projektionsmatrix. Was ist der Inhalt dieser Matrix? Und für mich sieht es so aus, als ob Sie die Modelview-Matrix nie einstellen würden. Nimmst du nie glTranslatef/glRotatef beim Zeichnen des Schiffes? – BDL

Antwort

5

Sie müssen die gleiche Projektionsmatrix in gluProject verwenden, die Sie für das Rendern Ihres Schiffes verwenden. In Ihrem Fall wird das Schiff mit einer perspektivischen Projektion gerendert, aber beim Aufruf von gluProject wird eine orthographische Projektion verwendet.

Allgemeine Theorie über Koordinatensysteme in OpenGL

In den meisten Fällen Geometrie eines Modells in der Szene (zum Beispiel das Schiff) in einem Modell-Koordinatensystem gegeben ist. Dies ist der Bereich, in dem Ihre Eckpunktkoordinaten vorhanden sind. Wenn Sie nun das Modell in Ihre Szene einfügen, wenden wir die Modellmatrix auf jeden Eckpunkt an, um die Koordinaten zu erhalten, die das Schiff in der Szene hat. Dieses Koordinatensystem heißt world space. Beim Betrachten der Szene von einem gegebenen Blickpunkt und einer Betrachtungsrichtung wird wiederum eine Transformation benötigt, die die Szene so transformiert, dass der Blickpunkt im Ursprung (0,0,0) und die Blickrichtung entlang der negativen z-Achse liegt. Dies ist das Ansichtskoordinatensystem. Der letzte Schritt besteht darin, die Ansichtskoordinaten in ndc zu transformieren, was über eine Projektionsmatrix erfolgt.

Insgesamt erhalten wir die Transformation von einer Ecke zum Bildschirm:

v_screen = Projection * View * Model * v_model 

Im alten OpenGL (wie Sie es verwenden) Ansicht und Modell werden zusammen in der Modelview-Matrix gespeichert.

(ich hier einige Probleme als Perspektive Kluft übersprungen, aber es sollte das Problem sein. Ausreichend zu verstehen)

Ihr Problem

Sie haben bereits eine Position im Welt-Raum (x, y, z) von deinem Schiff. So ist die Transformation mit Model bereits passiert. Was bleibt, ist

v_screen = Projection * View * v_worldspace 

Hierfür sehen wir, dass in unserem Fall die Modelview-Matrix, die zu gluProject eingegeben wird genau die Ansicht Matrix sein.

Ich kann Ihnen nicht sagen, wo Sie die Ansichtsmatrix in Ihrem Code erhalten, da ich diesen Teil Ihres Codes nicht kenne.

+0

Ich habe das OP mit dem neuen Code aktualisiert. Es hat es definitiv besser gemacht, vielen Dank für Ihren Vorschlag, aber aus irgendeinem Grund ist der Code immer noch nicht perfekt und funktioniert nicht. – Joehot200

+0

Wahrscheinlich, weil Sie das gleiche Problem mit der MODELVIEW-Matrix haben. Wenn sich (x, y, z) in Weltkoordinaten befinden, sollte Ihre MODELVIEW-Matrix nur die Ansichtsmatrix, aber nicht die Modellmatrix enthalten. – BDL

+0

Was? Ich verstehe das nicht, Entschuldigung. Ich setze die 2D-Koordinaten auf die exakte Linie, nachdem das Schiff gerendert wurde. Ist das nicht korrekt? Und wie mache ich nicht die Modellmatrix, sondern nur die Ansichtsmatrix? – Joehot200

0

Ich habe eine Antwort auf mein Problem gefunden!

benutzte ich

font.drawString(drawx - offset, drawy, (sh.username + " || " + drawx + " | " + drawy), Color.orange); 

Wenn es

gewesen sein sollte
font.drawString(drawx - offset, Display.getHeight() - drawy, (sh.username + " || " + drawx + " | " + drawy), Color.orange); 
Verwandte Themen