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

Aktuelle Zeit: Fr Jul 18, 2025 12:09

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



Ein neues Thema erstellen Auf das Thema antworten  [ 3 Beiträge ] 
Autor Nachricht
 Betreff des Beitrags: Seltsames Picking Problem
BeitragVerfasst: Do Mai 17, 2007 13:06 
Offline
DGL Member
Benutzeravatar

Registriert: Di Mai 15, 2007 20:08
Beiträge: 1
Ich habe hier ein Problem welches ich mir überhaupt nicht erklären kann. Ich zeichne mehrere Quads, klicke eines davon an und möchte dann mit Hilfe der 'Colormethode' rausfinden, auf welches geklickt wurde. Dies klappt alles mehr oder weniger, aber hier ist auch das Problem.

Manchmal tut es, manchmal nicht. Was ich mir überhaupt nicht erklären kann, da dieser Unterschied auch vorkommt wenn ich überhaupt nichts am Code änder.

Beispiel
- Programm compilieren
- tut
- Programm schließen
- Programm neu compilieren
- tut nicht

Wie kann sowas sein?

Hier mal der vollständige Code:


Code:
  1. unit Unit1;
  2.  
  3. interface
  4.  
  5. uses
  6.   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  7.   Dialogs, DGLOpenGL, StdCtrls, ExtCtrls, glBitmap;
  8.  
  9. type
  10.   TMyQuad = record
  11.     px, py, pz  : Single;
  12.     sx, sy, sz  : Single;
  13.     rx, ry, rz  : Single;
  14.     id          : Integer;
  15.     texture     : TglBitmap2D;
  16.   end;
  17.  
  18.   TForm1 = class(TForm)
  19.     Timer1: TTimer;
  20.     ListBox1: TListBox;
  21.     procedure FormMouseWheelUp(Sender: TObject; Shift: TShiftState;
  22.       MousePos: TPoint; var Handled: Boolean);
  23.     procedure FormMouseWheelDown(Sender: TObject; Shift: TShiftState;
  24.       MousePos: TPoint; var Handled: Boolean);
  25.     procedure FormMouseDown(Sender: TObject; Button: TMouseButton;
  26.       Shift: TShiftState; X, Y: Integer);
  27.     procedure Timer1Timer(Sender: TObject);
  28.     procedure FormDestroy(Sender: TObject);
  29.     procedure FormResize(Sender: TObject);
  30.     procedure FormCreate(Sender: TObject);
  31.   private
  32.     { Private declarations }
  33.   public
  34.     { Public declarations }
  35.     DC                                : HDC;  //Handle auf Zeichenfläche
  36.     RC                                : HGLRC;//Rendering Context
  37.     procedure SetupGL;
  38.     procedure Init;
  39.     procedure IdleHandler(Sender: TObject; var Done: Boolean);
  40.     procedure Render;
  41.     procedure ErrorHandler;
  42.     procedure DrawMyQuad(q: TMyQuad);
  43.     procedure CreateMyQuad(var mq: TMyQuad; _px,_py,_pz,_sx,_sy,_sz,_rx,_ry,_rz: Single);
  44.     procedure ID2RGB(ID: Integer; var r,g,b: Byte);
  45.     procedure CreateTexture(ID: Integer);
  46.     function GetNextCubeID: Integer;
  47.     function Pick(x,y: Integer): Integer;
  48.     procedure Interact(x, y: Integer);
  49.  
  50.   end;
  51.  
  52. const
  53.   NearClipping = 1;
  54.   FarClipping  = 1000;
  55.   MaxDrawTime  = 20;
  56.  
  57. var
  58.   Form1             : TForm1;
  59.   viewangle         : Single = 45.0;
  60.   FPS,
  61.   StartTime,
  62.   DrawTime,
  63.   TimeCount,
  64.   FrameCount        : Integer;
  65.   myQuads           : Array[0..5] of TMyQuad;
  66.   a                 : Integer = 0;
  67.   up                : boolean = true;
  68.   nextCubeID        : Integer;
  69.   pickMode          : Boolean;
  70.   camPos            : TGLVectorf3;
  71.  
  72.  
  73. implementation
  74.  
  75. {$R *.dfm}
  76.  
  77. procedure TForm1.Interact(x, y: Integer);
  78. var id: Integer;
  79. begin
  80.  // erstmal schaun welches angeklickt wurde
  81.  id := pick(x, y);
  82.  // wenns ok ist, dann nach inten verschieben
  83.  {
  84.  if id <> -1 then
  85.    myQuads[id].pz := myQuads[id].pz - 0.1;
  86.  }
  87.  // noch anzeigen auf was geklickt wurde
  88.  ListBox1.Items.Add(IntToStr(id));
  89.  ListBox1.ItemIndex := ListBox1.Items.Count-1;
  90. end;
  91.  
  92. procedure TForm1.CreateTexture(ID: Integer);
  93. var bmp: TBitmap;
  94. begin
  95.  // bitmap erstellen
  96.  bmp              := TBitmap.Create;
  97.  bmp.PixelFormat  := pf24bit;
  98.  bmp.Width        := 32;
  99.  bmp.Height       := 32;
  100.  
  101.  // textur auf bitmap zeichnen
  102.  with bmp.Canvas do begin
  103.    Brush.Style    := bsSolid;
  104.    Brush.Color    := random(255*255*255);
  105.    Rectangle(-1, -1, 33, 33);
  106.    Brush.Style    := bsClear;
  107.    TextOut(2, 2, IntToStr(id));
  108.  end;
  109.  
  110.  // richtige textur erstellen
  111.  myQuads[id].texture := TglBitmap2D.Create;
  112.  
  113.  // der richtigen textur den bitmap zuweisen
  114.  if myQuads[id].texture.AssignFromBitmap(bmp) then begin
  115.    //AddAlphaFromColorKey(255, 0, 255, 0);
  116.    myQuads[id].texture.GenTexture();
  117.  end else
  118.    ShowMessage('Textur konnte nicht erzeugt werden.');
  119.  
  120.  bmp.Free;
  121.  
  122. end;
  123.  
  124. procedure TForm1.CreateMyQuad(var mq: TMyQuad; _px,_py,_pz,_sx,_sy,_sz,_rx,_ry,_rz: Single);
  125. begin
  126.  with mq do begin
  127.    px := _px; py := _py; pz := _pz;
  128.    sx := _sx; sy := _sy; sz := _sz;
  129.    rx := _rx; ry := _ry; rz := _rz;
  130.    id := GetNextCubeID;
  131.  end;
  132.  CreateTexture(mq.id);
  133. end;
  134.  
  135. procedure TForm1.FormCreate(Sender: TObject);
  136. begin
  137.  DC:= GetDC(Handle);
  138.  if not InitOpenGL then begin
  139.     ShowMessage('OpenGL kann nicht initialisiert werden. Programm wird beeendet');
  140.     Application.Terminate;
  141.  end;
  142.  RC:= CreateRenderingContext(   DC,
  143.                                 [opDoubleBuffered],
  144.                                 32,
  145.                                 24,
  146.                                 0,0,0,
  147.                                 0);
  148.   ActivateRenderingContext(DC, RC);
  149.   Application.OnIdle := IdleHandler;
  150.   SetupGL;
  151.   Init;
  152. end;
  153.  
  154. procedure TForm1.ID2RGB(ID: Integer; var r,g,b: Byte);
  155. begin
  156.   r := ID div 65025;
  157.   ID := ID - (r*65025);
  158.   g := ID div 255;
  159.   ID := ID - (g*255);
  160.   b := ID
  161. end;
  162.  
  163. function TForm1.GetNextCubeID: Integer;
  164. begin
  165.  result := nextCubeID;
  166.  inc(nextCubeID);
  167. end;
  168.  
  169. function TForm1.Pick(x, y: Integer): Integer;
  170. var c: TColor;
  171. begin
  172.  pickMode := true;
  173.  render;
  174.  
  175.  glReadPixels(X, (ClientHeight - 1 - Y), 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, @c);
  176.  c := c AND $ffffff;
  177.  result := GetRValue(c) * 65025 +
  178.            GetGValue(c) * 255 +
  179.            GetBValue(c);
  180.  
  181.  // checkt result range
  182.  if (result > nextCubeID-1) or (result < 0) then
  183.   result := -1;
  184.            
  185.  pickMode := false;
  186. end;
  187.  
  188. procedure TForm1.SetupGL;
  189. begin
  190.   glClearColor(0.3, 0.4, 0.7, 0.0);
  191.   glEnable(GL_DEPTH_TEST);
  192.   glEnable(GL_TEXTURE_2D);
  193.   //glEnable(GL_CULL_FACE);        
  194. end;
  195.  
  196. procedure TForm1.Init;
  197. begin
  198.   randomize();
  199.   nextCubeID  := 0;
  200.   pickMode    := false;
  201.   camPos[0] := 0;
  202.   camPos[1] := 0;
  203.   camPos[2] := -4;
  204.   CreateMyQuad(myQuads[0], -1.5, 0, 0, 1, 1, 0, 0, 0, 0);
  205.   CreateMyQuad(myQuads[1], 0, 0, 0, 1, 1, 0, 0, 0, 0);
  206.   CreateMyQuad(myQuads[2], 1.5, 0, 0, 1, 1, 0, 0, 0, 0);
  207.   CreateMyQuad(myQuads[3], 0, 1.5, 0, 1, 1, 0, 0, 0, 0);
  208.   CreateMyQuad(myQuads[4], 0, -1.5, 0, 1, 1, 0, 0, 0, 0);
  209.   CreateMyQuad(myQuads[5], 0, -2.5, 0, 1, 1, 0, 0, 0, 0);
  210. end;
  211.  
  212. procedure TForm1.Render;
  213. var i: Integer;
  214. begin
  215.   glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
  216.  
  217.   glMatrixMode(GL_PROJECTION);
  218.   glLoadIdentity;
  219.   gluPerspective(viewangle, ClientWidth/ClientHeight, NearClipping, FarClipping);
  220.  
  221.   glMatrixMode(GL_MODELVIEW);
  222.   glLoadIdentity;
  223.  
  224.   // cam translations
  225.   glTranslatef(camPos[0], camPos[1], camPos[2]);
  226.   glRotated(a, 0, 1, 0);
  227.  
  228.   if pickMode then
  229.     glShadeModel(GL_FLAT)
  230.   else
  231.     glShadeModel(GL_SMOOTH);
  232.  
  233.   // alle Zeichen wo sie sind
  234.   for i := 0 to High(myQuads) do
  235.    DrawMyQuad(myQuads[i]);
  236.  
  237.   if not pickMode then
  238.     SwapBuffers(DC);
  239. end;
  240.  
  241. procedure TForm1.DrawMyQuad(q: TMyQuad);
  242. var r,g,b: Byte;
  243. begin
  244.   glPushMatrix;
  245.  
  246.   glTranslatef(q.px, q.py, q.pz);
  247.  
  248.   glRotated(q.rx, 1, 0, 0);
  249.   glRotated(q.ry, 0, 1, 0);
  250.   glRotated(q.rz, 0, 0, 1);
  251.  
  252.   if pickMode then begin
  253.     ID2RGB(q.id, r, g, b);
  254.     glColor3f(r/255, g/255, b/255);
  255.     glBegin(GL_QUADS);
  256.       glVertex3f(-(q.sx/2), -(q.sy/2), 0);
  257.       glVertex3f( (q.sx/2), -(q.sy/2), 0);
  258.       glVertex3f(( q.sx/2),  (q.sy/2), 0);
  259.       glVertex3f(-(q.sx/2),  (q.sy/2), 0);
  260.     glEnd;
  261.   end else begin
  262.     glColor3f(1, 1, 1);
  263.     q.texture.Bind();
  264.     glBegin(GL_QUADS);
  265.       glTexCoord2f(0, 0);  glVertex3f(-(q.sx/2), -(q.sy/2), 0);
  266.       glTexCoord2f(1, 0);  glVertex3f( (q.sx/2), -(q.sy/2), 0);
  267.       glTexCoord2f(1, 1);  glVertex3f(( q.sx/2),  (q.sy/2), 0);
  268.       glTexCoord2f(0, 1);  glVertex3f(-(q.sx/2),  (q.sy/2), 0);
  269.     glEnd;
  270.   end;
  271.  
  272.   glPopMatrix;
  273. end;
  274.  
  275. procedure TForm1.IdleHandler(Sender: TObject; var Done: Boolean);
  276. begin
  277.   StartTime:= GetTickCount;
  278.   Render;
  279.   DrawTime:= GetTickCount - StartTime;
  280.   Inc(TimeCount, DrawTime);
  281.   Inc(FrameCount);
  282.  
  283.   if DrawTime < MaxDrawTime then
  284.     Sleep(MaxDrawTime - DrawTime);
  285.  
  286.   if TimeCount >= 1000 then begin
  287.     FPS:= FrameCount;
  288.     TimeCount:= TimeCount - 1000;
  289.     FrameCount:= 0;
  290.     ErrorHandler;
  291.   end;
  292.  
  293.   Done:= false;
  294. end;
  295.  
  296. procedure TForm1.ErrorHandler;
  297. begin
  298.   Form1.Caption := gluErrorString(glGetError);
  299. end;
  300.  
  301. procedure TForm1.FormResize(Sender: TObject);
  302. var tmpBool : Boolean;
  303. begin
  304.  glViewport(0, 0, ClientWidth, ClientHeight);
  305.  glMatrixMode(GL_PROJECTION);
  306.  glLoadIdentity;
  307.  gluPerspective(viewangle, ClientWidth/ClientHeight, NearClipping, FarClipping);
  308.  
  309.  glMatrixMode(GL_MODELVIEW);
  310.  glLoadIdentity;
  311.  IdleHandler(Sender, tmpBool);
  312. end;
  313.  
  314. procedure TForm1.FormDestroy(Sender: TObject);
  315. begin
  316.  DeactivateRenderingContext;
  317.  DestroyRenderingContext(RC);
  318.  ReleaseDC(Handle, DC);
  319. end;
  320.  
  321. procedure TForm1.Timer1Timer(Sender: TObject);
  322. var i: Integer;
  323. begin
  324.  inc(a, 2);
  325.  if a > 360 then a := a - 360;
  326.  
  327.  for i := 0 to High(myQuads) do
  328.    myQuads[i].rz := a;
  329. end;
  330.  
  331. procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  332. begin
  333.  InterAct(x, y);
  334. end;
  335.  
  336. procedure TForm1.FormMouseWheelDown(Sender: TObject; Shift: TShiftState;  MousePos: TPoint; var Handled: Boolean);
  337. begin
  338.  CamPos[2] := CamPos[2] - 0.5;
  339. end;
  340.  
  341. procedure TForm1.FormMouseWheelUp(Sender: TObject; Shift: TShiftState;  MousePos: TPoint; var Handled: Boolean);
  342. begin
  343.  CamPos[2] := CamPos[2] + 0.5;
  344. end;
  345.  
  346. end.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Mai 17, 2007 13:20 
