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

Aktuelle Zeit: Di Jul 15, 2025 20:33

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



Ein neues Thema erstellen Auf das Thema antworten  [ 4 Beiträge ] 
Autor Nachricht
 Betreff des Beitrags: Problem mit selection...
BeitragVerfasst: Di Nov 29, 2005 16:32 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Feb 02, 2005 14:22
Beiträge: 81
Hallo Forum!
Nach längerer Pause beschäftige ich mich wieder mit OpenGL. Ich habe das Selection-Tut gelesen, habe aber immer noch Probleme. Dieses Problem ist zwar bereits in einigen Beiträgen behandelt worden, aber die dortigen Hinweise haben mir leider nicht weiter geholfen.
Vielleicht liegt es daran, dass ich jetzt schon recht lange immer und immer wieder denselben Quelltext lese und den Fehler immer wieder übersehe…

Wenn ich das Programm starte, bekomme ich immer die Meldung „Sie haben auf das Dreieck geklickt“. Stimmt aber nicht ;)

Vielleicht ist ja jemand von euch so gnädig zum x-ten Male „dieses“ Problem zu lösen.

MfG,
Michael

Code:
  1. unit Unit1;
  2.  
  3. interface
  4.  
  5. uses
  6.   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  7.   Dialogs, DGLOpenGL, ExtCtrls, ComCtrls, StdCtrls;
  8.  
  9. type
  10. TForm1 = class(TForm)
  11.     Timer1: TTimer;
  12.     StatusBar1: TStatusBar;
  13.     procedure FormCreate(Sender: TObject);
  14.     procedure IdleHandler(Sender: TObject; var Done: Boolean);
  15.     procedure FormResize(Sender: TObject);
  16.     procedure FormDestroy(Sender: TObject);
  17.     procedure Timer1Timer(Sender: TObject);
  18.     procedure FormMouseDown(Sender: TObject; Button: TMouseButton;
  19.       Shift: TShiftState; X, Y: Integer);
  20.   private    { Private-Deklarationen }
  21.     StartTime, TimeCount, FrameCount  : Cardinal; //FrameCounter
  22.     Frames, DrawTime                  : Cardinal; //& Timebased Movement
  23.     procedure SetupGL;
  24. //    procedure Init;       // Leere Prozedur \"für Variablen\"
  25.     procedure Render;
  26.     procedure ErrorHandler;
  27.   public    { Public-Deklarationen }
  28.     DC                                : HDC;  //Handle auf Zeichenfläche
  29.     RC                                : HGLRC;//Rendering Context
  30.   end;
  31.  
  32. var
  33.   Form1: TForm1;
  34.   xs,ys : integer;
  35.  
  36. const
  37.   NearClipping = 1;
  38.   FarClipping  = 1000;
  39.  
  40.   dreieck = 1;
  41.   viereck = 2;
  42.   stern = 3;
  43.   namen : array[-1..3] of string = ('nichts', '', 'das Dreieck', 'das Viereck', 'den Stern');
  44.  
  45. implementation
  46.  
  47. {$R *.dfm}
  48.  
  49. procedure TForm1.ErrorHandler;
  50. begin
  51.   Form1.Caption := gluErrorString(glGetError);
  52. end;
  53.  
  54. procedure TForm1.IdleHandler(Sender: TObject; var Done: Boolean);
  55. begin
  56.   StartTime:= GetTickCount;
  57.   Render;
  58.   DrawTime:= GetTickCount - StartTime;
  59.   Inc(TimeCount, DrawTime);
  60.   Inc(FrameCount);
  61.  
  62.   if TimeCount >= 1000 then begin
  63.     Frames:= FrameCount;
  64.     TimeCount:= TimeCount - 1000;
  65.     FrameCount:= 0;
  66.     Form1.Caption:= InttoStr(Frames) + 'FPS';
  67.     ErrorHandler;
  68.   end;
  69.  
  70.   Done:= false;
  71. end;
  72.  
  73. procedure TForm1.FormDestroy(Sender: TObject);
  74. begin
  75.   DeactivateRenderingContext;
  76.   DestroyRenderingContext(RC);
  77.   ReleaseDC(Handle, DC);
  78. end;
  79.  
  80. procedure TForm1.FormResize(Sender: TObject);
  81. var
  82.   tmpBool : Boolean;
  83. begin
  84.   glViewport(0, 0, ClientWidth, ClientHeight);
  85.   glMatrixMode(GL_PROJECTION);
  86.   glLoadIdentity;
  87.   gluPerspective(45.0, ClientWidth/ClientHeight, NearClipping, FarClipping);
  88.  
  89.   glMatrixMode(GL_MODELVIEW);
  90.   glLoadIdentity;
  91.   IdleHandler(Sender, tmpBool);
  92. end;
  93.  
  94. procedure TForm1.SetupGL;
  95. begin
  96.   glClearColor(0.0, 0.0, 0.0, 0.0); //Hintergrundfarbe
  97.   glEnable(GL_DEPTH_TEST);          //Tiefentest aktivieren
  98. //  glEnable(GL_CULL_FACE);           //Backface Culling aktivieren
  99. end;
  100.  
  101. procedure TForm1.FormCreate(Sender: TObject);
  102. begin
  103.   DC:= GetDC(Handle);
  104.   if not InitOpenGL then Application.Terminate;
  105.   RC:= CreateRenderingContext(DC, [opDoubleBuffered], 32, 24, 0, 0, 0, 0);
  106.   ActivateRenderingContext(DC, RC);
  107.   SetupGL;
  108. end;
  109.  
  110. procedure TForm1.Render;
  111. begin
  112. glMatrixMode(GL_MODELVIEW);
  113. glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT); //Farb und Tiefenpuffer löschen
  114.  
  115. glMatrixMode(GL_PROJECTION);
  116. glLoadIdentity;
  117. //Perspektive wird gesetzt
  118. gluPerspective(45.0, ClientWidth/ClientHeight, NearClipping, FarClipping);
  119. glTranslatef(0,0,-6);
  120.  
  121. glinitnames;
  122. glpushname(0);
  123.  
  124. glMatrixMode(GL_MODELVIEW);
  125.  
  126. glLoadIdentity;
  127. //gltranslatef(0,0,-6);
  128.  
  129. glcolor3f(1,0,0);
  130. glloadname(dreieck);
  131. glbegin(gl_triangles);
  132.   glvertex3f(-0.5,1,0);
  133.   glvertex3f(0.5,1,0);
  134.   glvertex3f(0,2,0);
  135. glend;
  136.  
  137. glcolor3f(0,1,0);
  138. glloadname(viereck);
  139. glbegin(gl_quads);
  140.   glvertex3f(-1,0,0);
  141.   glvertex3f(-2,0,0);
  142.   glvertex3f(-2,-1,0);
  143.   glvertex3f(-1,-1,0);
  144. glend;
  145.  
  146. glcolor3f(1,1,0);
  147. glloadname(stern);
  148. glbegin(gl_triangles);
  149.   glvertex3f(1,0,0);
  150.   glvertex3f(2,0,0);
  151.   glvertex3f(1.5,-1,0);
  152.  
  153.   glvertex3f(1,-0.65,0);
  154.   glvertex3f(2,-0.65,0);
  155.   glvertex3f(1.5,0.35,0);
  156. glend;
  157.  
  158. SwapBuffers(DC);                             //scene ausgeben
  159. end;
  160.  
  161. function Selection : integer;
  162. var
  163. Puffer       : array[0..256] of GLUInt;
  164. Viewport     : TGLVectori4;  // ehemals array[0..3] of Integer
  165. Treffer,i    : Integer;
  166. Z_Wert       : GLUInt;
  167. Getroffen    : GLUInt;
  168. begin
  169. glGetIntegerv(GL_VIEWPORT, @viewport);      //Die Sicht speichern
  170. glSelectBuffer(256, @Puffer);               //Den Puffer zuordnen
  171. glRenderMode(GL_SELECT);                    //In den Selectionsmodus schalten
  172. glmatrixmode(gl_projection);                //In den Projektionsmodus
  173. glPushMatrix;                               //Um unsere Matrix zu sichern
  174. glLoadIdentity;                             //Und dieselbige wieder zurückzusetzen
  175.  
  176. gluPickMatrix(xs, viewport[3]-ys, 1.0, 1.0, viewport);       // ehemals @viewport
  177. gluPerspective(45.0, form1.ClientWidth/form1.ClientHeight, 1, 100);
  178.  
  179. Form1.Render;                                     //Die Szene zeichnen
  180. glmatrixmode(gl_projection);                //Wieder in den Projektionsmodus
  181. glPopMatrix;                                //um unsere alte Matrix wiederherzustellen
  182.  
  183. treffer := glRenderMode(GL_RENDER);         //Anzahl der Treffer auslesen
  184.  
  185. Getroffen := High(GLUInt);                  //Höchsten möglichen Wert annehmen
  186. Z_Wert := High(GLUInt);                     //Höchsten Z - Wert
  187. for i := 0 to Treffer-1 do
  188. if Puffer[(i*4)+1] < Z_Wert then
  189.  begin
  190.  getroffen       := Puffer[(i*4)+3];
  191.  Z_Wert := Puffer[(i*4)+1];
  192.  end;
  193.  
  194.  Result := getroffen;
  195. end;
  196.  
  197. procedure TForm1.Timer1Timer(Sender: TObject);
  198. begin
  199.    inc(FrameCount);
  200.    Render;
  201.    If FrameCount = 20 then
  202.       begin
  203.            ErrorHandler;
  204.            FrameCount := 0;
  205.       end;
  206. end;
  207.  
  208. procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
  209.   Shift: TShiftState; X, Y: Integer);
  210. begin
  211. xs := x;
  212. ys := y;
  213. statusbar1.Simpletext := 'Sie haben auf ' + namen[selection] + ' geklickt!';
  214. end;
  215.  
  216. end.
