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

Aktuelle Zeit: Fr Jul 18, 2025 21:03

Foren-Übersicht » Programmierung » OpenGL
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 5 Beiträge ] 
Autor Nachricht
 Betreff des Beitrags: Seltsame Ergebnisse bei Selektion
BeitragVerfasst: Do Feb 15, 2007 21:26 
Offline
DGL Member

Registriert: Sa Feb 03, 2007 11:10
Beiträge: 26
Wohnort: Dingolfing
Hallo.

Ich versuche gerade, eine Selektion zu implementieren. Ich hab mir folgendes gebastelt:

Code:
  1. function TMCEngine.GetClickedObject(X, Y: Integer): TMCObject;
  2. var Buffer: array[0..255] of Cardinal;
  3.     view: TGLVectori4;
  4.     I, hitcount, id: Integer;
  5.     z: Cardinal;
  6. begin
  7.   glGetIntegerv(GL_VIEWPORT, @view);
  8.   glSelectBuffer(256, @Buffer);
  9.   glMatrixMode(GL_PROJECTION);
  10.   glRenderMode(GL_SELECT);  
  11.   glPushMatrix;
  12.   glLoadIdentity;
  13.   gluPickMatrix(X, view[3]-Y, 1.0, 1.0, view);
  14.   gluPerspective(45, view[2]/view[3], 1, 256);
  15.  
  16.   //Ab hier wird gerendert
  17.   glMatrixMode(GL_MODELVIEW);
  18.   glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
  19.   glLoadIdentity;
  20.   glInitNames;
  21.   glPushName(0);
  22.   World.Camera.Apply;
  23.   for I:=0 to World.Objects.Count-1 do
  24.     if World.Objects[I] is TMCVisibleObject then
  25.     begin
  26.       glPushName(I+1);
  27.       glLoadName(I+1);
  28.       (World.Objects[I] as TMCVisibleObject).Render;
  29.     end;
  30.   SDL_GL_SwapBuffers;
  31.   //Fertig gerendert
  32.  
  33.   glMatrixMode(GL_PROJECTION);
  34.   glPopMatrix;
  35.  
  36.   hitcount:=glRenderMode(GL_RENDER);
  37.   id:=0;
  38.   z:=high(Cardinal);
  39.   for I:=0 to hitcount-1 do
  40.     if Buffer[(i*4)+1]<z then
  41.     begin
  42.       id:=Buffer[(I*4)+3];
  43.       z:=Buffer[(I*4)+1];
  44.     end;
  45.  
  46.   if id=0 then
  47.     Result:=nil
  48.   else
  49.     Result:=World.Objects[id-1];
  50.  
  51.   glMatrixMode(GL_MODELVIEW);
  52. end;


TVisibleObject.Render sieht so aus:
Code:
  1. procedure TMCVisibleObject.Render;
  2. begin
  3.   glPushMatrix;
  4.  
  5.   glTranslatef(FX, FY, FZ);
  6.   glMultMatrixf(@FRotMatrix[0, 0]);
  7.  
  8.   if assigned(FTexture) then
  9.   begin
  10.     glEnable(GL_TEXTURE_2D);
  11.     glColor3f(1, 1, 1);    
  12.     FTexture.Apply;
  13.   end else
  14.   begin
  15.     glDisable(GL_TEXTURE_2D);
  16.     SetColor(FColor);    
  17.   end;
  18.   DoRender;
  19.  
  20.   glPopMatrix;
  21. end;


Das konkrete Rendern eines Objektes, z.B. eines Würfels, sieht so aus:
Code:
  1. procedure TMCCube.DoRender;
  2. var ss, st: Single;
  3. begin
  4.   inherited DoRender;
  5.  
  6.   if assigned(FTexture) then  //Texturenstreckung, unwichtig in dem Fall
  7.   begin
  8.     ss:=FTexture.ScaleS;
  9.     st:=FTexture.ScaleT;
  10.   end else
  11.   begin
  12.     ss:=1;
  13.     st:=1;
  14.   end;
  15.  
  16.   glBegin(GL_QUADS);
  17.  
  18.   if assigned(FTexture) then glTexCoord2f(0, 0);
  19.   glVertex3f(-Width/2, -Height/2, -Depth/2);
  20.   if assigned(FTexture) then glTexCoord2f(0, 1/st);
  21.   glVertex3f(-Width/2, +Height/2, -Depth/2);
  22.   if assigned(FTexture) then glTexCoord2f(1/ss, 1/st);
  23.   glVertex3f(+Width/2, +Height/2, -Depth/2);
  24.   if assigned(FTexture) then glTexCoord2f(1/ss, 0);
  25.   glVertex3f(+Width/2, -Height/2, -Depth/2);
  26.  
  27.   //Und jetzt noch 5 andere Seiten, das lasse ich mal weg
  28.  
  29.   glEnd;
  30. end;



