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

Aktuelle Zeit: Di Jul 08, 2025 21:41

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



Ein neues Thema erstellen Auf das Thema antworten  [ 8 Beiträge ] 
Autor Nachricht
 Betreff des Beitrags: Problem bei der Objektseletion
BeitragVerfasst: Di Feb 17, 2004 14:51 
Offline
DGL Member

Registriert: Di Feb 17, 2004 14:36
Beiträge: 4
Hallo!

Zuerst vorneweg: Ich bin ziemlicher OpenGL-Anfänger.
Mein erstes Teilziel soll sein, die Basis des R3-Koordinatensystems hinzuzeichnen und einen Klick auf eine Achse zu erkennen.

Ersteres ist ja das geringere Problem, aber mit der Selektion klappts nicht so ganz. Ich hab es so gemacht, wie es im Tutorial steht. Meine Selction-Prozedur sieht also so aus:

Code:
  1.  
  2. function TMyApp.Selection(x, y: Integer): Integer;
  3. var
  4.   Buffer: array[0..256] of GLUInt;
  5.   ViewPort: Array[0..3] of Integer;
  6.   Z_Wert: GLUInt;
  7.   hit: GLUInt;
  8.   treffer, i: Integer;
  9. begin
  10.   glGetIntegerv(GL_VIEWPORT, @ViewPort);
  11.   glSelectBuffer(256, @Buffer);
  12.   glRenderMode(GL_SELECT);
  13.   glMatrixMode(GL_PROJECTION);
  14.   glPushMatrix;
  15.   glLoadIdentity;
  16.   gluPickMatrix(x, ViewPort[3] - y, 1.0, 1.0, @ViewPort);
  17.   gluPerspective(45.0, Size.X / Size.Y, 1, 100);
  18.   DrawGl;
  19.   glMatrixMode(GL_PROJECTION);
  20.   glPopMatrix;
  21.   treffer := glRenderMode(GL_RENDER);
  22.  
  23.   hit := High(GLUInt);                  //Höchsten möglichen Wert annehmen
  24.   Z_Wert := High(GLUInt);                     //Höchsten Z - Wert
  25.   for i := 0 to Treffer-1 do
  26.    if Buffer[(i*4)+1] < Z_Wert then
  27.    begin
  28.      hit := Buffer[(i*4)+3];
  29.      Z_Wert := Buffer[(i*4)+1];
  30.    end;
  31.  
  32.  Result := hit;
  33. end;


Leider ist die Anzahl der Treffer immer 0, egal, wo ich hinklicke.
Ist also meine Selection-Prozedur falsch, oder liegt der Fehler woanders? Auf was muss ich beim Rendern achten?

Falls es hilft, hier meine Renderprozedur:

Code:
  1.  
  2. glMatrixMode(GL_MODELVIEW);
  3. glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
  4. glLoadIdentity;
  5. glRotate(45, 1, 1, 1);
  6.  
  7.   glInitNames;
  8.   glPushName(0);
  9.  
  10.   glLoadName(BASE_X);
  11.   glBegin(GL_LINES);
  12.     glVertex(-1, 0, 0);
  13.     glVertex( 1, 0, 0);
  14.   glEnd;
  15.  
  16.   glLoadName(BASE_Y);
  17.   glBegin(GL_LINES);
  18.     glVertex(0, -1, 0);
  19.     glVertex(0,  1, 0);
  20.   glEnd;
  21.  
  22.   glLoadName(BASE_Z);
  23.   glbegin(GL_LINES);
  24.     glVertex(0, 0, -1);
  25.     glVertex(0, 0,  1);
  26.   glEnd;
  27. SwapBuffers(DC);


Danke schonmal im Voraus!


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Feb 17, 2004 15:33 
Offline
Forenkatze
Benutzeravatar

Registriert: Mi Okt 22, 2003 18:30
Beiträge: 1945
Wohnort: Närnberch
Programmiersprache: Scala, Java, C*
Würde mich wundern, wenn Picking mit GL_LINES funktioniert.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Feb 17, 2004 16:06 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Sep 23, 2002 19:27
Beiträge: 5812
Programmiersprache: C++
Der Selektionsmodus funktioniert mit ALLEN Primitiven, also auch mit Linien.
Dein Problem ist allerdings in folgender Zeile zu finden :
Code:
  1. gluPerspective(45.0, Size.X / Size.Y, 1, 100);

Du setzt deine Near-Clippingplane auf 1, also werden alle Objekte mit Z <= 1 (bei ner Z-Translation = 0) nicht gerendert. Deine Linien sind also bei dieser Perspektiveneinstellung nicht sichtbar und können daher auch nicht selektiert werden. Du musst also entweder deine Linien auf der Z-Achse in den Bereich zwischen Z-Near und Z-Far verschieben, oder die Near-Clipping-Plane verkleiner.

Kleiner Hinweis am Rande : Für die Selektion sollte man allerdings auf GL_LINES verzichten, da deren Selektion für den User schonmal zum Geduldsspiel werden kann, besonders wenn z.B. AA aktiviert ist. Ausserdem wird selbst bei größeren Linienbreiten (glLineWidth) für die Selektion immernur eine Linienbreite von 1 angenommen. Also am besten statt der Linien im Selektionsmodus etwas breitere Quads o.ä. rendern.

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


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Feb 17, 2004 16:12 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
Hmm. SOS war schneller.