[/pascal]


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Nov 30, 2005 09:31 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Feb 02, 2005 14:22
Beiträge: 81
Etwas weiter bin ich gekommen...
Bei der unten beschriebenen Render-Prozedur wird alles wie gewollt gezeichnet. Allerdings bekomme ich in der StatusBar immer die Meldung:"Sie haben auch nichts geklickt!", was falsch ist.

Lasse ich Quelltextzeile 7 weg, wird zwar nichts gezeichnet, ich kann es aber anklicken! Die ungefähren Positionen der drei Objekte sind ja bekannt und ich kann sie ohne Zeile 7 tatsächlich anklicken...

...jetzt muss halt beides noch kombiniert werden ;)

Ich hoffe mir kann dabei jemand helfen!

cu,
Michael


Code:
  1. procedure TForm1.Render;
  2. begin
  3. glMatrixMode(GL_MODELVIEW);
  4. glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT); //Farb und Tiefenpuffer löschen
  5.  
  6. glLoadIdentity;
  7. gluPerspective(45.0, form1.ClientWidth/form1.ClientHeight, NearClipping, FarClipping);
  8. gltranslatef(0,0,-6);
  9.  
  10. glinitnames;
  11. glpushname(0);
  12.  
  13. glcolor3f(1,0,0);
  14. glloadname(dreieck);
  15. glbegin(gl_triangles);
  16.   glvertex3f(-0.5,1,0);
  17.   glvertex3f(0.5,1,0);
  18.   glvertex3f(0,2,0);
  19. glend;
  20.  
  21. glcolor3f(0,1,0);
  22. glloadname(viereck);
  23. glbegin(gl_quads);
  24.   glvertex3f(-1,0,0);
  25.   glvertex3f(-2,0,0);
  26.   glvertex3f(-2,-1,0);
  27.   glvertex3f(-1,-1,0);
  28. glend;
  29.  
  30. glcolor3f(1,1,0);
  31. glloadname(stern);
  32. glbegin(gl_triangles);
  33.   glvertex3f(1,0,0);
  34.   glvertex3f(2,0,0);
  35.   glvertex3f(1.5,-1,0);
  36.  
  37.   glvertex3f(1,-0.65,0);
  38.   glvertex3f(2,-0.65,0);
  39.   glvertex3f(1.5,0.35,0);
  40. glend;
  41.  
  42. SwapBuffers(DC);                             //scene ausgeben
  43. end;
