PDA

View Full Version : Rendering frustum shape



Brainer
26-04-2008, 04:22 AM
:arrow: System: Windows Vista SP1
:arrow: Compiler/IDE: Turbo Delphi
:arrow: Libraries/API: OpenGL

Hello. :)

I want to render the shape of the frustum. I use this code to extract the frustum from projection matrix.

procedure TFrustum.Calculate;
var
ProjM, ModM, Clip: array[0..15] of Single;
begin
glGetFloatv(GL_PROJECTION_MATRIX, @ProjM);
glGetFloatv(GL_MODELVIEW_MATRIX, @ModM);

Clip[0] := ModM[0] * ProjM[0] + ModM[1] * ProjM[4] + ModM[2] * ProjM[8] +
ModM[3] * ProjM[12];
Clip[1] := ModM[0] * ProjM[1] + ModM[1] * ProjM[5] + ModM[2] * ProjM[9] +
ModM[3] * ProjM[13];
Clip[2] := ModM[0] * ProjM[2] + ModM[1] * ProjM[6] + ModM[2] * ProjM[10] +
ModM[3] * ProjM[14];
Clip[3] := ModM[0] * ProjM[3] + ModM[1] * ProjM[7] + ModM[2] * ProjM[11] +
ModM[3] * ProjM[15];
Clip[4] := ModM[4] * ProjM[0] + ModM[5] * ProjM[4] + ModM[6] * ProjM[8] +
ModM[7] * ProjM[12];
Clip[5] := ModM[4] * ProjM[1] + ModM[5] * ProjM[5] + ModM[6] * ProjM[9] +
ModM[7] * ProjM[13];
Clip[6] := ModM[4] * ProjM[2] + ModM[5] * ProjM[6] + ModM[6] * ProjM[10] +
ModM[7] * ProjM[14];
Clip[7] := ModM[4] * ProjM[3] + ModM[5] * ProjM[7] + ModM[6] * ProjM[11] +
ModM[7] * ProjM[15];
Clip[8] := ModM[8] * ProjM[0] + ModM[9] * ProjM[4] + ModM[10] * ProjM[8] +
ModM[11] * ProjM[12];
Clip[9] := ModM[8] * ProjM[1] + ModM[9] * ProjM[5] + ModM[10] * ProjM[9] +
ModM[11] * ProjM[13];
Clip[10] := ModM[8] * ProjM[2] + ModM[9] * ProjM[6] + ModM[10] * ProjM[10] +
ModM[11] * ProjM[14];
Clip[11] := ModM[8] * ProjM[3] + ModM[9] * ProjM[7] + ModM[10] * ProjM[11] +
ModM[11] * ProjM[15];
Clip[12] := ModM[12] * ProjM[0] + ModM[13] * ProjM[4] + ModM[14] * ProjM[8] +
ModM[15] * ProjM[12];
Clip[13] := ModM[12] * ProjM[1] + ModM[13] * ProjM[5] + ModM[14] * ProjM[9] +
ModM[15] * ProjM[13];
Clip[14] := ModM[12] * ProjM[2] + ModM[13] * ProjM[6] + ModM[14] * ProjM[10] +
ModM[15] * ProjM[14];
Clip[15] := ModM[12] * ProjM[3] + ModM[13] * ProjM[7] + ModM[14] * ProjM[11] +
ModM[15] * ProjM[15];

FFrustum[Right][0] := Clip[3] - Clip[0];
FFrustum[Right][1] := Clip[7] - Clip[4];
FFrustum[Right][2] := Clip[11] - Clip[8];
FFrustum[Right][3] := Clip[15] - Clip[12];
NormalizePlane(FFrustum[Right]);

FFrustum[Left][0] := Clip[3] + Clip[0];
FFrustum[Left][1] := Clip[7] + Clip[4];
FFrustum[Left][2] := Clip[11] + Clip[8];
FFrustum[Left][3] := Clip[15] + Clip[12];
NormalizePlane(FFrustum[Left]);

FFrustum[Bottom][0] := Clip[3] + Clip[1];
FFrustum[Bottom][1] := Clip[7] + Clip[5];
FFrustum[Bottom][2] := Clip[11] + Clip[9];
FFrustum[Bottom][3] := Clip[15] + Clip[13];
NormalizePlane(FFrustum[Bottom]);

