2d Szene - Bildschirm- zu Weltkoordinaten?


#21

Moin,

wenn ein OpenGL Kontext erzeugt wird, wird die Viewport Transformation initial auf die Fenstergröße gesetzt. Der äquivalente Aufruf wäre: glViewport(0, 0, width, height).

Ansonsten, noch mal aus dem Link von Marco:
OpenGL Transformation

Viele Grüße
Fancy


#22

moment…

Für VertexData, ModelViewMatrix und ProjectionMatrix sorgt man ja selber.
Ogl macht dann alleine den ViewportTransform oder wie?

Aber das hilft mir irgendwie nicht weiter. An welchem Punkt (welche werte brauche ich jetzt) um die mit den screen koordinaten zu vergleichen?

*** Edit ***

Moment mal. Oder soll ich glViewport dazu benutzen um die punkte für mich auf der cpu umzurechnen, um
die dann mit den screen coords zu vergleichen? Aber wie genau soll das gehen? (ne void methode hilft irgendwie wenig)


#23

So ist es wohl.

[QUOTE=mymaksimus;95452]
Aber das hilft mir irgendwie nicht weiter. An welchem Punkt (welche werte brauche ich jetzt) um die mit den screen koordinaten zu vergleichen?

Moment mal. Oder soll ich glViewport dazu benutzen um die punkte für mich auf der cpu umzurechnen, um
die dann mit den screen coords zu vergleichen?[/QUOTE]

Diese Umrechnung wirst du CPU-Seitig selbst machen müssen, aus den Informationen, die du woanders ja auch an glViewport übergibst.


#24

aber… häää?

Marco, aus meinen ursprünglichen antworten weißt du doch was ich für informationen hab.
Wie genau konkret soll ich jetzt vorgehen um weiterzumachen?


#25

Hmja, sorry, das ist viel Text und einige Matrizen, an denen man erstmal wenig bis gar nichts sieht (und “das Thema 3D und Viewing” zieht sich ja jetzt schon durch einige Threads … ). Und wie schon weiter oben erwähnt ist (mir) trotzdem nicht mal ganz klar, was du willst. (Welt zu Sceen? Das macht OpenGL, siehe Bild in Fancys Beitrag. Screen zu Welt? Das geht erstmal nicht. weil ein Punkt auf dem Bildschirm einen Strahl definiert…). Ich werde dir NICHT empfehlen, irgendeine EXE von irgendeiner Seite einfach so zu starten, aber … die Screenshots von http://www.songho.ca/opengl/gl_transform.html sehen aus, als ob diese Programme hilfreich sein könnten (ggf. kann man sie ja selbst compilieren…)


#26

Ja es ist ein Strahl - wenn es 3d ist. Bei 2d wird es doch möglich sein anhand eines BILDSCHIRMPUNKTS den
WELTPUNKT herauszufinden … oder nicht? irgendwie geht es ja auf jedenfall…
Ich versuch nachher mal noch einmal ganz konkret zusammenzufassen was ich hab und was ich will…


#27

Eben nicht. Aus einem 2D-Punkt kann man keinen 3D-Punkt machen. Es werden ja unendlich viele 3D-Punkte auf denselben 2D-Punkt abgebildet. Nämlich alle, die auf dem Strahl liegen. Aber vielleicht klärt sich das ja dann noch.


#28

Marco… Ich will doch überhaupt keinen 3d punkt haben! xD Das mit dem Strahl ist mir ja klar, aber es geht hier doch überhaupt nicht um 3d! xD


#29

Oder doch anders. Ich bin irgendwo auf die Methode GLU.gluUnproject(…) gestoßen. Die sieht so aus:

