ReactOS  0.4.13-dev-247-g0f29b3f
fog.c
Go to the documentation of this file.
1 /* $Id: fog.c,v 1.9 1997/07/24 01:25:01 brianp Exp $ */
2 
3 /*
4  * Mesa 3-D graphics library
5  * Version: 2.4
6  * Copyright (C) 1995-1996 Brian Paul
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Library General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Library General Public License for more details.
17  *
18  * You should have received a copy of the GNU Library General Public
19  * License along with this library; if not, write to the Free
20  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21  */
22 
23 
24 /*
25  * $Log: fog.c,v $
26  * Revision 1.9 1997/07/24 01:25:01 brianp
27  * changed precompiled header symbol from PCH to PC_HEADER
28  *
29  * Revision 1.8 1997/06/20 04:14:47 brianp
30  * changed color components from GLfixed to GLubyte
31  *
32  * Revision 1.7 1997/05/28 03:24:54 brianp
33  * added precompiled header (PCH) support
34  *
35  * Revision 1.6 1997/05/22 03:03:47 brianp
36  * don't apply fog to alpha values
37  *
38  * Revision 1.5 1997/04/20 20:28:49 brianp
39  * replaced abort() with gl_problem()
40  *
41  * Revision 1.4 1996/11/04 02:30:15 brianp
42  * optimized gl_fog_color_pixels() and gl_fog_index_pixels()
43  *
44  * Revision 1.3 1996/09/27 01:26:52 brianp
45  * added missing default cases to switches
46  *
47  * Revision 1.2 1996/09/15 14:17:30 brianp
48  * now use GLframebuffer and GLvisual
49  *
50  * Revision 1.1 1996/09/13 01:38:16 brianp
51  * Initial revision
52  *
53  */
54 
55 
56 #ifdef PC_HEADER
57 #include "all.h"
58 #else
59 #include <math.h>
60 #include <stdlib.h>
61 #include "context.h"
62 #include "fog.h"
63 #include "dlist.h"
64 #include "macros.h"
65 #include "types.h"
66 #endif
67 
68 
69 
71 {
72  GLenum m;
73 
74  switch (pname) {
75  case GL_FOG_MODE:
76  m = (GLenum) (GLint) *params;
77  if (m==GL_LINEAR || m==GL_EXP || m==GL_EXP2) {
78  ctx->Fog.Mode = m;
79  }
80  else {
81  gl_error( ctx, GL_INVALID_ENUM, "glFog" );
82  }
83  break;
84  case GL_FOG_DENSITY:
85  if (*params<0.0) {
86  gl_error( ctx, GL_INVALID_VALUE, "glFog" );
87  }
88  else {
89  ctx->Fog.Density = *params;
90  }
91  break;
92  case GL_FOG_START:
93 #ifndef GL_VERSION_1_1
94  if (*params<0.0F) {
95  gl_error( ctx, GL_INVALID_VALUE, "glFog(GL_FOG_START)" );
96  return;
97  }
98 #endif
99  ctx->Fog.Start = *params;
100  break;
101  case GL_FOG_END:
102 #ifndef GL_VERSION_1_1
103  if (*params<0.0F) {
104  gl_error( ctx, GL_INVALID_VALUE, "glFog(GL_FOG_END)" );
105  return;
106  }
107 #endif
108  ctx->Fog.End = *params;
109  break;
110  case GL_FOG_INDEX:
111  ctx->Fog.Index = *params;
112  break;
113  case GL_FOG_COLOR:
114  ctx->Fog.Color[0] = params[0];
115  ctx->Fog.Color[1] = params[1];
116  ctx->Fog.Color[2] = params[2];
117  ctx->Fog.Color[3] = params[3];
118  break;
119  default:
120  gl_error( ctx, GL_INVALID_ENUM, "glFog" );
121  }
122 }
123 
124 
125 
126 
127 /*
128  * Compute the fogged color for an array of vertices.
129  * Input: n - number of vertices
130  * v - array of vertices
131  * color - the original vertex colors
132  * Output: color - the fogged colors
133  */
135  GLuint n, GLfloat v[][4], GLubyte color[][4] )
136 {
137  GLuint i;
138  GLfloat d;
139  GLfloat fogr = ctx->Fog.Color[0] * ctx->Visual->RedScale;
140  GLfloat fogg = ctx->Fog.Color[1] * ctx->Visual->GreenScale;
141  GLfloat fogb = ctx->Fog.Color[2] * ctx->Visual->BlueScale;
142  GLfloat end = ctx->Fog.End;
143 
144  switch (ctx->Fog.Mode) {
145  case GL_LINEAR:
146  d = 1.0F / (ctx->Fog.End - ctx->Fog.Start);
147  for (i=0;i<n;i++) {
148  GLfloat f = (end - ABSF(v[i][2])) * d;
149  f = CLAMP( f, 0.0F, 1.0F );
150  color[i][0] = f * color[i][0] + (1.0F-f) * fogr;
151  color[i][1] = f * color[i][1] + (1.0F-f) * fogg;
152  color[i][2] = f * color[i][2] + (1.0F-f) * fogb;
153  }
154  break;
155  case GL_EXP:
156  d = -ctx->Fog.Density;
157  for (i=0;i<n;i++) {
158  GLfloat f = exp( d * ABSF(v[i][2]) );
159  f = CLAMP( f, 0.0F, 1.0F );
160  color[i][0] = f * color[i][0] + (1.0F-f) * fogr;
161  color[i][1] = f * color[i][1] + (1.0F-f) * fogg;
162  color[i][2] = f * color[i][2] + (1.0F-f) * fogb;
163  }
164  break;
165  case GL_EXP2:
166  d = -(ctx->Fog.Density*ctx->Fog.Density);
167  for (i=0;i<n;i++) {
168  GLfloat z = ABSF(v[i][2]);
169  GLfloat f = exp( d * z*z );
170  f = CLAMP( f, 0.0F, 1.0F );
171  color[i][0] = f * color[i][0] + (1.0F-f) * fogr;
172  color[i][1] = f * color[i][1] + (1.0F-f) * fogg;
173  color[i][2] = f * color[i][2] + (1.0F-f) * fogb;
174  }
175  break;
176  default:
177  gl_problem(ctx, "Bad fog mode in gl_fog_color_vertices");
178  return;
179  }
180 }
181 
182 
183 
184 /*
185  * Compute the fogged color indexes for an array of vertices.
186  * Input: n - number of vertices
187  * v - array of vertices
188  * In/Out: indx - array of vertex color indexes
189  */
191  GLuint n, GLfloat v[][4], GLuint indx[] )
192 {
193  /* NOTE: the extensive use of casts generates better/faster code for MIPS */
194  switch (ctx->Fog.Mode) {
195  case GL_LINEAR:
196  {
197  GLfloat d = 1.0F / (ctx->Fog.End - ctx->Fog.Start);
198  GLfloat fogindex = ctx->Fog.Index;
199  GLfloat fogend = ctx->Fog.End;
200  GLuint i;
201  for (i=0;i<n;i++) {
202  GLfloat f = (fogend - ABSF(v[i][2])) * d;
203  f = CLAMP( f, 0.0F, 1.0F );
204  indx[i] = (GLint)
205  ((GLfloat) (GLint) indx[i] + (1.0F-f) * fogindex);
206  }
207  }
208  break;
209  case GL_EXP:
210  {
211  GLfloat d = -ctx->Fog.Density;
212  GLfloat fogindex = ctx->Fog.Index;
213  GLuint i;
214  for (i=0;i<n;i++) {
215  GLfloat f = exp( d * ABSF(v[i][2]) );
216  f = CLAMP( f, 0.0F, 1.0F );
217  indx[i] = (GLint)
218  ((GLfloat) (GLint) indx[i] + (1.0F-f) * fogindex);
219  }
220  }
221  break;
222  case GL_EXP2:
223  {
224  GLfloat d = -(ctx->Fog.Density*ctx->Fog.Density);
225  GLfloat fogindex = ctx->Fog.Index;
226  GLuint i;
227  for (i=0;i<n;i++) {
228  GLfloat z = ABSF(v[i][2]);
229  GLfloat f = exp( -d * z*z );
230  f = CLAMP( f, 0.0F, 1.0F );
231  indx[i] = (GLint)
232  ((GLfloat) (GLint) indx[i] + (1.0F-f) * fogindex);
233  }
234  }
235  break;
236  default:
237  gl_problem(ctx, "Bad fog mode in gl_fog_index_vertices");
238  return;
239  }
240 }
241 
242 
243 
244 
245 /*
246  * Apply fog to an array of RGBA pixels.
247  * Input: n - number of pixels
248  * z - array of integer depth values
249  * red, green, blue, alpha - pixel colors
250  * Output: red, green, blue, alpha - fogged pixel colors
251  */
253  GLuint n, const GLdepth z[], GLubyte red[],
255 {
256  GLfloat c = ctx->ProjectionMatrix[10];
257  GLfloat d = ctx->ProjectionMatrix[14];
258  GLuint i;
259 
260  GLfloat fog_red = ctx->Fog.Color[0] * ctx->Visual->RedScale;
261  GLfloat fog_green = ctx->Fog.Color[1] * ctx->Visual->GreenScale;
262  GLfloat fog_blue = ctx->Fog.Color[2] * ctx->Visual->BlueScale;
263 
264  GLfloat tz = ctx->Viewport.Tz;
265  GLfloat szInv = 1.0F / ctx->Viewport.Sz;
266 
267  switch (ctx->Fog.Mode) {
268  case GL_LINEAR:
269  {
270  GLfloat fogEnd = ctx->Fog.End;
271  GLfloat fogScale = 1.0F / (ctx->Fog.End - ctx->Fog.Start);
272  for (i=0;i<n;i++) {
273  GLfloat ndcz = ((GLfloat) z[i] - tz) * szInv;
274  GLfloat eyez = -d / (c+ndcz);
275  GLfloat f, g;
276  if (eyez < 0.0) eyez = -eyez;
277  f = (fogEnd - eyez) * fogScale;
278  f = CLAMP( f, 0.0F, 1.0F );
279  g = 1.0F - f;
280  red[i] = (GLint) (f * (GLfloat) red[i] + g * fog_red);
281  green[i] = (GLint) (f * (GLfloat) green[i] + g * fog_green);
282  blue[i] = (GLint) (f * (GLfloat) blue[i] + g * fog_blue);
283  }
284  }
285  break;
286  case GL_EXP:
287  for (i=0;i<n;i++) {
288  GLfloat ndcz = ((GLfloat) z[i] - tz) * szInv;
289  GLfloat eyez = -d / (c+ndcz);
290  GLfloat f, g;
291  if (eyez < 0.0) eyez = -eyez;
292  f = exp( -ctx->Fog.Density * eyez );
293  f = CLAMP( f, 0.0F, 1.0F );
294  g = 1.0F - f;
295  red[i] = (GLint) (f * (GLfloat) red[i] + g * fog_red);
296  green[i] = (GLint) (f * (GLfloat) green[i] + g * fog_green);
297  blue[i] = (GLint) (f * (GLfloat) blue[i] + g * fog_blue);
298  }
299  break;
300  case GL_EXP2:
301  {
302  GLfloat negDensitySquared = -ctx->Fog.Density * ctx->Fog.Density;
303  for (i=0;i<n;i++) {
304  GLfloat ndcz = ((GLfloat) z[i] - tz) * szInv;
305  GLfloat eyez = -d / (c+ndcz);
306  GLfloat f, g;
307  if (eyez < 0.0) eyez = -eyez;
308  f = exp( negDensitySquared * eyez*eyez );
309  f = CLAMP( f, 0.0F, 1.0F );
310  g = 1.0F - f;
311  red[i] = (GLint) (f * (GLfloat) red[i] + g * fog_red);
312  green[i] = (GLint) (f * (GLfloat) green[i] + g * fog_green);
313  blue[i] = (GLint) (f * (GLfloat) blue[i] + g * fog_blue);
314  }
315  }
316  break;
317  default:
318  gl_problem(ctx, "Bad fog mode in gl_fog_color_pixels");
319  return;
320  }
321 }
322 
323 
324 
325 
326 /*
327  * Apply fog to an array of color index pixels.
328  * Input: n - number of pixels
329  * z - array of integer depth values
330  * index - pixel color indexes
331  * Output: index - fogged pixel color indexes
332  */
334  GLuint n, const GLdepth z[], GLuint index[] )
335 {
336  GLfloat c = ctx->ProjectionMatrix[10];
337  GLfloat d = ctx->ProjectionMatrix[14];
338  GLuint i;
339 
340  GLfloat tz = ctx->Viewport.Tz;
341  GLfloat szInv = 1.0F / ctx->Viewport.Sz;
342 
343  switch (ctx->Fog.Mode) {
344  case GL_LINEAR:
345  {
346  GLfloat fogEnd = ctx->Fog.End;
347  GLfloat fogScale = 1.0F / (ctx->Fog.End - ctx->Fog.Start);
348  for (i=0;i<n;i++) {
349  GLfloat ndcz = ((GLfloat) z[i] - tz) * szInv;
350  GLfloat eyez = -d / (c+ndcz);
351  GLfloat f;
352  if (eyez < 0.0) eyez = -eyez;
353  f = (fogEnd - eyez) * fogScale;
354  f = CLAMP( f, 0.0F, 1.0F );
355  index[i] = (GLuint) ((GLfloat) index[i] + (1.0F-f) * ctx->Fog.Index);
356  }
357  }
358  break;
359  case GL_EXP:
360  for (i=0;i<n;i++) {
361  GLfloat ndcz = ((GLfloat) z[i] - tz) * szInv;
362  GLfloat eyez = -d / (c+ndcz);
363  GLfloat f;
364  if (eyez < 0.0) eyez = -eyez;
365  f = exp( -ctx->Fog.Density * eyez );
366  f = CLAMP( f, 0.0F, 1.0F );
367  index[i] = (GLuint) ((GLfloat) index[i] + (1.0F-f) * ctx->Fog.Index);
368  }
369  break;
370  case GL_EXP2:
371  {
372  GLfloat negDensitySquared = -ctx->Fog.Density * ctx->Fog.Density;
373  for (i=0;i<n;i++) {
374  GLfloat ndcz = ((GLfloat) z[i] - tz) * szInv;
375  GLfloat eyez = -d / (c+ndcz);
376  GLfloat f;
377  if (eyez < 0.0) eyez = -eyez;
378  f = exp( negDensitySquared * eyez*eyez );
379  f = CLAMP( f, 0.0F, 1.0F );
380  index[i] = (GLuint) ((GLfloat) index[i] + (1.0F-f) * ctx->Fog.Index);
381  }
382  }
383  break;
384  default:
385  gl_problem(ctx, "Bad fog mode in gl_fog_index_pixels");
386  return;
387  }
388 }
389 
#define GL_FOG_DENSITY
Definition: gl.h:416
#define GL_EXP2
Definition: gl.h:423
unsigned char GLubyte
Definition: gl.h:157
GLdouble n
Definition: glext.h:7729
void gl_fog_color_pixels(GLcontext *ctx, GLuint n, const GLdepth z[], GLubyte red[], GLubyte green[], GLubyte blue[], GLubyte alpha[])
Definition: fog.c:252
#define GL_FOG_END
Definition: gl.h:420
GLvisual * Visual
Definition: types.h:1272
GLuint GLuint end
Definition: gl.h:1545
const GLfloat * m
Definition: glext.h:10848
GLenum pname
Definition: glext.h:5645
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLenum const GLfloat * params
Definition: glext.h:5645
#define ABSF(X)
Definition: macros.h:141
GLuint color
Definition: glext.h:6243
#define CLAMP(f, min, max)
Definition: tif_color.c:177
GLdouble GLdouble z
Definition: glext.h:5874
GLfloat BlueScale
Definition: types.h:1142
GLuint index
Definition: glext.h:6031
GLclampf GLclampf blue
Definition: gl.h:1740
GLfloat GreenScale
Definition: types.h:1141
void gl_fog_index_pixels(GLcontext *ctx, GLuint n, const GLdepth z[], GLuint index[])
Definition: fog.c:333
struct gl_fog_attrib Fog
Definition: types.h:1323
#define GL_FOG_MODE
Definition: gl.h:415
GLboolean GLboolean g
Definition: glext.h:6204
GLfloat f
Definition: glext.h:7540
GLint GLdepth
Definition: types.h:218
#define d
Definition: ke_i.h:81
#define GL_FOG_INDEX
Definition: gl.h:418
#define GL_FOG_COLOR
Definition: gl.h:417
const GLubyte * c
Definition: glext.h:8905
GLclampf green
Definition: gl.h:1740
#define red
Definition: linetest.c:67
#define GL_LINEAR
Definition: gl.h:421
#define GL_INVALID_VALUE
Definition: gl.h:695
void gl_fog_index_vertices(GLcontext *ctx, GLuint n, GLfloat v[][4], GLuint indx[])
Definition: fog.c:190
void gl_Fogfv(GLcontext *ctx, GLenum pname, const GLfloat *params)
Definition: fog.c:70
#define GL_EXP
Definition: gl.h:422
unsigned int GLenum
Definition: gl.h:150
void gl_problem(const GLcontext *ctx, const char *s)
Definition: context.c:1394
void gl_error(GLcontext *ctx, GLenum error, const char *s)
Definition: context.c:1421
const GLdouble * v
Definition: gl.h:2040
unsigned int GLuint
Definition: gl.h:159
GLfloat RedScale
Definition: types.h:1140
#define f
Definition: ke_i.h:83
#define GL_INVALID_ENUM
Definition: gl.h:694
struct gl_viewport_attrib Viewport
Definition: types.h:1336
GLbyte GLbyte tz
Definition: glext.h:8756
DWORD exp
Definition: msg.c:15681
float GLfloat
Definition: gl.h:161
GLfloat ProjectionMatrix[16]
Definition: types.h:1292
GLclampf GLclampf GLclampf alpha
Definition: gl.h:1740
int GLint
Definition: gl.h:156
void gl_fog_color_vertices(GLcontext *ctx, GLuint n, GLfloat v[][4], GLubyte color[][4])
Definition: fog.c:134
#define GL_FOG_START
Definition: gl.h:419
#define F(x, y, z)
Definition: md5.c:51