Files |  Tutorials |  Articles |  Links |  Home |  Team |  Forum |  Wiki |  Impressum

Aktuelle Zeit: Fr Jul 11, 2025 09:06

Foren-Übersicht » Programmierung » Einsteiger-Fragen
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 10 Beiträge ] 
Autor Nachricht
 Betreff des Beitrags: Probleme mit Objektselektion
BeitragVerfasst: Do Feb 26, 2009 19:02 
Offline
DGL Member

Registriert: Do Dez 18, 2008 21:38
Beiträge: 60
Hallo, ich hab (mal wieder :wink:) ein Problem:

Ich habe mir das Tutorial zum Thema Objektselektion durchgelsen, aber als ich einfach mal den Code vom Tutorial kopiert und nach C umgeschrieben hatte funktionierte es irgendwie nicht richtig :(

Das Ergebnis war immer -1 (Nichts) und die Treffer wechselten merkwürdigerweise zwischen 0 und 1, manchmal auch 2, auch wenn ich auf der selben Stelle geklickt habe. Die Angaben bei gluPerspective sind auch die gleichen wie beim rendern.
Die Funktion selection(int xs, int ys) rufe ich immer auf, wenn ich eine Klick-Event bekomme (mit x / y Koordinaten der Maus)

Hier der Quelltext (allerdings in C):
Code:
  1. int selection(int xs, int ys)
  2. {
  3.   GLuint Puffer[100];
  4.   GLint Viewport[4];
  5.   int treffer, i;
  6.   GLuint Z_Wert;
  7.   GLint Getroffen;
  8.   int Result;
  9.  
  10.   glGetIntegerv(GL_VIEWPORT, &Viewport[0]);      //Die Sicht speichern
  11.   glSelectBuffer(100, &Puffer[0]);               //Den Puffer zuordnen
  12.  
  13.   glMatrixMode(GL_PROJECTION);                //In den Projektionsmodus
  14.   glRenderMode(GL_SELECT);                    //In den Selectionsmodus schalten
  15.   glPushMatrix();                               //Um unsere Matrix zu sichern
  16.   glLoadIdentity();                             //Und dieselbige wieder zurückzusetzen
  17.  
  18.   gluPickMatrix(xs, Viewport[3]-ys, 1.0, 1.0, Viewport);
  19.   gluPerspective(45.0, Viewport[2]/Viewport[3], 0.1, 100);
  20.  
  21.   updateGL();                                     //Die Szene zeichnen
  22.   glMatrixMode(GL_PROJECTION);                //Wieder in den Projektionsmodus
  23.   glPopMatrix();                                //und unsere alte Matrix wiederherzustellen
  24.  
  25.   treffer = glRenderMode(GL_RENDER);         //Anzahl der Treffer auslesen
  26.  
  27.   Getroffen = -1;                  //Höchsten möglichen Wert annehmen ???
  28.   Z_Wert = 100;                     //Höchsten Z - Wert ???
  29.   for (i=0; i < treffer; ++i) {
  30.     if (Puffer[(i*4)+1] < Z_Wert) {
  31.       Getroffen = Puffer[(i*4)+3];
  32.       Z_Wert = Puffer[(i*4)+1];
  33.     }
  34.   }
  35.    
  36.   if (Getroffen == -1)
  37.     Result = -1;
  38.   else
  39.     Result = Getroffen;
  40.  
  41.   return Result;
  42. }
  43.  


Ich verstehe nur nicht ganz, wo der Unterschied ist zwischen dem Quelltext im Tutorial und diesem hier, vermutlich habe ich da irgendwo einen ganz blöden Fehler gemacht :wink:
Eine Frage habe ich dann noch: Was bewirkt das High(GLUInt), warum muss die Variable den höchsten Wert annehmen? Vielleicht liegt dort ja schon der Fehler...

Danke für Hilfe im Vorraus!


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Feb 26, 2009 19:07 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Sep 23, 2002 19:27
Beiträge: 5812
Programmiersprache: C++
Du darfst deine mit gluPickMatrix erstellte Pickingprojektionsmatrix nirgendwo überschreiben. Den Fehler machen viele, du musst z.B. in deiner Renderprozedur eine Ausnahme einbauen die die Projektionsmatrix während der Selektion nicht verändert.

_________________
www.SaschaWillems.de | GitHub | Twitter | GPU Datenbanken (Vulkan, GL, GLES)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Feb 26, 2009 19:37 
Offline
DGL Member

Registriert: Do Dez 18, 2008 21:38
Beiträge: 60
Danke für den Tipp, aber das mache ich beim Rendern gar nicht:

RED, YELLOW, BLUE und GREEN sind mit den Werten 1-4 belegt, allerdings sind es Konstanten (#define)
Code:
  1.  
  2. void paintGL()
  3. {
  4.   glMatrixMode(GL_MODELVIEW);
  5.   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);  // Clear Screen And Depth Buffer
  6.   glLoadIdentity();                                    // Reset The Current Matrix
  7.   glTranslatef(0.0f,0.0f,-20.0f);                       // Move Into The Screen 20 Units
  8.  
  9.   glInitNames();
  10.   glPushName(0);
  11.  
  12.   glRotatef(45,0,0,1);
  13.   glPushMatrix();
  14.   glTranslatef(-5,0,0);
  15.   glColor3f(1,0,0);
  16.   glLoadName(RED);
  17.   glBegin(GL_QUADS);
  18.     glVertex3f(-1.0f,1.0f,0.0f);
  19.     glVertex3f(1.0f,1.0f,0.0f);
  20.     glVertex3f(1.0f,-1.0f,0.0f);
  21.     glVertex3f(-1.0f,-1.0f,0.0f);
  22.   glEnd();
  23.  
  24.   glPopMatrix();
  25.   glRotatef(90,0,0,1);
  26.   glPushMatrix();
  27.   glTranslatef(-5,0,0);
  28.   glRotatef(15,0,0,1);
  29.   glColor3f(1,1,0);
  30.   glLoadName(YELLOW);
  31.   glBegin(GL_QUADS);
  32.   glVertex3f(-1.0f,1.0f,0.0f);
  33.   glVertex3f(1.0f,1.0f,0.0f);
  34.   glVertex3f(1.0f,-1.0f,0.0f);
  35.   glVertex3f(-1.0f,-1.0f,0.0f);
  36.   glEnd();
  37.  
  38.   glPopMatrix();
  39.   glRotatef(90,0,0,1);
  40.   glPushMatrix();
  41.   glTranslatef(-5,0,0);
  42.   glRotatef(30,0,0,1);
  43.   glColor3f(0,0,1);
  44.   glLoadName(BLUE);
  45.   glBegin(GL_QUADS);
  46.   glVertex3f(-1.0f,1.0f,0.0f);
  47.   glVertex3f(1.0f,1.0f,0.0f);
  48.   glVertex3f(1.0f,-1.0f,0.0f);
  49.   glVertex3f(-1.0f,-1.0f,0.0f);
  50.   glEnd();
  51.  
  52.   glPopMatrix();
  53.   glRotatef(90,0,0,1);
  54.   glPushMatrix();
  55.   glTranslatef(-5,0,0);
  56.   glRotatef(45,0,0,1);
  57.   glColor3f(0,1,0);
  58.   glLoadName(GREEN);
  59.   glBegin(GL_QUADS);
  60.   glVertex3f(-1.0f,1.0f,0.0f);
  61.   glVertex3f(1.0f,1.0f,0.0f);
  62.   glVertex3f(1.0f,-1.0f,0.0f);
  63.   glVertex3f(-1.0f,-1.0f,0.0f);
  64.   glEnd();
  65. }
  66.  

Die ganzen Rotate-Aufrufe sind natürlich nicht nötig, aber ich wollte halt nicht einfach 4 Quads haben :)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Feb 26, 2009 19:38 
Offline
DGL Member

