openGL - Selection (Maus)

Cromon

Erfahrenes Mitglied
Hallo meine lieben Tutorials.de - Mitglieder!

Wer hätte es gedacht, ich stecke mal wieder bei einem Problem mit openGL fest (ich mach jetzt dann glaub einen Sammelthread...). ;)

Es geht diesmal darum wie ich herausfinde, an welcher Position in der 3D-Welt der Spieler mit der Maus gedrückt hat. Ich habe dazu schon einige Mittel online gelesen und auch versucht, aber bis jetzt noch keines erfolgreich anwenden können.

Was ich versucht habe:
Mit der Variante von OpenGL und SELECTION-Rendermode. Allerdings stelle ich es mir irgendwie etwas übel vor jede Szene immer zweimal zu rendern.

- Mit gluUnproject mal die Koordinaten entsprechend umzuwandeln.
Code:
GLdouble modelMatrix[16];
	glGetDoublev(GL_MODELVIEW_MATRIX, modelMatrix);
	GLdouble projMatrix[16];
	glGetDoublev(GL_PROJECTION_MATRIX, projMatrix);
	int viewport[4];
	glGetIntegerv(GL_VIEWPORT, viewport);
	double position[3] = { 0 };
	gluUnProject(x, y, 0.0f, modelMatrix, projMatrix, viewport, &position[0], &position[1], &position[2]);
	printf("Position: %f %f %f\n", position[0], position[1], position[2]);

Die Ausgabe sieht jedoch folgendermassen aus:
Position: x y 1

Wobei x und y die Druckkoordinaten sind im 2-D Bereich.

Welche Möglichkeiten habe ich nun performant zu berechnen, an welchen ungefähren Koordinaten der Mausklick stattgefunden hat?

Mit besten Grüssen
Cromon
 
Ich habe das mal versucht folgendermassen umzusetzen:
Code:
float info = 0;
glReadPixels(x, y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &info);
printf("Info: %f\n", info);

Als Ausgabe erhalte ich dann exemplarisch:
Code:
Info: 0.998449
Info: 0.999101
Info: 1.000000
Info: 1.000000
Info: 0.998571
Info: 0.998268
Info: 0.997840
Info: 0.997457
Info: 0.997060
Info: 0.997560
Info: 0.997998
Info: 0.998110
Info: 0.998350
Info: 0.998540
Info: 1.000000
Info: 1.000000
Info: 1.000000
Info: 1.000000
Info: 1.000000
Info: 1.000000
Info: 1.000000

Da hab ich wohl was falsch verstanden, oder? (Nachgelesen unter: http://wiki.delphigl.com/index.php/glReadPixels)
 
Zuletzt bearbeitet:
Ok, das war ein Denkfehler, habe vergessen die y-Koordinate umzudrehen. Jetzt machen die Werte natürlich auch Sinn, da der Hintergrund im Schwarzen leeren Raum 1.0 ergibt und das andere entsprechend der Nähe des Terrains!

gluUnProject liefert jedoch noch immer nichts anderes zurück als die als Anfangsparameter eingegebenen Koordinaten.

Hier ein Beispiel:
http://imagr.eu/upload/0742044001251716080_click.JPG

Ich habe auf die braune Fläche im roten Kreis gedrückt. Die Koordinaten unten sind Kamerposition und Kameraziel.

In der Konsole wird ausgegeben:
Position: 504.000011 529.999987 -0.998476

Verwendeter Code:
Code:
GLdouble modelMatrix[16];
	glGetDoublev(GL_MODELVIEW_MATRIX, modelMatrix);
	GLdouble projMatrix[16];
	glGetDoublev(GL_PROJECTION_MATRIX, projMatrix);
	int viewport[4];
	glGetIntegerv(GL_VIEWPORT, viewport);
	float info = 0;
	double position[3] = { 0 };
	glReadPixels(x, 600 - y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &info);
	gluUnProject(x, 600 - y, info, modelMatrix, projMatrix, viewport, &position[0], &position[1], &position[2]);
	printf("Position: %f %f %f\n", position[0], position[1], position[2]);
 
Zuletzt bearbeitet:
Schau mal (z.B. mit dem Debugger), ob die Matrizen auch stimmen. Wenn immer nur die eingegebenen Werte wieder unverändert rauskommen, wäre das ein Indiz dafür, dass das einfach nur Einheitsmatrizen sind. Außerdem könntest du den Rückgabewert von gluUnProject überprüfen.

Grüße, Matthias
 
Hallo Matthias,

Auf den ersten Blick ist mir eigentlich alles bei Matrizen und Rückgabewert als korrekt erschienen. Als ich dann allerdings lange darüber gebrütet habe ist mir in den Sinn gekommen, dass ich ja nach den Modellen noch das Userinterface rendere und da natürlich wieder eine 2-dimensionale Umgebung schaffe. Daher sind auch die x- und y-Koordinaten so herausgekommen, wie ich sie eingegeben habe.

Ich speichere die entsprechenden Werte (Projektion, Modellmatrix und Viewport) jetzt einfach bei jedem Rendervorgang, wenn sich etwas geändert haben sollte neu ab und verwende dann diese.

Damit klappt es jetzt für die Koordinaten einwandfrei!

Danke für den Hinweis, du bist mir wirklich eine wahnsinnig grosse Hilfe!

Gruss und nochmals Dank
Cromon
 
Ich speichere die entsprechenden Werte (Projektion, Modellmatrix und Viewport) jetzt einfach bei jedem Rendervorgang, wenn sich etwas geändert haben sollte neu ab und verwende dann diese.
Dazu könntest du auch den Matrizen-Stack von OpenGL verwenden (glPushMatrix und glPopMatrix).

Danke für den Hinweis, du bist mir wirklich eine wahnsinnig grosse Hilfe!
Das freut mich :)

Grüße, Matthias
 
Zurück