OpenGL v Delphi4



Míření


Příklad a zdroják ke stažení (277k)



Příklad, jak vypočítat souřadnice bodu, kam zrovna ukazuje myš, pomocí funkce 'glReadPixels'.



Nové proměnné jsou:

MousePosition : TPoint2;                     //Pozice myši   
MouseAiming: TPoint3;                        //Výsledná hodnota souřadnice bodu, kam myš ukazuje
ViewAngle, NearClip, FarClip: single;        //Hodnoty, které se zadávají do funkce 'gluPerspective'



Vše se počítá v proceduře:

procedure Aiming;
var
X,Y: integer;
DX,DY,DZ: double;
zbuf, d: single;
begin
  X := MousePosition.x;
  Y := MousePosition.y;

  glReadPixels(x,Form1.ClientHeight-y, 1,1, GL_DEPTH_COMPONENT, GL_Float,@zbuf);
  zbuf := NearClip*FarClip/((NearClip-FarClip)*(ZBuf+FarClip/(NearClip-FarClip)));
  d:=(Form1.ClientHeight/2)/tan(ViewAngle/2*Pi/180);
  MouseAiming.z := zbuf;
  MouseAiming.x:=(x-Form1.ClientWidth div 2)*MouseAiming.z/d;
  MouseAiming.y:=-(y-Form1.ClientHeight div 2)*MouseAiming.z/d;
  with Angle do begin
    MouseAiming:=RotateVector(MouseAiming,-x,-y,-z);     
  end;

  MouseAiming:=TranslateVector(MouseAiming,Tran);

  if zbuf=FarClip then begin
    MouseAiming.x:=0;
    MouseAiming.y:=0;
    MouseAiming.z:=0;
  end;

  DX := Round(MouseAiming.x * 100)/100;
  DY := Round(MouseAiming.y * 100)/100;
  DZ := Round(MouseAiming.z * 100)/100;

  Form1.Label1.Caption := 'X: '+ FloatToStr(DX);
  Form1.Label2.Caption := 'Y: '+ FloatToStr(DY);
  Form1.Label3.Caption := 'Z: '+ FloatToStr(DZ);
end;


Nejdříve dosadíme do proměnné X,Y pozici myši

  X := MousePosition.x;
  Y := MousePosition.y;


Funkce

  glReadPixels(x,Form1.ClientHeight-y, 1,1, GL_DEPTH_COMPONENT, GL_Float,@zbuf);

přečte Z-Bufer a dosadí do proměnné 'zbuf'.


Vypočítáme vzdálenost od objektu a dosadíme do 'zbuf'

  zbuf := NearClip*FarClip/((NearClip-FarClip)*(ZBuf+FarClip/(NearClip-FarClip)));


Vypočítáme si vzdálenost pozorovatele od stínítka

  d:=(Form1.ClientHeight/2)/tan(ViewAngle/2*Pi/180);


Nakonec vypočítáme souřadnice bodu, kam myš ukazuje

  MouseAiming.z := zbuf;
  MouseAiming.x:=(x-Form1.ClientWidth div 2)*MouseAiming.z/d;
  MouseAiming.y:=-(y-Form1.ClientHeight div 2)*MouseAiming.z/d;


Nyní máme vypočítaný souřadnice, ale pokud hneme s kamerou, výpočty nebudou souhlasit. Proto musíme výsledné souřadnice násobit maticí rotace kamery

  with Angle do begin
    MouseAiming:=RotateVector(MouseAiming,-x,-y,-z);     
  end;

(protože je souřadnicový systém vůči kameře opačně natočen, musíme zadat záporné hodnoty '-x,-y,-z')
a ještě musíme přepočítat vektory bodu, vůči pozici kamery.

  MouseAiming:=TranslateVector(MouseAiming,Tran);

Na obě použité funkce můžete mrknout tady


No a je vlastně hotovo. Ještě jsem přidal detekci, která zjistí jesli myší ukazuju na objekt, nebo mimo něj. Pokud ukazuju mimo, vyhodí to nuly.

  if zbuf=FarClip then begin
    MouseAiming.x:=0;
    MouseAiming.y:=0;
    MouseAiming.z:=0;
  end;


Nakonec jsem výsledné hodnoty bodu převed na dvě desetiná místa a hodnotu vypsal pomoci 'Label' na obrazovku.

  DX := Round(MouseAiming.x * 100)/100;
  DY := Round(MouseAiming.y * 100)/100;
  DZ := Round(MouseAiming.z * 100)/100;

  Form1.Label1.Caption := 'X: '+ FloatToStr(DX);
  Form1.Label2.Caption := 'Y: '+ FloatToStr(DY);
  Form1.Label3.Caption := 'Z: '+ FloatToStr(DZ);




Celej zdroják je tady
Aiming_f



3D Fonty, výpočet FPS Průhlený okraj textury
Home