OpenGL Selection

üäpöol

Erfahrenes Mitglied
Hi,

ich versuche seit einigen Tagen herauszufinden, auf welches Objekt geklickt wurde und hab mit mehrere Tutorials angeschaut. Leider wird immer 0 zurück gegeben.
Weil ich nicht will, dass einfach mein Code repariert wird, zeige ich euch erstmal meine Funktion. Sagt mir bitte einfach nur, ob in dieser Funktion ein Fehler ist. Dann weiß ich, wo ich suchen soll. (Vlt. ist auch die ganze Funktion falsch ;))

C++:
int ObjektSelection() {
	GLuint SelectBuffer[512];
	GLint Viewport[4];
	int Hits = NULL, i;
	GLint HitZ = NULL;
	GLint Hit = NULL;

	glGetIntegerv(GL_VIEWPORT, Viewport);
	glSelectBuffer(512, SelectBuffer);
	glRenderMode(GL_SELECT);
	glInitNames();
	glPushName(0);
	glPushMatrix();
	glLoadIdentity();
	gluPickMatrix(MX, Viewport[3]-MY, 1.0, 1.0, Viewport);
	gluPerspective(45.0f, width/height, 0.1, 1000.0f);
	SceneZeichnen();
	glPopMatrix();
	Hits = glRenderMode(GL_RENDER);
	for (i=0; i<= Hits; i++)
	{
		if (SelectBuffer[(i*4)+1] < HitZ) {
			Hit = SelectBuffer[(i*4)+3];
			HitZ = SelectBuffer[(i*4)+1];
		}
	}
	return Hit;
}

Vielen Dank

üäpöol
 
Zuletzt bearbeitet von einem Moderator:
Ich glaube, meine Frage wurde nicht ganz richtig verstanden. Also nochmal: :D
Ich habe diese Funktion geschreiben, die zurückgeben soll, welches Objekt angeklickt wurde.
Im Moment ist Hits - egal, ob ich Namestack initialisieren also glInitNames(); glPushName(0); glLoadName(1); oder nicht, was ich überhaupt nicht verstehe - 1, aber Hit ist dennoch 0. Jetzt ist meine Frage, ob ihr einen Fehler in dieser Funktion seht, weil ich nur ungerne den ganzen Code poste.
Ich hoffe, jetzt ist mein Problem klarer und mir mkann geholfen werden. :)
Danke im Vorraus.

PS: Beim SceneZeichnen, zeichne ich einfach alle Objekte mit glBegin und mache Nebel, Licht, etc.
 
Ich verstehe nicht ganz wie du die Matrizen rechnest. Verwendest du RayCast/ConvexCast? Wenn ja musst du noch die Inverse Matrix von deinen Pickingkoordinaten nehmen. Wie stellst du dir denn vor herauszukriegen ob überhaupt ein Objekt angeklickt wurde. Das die Funktion immer 0 zurück gibt kann eigentlich nur an Hits = glRenderMode(GL_RENDER); liegen. Prüfe mal ob die Schleife ausgeführt wird.
 
Tut mir Leid, die Funktion funktioniert, ich war nur so blöd, dass ich glLoadName an einer Stelle falsch aufgerufen habe. Vielen Dank für die Bemühungen! Ich lasse das Thema noch mal einen Tag offen, für den Fall, dass ich noch eine Frage habe.
 
Dann kannst du es ja jederzeit wieder aufmachen
(wobei "Erledigt" sowieso nicht "Geschlossen" ist, also kein Schreibverbot deswegen.
Nur ein Hinweis, dass das Problem gelöst ist.)

Solange setz ich das Thema dann auf Erledigt.
 
OK, Danke.
Ich habe sogar noch eine Frage.
Ich kann jetzt zwar, ohne Probleme anzeigen, auf welches Objekt geklickt wurde, aber ich weiß noch nicht wie weit ich vom Objekt weg bin.
Weiß vielleicht jemand, wie man diese komischen Z-Werte (der "Himmel" hat z.B. immer den Wert -2304) in normale Einheiten umrechnet, hab leider im Internet dazu nichts finden können.
 
Wie meinst du das? Du bekommst ein Richtungsvektor. Du kannst einfach die Matrix des Objektes abfrage und die position auslesen. Dann einfach auch noch die Position von "dir" auslesen. Den rest kann man brechen wenn ich mich nicht irre so: |Objekt| - |Du| falls ich irre bitte verbessern ;)
EDIT:
|Objekt| - |Du| = X
|X| = Entfernung
 
Der Tiefenwert, den du im SelectBuffer hast wird und der zwischen 0 und 1 ist wird mit 2^32 - 1 multipliziert. Wenn du also den Tiefenwert und damit (mit gluUnproject) die genaue Koordinate haben willst musst du ihn einfach wieder durch 2^32 - 1 teilen.
 
@MSVCplusplus
Meine Position habe ich natürlich, aber ich verstehe nicht, wie ich die Position des angeklickten Objekts abfragen kann. Vielleicht liegt's daran, dass ich mich mit dem Thema nicht wirklich gut auskenne. :D

@Muepe32
Die Tiefenwerte, die im Selectionbuffer sind, sind negativ, werden je näher ich komme kleiner und sind meistens im achstelligen Bereich. Sie verhalten sich auch nicht proportional.

Meine Funktion ist inzwischen zwar leicht verändert, tut aber im Prinzip das selbe wie die oben (1. Beitrag).

Ich bedanke mich im Vorraus für weitere Hilfe. :)
 
Zurück