Registriert: Sa Okt 18, 2008 11:59
Beiträge: 180
Ich hab selbst so meine Probleme mit der Selektion und sie erstmal beiseite gelegt, das nur nebenbei.

HIGH ist dazu da einer Variable den höchsten Wert zuzuweisen, richtig, dies ist deshalb wichtig, damit die Funktion auch den kleinsten Wert findet (indem sie immer den kleineren Wert übernimmt, was aber nicht geht, wenn sie selbst schon 0 ist, dadurch würde dann der Vergleich nicht anschlagen und den Wert aktualisieren).

Alternativ sollte es auch möglich sein der Variable den Wert des 1. Objektes zuzuweisen, allerdings weiß ich nicht ob der Wert bei nicht anschlagen vllt schon auf 0 gesetzt wird, was bedeutet das du einen Fehler hast, wenn du nicht alle Treffer speicherst.


Irre ich mich oder ist das ein Fehler:
glSelectBuffer(100, &Puffer[0]); //Den Puffer zuordnen
? Der 1. Parameter sollte irgendwas mit 2^n sein.


Einer der Erfahreneren soll mich korrigieren, fals ich mich irre.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Feb 26, 2009 19:48 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Sep 23, 2002 19:27
Beiträge: 5812
Programmiersprache: C++
Dein Quellcode scheint in Ordnung, evtl. liegt dein Problem an einer anderen Stelle. Also am besten mal debuggen, wenns geht visuell. Also nicht glRenderMode aufrufen, sondern da einfach eine Pause einbauen. Dann siehst du schonmal ob überhaupt an die richtige Stelle der Szene geklickt wird.

