1 /* $Id: s_fog.c,v 1.4 2000/12/13 17:35:43 brianp Exp $ */
4 * Mesa 3-D graphics library
7 * Copyright (C) 1999-2000 Brian Paul All Rights Reserved.
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
34 #include "s_context.h"
39 * Apply fog to an array of RGBA pixels.
40 * Input: n - number of pixels
41 * fog - array of interpolated screen-space fog coordinates in [0..1]
42 * red, green, blue, alpha - pixel colors
43 * Output: red, green, blue, alpha - fogged pixel colors
46 _mesa_fog_rgba_pixels( const GLcontext
*ctx
,
51 GLfixed rFog
= ctx
->Fog
.Color
[0] * CHAN_MAXF
;
52 GLfixed gFog
= ctx
->Fog
.Color
[1] * CHAN_MAXF
;
53 GLfixed bFog
= ctx
->Fog
.Color
[2] * CHAN_MAXF
;
57 GLfixed f
= CLAMP(fog
[i
], 0, FIXED_ONE
);
58 GLfixed g
= FIXED_ONE
- f
;
59 rgba
[i
][0] = (f
*rgba
[i
][0] + g
*rFog
) >> FIXED_SHIFT
;
60 rgba
[i
][1] = (f
*rgba
[i
][1] + g
*gFog
) >> FIXED_SHIFT
;
61 rgba
[i
][2] = (f
*rgba
[i
][2] + g
*bFog
) >> FIXED_SHIFT
;
69 * Apply fog to an array of color index pixels.
70 * Input: n - number of pixels
71 * z - array of integer depth values
72 * index - pixel color indexes
73 * Output: index - fogged pixel color indexes
76 _mesa_fog_ci_pixels( const GLcontext
*ctx
,
77 GLuint n
, const GLfixed fog
[], GLuint index
[] )
79 GLuint idx
= ctx
->Fog
.Index
;
83 GLfloat f
= FixedToFloat(CLAMP(fog
[i
], 0, FIXED_ONE
));
84 index
[i
] = (GLuint
) ((GLfloat
) index
[i
] + (1.0F
-f
) * idx
);
91 * Calculate fog coords from window z values
92 * Input: n - number of pixels
93 * z - array of integer depth values
94 * red, green, blue, alpha - pixel colors
95 * Output: red, green, blue, alpha - fogged pixel colors
97 * Use lookup table & interpolation?
100 _mesa_win_fog_coords_from_z( const GLcontext
*ctx
,
105 const GLboolean ortho
= (ctx
->ProjectionMatrix
.m
[15] != 0.0F
);
106 const GLfloat p10
= ctx
->ProjectionMatrix
.m
[10];
107 const GLfloat p14
= ctx
->ProjectionMatrix
.m
[14];
108 const GLfloat tz
= ctx
->Viewport
._WindowMap
.m
[MAT_TZ
];
109 const GLfloat szInv
= 1.0F
/ ctx
->Viewport
._WindowMap
.m
[MAT_SZ
];
113 * Note: to compute eyeZ from the ndcZ we have to solve the following:
115 * p[10] * eyeZ + p[14] * eyeW
116 * ndcZ = ---------------------------
117 * p[11] * eyeZ + p[15] * eyeW
121 * p[14] * eyeW - p[15] * eyeW * ndcZ
122 * eyeZ = ----------------------------------
123 * p[11] * ndcZ - p[10]
126 * a) if using an orthographic projection, p[11] = 0 and p[15] = 1.
127 * b) if using a perspective projection, p[11] = -1 and p[15] = 0.
128 * c) we assume eyeW = 1 (not always true- glVertex4)
130 * Then we can simplify the calculation of eyeZ quite a bit. We do
131 * separate calculations for the orthographic and perspective cases below.
132 * Note that we drop a negative sign or two since they don't matter.
135 switch (ctx
->Fog
.Mode
) {
138 GLfloat fogEnd
= ctx
->Fog
.End
;
139 GLfloat fogScale
= (GLfloat
) FIXED_ONE
/ (ctx
->Fog
.End
-
143 GLfloat ndcz
= ((GLfloat
) z
[i
] - tz
) * szInv
;
144 GLfloat eyez
= (ndcz
- p14
) / p10
;
145 if (eyez
< 0.0) eyez
= -eyez
;
146 fogcoord
[i
] = (GLint
) ((fogEnd
- eyez
) * fogScale
);
152 GLfloat ndcz
= ((GLfloat
) z
[i
] - tz
) * szInv
;
153 GLfloat eyez
= p14
/ (ndcz
+ p10
);
154 if (eyez
< 0.0) eyez
= -eyez
;
155 fogcoord
[i
] = (GLint
) ((fogEnd
- eyez
) * fogScale
);
163 GLfloat ndcz
= ((GLfloat
) z
[i
] - tz
) * szInv
;
164 GLfloat eyez
= (ndcz
- p14
) / p10
;
165 if (eyez
< 0.0) eyez
= -eyez
;
166 fogcoord
[i
] = FloatToFixed(exp( -ctx
->Fog
.Density
* eyez
));
172 GLfloat ndcz
= ((GLfloat
) z
[i
] - tz
) * szInv
;
173 GLfloat eyez
= p14
/ (ndcz
+ p10
);
174 if (eyez
< 0.0) eyez
= -eyez
;
175 fogcoord
[i
] = FloatToFixed(exp( -ctx
->Fog
.Density
* eyez
));
181 GLfloat negDensitySquared
= -ctx
->Fog
.Density
* ctx
->Fog
.Density
;
184 GLfloat ndcz
= ((GLfloat
) z
[i
] - tz
) * szInv
;
185 GLfloat eyez
= (ndcz
- p14
) / p10
;
186 GLfloat tmp
= negDensitySquared
* eyez
* eyez
;
187 #if defined(__alpha__) || defined(__alpha)
188 /* XXX this underflow check may be needed for other systems*/
189 if (tmp
< FLT_MIN_10_EXP
)
190 tmp
= FLT_MIN_10_EXP
;
192 fogcoord
[i
] = FloatToFixed(exp( tmp
));
198 GLfloat ndcz
= ((GLfloat
) z
[i
] - tz
) * szInv
;
199 GLfloat eyez
= p14
/ (ndcz
+ p10
);
200 GLfloat tmp
= negDensitySquared
* eyez
* eyez
;
201 #if defined(__alpha__) || defined(__alpha)
202 /* XXX this underflow check may be needed for other systems*/
203 if (tmp
< FLT_MIN_10_EXP
)
204 tmp
= FLT_MIN_10_EXP
;
206 fogcoord
[i
] = FloatToFixed(exp( tmp
));
212 gl_problem(ctx
, "Bad fog mode in _mesa_win_fog_coords_from_z");
219 * Apply fog to an array of RGBA pixels.
220 * Input: n - number of pixels
221 * z - array of integer depth values
222 * red, green, blue, alpha - pixel colors
223 * Output: red, green, blue, alpha - fogged pixel colors
226 _mesa_depth_fog_rgba_pixels( const GLcontext
*ctx
,
227 GLuint n
, const GLdepth z
[], GLchan rgba
[][4] )
229 GLfixed fog
[MAX_WIDTH
];
230 _mesa_win_fog_coords_from_z( ctx
, n
, z
, fog
);
231 _mesa_fog_rgba_pixels( ctx
, n
, fog
, rgba
);
236 * Apply fog to an array of color index pixels.
237 * Input: n - number of pixels
238 * z - array of integer depth values
239 * index - pixel color indexes
240 * Output: index - fogged pixel color indexes
243 _mesa_depth_fog_ci_pixels( const GLcontext
*ctx
,
244 GLuint n
, const GLdepth z
[], GLuint index
[] )
246 GLfixed fog
[MAX_WIDTH
];
247 _mesa_win_fog_coords_from_z( ctx
, n
, z
, fog
);
248 _mesa_fog_ci_pixels( ctx
, n
, fog
, index
);