rewrite of _mesa_win_fog_coords_from_z() so that both perspective and orthographic projection are handled correctly

This commit is contained in:
Brian Paul
2000-11-15 00:26:01 +00:00
parent 4fae0260a6
commit 30971cd098
+85 -24
View File
@@ -1,4 +1,4 @@
/* $Id: s_fog.c,v 1.2 2000/11/05 18:24:40 keithw Exp $ */
/* $Id: s_fog.c,v 1.3 2000/11/15 00:26:01 brianp Exp $ */
/*
* Mesa 3-D graphics library
@@ -102,12 +102,35 @@ _mesa_win_fog_coords_from_z( const GLcontext *ctx,
const GLdepth z[],
GLfixed fogcoord[] )
{
GLfloat c = ctx->ProjectionMatrix.m[10];
GLfloat d = ctx->ProjectionMatrix.m[14];
const GLboolean ortho = (ctx->ProjectionMatrix.m[15] != 0.0F);
const GLfloat p10 = ctx->ProjectionMatrix.m[10];
const GLfloat p14 = ctx->ProjectionMatrix.m[14];
const GLfloat tz = ctx->Viewport._WindowMap.m[MAT_TZ];
const GLfloat szInv = 1.0F / ctx->Viewport._WindowMap.m[MAT_SZ];
GLuint i;
GLfloat tz = ctx->Viewport._WindowMap.m[MAT_TZ];
GLfloat szInv = 1.0F / ctx->Viewport._WindowMap.m[MAT_SZ];
/*
* Note: to compute eyeZ from the ndcZ we have to solve the following:
*
* p[10] * eyeZ + p[14] * eyeW
* ndcZ = ---------------------------
* p[11] * eyeZ + p[15] * eyeW
*
* Thus:
*
* p[14] * eyeW - p[15] * eyeW * ndcZ
* eyeZ = ----------------------------------
* p[11] * ndcZ - p[10]
*
* If we note:
* a) if using an orthographic projection, p[11] = 0 and p[15] = 1.
* b) if using a perspective projection, p[11] = -1 and p[15] = 0.
* c) we assume eyeW = 1 (not always true- glVertex4)
*
* Then we can simplify the calculation of eyeZ quite a bit. We do
* separate calculations for the orthographic and perspective cases below.
* Note that we drop a negative sign or two since they don't matter.
*/
switch (ctx->Fog.Mode) {
case GL_LINEAR:
@@ -115,35 +138,73 @@ _mesa_win_fog_coords_from_z( const GLcontext *ctx,
GLfloat fogEnd = ctx->Fog.End;
GLfloat fogScale = (GLfloat) FIXED_ONE / (ctx->Fog.End -
ctx->Fog.Start);
for (i=0;i<n;i++) {
GLfloat ndcz = ((GLfloat) z[i] - tz) * szInv;
GLfloat eyez = -d / (c+ndcz);
if (eyez < 0.0) eyez = -eyez;
fogcoord[i] = (GLint)(fogEnd - eyez) * fogScale;
if (ortho) {
for (i=0;i<n;i++) {
GLfloat ndcz = ((GLfloat) z[i] - tz) * szInv;
GLfloat eyez = (ndcz - p14) / p10;
if (eyez < 0.0) eyez = -eyez;
fogcoord[i] = (GLint) ((fogEnd - eyez) * fogScale);
}
}
else {
/* perspective */
for (i=0;i<n;i++) {
GLfloat ndcz = ((GLfloat) z[i] - tz) * szInv;
GLfloat eyez = p14 / (ndcz + p10);
if (eyez < 0.0) eyez = -eyez;
fogcoord[i] = (GLint) ((fogEnd - eyez) * fogScale);
}
}
}
break;
case GL_EXP:
for (i=0;i<n;i++) {
GLfloat ndcz = ((GLfloat) z[i] - tz) * szInv;
GLfloat eyez = d / (c+ndcz);
if (eyez < 0.0) eyez = -eyez;
fogcoord[i] = FloatToFixed(exp( -ctx->Fog.Density * eyez ));
}
if (ortho) {
for (i=0;i<n;i++) {
GLfloat ndcz = ((GLfloat) z[i] - tz) * szInv;
GLfloat eyez = (ndcz - p14) / p10;
if (eyez < 0.0) eyez = -eyez;
fogcoord[i] = FloatToFixed(exp( -ctx->Fog.Density * eyez ));
}
}
else {
/* perspective */
for (i=0;i<n;i++) {
GLfloat ndcz = ((GLfloat) z[i] - tz) * szInv;
GLfloat eyez = p14 / (ndcz + p10);
if (eyez < 0.0) eyez = -eyez;
fogcoord[i] = FloatToFixed(exp( -ctx->Fog.Density * eyez ));
}
}
break;
case GL_EXP2:
{
GLfloat negDensitySquared = -ctx->Fog.Density * ctx->Fog.Density;
for (i=0;i<n;i++) {
GLfloat ndcz = ((GLfloat) z[i] - tz) * szInv;
GLfloat eyez = d / (c+ndcz);
GLfloat tmp = negDensitySquared * eyez * eyez;
if (ortho) {
for (i=0;i<n;i++) {
GLfloat ndcz = ((GLfloat) z[i] - tz) * szInv;
GLfloat eyez = (ndcz - p14) / p10;
GLfloat tmp = negDensitySquared * eyez * eyez;
#if defined(__alpha__) || defined(__alpha)
/* XXX this underflow check may be needed for other systems */
if (tmp < FLT_MIN_10_EXP)
tmp = FLT_MIN_10_EXP;
/* XXX this underflow check may be needed for other systems*/
if (tmp < FLT_MIN_10_EXP)
tmp = FLT_MIN_10_EXP;
#endif
fogcoord[i] = FloatToFixed(exp( tmp ));
fogcoord[i] = FloatToFixed(exp( tmp ));
}
}
else {
/* perspective */
for (i=0;i<n;i++) {
GLfloat ndcz = ((GLfloat) z[i] - tz) * szInv;
GLfloat eyez = p14 / (ndcz + p10);
GLfloat tmp = negDensitySquared * eyez * eyez;
#if defined(__alpha__) || defined(__alpha)
/* XXX this underflow check may be needed for other systems*/
if (tmp < FLT_MIN_10_EXP)
tmp = FLT_MIN_10_EXP;
#endif
fogcoord[i] = FloatToFixed(exp( tmp ));
}
}
}
break;