source: trunk/src/opengl/mesa/fog_tmp.h

Last change on this file was 3582, checked in by jeroen, 25 years ago

* empty log message *

File size: 12.6 KB
Line 
1/* $Id: fog_tmp.h,v 1.2 2000-05-21 20:46:23 jeroen Exp $ */
2
3/*
4 * Mesa 3-D graphics library
5 * Version: 3.1
6 *
7 * Copyright (C) 1999 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/* For 3.2: Add a helper function for drivers to do fog coordinate
28 * calculation. Not called from standard pipelines.
29 */
30static void TAG(make_fog_coord)( struct vertex_buffer *VB,
31 const GLvector4f *eye,
32 GLubyte flag)
33{
34 const GLcontext *ctx = VB->ctx;
35 GLfloat end = ctx->Fog.End;
36 GLubyte *cullmask = VB->CullMask + VB->Start;
37 GLfloat *v = eye->start;
38 GLuint stride = eye->stride;
39 GLuint n = VB->Count - VB->Start;
40 GLubyte (*out)[4];
41 GLfloat d;
42 GLuint i;
43
44 (void) cullmask;
45 (void) flag;
46
47 /* Use specular alpha (front side) as fog coordinate.
48 */
49 out = VB->Spec[0] + VB->Start;
50
51 if (VB->EyePtr->size > 2) {
52 switch (ctx->Fog.Mode) {
53 case GL_LINEAR:
54 d = 1.0F / (ctx->Fog.End - ctx->Fog.Start);
55 for ( i = 0 ; i < n ; i++, STRIDE_F(v, stride)) {
56 CULLCHECK {
57 GLfloat f = (end - ABSF(v[2])) * d;
58 FLOAT_COLOR_TO_UBYTE_COLOR(out[i][3], f);
59 }
60 }
61 break;
62 case GL_EXP:
63 d = -ctx->Fog.Density;
64 for ( i = 0 ; i < n ; i++, STRIDE_F(v,stride)) {
65 CULLCHECK {
66 GLfloat f = exp( d*ABSF(v[2]) ); /* already clamped */
67 FLOAT_COLOR_TO_UBYTE_COLOR(out[i][3], f);
68 }
69 }
70 break;
71 case GL_EXP2:
72 d = -(ctx->Fog.Density*ctx->Fog.Density);
73 for ( i = 0 ; i < n ; i++, STRIDE_F(v, stride)) {
74 CULLCHECK {
75 GLfloat z = v[2];
76 GLfloat f = exp( d*z*z ); /* already clamped */
77 FLOAT_COLOR_TO_UBYTE_COLOR(out[i][3], f);
78 }
79 }
80 break;
81 default:
82 gl_problem(ctx, "Bad fog mode in make_fog_coord");
83 return;
84 }
85 }
86 else
87 {
88 GLubyte r = 0;
89
90 if (ctx->Fog.Mode == GL_LINEAR) {
91 GLfloat f = ctx->Fog.End * (ctx->Fog.End - ctx->Fog.Start);
92 CLAMP_FLOAT_COLOR( f );
93 f = 1.0 - f;
94 FLOAT_COLOR_TO_UBYTE_COLOR(r, f);
95 }
96
97 for (i = 0 ; i < n ; i++)
98 out[i][3] = r;
99 }
100}
101
102
103
104
105
106#if 0
107/* TODO : use fog coordinates as intermediate step in all fog
108 * calculations.
109 */
110
111static void TAG(fog_rgba_vertices)( struct vertex_buffer *VB,
112 GLuint side,
113 GLubyte flag)
114{
115 const GLcontext *ctx = VB->ctx;
116 const GLubyte rFog = ctx->Fog.ByteColor[0];
117 const GLubyte gFog = ctx->Fog.ByteColor[1];
118 const GLubyte bFog = ctx->Fog.ByteColor[2];
119 GLfloat end = ctx->Fog.End;
120 GLubyte *cullmask = VB->CullMask + VB->Start;
121 GLubyte (*fcoord)[4] = VB->SpecPtr[0]->start;
122 GLuint stride = VB->SpecPtr[0]->stride;
123 GLuint n = VB->Count - VB->Start;
124 GLubyte *in;
125 GLuint in_stride;
126 GLubyte (*out)[4];
127 GLfloat d,t;
128 GLuint i;
129
130 (void) cullmask;
131 (void) flag;
132
133 /* Get correct source and destination for fogged colors.
134 */
135 in_stride = VB->Color[side]->stride;
136 in = VB->Color[side]->start;
137 VB->Color[side] = VB->FoggedColor[side];
138 VB->ColorPtr = VB->Color[0];
139 out = (GLubyte (*)[4])VB->Color[side]->start;
140
141 FLOAT_COLOR_TO_UBYTE_COLOR( rFog, ctx->Fog.Color[0] );
142
143 for ( i = 0 ; i < n ; i++, STRIDE_F(spec, sp_stride), in += in_stride) {
144 CULLCHECK {
145 GLint fc = (GLint) spec[3], ifc = 255 - fc;
146
147 out[i][0] = (fc * in[0] + ifc * rFog) >> 8;
148 out[i][1] = (fc * in[1] + ifc * gFog) >> 8;
149 out[i][2] = (fc * in[2] + ifc * bFog) >> 8;
150 }
151 }
152}
153
154
155
156static void TAG(fog_ci_vertices)( struct vertex_buffer *VB,
157 GLuint side,
158 GLubyte flag )
159{
160 GLcontext *ctx = VB->ctx;
161
162 GLubyte *cullmask = VB->CullMask + VB->Start;
163
164 GLfloat *v = VB->EyePtr->start;
165 GLuint stride = VB->EyePtr->stride;
166 GLuint vertex_size = VB->EyePtr->size;
167 GLuint n = VB->EyePtr->count;
168
169 GLuint *in;
170 GLuint in_stride;
171 GLuint *out;
172 GLuint i;
173
174 (void) flag;
175 (void) cullmask;
176
177
178 in = VB->Index[side]->start;
179 in_stride = VB->Index[side]->stride;
180 VB->IndexPtr = VB->FoggedIndex[side];
181 out = VB->IndexPtr->start;
182
183
184 /* NOTE: the use of casts generates better/faster code for MIPS */
185 for ( i = 0; i < n ; i++, STRIDE_F(v,stride), STRIDE_UI(in,in_stride))
186 CULLCHECK {
187 GLfloat f = (fogend - ABSF(v[2])) * d;
188 f = CLAMP( f, 0.0, 1.0 );
189 *out = (GLint) ((GLfloat)(GLint) *in + (1.0F-f) * fogindex);
190 }
191}
192
193#endif
194
195
196
197
198
199
200
201static void TAG(fog_rgba_vertices)( struct vertex_buffer *VB,
202 GLuint side,
203 GLubyte flag)
204{
205 const GLcontext *ctx = VB->ctx;
206 GLfloat rFog = ctx->Fog.Color[0];
207 GLfloat gFog = ctx->Fog.Color[1];
208 GLfloat bFog = ctx->Fog.Color[2];
209 GLfloat end = ctx->Fog.End;
210 GLubyte *cullmask = VB->CullMask + VB->Start;
211 GLfloat *v = VB->EyePtr->start;
212 GLuint stride = VB->EyePtr->stride;
213 GLuint n = VB->EyePtr->count;
214 GLubyte *in;
215 GLuint in_stride;
216 GLubyte (*out)[4];
217 GLfloat d,t;
218 GLuint i;
219
220 (void) cullmask;
221 (void) flag;
222
223 /* Get correct source and destination for fogged colors.
224 */
225 in_stride = VB->Color[side]->stride;
226 in = VB->Color[side]->start;
227 VB->Color[side] = VB->FoggedColor[side];
228 VB->ColorPtr = VB->Color[0];
229 out = (GLubyte (*)[4])VB->Color[side]->start;
230
231
232 if (VB->EyePtr->size > 2) {
233 switch (ctx->Fog.Mode) {
234 case GL_LINEAR:
235 d = 1.0F / (ctx->Fog.End - ctx->Fog.Start);
236 for ( i = 0 ; i < n ; i++, STRIDE_F(v, stride), in += in_stride) {
237 CULLCHECK {
238 GLfloat f = (end - ABSF(v[2])) * d;
239 if (f >= 1.0) continue;
240 if (f < 0) {
241 CLAMPED_FLOAT_COLOR_TO_UBYTE_COLOR(out[i][0], rFog);
242 CLAMPED_FLOAT_COLOR_TO_UBYTE_COLOR(out[i][1], gFog);
243 CLAMPED_FLOAT_COLOR_TO_UBYTE_COLOR(out[i][2], bFog);
244 } else {
245 t = f * UBYTE_COLOR_TO_FLOAT_COLOR(in[0]) + (1.0F-f)*rFog;
246 CLAMPED_FLOAT_COLOR_TO_UBYTE_COLOR(out[i][0], t);
247
248 t = f * UBYTE_COLOR_TO_FLOAT_COLOR(in[1]) + (1.0F-f)*gFog;
249 CLAMPED_FLOAT_COLOR_TO_UBYTE_COLOR(out[i][1], t);
250
251 t = f * UBYTE_COLOR_TO_FLOAT_COLOR(in[2]) + (1.0F-f)*bFog;
252 CLAMPED_FLOAT_COLOR_TO_UBYTE_COLOR(out[i][2], t);
253
254 }
255 }
256 }
257 break;
258 case GL_EXP:
259 d = -ctx->Fog.Density;
260 for ( i = 0 ; i < n ; i++, STRIDE_F(v,stride), in += in_stride) {
261 CULLCHECK {
262 GLfloat f = exp( d*ABSF(v[2]) ); /* already clamped */
263
264 t = f * UBYTE_COLOR_TO_FLOAT_COLOR(in[0]) + (1.0F-f)*rFog;
265 CLAMPED_FLOAT_COLOR_TO_UBYTE_COLOR(out[i][0], t);
266
267 t = f * UBYTE_COLOR_TO_FLOAT_COLOR(in[1]) + (1.0F-f)*gFog;
268 CLAMPED_FLOAT_COLOR_TO_UBYTE_COLOR(out[i][1], t);
269
270 t = f * UBYTE_COLOR_TO_FLOAT_COLOR(in[2]) + (1.0F-f)*bFog;
271 CLAMPED_FLOAT_COLOR_TO_UBYTE_COLOR(out[i][2], t);
272 }
273 }
274 break;
275 case GL_EXP2:
276 d = -(ctx->Fog.Density*ctx->Fog.Density);
277 for ( i = 0 ; i < n ; i++, STRIDE_F(v, stride), in += in_stride) {
278 CULLCHECK {
279 GLfloat z = v[2];
280 GLfloat f = exp( d*z*z ); /* already clamped */
281
282 t = f * UBYTE_COLOR_TO_FLOAT_COLOR(in[0]) + (1.0F-f)*rFog;
283 CLAMPED_FLOAT_COLOR_TO_UBYTE_COLOR(out[i][0], t);
284
285 t = f * UBYTE_COLOR_TO_FLOAT_COLOR(in[1]) + (1.0F-f)*gFog;
286 CLAMPED_FLOAT_COLOR_TO_UBYTE_COLOR(out[i][1], t);
287
288 t = f * UBYTE_COLOR_TO_FLOAT_COLOR(in[2]) + (1.0F-f)*bFog;
289 CLAMPED_FLOAT_COLOR_TO_UBYTE_COLOR(out[i][2], t);
290 }
291 }
292 break;
293 default:
294 gl_problem(ctx, "Bad fog mode in gl_fog_rgba_vertices");
295 return;
296 }
297 }
298 else if (ctx->Fog.Mode == GL_LINEAR)
299 {
300 /* 2-vector vertices */
301 GLubyte r,g,b;
302 GLfloat f = ctx->Fog.End * (ctx->Fog.End - ctx->Fog.Start);
303 CLAMP_FLOAT_COLOR( f );
304 f = 1.0 - f;
305 rFog *= f;
306 bFog *= f;
307 gFog *= f;
308
309 CLAMPED_FLOAT_COLOR_TO_UBYTE_COLOR(r, rFog);
310 CLAMPED_FLOAT_COLOR_TO_UBYTE_COLOR(g, gFog);
311 CLAMPED_FLOAT_COLOR_TO_UBYTE_COLOR(b, bFog);
312
313 for (i = 0 ; i < n ; i++) {
314 /* CULLCHECK */ {
315 out[i][0] = r;
316 out[i][1] = g;
317 out[i][2] = b;
318 }
319 }
320 }
321}
322
323
324
325/*
326 * Compute the fogged color indexes for an array of vertices.
327 * Input: n - number of vertices
328 * v - array of vertices
329 * In/Out: indx - array of vertex color indexes
330 */
331static void TAG(fog_ci_vertices)( struct vertex_buffer *VB,
332 GLuint side,
333 GLubyte flag )
334{
335 GLcontext *ctx = VB->ctx;
336
337 GLubyte *cullmask = VB->CullMask + VB->Start;
338
339 GLfloat *v = VB->EyePtr->start;
340 GLuint stride = VB->EyePtr->stride;
341 GLuint vertex_size = VB->EyePtr->size;
342 GLuint n = VB->EyePtr->count;
343
344 GLuint *in;
345 GLuint in_stride;
346 GLuint *out;
347 GLuint i;
348
349 (void) flag;
350 (void) cullmask;
351
352
353 in = VB->Index[side]->start;
354 in_stride = VB->Index[side]->stride;
355 VB->IndexPtr = VB->FoggedIndex[side];
356 out = VB->IndexPtr->start;
357
358
359 /* NOTE: the extensive use of casts generates better/faster code for MIPS */
360 if (vertex_size > 2) {
361 switch (ctx->Fog.Mode) {
362 case GL_LINEAR:
363 {
364 GLfloat d = 1.0F / (ctx->Fog.End - ctx->Fog.Start);
365 GLfloat fogindex = ctx->Fog.Index;
366 GLfloat fogend = ctx->Fog.End;
367
368 for ( i = 0; i < n ; i++, STRIDE_F(v,stride), STRIDE_UI(in,in_stride))
369 {
370 CULLCHECK {
371 GLfloat f = (fogend - ABSF(v[2])) * d;
372 f = CLAMP( f, 0.0, 1.0 );
373 *out = (GLint) ((GLfloat)(GLint) *in + (1.0F-f) * fogindex);
374 }
375 }
376 break;
377 }
378 case GL_EXP:
379 {
380 GLfloat d = -ctx->Fog.Density;
381 GLfloat fogindex = ctx->Fog.Index;
382 for ( i = 0; i < n ; i++, STRIDE_F(v,stride), STRIDE_UI(in,in_stride))
383 {
384 CULLCHECK {
385 GLfloat f = exp( d * ABSF(v[2]) );
386 *out = (GLint) ((GLfloat)(GLint) *in + (1.0F-f) * fogindex);
387 }
388 }
389 break;
390 }
391 case GL_EXP2:
392 {
393 GLfloat d = -(ctx->Fog.Density*ctx->Fog.Density);
394 GLfloat fogindex = ctx->Fog.Index;
395 for ( i = 0; i < n ; i++, STRIDE_F(v,stride),STRIDE_UI(in,in_stride))
396 {
397 CULLCHECK {
398 GLfloat z = v[2]; /*ABSF(v[i][2]);*/
399 GLfloat f = exp( d * z*z ); /* was -d ??? */
400 out[i] = (GLint) ((GLfloat)(GLint) *in + (1.0F-f) * fogindex);
401 }
402 }
403 break;
404 }
405 default:
406 gl_problem(ctx, "Bad fog mode in gl_fog_ci_vertices");
407 return;
408 }
409 } else if (ctx->Fog.Mode == GL_LINEAR) {
410 GLuint fogindex;
411 GLfloat f = ctx->Fog.End / (ctx->Fog.End - ctx->Fog.Start);
412
413 f = 1.0 - CLAMP( f, 0.0F, 1.0F );
414 fogindex = (GLuint)(f * ctx->Fog.Index);
415 if (fogindex) {
416 for ( i = 0; i < n ; i++, STRIDE_F(v,stride), STRIDE_UI(in,in_stride))
417 {
418 CULLCHECK {
419 *out = *in + fogindex;
420 }
421 }
422 }
423 }
424}
425
426static void TAG(init_fog_tab)(void)
427{
428 fog_ci_tab[IDX] = TAG(fog_ci_vertices);
429 fog_rgba_tab[IDX] = TAG(fog_rgba_vertices);
430 make_fog_coord_tab[IDX] = TAG(make_fog_coord);
431}
432
433#undef TAG
434#undef CULLCHECK
435#undef IDX
Note: See TracBrowser for help on using the repository browser.