Registriert: Do Mai 27, 2004 15:22 Beiträge: 25 Wohnort: Stuttgart
Hallo Leute,
nach dem Dilemma mit den Binden der Textur mit den Font - gell ionos Mach ich mich nun an die Selektion ran - im Orthomodus (bevor jemand wieder kommt für was man Selektion braucht in diesem Modus... Ja man braucht es).
Um mich an mein erstes "Testspiel" zu wagen will ich halt alle Dinge die man braucht schon mal vorher in wissen und ausprobiert haben.
Folgendes ist mir aufgefallen.
Die beiden Tutorials im Wiki habe ich gelesen. Und trotz daß es Probleme gibt mit den neuen Treibern ab 90.xx bei NVidia bei dieser Methode (siehe dieser Beitrag http://www.delphigl.com/forum/viewtopic.php?t=5902&highlight=selektion ) schreiben viele Leute ihre Probleme das dies und jenes nicht funktioniert hier im Einsteiger Forum. Aber in keinem Thema das sich mit mit dieser Selektionsmethode beschäftigt (mehr als 4 Stunden rumgesucht), wird von anderen bis auf Ausnahmefälle erklärt, das es langsam geht und/oder auch andere Möglichkeiten gibt.
Für mich hat sich also diese Methode erledigt, da man nicht erwarten kann das alle noch bei NVidia den alten 80er Treiber draufhaben bzw. für Dein Programm/Spiel den draufmachen nur damit die FPS bei Selektion nicht unter die 10 kippt.
Also dann käme noch in Frage:
- wie schon kurz erwähnt die Szene ohne Licht, Texturen ect. zu rendern sondern nur den Objekten eine unterschiedliche
Farbe zu geben und dann mittels Lesen des Farbpuffers (ReadPixels?) auszulesen. Bingo! Wäre ne Möglichkeit. Aber glReadPixels soll langsam sein und dann muss ich ja theoretisch falls sich mal was geändert hat (kann ja sein) das man "anklicken" kann wieder die ganze Sache von vorn machen?
Also ReadPixels zu langsam... Oder doch nicht.
Beispiel ich hab im Orhtomodus 20-30 Objekte (runde Buttons, eckige Buttons, Text) zum anklicken. Geb den allen verschiedene Farben und benutz dann ReadPixels
PseudoCode (Auflösung 1024x768 Vollbild)
Code:
for x:=0to1024do
begin
For y:=0to768do
begin
farbe:= glReadPixel(blabla Parameter);
end;
end;
Nicht so das wahre oder.
2. Möglichkeit
RenderToTexture - vorher natürlich das gleiche. Rendern ohne Texturen, Licht usw. Nur die verschiedenen anklickbaren Objekte mit verschiedenen Farben versehen. Dann rendern in ne Texture und bei einem Klick an der Position den RGB Wert auslesen und schon hätte man ein passendes Objekt.
Oder macht Ihr das ganz anders (ausser dem GL-Select) ?
Meldet sich jemand freiwillig für ein neues Tut welches sich das Thema annimmt ?
Hat jemand mal auch ein paar Zeilen Code dazu?
Bis jetzt keine Ahnung wie man das mit RenderToTexture (nix per Suche deswegen gefunden) machen kann.
Registriert: Di Okt 03, 2006 14:07 Beiträge: 1277 Wohnort: Wien
Hallo Kathmai,
Du denkst viel zu kompliziert. Es geht FÜR DEN ORTHOMODUS viel einfacher.
Zuerst musst Du Deinen Viewport auf die Pixel-Breite und Pixel-Höhe Deines Fensters setzen.
Code:
glViewport(0,0,AWidth,AHeight);
Wenn Du es Windows-mäßig machen willst, ist der Ursprung links oben, es geht aber auch mit links unten, man muss dann eben die Mauskoordinaten immer korrigieren. Für links oben setzt Du den Orthomodus so:
Code:
Procedure OrthoModusON;
Var
Viewport:Array[0..3]OfInteger;
Begin
glMatrixMode(GL_PROJECTION);
glPushMatrix;
glLoadIdentity;
glGetIntegerv(GL_VIEWPORT,@Viewport);
glOrtho(0,ViewPort[2],ViewPort[3],0,+1,-1);
glMatrixMode(GL_MODELVIEW);
glPushMatrix;
glLoadIdentity;
End;
Procedure OrthoModusOFF;
Begin
glMatrixMode(GL_MODELVIEW);
glPopMatrix;
glMatrixMode(GL_PROJECTION);
glPopMatrix;
End;
Und dann fragst Du nach einem Mausklick einfach Dein Widget, ob es getroffen wurde:
Code:
Function TWidget.Hit(X,Y:Integer):Boolean;
Begin
Result:=False;
If(fVisible)And
(X >= fLeft)And(X <= fLeft+fWidth)And
(Y >= fTop)And(Y <= fTop+fHeight)
Then Result:=True;
End;
Das ist schon alles.
Selbstverständlich lässt sich das noch optimieren, indem man die Widgets gut organisiert, in einem Baum beispielsweise. Wenns aber nur wenige Widgets sind, reicht eine einfache Liste auch.
Traude
(die hofft, dafür gesorgt zu haben, dass es nicht wieder vier Uhr morgens bei Dir wird)
Registriert: Do Mai 27, 2004 15:22 Beiträge: 25 Wohnort: Stuttgart
Hi Traude,
wenn meine Wege so kompliziert aussehen dann wahrscheinlich daher, daß ich vorher nicht wusste was Widgets sind.
Weder im DGL Wiki (kein Ergebnis) noch Forumsuche (13 Themen) in denen darauf eingegangen wird wie man das bewerkstelligt. Es wird in den Suchergenissen nur der Hinweis gegeben es doch mal mit Widgets zu probieren.
Was zum Geier sind Widgets ah jetzt ja.. Wikipedia gibt die Antwort. Delphi's bzw. Borlands VCL sind "Widgets" - aka "Dingsbums".
Aber wie implementiert man das ganze so das man eine Selektion hinbekommt in OpenGL.
Viewport ist richtig gesetzt.
Vielleicht denk ich ja falsch aus mangelnder Erfahrung in OGL aber Dein Code funktioniert doch nur bei Rechteckigen "Widgets" dann wärs kein Problem - Hab ich auch in Dos-Zeiten gemacht so im Grafikmodus. Aber wie kapselt man so ein Widget Objekt z.b. an einem Klickbaren Objekt wie einer Raute, Quader, Kreis usw ? Das ist das Problem... Dein Code funktioniert dann nur halt bei Rechteckigen Objekten.
Ich glaub es besteht bei uns Anfängern ein Aufklärungsbedarf Wer ein Tutorial dazu haben will zur "Ordentlichen und schnellen Selektion" der meldet sich *finger heb*
cya
Tom
Traude hat geschrieben:
Traude (die hofft, dafür gesorgt zu haben, dass es nicht wieder vier Uhr morgens bei Dir wird)
Nene, aber als Krankenpfleger im Nachtdienst auf der Wachkomastation hat man nicht sehr viel zu tun Und bei Freunden bin ich bekannt dafür das nach 1 gleich 3 kommt. Soll heissen wenn ich mir was in Kopp gesetzt hab das es jetzt und sofort sein muss (kann man negativ oder positiv werten)
Was mich interessieren würde, warum Du bei der elektion ALLE Pixel des Bildschirms auslesen musst. Es reichen doch die des SetPoints der Maus und eventuell ein paar drumrum, um das angeklickte Objekt zu ermitteln. Gut wenn man eine Flächenmarkierung hinkriegen will sind das ein paar mehr, aber da kann man ja den Umweg über eine Bitmap gehen und per scanline arbeiten.
_________________ Manchmal sehen Dinge, die wie Dinge aussehen wollen, mehr wie Dinge aus, als Dinge.
<Esmerelda Wetterwax>
Es kann vorkommen, dass die Nachkommen trotz Abkommen mit ihrem Einkommen nicht auskommen und umkommen.
Registriert: Di Okt 03, 2006 14:07 Beiträge: 1277 Wohnort: Wien
Widgets werden in Windows Controls genannt und sind die anklickbaren Dinge, die eine Reaktion auslösen. Du weiß schon, jeder von uns hat eine andere Welt in seinem Kopf, da kanns schon mal passieren, dass man Ausdrücke verwendet, die nicht allgemein verständlich sind, sorry.
Das mit den rechteckigen Objekten ist natürlich richtig. Das oben gezeigte ist ein gewöhnlicher Bounding Box Test in 2D. Es empfiehlt sich IMMER, zuerst so einen Test auszuführen, wegen der Performance. Es ist erst dann sinnvoll, eine genauere Prüfung zu machen, wenn der Bounding Box Test ein "Getroffen" zurückgibt.
Jetzt kommt es darauf an, wie Deine Widgets gebaut sind:
1) sie bestehen aus Texturen, die teilweise transparent sind - damit hab ich mich nocht nicht beschäftigt
2) sie bestehen aus Polygonen.
Folgende Möglichkeiten für Polygone kenne ich:
- die normale OpenGL-Selektion, die Du nicht willst
- die Tests auf Punkt-in-Polygon
Wenn Deine Widgets aus Polygonen aufgebaut sind musst Du - wenn der Bounding-Box-Test positiv verlaufen ist - die einzelnen Polygone auf "getroffen" prüfen. Damit kann man einen punktgenauen Hittest machen.
Traude
EDIT: Wenn Dich die Hittests interessieren muss ich Dich vorwarnen: Achtung es wird mathematisch.
Registriert: Do Mai 27, 2004 15:22 Beiträge: 25 Wohnort: Stuttgart
Hi!
@Traude:
Die Selektion bezieht... halt andersrum.
Folgende Situation:
Für mich spielt 3D mit OGL momentan keine Rolle sondern 2D da ich in absehbarer Zukunft (so in 2-3 Jahren wenn ich OGL kapiere richtig *man bin ich sarkastisch heut*) ein Spiel in ISO - Sicht machen möchte. Eine WiSim.
Darin enthalten:
- ISO Karte mit Tiles (ca. 2 Layer) darauf Gebäude die man auch anklicken kann
- darüber ein HUD mit Buttons, text ect. wie z.b. Age of Empires oder ähnliche und das besteht nicht nur aus rechteckigen Dingsbums ähm Widgets
Halt alles 2D. Und da bietet sich doch der Orthomodus an oder nicht?!
Es sind alles Quads wo Texturen Draufgepappt sind, einige mit Alphamasking.
@Sidorion:
Alle Pixel sollen ja ausgelesen werden damit alles in einem Rutsch geht. Vor dem eigentlichen Rendern mit Texturen werden halt die Objekte eingefärbt die anklickbar sind. Und wenn ich das dann erst mach wenn der Benutzer die Maus drückt müsste ich es komplizerter machen also nur einen kleine Ausschnitt per scanline oder Readpixel durchführen. Bringt aber irgendwie nix wenn es wieder ein andersartiges Objekt als ein rechteckiges ist z.b kreis
Das kommt davon wenn nach 1 gleich 3 kommt. Ich glaub ich trink erst mal nen kaffee....
Registriert: Di Okt 03, 2006 14:07 Beiträge: 1277 Wohnort: Wien
Zitat:
Halt alles 2D. Und da bietet sich doch der Orthomodus an oder nicht?!
Ja.
Zitat:
Es sind alles Quads wo Texturen Draufgepappt sind, einige mit Alphamasking.
Damit wir uns recht verstehen: Du hast ein Quad, und da ist - sagen wir mal - eine Textur mit einem Kreis drauf. Alles was nicht innerhalb des Kreises ist, ist transparent. Wenn auf die transparenten Stellen geklickt wird, willst Du KEIN "getroffen" haben.
Ist das so?
Registriert: Do Dez 05, 2002 10:35 Beiträge: 4234 Wohnort: Dortmund
glReadPixel: Wenn du alles einliest, dann machst du zu viel. glReadPixels ist nicht das Schnellste und da solltest du auch nur das einlesen was du auch wirklich brauchst. So wie es derzeit ist würdest es extrem viel Zeit in Anspruch nehmen. Da wirst du nicht drumherum kommen es gleich etwas komplizierter zu gestalten.
Wenn du einen größeren Bereich einlesen möchtest, dann kannst du dies auch mit einem einzigen glReadPixels erledigen. Du musst dann aber dafür sorgen, dass der Speicherbereich den du übergibst entsprechend größer ist und die Breite/Höhe entsprechend angepasst ist.
Transparente Texturen sind recht spannend. Denn die Farbselektion lässt sich durch Blending aus dem Tritt bringen (Farbverläufe) und die klassische Selektion kommt auch nicht damit klar. Farbselektion mit Alphatest würde gehen aber dann bräuchtest du reine Alphatexturen was das ganze wieder unpraktikabel macht. Wenn du dort dann aber nur Quads hast, dann müsste man schon etwas mehr Aufwand betreiben. Wobei es den meisten auch gar nicht auffallen würde wenn es nur leichte Rundungen wären. Da muss man abwägen ob einem der Aufwand wert ist oder nicht.
Registriert: Do Mai 27, 2004 15:22 Beiträge: 25 Wohnort: Stuttgart
Traude hat geschrieben:
Es sind alles Quads wo Texturen Draufgepappt sind, einige mit Alphamasking.
Damit wir uns recht verstehen: Du hast ein Quad, und da ist - sagen wir mal - eine Textur mit einem Kreis drauf. Alles was nicht innerhalb des Kreises ist, ist transparent. Wenn auf die transparenten Stellen geklickt wird, willst Du KEIN "getroffen" haben. Ist das so?
JEPP JEPP JEPP Genau so wollt ich dat.
@iOnOs: Wenn Du das machen würdest, wie das was ich brauch und ich denke mal früher oder später werden es auch andere mal, dann werde nicht nur ich abends vorm Bett gehen Dir nen Gebet widmen. Zumahl im Wiki nichts oder nix brauchbares zu ReadPixel im Wiki ala Tutorial steht.
@Lossy:
Hehe und das sag mal einen Anfänger - ist das denn niemanden vorher aufgefallen zumindest in der Form *grübel*
Es muss ja kein Quad sein wo ich ne Textur mit Alpha draufknall. Aber das HUD würde ich dann in Cinema 4D rendern (wo ich mehr Ahnung hab) und da würden halt bei nem schicken HUD mal ab und zu klitzekleine Rundungchen vorkommen.
Ja OK muss nicht unbedingt sein wenn man die "anklickbaren" objeckte im HUD selbst noch mal rendert oben drauf die dann auch rechteckig sind.
Warum muss bei mir immer alles so kompliziert sein.
_________________ cya
Tom
Zuletzt geändert von Kathmai am Do Mai 10, 2007 09:08, insgesamt 2-mal geändert.
Registriert: Di Okt 03, 2006 14:07 Beiträge: 1277 Wohnort: Wien
@ Lossy: Dann wäre es für Texturen die einen Alphakanal haben (TGA-Format) praktikabel, wenn man
1) den Bounding-Box-Hitest macht
2) wenn getroffen, dann nur das eine getroffene Pixel per glReadPixel ausliest und auf Pixel.Alpha <> 0 prüft? (eventuell mit einer Toleranz drin)
Wenn ja, dann müsste das doch auch für transformierte (rotierte,verschobene,skalierte) Quads möglich sein und eigentlich recht schnell.
Registriert: Do Mai 27, 2004 15:22 Beiträge: 25 Wohnort: Stuttgart
Lossy eX hat geschrieben:
Transparente Texturen sind recht spannend. Denn die Farbselektion lässt sich durch Blending aus dem Tritt bringen (Farbverläufe) und die klassische Selektion kommt auch nicht damit klar. Farbselektion mit Alphatest würde gehen aber dann bräuchtest du reine Alphatexturen was das ganze wieder unpraktikabel macht. Wenn du dort dann aber nur Quads hast, dann müsste man schon etwas mehr Aufwand betreiben. Wobei es den meisten auch gar nicht auffallen würde wenn es nur leichte Rundungen wären. Da muss man abwägen ob einem der Aufwand wert ist oder nicht.
Man könnte es ja Theoretisch auch so machen, daß man halt Alles rendert mit Texturen nur das die Texturen einfarbig sind soll heißen, auf ein Quad oder anderem die Textur (z.b kreis) mit Alpha draufhaut wobei z.b. der kreis grün wäre. Und dann die Richtige Kreistextur nehmen die eigentlich drauf kommen soll. Nur müsste für jede Textur die ein objekt darstellt das nicht rechteckig ist eine zweite erstellt werden aber ob das Sinn und zweck der sache ist?!
Ist eigentlich eine ähnliche Lösung wie oben von Sidorion, nur eben mit einer Alphamaske (ein Bit pro Pixel würde genügen) und daher völlig plattformunabhängig und sollte recht schnell sein.
Wobei das zunächst nur eine Lösung für nicht transformierte Quads ist. Für transformierte Quads stelle ich mir folgende Lösung vor (Voraussetzung: wir befinden uns im Orthomodus mit Pixel-Koordinaten)
1) Wenn der Bounding Box-Hittest True ist (N.B.: es handelt sich um die transformierte Bounding Box)
2) Mauskoordinaten mit der invertierten Modelviewmatrix multiplizieren = Korrigierte Mauskoordinaten
3) Korrigierte Mauskoordinaten von fensterbezogenen auf quadbezogene Koordinaten umrechnen = quadbezogene Mauskoordinaten
5) Hittest mit den quadbezogenen Mauskoordinaten angewendet auf die Alphamaske aus dem oben genannten Thread
Registriert: Do Sep 25, 2003 15:56 Beiträge: 7810 Wohnort: Sachsen - ERZ / C
Programmiersprache: Java (, Pascal)
Hast du das mit dem "alle Pixel auslesen" aufgegeben oder steht das immer noch zur Debatte?
Du musst wirklich, wie bereits gesagt wurde, nur die Pixel auswählen wo hingeklickt wurde. Und zwar renderst du für einen(!) Frame die Szene komplett neu mit den Farben (ohne texturen/licht und den spass) und machst dann Readpixel. Das dazu der Code natürlich etwas angepasst werden muss ist klar. Aber besser als >800.000 ReadPixel-Aufrufe ist das allemal.
_________________ Blog: kevin-fleischer.de und fbaingermany.com
Registriert: Sa Jan 01, 2005 17:11 Beiträge: 2068
Programmiersprache: C++
@ Flash:
Dies geht aber nicht da er Texturen mit Alphawerten hat, wo er gerne nicht die gesamte Textur als Zielklick haben will.
Und so bekäme er die nur einfarbig wenn er eine Extratexture erstellt.
Vielleicht geht es noch mit einer Kombination von Blending und Alphatest, aber da wüsste ich gerade nicht wie.
Mitglieder in diesem Forum: 0 Mitglieder und 5 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.