Offline
DGL Member

Registriert: Di Sep 19, 2006 13:24
Beiträge: 173
Schonmal nen Stoppunkt in die pick Funktion gesetzt und Step by Step kontrolliert was in den Variablen steht?


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Mai 17, 2007 14:03 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 02, 2004 19:42
Beiträge: 4158
Programmiersprache: FreePascal, C++
Also was du schilderst klingt nach nicht initialisierten Variabeln, prüf dazu mal die Kompilerausgabe.

Was ich aber auch noch festgestellt habe ist, dass du mehrfach 65025 verwendest. Dieser Wert scheint mir im Zusammenhang etwas ungünstig gewählt.
Aus
Code:
  1.  
  2. glReadPixels(X, (ClientHeight - 1 - Y), 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, @c);
  3. c := c AND $ffffff;
  4. result := GetRValue(c) * 65025 +
  5.   GetGValue(c) * 255 +
  6.   GetBValue(c);

würde ich
Code:
  1.  
  2. glReadPixels(X, (ClientHeight - 1 - Y), 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, @c);
  3. c := c AND $ffffff;
  4. result := c;
  5.  

machen, während
Code:
  1.  
  2. procedure TForm1.ID2RGB(ID: Integer; var r,g,b: Byte);
  3. begin
  4.   r := ID div 65025;
  5.   ID := ID - (r*65025);
  6.   g := ID div 255;
  7.   ID := ID - (g*255);
  8.   b := ID
  9. end;
  10.  

so aussehen sollte:
Code:
  1.  
  2. procedure TForm1.ID2RGB(ID: Integer; var r,g,b: Byte);
  3. begin
  4.   r := (ID and $FF0000) shr 16;
  5.   g := (ID and $00FF00) shr 8;
  6.   b := (ID and $0000FF);
  7. end;
  8.  


Das ist ein wenig eleganter gelöst und spart auch ein wenig rechenzeit. Was bei der ColorMethode aber auch wichtig ist, dass du im moment fest davon ausgehst, dass du deinen 32 bzw. 24 Bit Rendering Context bekommst. Auf einem System, welches nur 16 Bit unterstützt würde jede zweite ID den gleichen Farbwert haben. Das solltest du nicht außer acht lassen.

Gruß Lord Horazont

_________________
If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung.
current projects: ManiacLab; aioxmpp
zombofant networkmy photostream
„Writing code is like writing poetry“ - source unknown


„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb


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


Wer ist online?

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