nach langer langer zeit bin ich endlich soweit die Selection von Objecten in mein programm zu implementieren
dies war zwar mit etwas aufwand verbunden da alles überlegt und angepasst werden musste aber ich habe es nun soweit das es im groben funktioniert
nur bibt es da ein problem, die funktion scheint immer den wert 3 zurückzugeben, niemals etwas anderes
ich werd mal versuchen zu erklären wie ich das gemacht habe bisher
also als erstes brauchen wir ja ein array mit allen namen
Code:
Names : array[-1..2000] of String;
dieses wird mit einer schleife befüllt
Code:
for x := 1 to 2000 do begin Names[x] := GameFiles.Names.ReadString ('Names', inttostr(x), 'Unbekannt'); end;
die datei dazu sieht wiefolgt aus
Zitat:
[Names] 1 = Kryta 2 = Fort Bush 3 = Außenposten Trenton
jedes object erhält eine ID die wieder aus einer datei geholt wird
Code:
for x := 1 to CurrentSystem.AnzahlObjekte do CurrentSystem.ObjektNamen[x]:= (GameFiles.System.ReadInteger('Objekt0' + inttostr(x), 'NameID', 0));
beim rendern wird nun jedem objekt der name zugewiesen
Code:
for x := 1 to CurrentSystem.AnzahlObjekte do begin gltranslatef(CurrentSystem.ObjektPosx[x],CurrentSystem.ObjektPosY[x],CurrentSystem.ObjektPosZ[x]); glLoadName(CurrentSystem.ObjektNamen[x]); CurrentSystem.Objekt[x].Render(); gltranslatef(CurrentSystem.ObjektPosx[x] * -1,CurrentSystem.ObjektPosY[x] * -1,CurrentSystem.ObjektPosZ[x] * -1); end;
nun wird bei jedem mousklick die position der maus an die funktion übergeben und diese ausgeführt
Code:
procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin MousePosX := X; MousePosY := Y; Clicked_On_Anything := false; GetMouseClickInterfaceOption; //im interface nachguggen ob auf etwas geklickt wurde if Clicked_On_Anything = false then //wenn nicht dann 3D-selection Player_Target := names[selection]; end;
aber egal worauf ich klicke bzw auch wenn ich auf "Nichts" klicke kommt er auf "3 = Außenposten Trenton"
Registriert: Do Mär 05, 2009 20:17 Beiträge: 284 Wohnort: Kaiserslautern
Ist Aussenposten Trenton das der Kammera nächste Objekt?
Dann hilft dir eventuell ein Blick in diesen Thread, da hatte ich zu Weihnachten ein ähnliches Problem und Schläfer hat mir dann irgendwann Nachts zwei Ansätze zum Lösen des Problems gegeben, von denen der erste funktionierte.
das objekt das meiner kamera am nächsten ist ist Kryta welches sind ungefähr 200 einheiten von mir entfernt befindet.. Trenton jedoch liegt weit über 5000 einheiten weg, aber ich werde mir den link ansehen und schauen ob ich was nützliches finde danke dir erstmal dafür
€: so ich hab das mal durchgespielt... allerdings ohne erfolg, ich bekomme immernoch jedes mal den wert 3 zurück.
desweiteren ist mir aufgefallen das die komplette bewegung nun kurz innehält wenn ich klicke ist das normal? (nur so ne halbe 1 sec)
Registriert: Do Mär 05, 2009 20:17 Beiträge: 284 Wohnort: Kaiserslautern
also bei mir habe ich die selektion auch getimed und sie braucht am laptop ca. ne sekunde. (ist bei mir abhängig von der modellgröße) am normalen pc braucht sie aber nur 0,016 oder 0 sekunden...
Registriert: Do Sep 25, 2003 15:56 Beiträge: 7810 Wohnort: Sachsen - ERZ / C
Programmiersprache: Java (, Pascal)
Die Zeiten die ihr nennt zeigen auch schon auf das Problem mit der alten Selection-Methode hin: Sie ist langsam - auf manchen Systemen sogar unakzeptabel langsam.
Einen Shooter könnte man damit nicht schreiben.
Die Lösung dafür ist Color-Picking. Ist im Wiki auch erklärt (gibt auch ein Tutorial dazu). Hier gibts ein Vorabversion als PDF für die Variante ohne Shader.
_________________ Blog: kevin-fleischer.de und fbaingermany.com
Anmerkung: EINE Variante ist Colorpickung. Man kann es z.B. auch über eine Physikengine regeln (Beispiel Shooter wieder).
_________________ Denn wer nur schweigt, weil er Konflikte scheut, der macht Sachen, die er hinterher bereut. Und das ist verkehrt, denn es ist nicht so schwer, jeden Tag zu tun als ob's der letzte wär’. Und du schaust mich an und fragst ob ich das kann. Und ich denk, ich werd' mich ändern irgendwann. _________________Farin Urlaub - Bewegungslos
ob das colorpicking die richtige lösung wäre kann ich mir nicht vorstellen da ja jedes object eine textur hat und ich kann ja nicht jedesmal die ganze sache auswerten nach farbe.
und mit ner engine, nur zum selectieren? wie geht das? gibts da en beispiel?
eigentlich müsste die function die ich habe ja auch funktionieren beri andreren geht es ja auch
Registriert: Mo Sep 23, 2002 19:27 Beiträge: 5812
Programmiersprache: C++
Wenn deine Selektion nicht funktioniert liegt es meistens daran dass du die Pickingmatrix in deinem Rendern für die Selektion überschreibst. Schau mal ob du das machst, wenn ja, musst du im Renderprozess ein Flag setzen dass die Pickingmatrizen im Selektionsmodus nicht überschreibt.
Ansonsten wurde es hier ja bereits erwähnt, die OpenGL-Selektion sollte man nicht mehr nutzen. Die läuft nur in Hardware, also selbst wenn du dann optimiert renderst (keine Texturen, keine Beleuchtung, etc.) ist diese viel zu langsam.
Daher ist Colorpicking eine sehr gute Option die extrem leicht zu implementieren ist und dann auch via Hardware viel schneller ist. Also einfach alle Objekte mit fester Farbe und ohne unnötige Sachen rendern, Texturen, Beleuchtung und Shader kann man also getrost fürs Colorpicking weglassen. Dann einfach in ner Schleife die Farbe abgleichen und fertig. Da ich diese Methoden schon länger nutze kann ich sagen dass sie selbst für komplexe Szenen sehr schnell ist, und immer schneller als die Softwareselektion in OpenGL.
Und wie Ziz sagte kann man dafür auch eine Physikengine nutzen. Wenn man eh Physik braucht kann man das einfach kombinieren. Physikengines wie Newton bieten nämlich Raycastfunktionen an, mit denen man einen Strahl "abfeuern" kann, und man kann ann in einem Callback sehen welches Objekt (wenn überhaupt) getroffen wurde. In Newton kann man also zu Beginn für jeden Körper diesen selbst als Nutzerdaten setzen, und schon kann man im Callback direkt auslesen welcher Körpfer getroffen wurde ([i]Hit := NewtonBodyGetUserData(me)). Und da man v.a. in Shootern o.ä. eh ne Physikengine für Kollisionen und Co. braucht ist dass auch die beste Methode. Rayscasts sind überhaupt sehr vielseitig einseztbar. Ich hab die schon genutzt für Selektion, Sichtbarkeitsprüfung, um Objekte vom Spieler aufheben zu lassen, Objekte aufm Boden zu platzieren, Höhenangaben, uvm.
Registriert: Do Sep 25, 2003 15:56 Beiträge: 7810 Wohnort: Sachsen - ERZ / C
Programmiersprache: Java (, Pascal)
Dropye hat geschrieben:
ob das colorpicking die richtige lösung wäre kann ich mir nicht vorstellen da ja jedes object eine textur hat und ich kann ja nicht jedesmal die ganze sache auswerten nach farbe.
Ließ dir mal durch wie ColorPicking funktioniert. Wenn der Nutzer Klickt wird, wie bei deiner OpenGLSelektion, ein extra Renderpass durchgeführt, wo Texturen und Beleuchtung ausgeschaltet sind und alle Selektierbaren Objekte in ihrer Selektionsfarbe gerendert werden.
So kompliziert ist das nicht.
_________________ Blog: kevin-fleischer.de und fbaingermany.com
Gerade bei komplexen Szenen ist ColorPicking sinnvoll, da die Grafikkarte nun mal wesentlich schneller Geometrie verarbeiten kann als die CPU. Es kann aber nicht schaden z.B. nur ein reduziertes Mesh mit weniger Dreiecken zu verwenden.
Die einzige Schwierigkeit liegt darin jedem Objekt (ggf. jedem Dreieck) eine andere, eindeutige Farbe zu verpassen. Sollte man am besten über Material- oder Vertexfarben lösen, nicht über eine Textur. Wenn du auch den Alpha-Kanal nutzt sind es übrigens sogar 256^4 bzw. 2^32 mögliche Farben.
Registriert: Mo Sep 23, 2002 19:27 Beiträge: 5812
Programmiersprache: C++
Bei der Farbselektion gibts theoretisch keine Begrenzung der Objektanzahl. Man prüft ja nie den kompletten Schirm, sondern i.d.R. nur einen kleinen Bereich um den Cursor herum (oft nur 3x3 Pixel). Und da man auch weiss wo man sich gerade mit dem Cursor befindet kann man diesen Bereich dann mittels Scissor abgrenzen (Performance), prüfen ob Objekte im "Frustum" des Mauszeigers liegen und dann nur diese einfärben. Oder man macht ne Art Subselektion mittels z.B. Octrees, wo dann zuerst nur geprüft wird in welchen Octree geklickt wurde, während man danach die echte Objektselektion nur innerhal der Octreenode macht. Die Methode ist also sehr flexibel.
ok ich hab mir das mit dem colorpicking jetzt mal zu gemüte gezogen
allerdings sind dazu aber auch shader notwendig und mit diesen habe ich noch nie gearbeitet, aber wir haben ja ne super wiki wo auch dafür was drinnesteht, nur leider nich alles^^
ich bin dem wiki-beitrag gefolgt und hab mich nach dem ersten mal lesen gleich ans werk gemacht,
alle variablen erstellen und den code in strings packen, den shader und die "codepackete" erstellen funktioniert super
aber wenn ich den code an mein Selekt_shader_vertex anhängen will braucht er die länge des codes in "pglint", das ist mir aber völlig neu und ich hab keine ahnung wo ich eine zahl in dem format herbekomm
mache ich da einfach was falsch oder hab ich nur was übersehen?
Registriert: Do Sep 25, 2003 15:56 Beiträge: 7810 Wohnort: Sachsen - ERZ / C
Programmiersprache: Java (, Pascal)
Du brauchst keine Shader dafür. In dem Tutorial ist ja diese "Vorab-Version" des Einsteigerfreundlichen Shaderfreien Colorpickingtutorials.
Wenn du das Prinzip verstanden hast, wirst du auch wissen, dass Shader nur noch für die Optimierung da sind. Das Prinzip ist auch ohne Shader anwendbar.
_________________ Blog: kevin-fleischer.de und fbaingermany.com
Mitglieder in diesem Forum: 0 Mitglieder und 2 Gäste
Du darfst keine neuen Themen in diesem Forum erstellen. Du darfst keine Antworten zu Themen in diesem Forum erstellen. Du darfst deine Beiträge in diesem Forum nicht ändern. Du darfst deine Beiträge in diesem Forum nicht löschen. Du darfst keine Dateianhänge in diesem Forum erstellen.