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
Home