FFrustum[Top][0] := Clip[3] - Clip[1];
FFrustum[Top][1] := Clip[7] - Clip[5];
FFrustum[Top][2] := Clip[11] - Clip[9];
FFrustum[Top][3] := Clip[15] - Clip[13];
NormalizePlane(FFrustum[Top]);

FFrustum[Back][0] := Clip[3] - Clip[2];
FFrustum[Back][1] := Clip[7] - Clip[6];
FFrustum[Back][2] := Clip[11] - Clip[10];
FFrustum[Back][3] := Clip[15] - Clip[14];
NormalizePlane(FFrustum[Back]);

FFrustum[Front][0] := Clip[3] + Clip[2];
FFrustum[Front][1] := Clip[7] + Clip[6];
FFrustum[Front][2] := Clip[11] + Clip[10];
FFrustum[Front][3] := Clip[15] + Clip[14];
NormalizePlane(FFrustum[Front]);
end;


I have absolutely no idea how to write a method that will let me render the shape of the frustum I extract. :? Any ideas?

Best Regards! :)

User137
26-04-2008, 11:22 PM
You need to know position of each 8 corner vertex and then render the 6 quads along them. Seeing from your code, i don't clearly understand how to draw it from that. Plane needs a position in addition to normal, but i would imagine it would be much simpler just calculate corner vertices position somehow.

But i can give helping tip for rendering part.

Assume you use vectors like that from within array of singles or from record. This is both fast and little code used:
var v1,v2,v3,v4: array[0..2] of single; // where 0..2 = x,y,z
...
glBegin(GL_QUADS);
glVertex3fv(@v1[0]);
glVertex3fv(@v2[0]);
glVertex3fv(@v3[0]);
glVertex3fv(@v4[0]);
glEnd;

May i ask where do you use frustum shape rendering? :)

Brainer
27-04-2008, 05:05 AM
Seeing from your code, i don't clearly understand how to draw it from that.

This is how the class looks like:

{ .: THmgPlane :. }
THmgPlane = array[0..3] of Single;

{ .: TFrustum :. }
TFrustum = class(TObject)
private
{ Private declarations }
FFrustum: array[0..5] of THmgPlane;
public
{ Public declarations }
procedure Calculate();

function PointInFrustum(V: TAffineVector): Boolean;
function SphereInFrustum(Sphere: TBSphere): Boolean;
function BoxInFrustum(Box: TAABB): Boolean;
end;


Any ideas now?


May i ask where do you use frustum shape rendering? :)
I just wanted to know, how the frustum looks like! :lol:

Andreaz
27-04-2008, 08:46 AM
try rendeing a quad for each of the 4 planes, that should do the trick.

Brainer
27-04-2008, 11:23 AM
try rendeing a quad for each of the 4 planes, that should do the trick.
Why 4 planes? There are six planes, aren't there? :?
Anyway, you mean something like that?

var
I: Integer;
begin
for I := 0 to 3 do
begin
glBegin(GL_QUADS);
glVertex3fv(@FFrustum[I]);
glEnd();
end;

User137
28-04-2008, 12:38 AM
No, more like:
(Where FFrustumPlane is the corner points that needs to be calculated first)

var
I: Integer;
begin
glBegin(GL_QUADS);
for I := 0 to 5 do begin
// Quad consists of 4 points
glVertex3fv(@FFrustumPlane[I].p1);
glVertex3fv(@FFrustumPlane[I].p2);
glVertex3fv(@FFrustumPlane[I].p3);
glVertex3fv(@FFrustumPlane[I].p4);
end;
glEnd();

{
glVertex3fv(@FFrustumPlane[I].p1);
means the same as
glVertex3f(FFrustumPlane[I].p1.x, FFrustumPlane[I].p1.y, FFrustumPlane[I].p1.z);
}

If you would only use mathematical plane (like your frustum plane currently is, by 4 values defining the entire plane) formula to define the quads, you would need to calculate 4 plane intersection lines. And then intersect those with the remaining 2 planes to get the corner points... which is all complicated and i wouldn't even try that way :lol:

Search out definitions for modelview and projection matrix and see if there's perhaps something that you could use to directly calculate corners. And actually this way doesn't seem to be simple either