summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian Paul <brian.paul@tungstengraphics.com>2000-11-15 00:26:01 +0000
committerBrian Paul <brian.paul@tungstengraphics.com>2000-11-15 00:26:01 +0000
commit30971cd098d147a4363df0dec0c338587dc1478f (patch)
tree285c7cf047f0506f376210e908eda0002a897dd2
parent4fae0260a6b9f73bbca8959b6d8f04fb43426a45 (diff)
rewrite of _mesa_win_fog_coords_from_z() so that both perspective and orthographic projection are handled correctly
-rw-r--r--src/mesa/swrast/s_fog.c109
1 files changed, 85 insertions, 24 deletions
diff --git a/src/mesa/swrast/s_fog.c b/src/mesa/swrast/s_fog.c
index 4cfea675d6..dfdc1821f2 100644
--- a/src/mesa/swrast/s_fog.c
+++ b/src/mesa/swrast/s_fog.c
@@ -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;
+#endif
+ 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;
+ /* 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 ));
+ }
}
}
break;