tutorials.de Buch-Aktion 05/2012
Seite 1 von 2 12 LetzteLetzte
ERLEDIGT
JA
ANTWORTEN
15
ZUGRIFFE
5821
EMPFEHLEN
  • An Twitter übertragen
  • An Facebook übertragen
AUF DIESES THEMA
ANTWORTEN
  1. #1
    üäpöol üäpöol ist offline Mitglied Gold
    Registriert seit
    Feb 2011
    Beiträge
    189
    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öol
    Geändert von üäpöol (22.12.11 um 12:46 Uhr) Grund: CPP statt CODE-Tag :D && Rechtschreibung
     

  2. #2
    Avatar von Muepe32
    Muepe32 Muepe32 ist offline Mitglied Brokat
    Registriert seit
    Mar 2011
    Beiträge
    353
    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!

  3. #3
    üäpöol üäpöol ist offline Mitglied Gold
    Registriert seit
    Feb 2011
    Beiträge
    189
    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.
     

  4. #4
    Avatar von MSVCplusplus
    MSVCplusplus MSVCplusplus ist offline Mitglied Brokat
    Registriert seit
    Dec 2010
    Ort
    Hessen
    Beiträge
    336
    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.
    üäpöol bedankt sich. 
    Fehlermeldung bitte!
    Google - Dein Freund und Helfer

  5. #5
    üäpöol üäpöol ist offline Mitglied Gold
    Registriert seit
    Feb 2011
    Beiträge
    189
    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.
     

  6. #6
    Avatar von sheel
    sheel sheel ist offline Moderator
    tutorials.de Moderator
    Registriert seit
    Jul 2007
    Beiträge
    4.501
    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.
    üäpöol bedankt sich. 
    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, ...?

  7. #7
    üäpöol üäpöol ist offline Mitglied Gold
    Registriert seit
    Feb 2011
    Beiträge
    189
    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.
     

  8. #8
    Avatar von MSVCplusplus
    MSVCplusplus MSVCplusplus ist offline Mitglied Brokat
    Registriert seit
    Dec 2010
    Ort
    Hessen
    Beiträge
    336
    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
    üäpöol bedankt sich. 
    Fehlermeldung bitte!
    Google - Dein Freund und Helfer

  9. #9
    Avatar von Muepe32
    Muepe32 Muepe32 ist offline Mitglied Brokat
    Registriert seit
    Mar 2011
    Beiträge
    353
    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.
    üäpöol bedankt sich. 
    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!

  10. #10
    üäpöol üäpöol ist offline Mitglied Gold
    Registriert seit
    Feb 2011
    Beiträge
    189
    @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.
     

  11. #11
    Avatar von MSVCplusplus
    MSVCplusplus MSVCplusplus ist offline Mitglied Brokat
    Registriert seit
    Dec 2010
    Ort
    Hessen
    Beiträge
    336
    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
    üäpöol bedankt sich. 
    Fehlermeldung bitte!
    Google - Dein Freund und Helfer

  12. #12
    üäpöol üäpöol ist offline Mitglied Gold
    Registriert seit
    Feb 2011
    Beiträge
    189
    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
     

  13. #13
    Avatar von Muepe32
    Muepe32 Muepe32 ist offline Mitglied Brokat
    Registriert seit
    Mar 2011
    Beiträge
    353
    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.
    üäpöol bedankt sich. 
    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!

  14. #14
    üäpöol üäpöol ist offline Mitglied Gold
    Registriert seit
    Feb 2011
    Beiträge
    189
    Wow, das ist ja schon mal gar nicht so schlecht.
    Wie kann ich denn dann diese Werte in Koordinaten umwandeln?
     

  15. #15
    Avatar von Muepe32
    Muepe32 Muepe32 ist offline Mitglied Brokat
    Registriert seit
    Mar 2011
    Beiträge
    353
    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.xml
    üäpöol bedankt sich. 
    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!

Ähnliche Themen

  1. Row Selection
    Von M-P im Forum Javascript & Ajax
    Antworten: 4
    Letzter Beitrag: 25.10.09, 13:23
  2. openGL - Selection (Maus)
    Von Cromon im Forum C/C++
    Antworten: 6
    Letzter Beitrag: 31.08.09, 22:37
  3. Antworten: 0
    Letzter Beitrag: 04.06.08, 15:13
  4. VRAY und Set Selection
    Von ITA im Forum Cinema 4D
    Antworten: 1
    Letzter Beitrag: 28.10.07, 13:33
  5. Selection in SWT Table
    Von darksmilie im Forum Swing, Java2D/3D, SWT, JFace
    Antworten: 2
    Letzter Beitrag: 28.08.06, 14:40

Stichworte