PDA

View Full Version : Frustum culling problem...



M109uk
09-04-2005, 08:57 AM
Hi all,

I have a problem with my frustum class, i have looked at several other sources and im still getting similar problems and i cant work out why :s

My problem is that the wrong tiles in my terrain are taken out when of course they shouldnt be:

<img source="http://www.freepgs.com/m109uk/Frustum_prob.jpg" height="100" width="100"> (http://www.freepgs.com/m109uk/Frustum_prob.jpg)

And my class is:

type
TxnFrustum = Class
private
procedure NormalizeFrustum(const Side: Integer);
public
Frustum: Array[0..5] Of Array[0..3] Of Single;
procedure CalculateFrustum;
function PointInFrustum(const X,Y,Z: Single): Boolean; overload;
function PointInFrustum(const p: TVertex3f): Boolean; overload;
end;

var
Frustum: TxnFrustum;

implementation
uses
dglOpenGL;

const
RIGHT = 0;
LEFT = 1;
BOTTOM = 2;
TOP = 3;
BACK = 4;
FRONT = 5;

//----< TxnFrustum >----//
procedure TxnFrustum.NormalizeFrustum(const Side: Integer);
var
Mag: Single;
begin
// I have also tried the following, with similar effects
// Mag := (Frust[0]*Frust[0]+Frust[1]*Frust[1]+Frust[2]*Frust[2]);
// Mag := Sqrt(Frust[0]*Frust[0]+Frust[1]*Frust[1]+Frust[2]*Frust[2]);

Mag := Sqrt(Sqr(Frustum[Side][0])+Sqr(Frustum[Side][1])+Sqr(Frustum[Side][2]));

Frustum[Side][0] := Frustum[Side][0]/Mag;
Frustum[Side][1] := Frustum[Side][1]/Mag;
Frustum[Side][2] := Frustum[Side][2]/Mag;
Frustum[Side][3] := Frustum[Side][3]/Mag;
end;

procedure TxnFrustum.CalculateFrustum;
var
proj,modl,clip: Array [0..15] Of Single;
begin
glGetFloatv(GL_PROJECTION_MATRIX, @proj);
glGetFloatv(GL_MODELVIEW_MATRIX, @modl);

clip[0] := modl[0]*proj[0]+modl[1]*proj[4]+modl[2]*proj[8]+modl[3]*proj[12];
clip[1] := modl[0]*proj[1]+modl[1]*proj[5]+modl[2]*proj[9]+modl[3]*proj[13];
clip[2] := modl[0]*proj[2]+modl[1]*proj[6]+modl[2]*proj[10]+modl[3]*proj[14];
clip[3] := modl[0]*proj[3]+modl[1]*proj[7]+modl[2]*proj[11]+modl[3]*proj[15];

clip[4] := modl[4]*proj[0]+modl[5]*proj[4]+modl[6]*proj[8]+modl[7]*proj[12];
clip[5] := modl[4]*proj[1]+modl[5]*proj[5]+modl[6]*proj[9]+modl[7]*proj[13];
clip[6] := modl[4]*proj[2]+modl[5]*proj[6]+modl[6]*proj[10]+modl[7]*proj[14];
clip[7] := modl[4]*proj[3]+modl[5]*proj[7]+modl[6]*proj[11]+modl[7]*proj[15];

clip[8] := modl[8]*proj[0]+modl[9]*proj[4]+modl[10]*proj[8]+modl[11]*proj[12];
clip[9] := modl[8]*proj[1]+modl[9]*proj[5]+modl[10]*proj[9]+modl[11]*proj[13];
clip[10] := modl[8]*proj[2]+modl[9]*proj[6]+modl[10]*proj[10]+modl[11]*proj[14];
clip[11] := modl[8]*proj[3]+modl[9]*proj[7]+modl[10]*proj[11]+modl[11]*proj[15];

clip[12] := modl[12]*proj[0]+modl[13]*proj[4]+modl[14]*proj[8]+modl[15]*proj[12];
clip[13] := modl[12]*proj[1]+modl[13]*proj[5]+modl[14]*proj[9]+modl[15]*proj[13];
clip[14] := modl[12]*proj[2]+modl[13]*proj[6]+modl[14]*proj[10]+modl[15]*proj[14];
clip[15] := modl[12]*proj[3]+modl[13]*proj[7]+modl[14]*proj[11]+modl[15]*proj[15];

Frustum[RIGHT][0] := clip[3]-clip[0];
Frustum[RIGHT][1] := clip[7]-clip[4];
Frustum[RIGHT][2] := clip[11]-clip[8];
Frustum[RIGHT][3] := clip[15]-clip[12];
NormalizeFrustum(RIGHT);

Frustum[LEFT][0] := clip[3]+clip[0];
Frustum[LEFT][1] := clip[7]+clip[4];
Frustum[LEFT][2] := clip[11]+clip[8];
Frustum[LEFT][3] := clip[15]+clip[12];
NormalizeFrustum(LEFT);

Frustum[BOTTOM][0] := clip[3]+clip[1];
Frustum[BOTTOM][1] := clip[7]+clip[5];
Frustum[BOTTOM][2] := clip[11]+clip[9];
Frustum[BOTTOM][3] := clip[15]+clip[13];
NormalizeFrustum(BOTTOM);

Frustum[TOP][0] := clip[3]-clip[1];
Frustum[TOP][1] := clip[7]-clip[5];
Frustum[TOP][2] := clip[11]-clip[9];
Frustum[TOP][3] := clip[15]-clip[13];
NormalizeFrustum(TOP);

Frustum[BACK][0] := clip[3]-clip[2];
Frustum[BACK][1] := clip[7]-clip[6];
Frustum[BACK][2] := clip[11]-clip[10];
Frustum[BACK][3] := clip[15]-clip[14];
NormalizeFrustum(BACK);

Frustum[FRONT][0] := clip[3]+clip[2];
Frustum[FRONT][1] := clip[7]+clip[6];
Frustum[FRONT][2] := clip[11]+clip[10];
Frustum[FRONT][3] := clip[15]+clip[14];
NormalizeFrustum(FRONT);
end;

function TxnFrustum.PointInFrustum(const X,Y,Z: Single): Boolean;
var
i: Integer;
begin
Result := True;
For i := 0 To 5 Do
If (Frustum[i][0]*X+Frustum[i][1]*Y+Frustum[i][2]*Z+Frustum[i][3] <= 0) Then
Begin
Result := False;
Exit;
End;
end;

function TxnFrustum.PointInFrustum(const p: TVertex3f): Boolean;
begin
Result := PointInFrustum(p[0], p[1], p[2]);
end;

initialization
Frustum := TxnFrustum.Create;

finalization
Frustum.Free;


Im calculating the frustum everytime i call a procedure in my camera class which is before i render my terrain.

Thanx for any help..

M109uk
09-04-2005, 09:29 AM
Ok i found what was causing the problem, i forgot i was using glScalef in the terrain rendering...