343		float winx,
344		float winy,
345		float winz,
346		FloatBuffer modelMatrix,
347		FloatBuffer projMatrix,
348		IntBuffer viewport,
349		FloatBuffer obj_pos) {
350		float[] in = Project.in;
351		float[] out = Project.out;
352
353		__gluMultMatricesf(modelMatrix, projMatrix, finalMatrix);
354
355		if (!__gluInvertMatrixf(finalMatrix, finalMatrix))
356			return false;
357
358		in[0] = winx;
359		in[1] = winy;
360		in[2] = winz;
361		in[3] = 1.0f;
362
363		// Map x and y from window coordinates
364		in[0] = (in[0] - viewport.get(viewport.position() + 0)) / viewport.get(viewport.position() + 2);
365		in[1] = (in[1] - viewport.get(viewport.position() + 1)) / viewport.get(viewport.position() + 3);
366
367		// Map to range -1 to 1
368		in[0] = in[0] * 2 - 1;
369		in[1] = in[1] * 2 - 1;
370		in[2] = in[2] * 2 - 1;
371
372		__gluMultMatrixVecf(finalMatrix, in, out);
373
374		if (out[3] == 0.0)
375			return false;
376
377		out[3] = 1.0f / out[3];
378
379		obj_pos.put(obj_pos.position() + 0, out[0] * out[3]);
380		obj_pos.put(obj_pos.position() + 1, out[1] * out[3]);
381		obj_pos.put(obj_pos.position() + 2, out[2] * out[3]);
382
383		return true;
384	}```

*** Edit ***

Das dürfte doch sein, was ich suche, oder?
Allerdings verstehe ich ein paar Parameter nicht: 

was ist viewport?

und modelmatrix - welche ist hier gemeint? quasi die kamera model matrix oder wie?

und was soll winz sein, ich dachte ein win sei 2dimensional..? xD

#30

Ja, das ist hat mit dem zu tun, was du (vermutlich ;)) vorhast. Das “winz” ist die z-Koordinate eines Punktes in Fensterkoordinaten. Normalerweise übergibt man dort einmal 0 und einmal 1, und hat dann zwei Punkte, mit denen man den Strahl definieren kann. Dort, wo jetzt “modelMatrix” steht, würde ich eigentlich die Camera- oder View-Matrix erwarten (nochmal: Das sind die Inversen voneinander). Vermutlich ist nur die Variable ungünstig benannt. Und … der viewport… zynisch na rate mal was DAS wohl sein kön… zynismus unterdrück :wink: Das ist der Viewport. Also praktisch die Fenstergröße. Bzw. das, was bei glViewport übergeben wurde…


#31

ah stimmt, 2 punkte gleich = 1 gerade ^^ (strahl, whatever)

viewport… bei glViewport übergebe ich x y width height. was ist denn bitte x y vom viewport?

Ich glaub ich experementier nachher etwas mit dieser methode rum, und bau die dann
für meine bedürfnisse ein… wenn das denn klappt…


#32

Das x und y ist bestenfalls theoretisch interessant (wenn man irgendwelche abgefahrenen Sachen mit ““unter-Fenstern”” (im Sinne von “Renderbereichen”) machen will. Nimm x,y einfach als 0,0 an (auch wenn’s natürlich “besser” ist, das in der Methode nicht zu tun, sondern mit x und y zu rechnen, egal ob sie 0 sind oder nicht)


#33

Hm. Irgendetwas stimmt da jedenfalls immer noch nicht.
Folgender Code:

viewport.put(0);
viewport.put(0);
viewport.put(Display.getWidth());
viewport.put(Display.getHeight());
viewport.flip();

float mousex = Mouse.getX();
float mousey = Mouse.getY();
float mousez = 0;

FloatBuffer inverseModel = BufferUtils.createFloatBuffer(16);
cam.getInverseCameraModel().store(inverseModel);
inverseModel.flip();

FloatBuffer inverseProjection = BufferUtils.createFloatBuffer(16);
cam.getInverseProjection().store(inverseProjection);
inverseProjection.flip();

FloatBuffer result = BufferUtils.createFloatBuffer(3);
GLU.gluUnProject(mousex, mousey, mousez, inverseModel, inverseProjection, viewport, result);

String labels[] = new String[]{"x", "y", "z"};
for(int i = 0; i < result.capacity(); i++){
	System.out.print(labels** + ": " + result.get(i) + ", ");
}```

