问题
I'm curious about gluPerspective function. I was translating the code for my engine when I saw that this function's code was messy.
void glhPerspectivef2(float *matrix, float fovyInDegrees, float aspectRatio,
float znear, float zfar)
{
float ymax, xmax;
float temp, temp2, temp3, temp4;
ymax = znear * tanf(fovyInDegrees * M_PI / 360.0);
//ymin = -ymax;
//xmin = -ymax * aspectRatio;
xmax = ymax * aspectRatio;
glhFrustumf2(matrix, -xmax, xmax, -ymax, ymax, znear, zfar);
}
Why does it create temp, temp2, temp3 and temp4? Why is there commented code? I suppose it's to specify some the parameters of glFrustum. But then, why xmin = -ymax * aspectRatio; and not xmin = -max;
回答1:
I have no idea where you've got that function from... But if you really want to calculate a perspective matrix you can do it like this.
Where the following m
is defined as float m[16];
and where the zero()
function sets all the floats in m
to 0.0f
void perspective(const float &fovy, const float &aspect, const float &zNear, const float &zFar)
{
float range = tanf(fovy / 2.0f) * zNear;
float sx = (2.0f * zNear) / (range * aspect + range * aspect);
float sy = zNear / range;
float sz = -(zFar + zNear) / (zFar - zNear);
float pz = -(2.0f * zFar * zNear) / (zFar - zNear);
zero();
m[0] = sx;
m[5] = sy;
m[10] = sz;
m[14] = pz;
m[11] = -1.0f;
}
回答2:
Did you get this code on this wiki page: http://www.opengl.org/wiki/GluPerspective_code by any chance?
Why does it create temp, temp2, temp3 and temp4?
Yes, unused variables. Most likely copied from the glhFrustumf2
implementation.
Why is there commented code? I suppose it's to specify some the parameters of glFrustum.
Yes, probably to explain the values of the parameters passed to the function glhFrustumf2
.
But then, why xmin = -ymax * aspectRatio; and not xmin = -max;
Yes, xmin = -xmax
is correct and avoids duplication.
I usually take a similar approach: perspective being implemented in terms of frustum, and frustum itself implemented in terms of simply setting all the coefficients of the matrix (this allows hiding the storage format, i.e. row-major v.s. column-major). Also having the same naming conventions for parameters as in the OpenGL man pages greatly helps when you later need to consult the code.
void
setPerspectiveMatrix4x4f(float fovy, float aspect, float zNear, float zFar, float* m)
{
const float bottom = -zNear * tanf(0.5f * fovy * M_PI / 180.0f);
const float top = -bottom;
const float left = aspect * bottom;
const float right = -left;
setFrustumMatrix4x4f(left, right, bottom, top zNear, zFar, m);
}
void
setFrustumMatrix4x4f(float left, float right, float bottom, float top, float zNear, float zFar, float* m)
{
const float dx = right - left;
const float dy = top - bottom;
const float dz = zFar - zNear;
const float mx = 0.5f * (left + right);
const float my = 0.5f * (bottom + top);
const float mz = 0.5f * (zNear + zFar);
const float n = zNear;
const float nf = zNear * zFar;
setMatrix4x4f(2.0f * n / dx, 0.0f, 2.0f * mx / dx, 0.0f,
0.0f, 2.0f * n / dy, 2.0f * my / dy, 0.0f,
0.0f, 0.0f, -2.0f * mz / dz, -2.0f * nf / dz,
0.0f, 0.0f, -1.0f, 0.0f,
m);
}
void
setMatrix4x4f(float m00, float m01, float m02, float m03,
float m10, float m11, float m12, float m13,
float m20, float m21, float m22, float m23,
float m30, float m31, float m32, float m33,
float* m)
{
// Fill m with m00, ... in row-major or column-major order
}
来源:https://stackoverflow.com/questions/21057640/gluperspective-code-messy