-
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
)
Code cpp:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
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öolGeändert von üäpöol (22.12.11 um 12:46 Uhr) Grund: CPP statt CODE-Tag :D && Rechtschreibung
-
Kommt halt ganz draufan, was du bei SceneZeichnen machst, da hast du ja auch noch pickingrelevante Dinge.
Viele Tutorials und Artikel zur Programmierung unter Windows mit C++ und C#. Tägliche Updates und Antworten auf eure Fragen:
Win32Easy - Blog
Es würde mich freuen, wenn ihr einen Kommentar postet!
-
Ich glaube, meine Frage wurde nicht ganz richtig verstanden. Also nochmal:

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.
-
24.12.11 13:20 #4
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.
Fehlermeldung bitte!
Google - Dein Freund und Helfer
-
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.Netiquette (vA §15) und Nutzungsregeln (vA §4.8) einhalten! Programmcode in Codetags/Codeboxen.
Sehr gute Beiträge bitte Bewerten (Stern darunter oder "Danke").
"Funktioniert nicht" ist zu ungenau! Code, Fehlermeldungen, Verhalten des Programms, ...?
-
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.
-
24.12.11 22:27 #8
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| = EntfernungFehlermeldung bitte!
Google - Dein Freund und Helfer
-
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.
Viele Tutorials und Artikel zur Programmierung unter Windows mit C++ und C#. Tägliche Updates und Antworten auf eure Fragen:
Win32Easy - Blog
Es würde mich freuen, wenn ihr einen Kommentar postet!
-
@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.
@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.
-
25.12.11 12:18 #11
Jetzt fange ich an mir nicht mehr sicher zu sein. Ich bin nämlich eher in DirectX tätig
Ich persönlich speichere immer die Position von einzelnen Objekten in Vektoren und setze dann vor dem Rendern die Translationsmatrix als Weltmatrix. Außerdem speicher ich immer eine ID oder ein String zur Beschreibung des Objektes. Anderst kann ich zumindest mir nicht vorstellen wie man das abfragen soll wo das Objekt liegt. Also wenn du die ID hast oder gleich ein Vektor im Objekt gespeichert hast, kannst du den/die auslesen und dann hast du die Position
Jetzt empfehle ich auch ein eigenen Modellverwalter zu schreiben, um solche Infos zu speichern. Also was mir noch einfallen würde, das du mir OpenGL irgendwie User Daten in Objekte speichern kannst. Aber so direkt kenn ich nichts, wie man aus dem angeklickten Objekt eine Position rauskriegt. Aber ich glaube du fragst auch so was wie eine ID in deine Picking Funktion ab, oder? Also ich würde dir empfelen für jedes Objekt die Position zu speichern. Wenn jemand eine bessere Methode hat, bitte schreiben. und falls ich jetzt Müll erzählt habe muss ich mich entschuldigen
Aber so mach ich das nur halt mit einer PhysikEngine
Fehlermeldung bitte!
Google - Dein Freund und Helfer
-
Also, so weitn ich weiß, wird dem Objekt ein Name zugewiesen, der dann später genauso wie Z-Werte im Buffer gespeichert werden. Ich gehe von diesem Tutorial (ist zwar in Delphi geschrieben, aber das macht ja nicht) http://wiki.delphigl.com/index.php/Tutorial_Selection. was jetzt alles funktioniert. Ich kann den Namen und Z-Werte auslesen. Diese Z-Werte sortiere ich dann und nimm den kleinsten (nahstes Objekt) Wert. Allerdings sind diese Z-Wetre unpropoortional (z.B. 10 Einheiten = -42526442 & 4 = -106957512). Jetzt kann ich zwar ungefähr sagen, wie weit das Objekt weg ist, aber eben nicht genau. Die zweite Frage stell ich eher aus Interesse.
Geändert von üäpöol (25.12.11 um 14:24 Uhr) Grund: "-" vergessen
-
Passt ja eigentlich soweit ganz gut was du da als Werte angibst.
Punkt 1:
Die Werte sind immer positiv.
Punkt 2:
Teile ich die Werte durch UINT_MAX kommen ganz vernünftige Sachen raus:
Code cpp:1 2 3 4 5 6 7
int i1 = -42526442; int i2 = -106957512; unsigned int a1 = *(unsigned int*)&i1; unsigned int a2 = *(unsigned int*)&i2; float d1 = a1 / (float)UINT_MAX; // -> 0.99f; float d2 = a2 / (float)UINT_MAX; // -> 0.97f;
Objekt 2 ist also näher als Objekt 1.Viele Tutorials und Artikel zur Programmierung unter Windows mit C++ und C#. Tägliche Updates und Antworten auf eure Fragen:
Win32Easy - Blog
Es würde mich freuen, wenn ihr einen Kommentar postet!
-
Wow, das ist ja schon mal gar nicht so schlecht.

Wie kann ich denn dann diese Werte in Koordinaten umwandeln?
-
Du kannst da zum Beispiel die Funktion gluUnProject verwenden. Als winZ-Wert kannst du dann den ermittelten Tiefenwert (0.97... z.B.) eingeben und winX und winY sind die x- bzw. y-Koordinate des Treffers im 2D-Bereich. Das rechnet dann in Weltkoordinaten um.
http://www.opengl.org/sdk/docs/man/x...uUnProject.xmlViele Tutorials und Artikel zur Programmierung unter Windows mit C++ und C#. Tägliche Updates und Antworten auf eure Fragen:
Win32Easy - Blog
Es würde mich freuen, wenn ihr einen Kommentar postet!
Ähnliche Themen
-
Row Selection
Von M-P im Forum Javascript & AjaxAntworten: 4Letzter Beitrag: 25.10.09, 13:23 -
openGL - Selection (Maus)
Von Cromon im Forum C/C++Antworten: 6Letzter Beitrag: 31.08.09, 22:37 -
Unterstützung für OpenGL Entwicklung mit Java via Netbeans und OpenGL Pack
Von Thomas Darimont im Forum JavaAntworten: 0Letzter Beitrag: 04.06.08, 15:13 -
VRAY und Set Selection
Von ITA im Forum Cinema 4DAntworten: 1Letzter Beitrag: 28.10.07, 13:33 -
Selection in SWT Table
Von darksmilie im Forum Swing, Java2D/3D, SWT, JFaceAntworten: 2Letzter Beitrag: 28.08.06, 14:40



7Danke

Zitieren

Login






