First of all: very helpful topic title indeed.
Secondly, if you don't want your program to drag all that GLU junk with it just for glulookat, etc.. you may want to consider this pascal code as alternative, translated from SGI'S opengl implementation sample.
Code:
// this is gluPickMatrix equivalent translated from ogl-sample.
procedure PickMatrix(x, y, deltax, deltay: GLfloat; viewport: array of integer);
begin
if (deltax <= 0) and (deltay <= 0) then
exit;
(* Translate and scale the picked region to the entire window *)
glTranslatef(
(viewport[2] - 2 * (x - viewport[0])) / deltax,
(viewport[3] - 2 * (y - viewport[1])) / deltay,
0);
glScalef(viewport[2] / deltax, viewport[3] / deltay, 1.0);
end;
// this is gluPerspective equivalent translated from ogl-sample.
// matrix should be double but i use single precision
procedure Perspective(fovy, aspect, zNear, zFar: single);
var
m: TMatrix4f;
sine, cotangent, deltaZ, radians: single;
begin
radians := fovy / 2 * Pi / 180;
deltaZ := zFar - zNear;
sine := sin(radians);
if ((deltaZ = 0) and (sine = 0) and (aspect = 0)) then
exit;
cotangent := COS(radians) / sine;
m := Identity;
m[0][0] := cotangent / aspect;
m[1][1] := cotangent;
m[2][2] := -(zFar + zNear) / deltaZ;
m[2][3] := -1;
m[3][2] := -2 * zNear * zFar / deltaZ;
m[3][3] := 0;
glMultMatrixf(@m[0][0]);
end;
// this is glulookat equivalent translated from ogl-sample.
// matrix should be single but i use single precision
procedure normalize(var v: array of single);
var
r: single;
begin
r := sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
if (r = 0) then
exit;
v[0] := v[0] / r;
v[1] := v[1] / r;
v[2] := v[2] / r;
end;
procedure crossp(var v1, v2, Result: array of single);
begin
Result[0] := v1[1] * v2[2] - v1[2] * v2[1];
Result[1] := v1[2] * v2[0] - v1[0] * v2[2];
Result[2] := v1[0] * v2[1] - v1[1] * v2[0];
end;
// translated from ogl-sample
procedure LookAt(eyex, eyey, eyez, centerx, centery, centerz, upx, upy, upz: single);
var
forw, side, up: array[0..2] of single;
m: TMatrix4f;
begin
forw[0] := centerx - eyex;
forw[1] := centery - eyey;
forw[2] := centerz - eyez;
up[0] := upx;
up[1] := upy;
up[2] := upz;
normalize(forw);
(* Side:= forw x up *)
crossp(forw, up, side);
normalize(side);
(* Recompute up as: up:= side x forw *)
crossp(side, forw, up);
m := Identity;
m[0][0] := side[0];
m[0][1] := side[1];
m[0][2] := side[2];
m[1][0] := up[0];
m[1][1] := up[1];
m[1][2] := up[2];
m[2][0] := -forw[0];
m[2][1] := -forw[1];
m[2][2] := -forw[2];
glMultMatrixf(@m);
glTranslated(-eyex, -eyey, -eyez);
end;
Bookmarks