Moved software rasterizer functionality to new directory.
[mesa.git] / src / mesa / swrast / s_fog.c
1 /* $Id: s_fog.c,v 1.1 2000/10/31 18:00:04 keithw Exp $ */
2
3 /*
4 * Mesa 3-D graphics library
5 * Version: 3.5
6 *
7 * Copyright (C) 1999-2000 Brian Paul All Rights Reserved.
8 *
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:
15 *
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
18 *
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.
25 */
26
27
28 #include "glheader.h"
29 #include "colormac.h"
30 #include "context.h"
31 #include "macros.h"
32 #include "mmath.h"
33
34 #include "s_fog.h"
35
36
37 /*
38 * Apply fog to an array of RGBA pixels.
39 * Input: n - number of pixels
40 * fog - array of interpolated screen-space fog coordinates in [0..1]
41 * red, green, blue, alpha - pixel colors
42 * Output: red, green, blue, alpha - fogged pixel colors
43 */
44 void
45 _mesa_fog_rgba_pixels( const GLcontext *ctx,
46 GLuint n,
47 const GLfixed fog[],
48 GLchan rgba[][4] )
49 {
50 GLfixed rFog = ctx->Fog.Color[0] * CHAN_MAXF;
51 GLfixed gFog = ctx->Fog.Color[1] * CHAN_MAXF;
52 GLfixed bFog = ctx->Fog.Color[2] * CHAN_MAXF;
53 GLuint i;
54
55 for (i=0;i<n;i++) {
56 GLfixed f = CLAMP(fog[i], 0, FIXED_ONE);
57 GLfixed g = FIXED_ONE - f;
58 rgba[i][0] = (f*rgba[i][0] + g*rFog) >> FIXED_SHIFT;
59 rgba[i][1] = (f*rgba[i][1] + g*gFog) >> FIXED_SHIFT;
60 rgba[i][2] = (f*rgba[i][2] + g*bFog) >> FIXED_SHIFT;
61 }
62 }
63
64
65
66
67 /*
68 * Apply fog to an array of color index pixels.
69 * Input: n - number of pixels
70 * z - array of integer depth values
71 * index - pixel color indexes
72 * Output: index - fogged pixel color indexes
73 */
74 void
75 _mesa_fog_ci_pixels( const GLcontext *ctx,
76 GLuint n, const GLfixed fog[], GLuint index[] )
77 {
78 GLuint idx = ctx->Fog.Index;
79 GLuint i;
80
81 for (i=0;i<n;i++) {
82 GLfixed f = FixedToFloat(CLAMP(fog[i], 0, FIXED_ONE));
83 index[i] = (GLuint) ((GLfloat) index[i] + (1.0F-f) * idx);
84 }
85 }
86
87
88
89 /*
90 * Calculate fog coords from window z values
91 * Input: n - number of pixels
92 * z - array of integer depth values
93 * red, green, blue, alpha - pixel colors
94 * Output: red, green, blue, alpha - fogged pixel colors
95 *
96 * Use lookup table & interpolation?
97 */
98 void
99 _mesa_win_fog_coords_from_z( const GLcontext *ctx,
100 GLuint n,
101 const GLdepth z[],
102 GLfixed fogcoord[] )
103 {
104 GLfloat c = ctx->ProjectionMatrix.m[10];
105 GLfloat d = ctx->ProjectionMatrix.m[14];
106 GLuint i;
107
108 GLfloat tz = ctx->Viewport.WindowMap.m[MAT_TZ];
109 GLfloat szInv = 1.0F / ctx->Viewport.WindowMap.m[MAT_SZ];
110
111 switch (ctx->Fog.Mode) {
112 case GL_LINEAR:
113 {
114 GLfloat fogEnd = ctx->Fog.End;
115 GLfloat fogScale = (GLfloat) FIXED_ONE / (ctx->Fog.End -
116 ctx->Fog.Start);
117 for (i=0;i<n;i++) {
118 GLfloat ndcz = ((GLfloat) z[i] - tz) * szInv;
119 GLfloat eyez = -d / (c+ndcz);
120 if (eyez < 0.0) eyez = -eyez;
121 fogcoord[i] = (GLint)(fogEnd - eyez) * fogScale;
122 }
123 }
124 break;
125 case GL_EXP:
126 for (i=0;i<n;i++) {
127 GLfloat ndcz = ((GLfloat) z[i] - tz) * szInv;
128 GLfloat eyez = d / (c+ndcz);
129 if (eyez < 0.0) eyez = -eyez;
130 fogcoord[i] = FloatToFixed(exp( -ctx->Fog.Density * eyez ));
131 }
132 break;
133 case GL_EXP2:
134 {
135 GLfloat negDensitySquared = -ctx->Fog.Density * ctx->Fog.Density;
136 for (i=0;i<n;i++) {
137 GLfloat ndcz = ((GLfloat) z[i] - tz) * szInv;
138 GLfloat eyez = d / (c+ndcz);
139 GLfloat tmp = negDensitySquared * eyez * eyez;
140 #if defined(__alpha__) || defined(__alpha)
141 /* XXX this underflow check may be needed for other systems */
142 if (tmp < FLT_MIN_10_EXP)
143 tmp = FLT_MIN_10_EXP;
144 #endif
145 fogcoord[i] = FloatToFixed(exp( tmp ));
146 }
147 }
148 break;
149 default:
150 gl_problem(ctx, "Bad fog mode in _mesa_win_fog_coords_from_z");
151 return;
152 }
153 }
154
155
156 /*
157 * Apply fog to an array of RGBA pixels.
158 * Input: n - number of pixels
159 * z - array of integer depth values
160 * red, green, blue, alpha - pixel colors
161 * Output: red, green, blue, alpha - fogged pixel colors
162 */
163 void
164 _mesa_depth_fog_rgba_pixels( const GLcontext *ctx,
165 GLuint n, const GLdepth z[], GLchan rgba[][4] )
166 {
167 GLfixed fog[MAX_WIDTH];
168 _mesa_win_fog_coords_from_z( ctx, n, z, fog );
169 _mesa_fog_rgba_pixels( ctx, n, fog, rgba );
170 }
171
172
173 /*
174 * Apply fog to an array of color index pixels.
175 * Input: n - number of pixels
176 * z - array of integer depth values
177 * index - pixel color indexes
178 * Output: index - fogged pixel color indexes
179 */
180 void
181 _mesa_depth_fog_ci_pixels( const GLcontext *ctx,
182 GLuint n, const GLdepth z[], GLuint index[] )
183 {
184 GLfixed fog[MAX_WIDTH];
185 _mesa_win_fog_coords_from_z( ctx, n, z, fog );
186 _mesa_fog_ci_pixels( ctx, n, fog, index );
187 }
188