Die Maus dann in die obere rechte Ecke verschoben, folgende ausgabe: `x: 0.6277513, y: 0.8335056, z: 0.0020001996`  
So. Theoretisch hätte ich jetzt quasi die left top right bottom werte erwartet. Die waren ja: `right: 1.5890049, left: -1.5890049, top: 1.1917536, bottom: -1.1917536`


was könnte da jetzt kaputt sein?..

#34

Hat @Fancy vielleicht eine Idee? :stuck_out_tongue:


#35

Poste nochmal die beiden Matrizen und ihre Inversen. Ich frag’ mich gerade wo die 0.002000 herkommt…


#36

Ich glaube ich hatte zwischenzeitlich mal ein paar werte geändert, bezüglich fov und so weiter, deshalb hier nochmal eine komplett beispiel datensammlung:

Camera Clip Werte: right: 0.5522848, left: -0.5522848, top: 0.41421357, bottom: -0.41421357

projection:

1.8106601 0.0 0.0 0.0
0.0 2.4142134 0.0 0.0
0.0 0.0 -0.0020001999 0.0
-0.0 -0.0 0.0 1.0

projection (inverse):

0.5522848 0.0 -0.0 0.0
0.0 0.4142136 0.0 -0.0
-0.0 0.0 -499.95 0.0
0.0 -0.0 0.0 1.0

camera und camera (inverse) eh nur ne einheitsmatrix, also:

1.0 0.0 0.0 0.0
0.0 1.0 0.0 0.0
0.0 0.0 1.0 0.0
0.0 0.0 0.0 1.0

und

1.0 -0.0 0.0 -0.0
-0.0 1.0 -0.0 0.0
0.0 -0.0 1.0 -0.0
-0.0 0.0 -0.0 1.0

viewport: IntBuffer(0, 0, 800, 600);

ausgabe nach glUnProject: x: 1.8016068, y: 2.3981187, z: 0.0020001999,

Übrigens: in glUnProject werden die matrizen doch nochmal invertiert, oder nicht? (siehe Zeile 355)
Aber bei den originalmatrizen, kommen noch seltsamere wahnsinns werte raus…

Die 0.002000… kommt offensichtlich von der original projektions matrix…


#37

Schnapp dir doch einfach ein Blatt Papier und rechne das an einem Beispiel durch, da steckt doch eigentlich nichts hinter.

(Stimmt so natürlich nur für die orthogonale Projektion, sonst muss noch die perspektivische Division beachtet werden. Und das FOV bei orthogonaler Projektion keinen Sinn macht, hat Marco schon erwähnt.)

Viele Grüße
Fancy


#38

was ist denn jetzt bitte die “viewport matrix” ? ._.
was ist Peye?
Und P world coordinates, sollte doch im (-1, 1) bereich sein…

und… und…

warum klappt dann die methode von lwjgl nicht?

ja fov macht nicht wirkich viel sinn. ich benutze es aber quasi als “scale” variable… denn je größer fov desto größer
werden ja left, right, top bottom… ist ja auch egal…


#39

World Space wäre das Koordinatensystem zwischen Model- und View- Matrix. Eye Space das nach der Modelview Matrix. Das Bild oben und der verlinkte Text veranschaulichen das.

Mit ein bisschen Phantasie hätte man drauf kommen können, dass mit P_eye ein Punkt im Eye Space und mit P_wc ein Punkt in Window Coordinates gemeint sein könnte.

M_viewport gehört zur Viewport Transformation. Damit werden die Normalized Device Coordinates auf die Window Coordinates abgebildet. Erklärt wird das auch in dem Link oben. Wie sich die Matrix zusammensetzt, wird z.B. hier ausführlich gezeigt.

Viele Grüße
Fancy


#40

Hm. Danke Fancy.
Ich hab das ja eigentlich verstanden.

Aber weißt du was jetzt mein letztes Problem ist?

Die Glu methode dazu. Wieso geht die nicht, und macht da offensichtlich was ganz anderes als… du?