Mir ist aber noch was anderes aufgefallen. Das "SwapBuffers(DC);" nach dem Zeichnen solltest du für den SelectionMode entfernen oder deaktivieren. Wenn du das Bild dann auf den Bildschirm bringst kann es zu Grafikfehlern kommen. Ich habe es bei mir folgendermaßen gemacht.
Code:
  1. var
  2.   RenderMode: Cardinal;
  3. begin
  4.   glGetIntegerv(GL_RENDER_MODE, @RenderMode);
  5.   ...
  6.   if (RenderMode = GL_RENDER)
  7.     then SwapBuffers(FDC);

So kannst du auch andere Sachen bei der Selektion ausschließen. Um es evtl . zu beschleunigen.
Oder sogar um für die Selektion notwendige Objecte hinzuzufügen. Um die Achsen zu verbreitern damit der Benutzer es einfacher hat.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Feb 17, 2004 17:08 
Offline
DGL Member

Registriert: Di Feb 17, 2004 14:36
Beiträge: 4
Danke für die Infos.
Hm, jetzt sieht es so aus: Wenn ich für den zNear-Wert von gluPerspective 0 einsetze, bekomme ich als Rückgabe immer 1, bei Zahlen kleiner oder gößer 0 -1. Zur Sicherheit habe ich es auch mit leichter anklickbaren Objekten wie einem Dreieck probiert, aber da kommt auch -1.

Hängt es vielleicht mit den Koordinaten zusammen? Die Koordinaten bei gluPickMatrix müssen Windows Coordinates sein, die, die ich einsetze, kommen von WM_LBUTTONDOWN. Sind das auch Window Coordinates? ich nehm an, ja, weil:

Zitat:
lParam
The low-order word specifies the x-coordinate of the cursor. The coordinate is relative to the upper-left corner of the client area.

The high-order word specifies the y-coordinate of the cursor. The coordinate is relative to the upper-left corner of the client area.


Aber so ganz sicher bin ich mir dabei nicht.

Woran könnte es denn noch liegen?


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Feb 17, 2004 17:19 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
Schaltest du vielleicht irgendwo in den 2D Modus. Also zum Ausgeben von irgendwelchem Text (in den Templates auf DGL wird das gemacht). Wenn du so etwas wärend dem Picken versuchst kommt nur Grütze bei raus.

Evtl. wäre es sinnvoll mal den gesammten Quellcode hoch zu laden.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Feb 17, 2004 17:27 
Offline
DGL Member

Registriert: Di Feb 17, 2004 14:36
Beiträge: 4
Lossy eX hat geschrieben:
Evtl. wäre es sinnvoll mal den gesammten Quellcode hoch zu laden.


Wenn sich da einer wirklich durchwühlt, gerne :)

OK, zur Erläuterung: Die Projektdatei kann ignoriert werden, sie dient nur zum Start. Die Unit appbase definiert eine programmklasse, die Unit main ist dann das eigentlich Programm. DrawGl ist die Renderprozedur.


Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Feb 17, 2004 20:23 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
So. Ich habe es gefunden und nü gehts. Das Problem lag nicht an deiner Selektion. Die war richtig. Das Problem lag daran, dass du nach Erstellen des RC's keine Perspective zugewiesen hattest.

Sie hier mal die Liste der Änderungen. Alle nur ziemlich klein.
Code:
  1. procedure TMyApp.InitGL(var msg: TMessage; hWnd: HWND);
  2. begin
  3.   ...
  4.   // Projection matrix
  5.   glMatrixMode(GL_PROJECTION);
  6.   glLoadIdentity();
  7.  
  8.   // Perspektive setzen
  9.   gluPerspective(45.0, Size.X / Size.Y, 1, 100);
  10.  
  11.   // Modelview Matrix
  12.   glMatrixMode(GL_MODELVIEW);
  13.   glLoadIdentity();
  14. end;

Das sollte eigentlich bei jedem Resize des Fensters aufgerufen werden. Und einem glViewPort davor.

Code:
  1. function TMyApp.Selection(x, y: Integer): Integer;
  2.   ...
  3.   gluPerspective(45.0, Size.X / Size.Y, 1, 100);
  4.   ...
  5. end;

Das zNear auf 1! Der ZBuffer ist so eine Sache für sich. In Quake3 wird zum Beispiel mit zNear von 4 gearbeitet.

Code:
  1. procedure TMyApp.DrawCoordinateBase;
  2. begin
  3.   glEnable(GL_LINE_SMOOTH);
  4.  
  5.   glTranslatef(0.0, 0.0, -7.5); // Neu
  6.   // Um die Primitive in das Bild zu schieben.
  7.  
  8.   glRotate(45, 1, 1, 1);
  9. end;


Das sollte es glaube ich gewesen sein.

PS: du solltest dir mal die dglOpenGL.pasanschauen. Die OpenGL.pas von borland ist veraltetet. Sehr veraltet.


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


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 4 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.009s | 14 Queries | GZIP : On ]