Ansonsten sollte man inzwischen eh die Finger von OpenGLs Selektion lassen. Die läuft in Software und ist v.a. auf neuen NVidia-Treibern extremst langsam. Eine viel bessere (und schnellere) Methode ist die Farbselektion. Die ist sehr einfach zu implementieren, kann sehr stark optimiert werden (da man sie ja selbst implementiert) und ist unabhängig von der Hardware. Einfach mal hier im Forum nach Farbselektion suchen. Implementationsaufwand sollte sich in einfachen Szenen auf wenige Minuten beschränken.

_________________
www.SaschaWillems.de | GitHub | Twitter | GPU Datenbanken (Vulkan, GL, GLES)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Feb 26, 2009 20:20 
Offline
DGL Member

Registriert: Do Dez 18, 2008 21:38
Beiträge: 60
Auch als ich was anderes als 100 bei glSelectBuffer eingestellt habe kam das gleiche Ergebnis. Und selbst wenn die Treffer mal >= 1 waren, kam immer -1 raus, offenbar stimmt mit der Schleife nicht die Getroffen den Wert zuweist.

Ich werde mir Farbselektion mal anschauen, vielleicht hilft mir das ja weiter


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Feb 26, 2009 20:43 
Offline
DGL Member

Registriert: Do Dez 18, 2008 21:38
Beiträge: 60
Noch mal eine Frage zu dem Objektselektionstutorial: Was ist TGLArrayi4 oder TGLVectori4 für ein Typ?
Kann ich da auch ein Array[4] vom Typ GLint nehmen?


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Feb 26, 2009 21:10 
Offline
DGL Member

Registriert: Do Dez 18, 2008 21:38
Beiträge: 60
Mit dem Source Code aus dem Tutorial Objektselektion B hat es FAST geklappt !!!
Die Treffer stimmen jetzt immer, das einzige was noch nicht stimmt ist der Buffer-Inhalt:

Hier jetzt nur die Schleife am Ende:
Code:
  1.  
  2. Hit = 1000;
  3. HitZValue = 1000; //Die Far-plane reicht nur bis 1000, also müsste dieser Wert doch klappen???
  4. for (i=0; i < Hits; ++i) {
  5.     if (SelectBuffer[(i*4)+1] < HitZValue) {
  6.       Hit       = SelectBuffer[(i*4)+3];
  7.       HitZValue = SelectBuffer[(i*4)+1];
  8.       fprintf(stderr,"HIT HIT HIT HIT HIT\n");
  9.     }
  10.   }
  11.  


Wenn es 1 Treffer gibt und i=0 ist (for-Schleife), dann ist (i*4)+1 immer 1, aber
SelectBuffer[1] = 4277767936
genauso wie SelectBuffer[2]

SelectBuffer[(i*4)+3], also SelectBuffer[3] ist in dem Fall i=0 ist aber richtig, also entspricht dem Namen des Objekts.

Zudem komisch ist, dass statt -1 bei "nichts" immer der Wert 0 herauskommt (also im Buffer steht).
Muss man den irgendwas noch mit SelectBuffer machen damit das klappt?
Weil ganz undefiniert ist das ja auch nicht, nur die Z-Werte stimmen anscheinend nicht...


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Feb 26, 2009 21:37 
Offline
DGL Member

Registriert: Do Dez 18, 2008 21:38
Beiträge: 60
Wie genau funktioniert denn glReadPixels ?
Kann jemand vielleicht mal einen kurzen Beispielcode posten der die Farbe eines Pixels z.B. auf Rot prüft ?

EDIT: glReadPixels ist doch das richtige für Farbselektion, oder?


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Feb 26, 2009 22:01 
Offline
Ernährungsberater
Benutzeravatar

Registriert: Sa Jan 01, 2005 17:11
Beiträge: 2068
Programmiersprache: C++
http://svn.delphigl.com/dglsdk_linux/trunk/samples/easySDL/selection/selection_color.dpr

_________________
Steppity,steppity,step,step,step! :twisted:
❆ ❄ ❄ ❄ ❅ ❄ ❆ ❄ ❅ ❄ ❅ ❄ ❅ ❄ ❄
❄ ❄ ❄ ❅ ❄ ❄ ❄ ❅ ❄ ❄ ❆ ❄ ❄


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 10 Beiträge ] 
Foren-Übersicht » Programmierung » Einsteiger-Fragen


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 11 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.

Suche nach:
Gehe zu:  
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.008s | 14 Queries | GZIP : On ]