:wink:


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Nov 30, 2005 10:47 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
Du hast das Problem schon richtig erkannt. Dadurch, dass du die Perspektive noch einmal setzt zerschießt du dir entweder das eine oder das andere. Du macht verschiedene Dinge die eigentlich gar nicht nötig wären. Schau dir mal den Code aus den Selection Beitrag im Wiki genau an. Das ist zwar 2D aber bis auf die Tatsache, dass die Befehle glOrtho und gluPerpective ausgetaucht wurden nichts anderes.

In der Renderprocedur sollte es vollkommen genügen, wenn du deine Modelviewmatrix zurücksetzt. Das setzen der Perspektive und somit das Löschen der Peojectionmatrix solltest du dort besser lassen. Das hast du außerdem ja auch schon in der Methode Selection getan. Außerdem solltest du das SwapBuffers so gestalten, dass du den RenderMode abfragst und nur bei nicht selection den Bild schwapst. Beim Selektion wird nichts gezeichnet sondern lediglich etwas in einen Feedbackbuffer geschrieben.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Nov 30, 2005 12:02 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Feb 02, 2005 14:22
Beiträge: 81
Hui, jetzt hab ich es entlich hinbekommen! Danke :!:


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


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 3 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:  
cron
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.009s | 14 Queries | GZIP : On ]