Bei GetClickedObject ist teilweise schon hitcount falsch, es wird ein Klick auf ein Objekt mit hitcount=0 gesehen, wenn ich weiter unten auf das gleiche Objekt klicke, kriege ich jedoch hitcount=1. Wenn ich dann mal einen richtig hitcount bekomme, ist jedoch der gefundene Name vollkommen falsch.

Ich habe mir jede der Methoden mehrmals durchgeschaut aber nirgendswo einen Fehler gefunden...


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Feb 16, 2007 09:39 
Offline
DGL Member

Registriert: Mo Dez 20, 2004 08:58
Beiträge: 442
Wohnort: Mittweida (Sachsen)
1. Du hast zuviele Namen im Namestack. Es reicht einmal am Anfang ein glPushName und vor dem Anfang eines jeden Objektes ein glLoadName.
2. Du kannst zur Selektion Deine normale Renderprozedur benutzen, da man glPushName und glLoadName immer rufen kann, auch wenn man nicht im Selection-Modus ist. Wenn Du dann selektieren willst, initialisierst Du Deine selektion(mit dem RenderMode) und rufst dann die normale Renderprozedur. Auf die Weise kannst Du sicherstellen, dass beim Darstellen und Selektieren genau das selbe gerendert wird. Dies ist eine wichtige Vorraussetzung, dass die Selektierung funktioniert. Nachdem er alles gerendert hat, wird eben kein SwapBuffers gerufen, sondern der RenderMode wieder auf Normal gesetzt und dann kannst Du Deinen Puffer auslesen.

_________________
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.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Feb 16, 2007 10:40 
Offline
Guitar Hero
Benutzeravatar

Registriert: Do Sep 25, 2003 15:56
Beiträge: 7810
Wohnort: Sachsen - ERZ / C
Programmiersprache: Java (, Pascal)
Wenn das dann funktioniert, solltest du trotzdem im Selection-Mode deine Renderprozedur etwas tunen, und alles ausschalten was man nicht unbedingt brauch. Also kein Licht, Blending, Texturen, .... Damits bisl flotter geht.

_________________
Blog: kevin-fleischer.de und fbaingermany.com


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Feb 16, 2007 12:51 
Offline
DGL Member
Benutzeravatar

Registriert: Fr Sep 23, 2005 20:31
Beiträge: 212
Wohnort: Sachsen/ Vogtland
Hiho,

Ich sträubte mich anfangs auch gegen den Umstieg der OGL-Selektion auf einen eigenen Pick-Mechanismus. Als ich jedoch feststellte dass meine recht einfache Szene (im Projekt "Memorix") auf einer Nvidia 6600 GT ruckelte, während es auf einer Radeon 9250 flockig lief, wars mir dann auch zuviel. Letztlich ist ein eigener Mechanismus mit ~ 10 Zeilen und 30 Minuten Einbauzeit fertiggestellt und funktioniert prima und schnell auf allen Grafikkarten. Falls es Dir mit GL_SELECT zu nervig wird, dann kann ich Dir eine kurze Anleitung geben.

Grüße, DNA

_________________
Heute code ich, morgen debug ich, und übermorgen caste ich die Königin auf int.
http://www.2ndmoon.de


Zuletzt geändert von DNA am Mi Jan 30, 2008 22:47, insgesamt 1-mal geändert.

Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Feb 16, 2007 15:05 
Offline
DGL Member

Registriert: Sa Feb 03, 2007 11:10
Beiträge: 26
Wohnort: Dingolfing
OK, mal schaun.

Dass ich nicht die normale Renderprozedur verwende, liegt daran, dass ich keine Rechenzeit mit dem Aktualisieren der Matrix in der Physikengine verschwenden will.


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


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast


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:  
cron
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.019s | 15 Queries | GZIP : On ]