Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygens_fog.c
Go to the documentation of this file.
00001 /* 00002 * Mesa 3-D graphics library 00003 * Version: 6.5.2 00004 * 00005 * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. 00006 * 00007 * Permission is hereby granted, free of charge, to any person obtaining a 00008 * copy of this software and associated documentation files (the "Software"), 00009 * to deal in the Software without restriction, including without limitation 00010 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 00011 * and/or sell copies of the Software, and to permit persons to whom the 00012 * Software is furnished to do so, subject to the following conditions: 00013 * 00014 * The above copyright notice and this permission notice shall be included 00015 * in all copies or substantial portions of the Software. 00016 * 00017 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 00018 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00019 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 00020 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 00021 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 00022 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00023 */ 00024 00025 00026 #include "main/glheader.h" 00027 #include "main/colormac.h" 00028 #include "main/context.h" 00029 #include "main/macros.h" 00030 00031 #include "s_context.h" 00032 #include "s_fog.h" 00033 00034 00038 GLfloat 00039 _swrast_z_to_fogfactor(GLcontext *ctx, GLfloat z) 00040 { 00041 GLfloat d, f; 00042 00043 switch (ctx->Fog.Mode) { 00044 case GL_LINEAR: 00045 if (ctx->Fog.Start == ctx->Fog.End) 00046 d = 1.0F; 00047 else 00048 d = 1.0F / (ctx->Fog.End - ctx->Fog.Start); 00049 f = (ctx->Fog.End - z) * d; 00050 return CLAMP(f, 0.0F, 1.0F); 00051 case GL_EXP: 00052 d = ctx->Fog.Density; 00053 f = EXPF(-d * z); 00054 f = CLAMP(f, 0.0F, 1.0F); 00055 return f; 00056 case GL_EXP2: 00057 d = ctx->Fog.Density; 00058 f = EXPF(-(d * d * z * z)); 00059 f = CLAMP(f, 0.0F, 1.0F); 00060 return f; 00061 default: 00062 _mesa_problem(ctx, "Bad fog mode in _swrast_z_to_fogfactor"); 00063 return 0.0; 00064 } 00065 } 00066 00067 00068 #define LINEAR_FOG(f, coord) f = (fogEnd - coord) * fogScale 00069 00070 #define EXP_FOG(f, coord) f = EXPF(density * coord) 00071 00072 #define EXP2_FOG(f, coord) \ 00073 do { \ 00074 GLfloat tmp = negDensitySquared * coord * coord; \ 00075 if (tmp < FLT_MIN_10_EXP) \ 00076 tmp = FLT_MIN_10_EXP; \ 00077 f = EXPF(tmp); \ 00078 } while(0) 00079 00080 00081 #define BLEND_FOG(f, coord) f = coord 00082 00083 00084 00090 #define FOG_LOOP(TYPE, FOG_FUNC) \ 00091 if (span->arrayAttribs & FRAG_BIT_FOGC) { \ 00092 GLuint i; \ 00093 for (i = 0; i < span->end; i++) { \ 00094 const GLfloat fogCoord = span->array->attribs[FRAG_ATTRIB_FOGC][i][0]; \ 00095 const GLfloat c = FABSF(fogCoord); \ 00096 GLfloat f, oneMinusF; \ 00097 FOG_FUNC(f, c); \ 00098 f = CLAMP(f, 0.0F, 1.0F); \ 00099 oneMinusF = 1.0F - f; \ 00100 rgba[i][RCOMP] = (TYPE) (f * rgba[i][RCOMP] + oneMinusF * rFog); \ 00101 rgba[i][GCOMP] = (TYPE) (f * rgba[i][GCOMP] + oneMinusF * gFog); \ 00102 rgba[i][BCOMP] = (TYPE) (f * rgba[i][BCOMP] + oneMinusF * bFog); \ 00103 } \ 00104 } \ 00105 else { \ 00106 const GLfloat fogStep = span->attrStepX[FRAG_ATTRIB_FOGC][0]; \ 00107 GLfloat fogCoord = span->attrStart[FRAG_ATTRIB_FOGC][0]; \ 00108 const GLfloat wStep = span->attrStepX[FRAG_ATTRIB_WPOS][3]; \ 00109 GLfloat w = span->attrStart[FRAG_ATTRIB_WPOS][3]; \ 00110 GLuint i; \ 00111 for (i = 0; i < span->end; i++) { \ 00112 const GLfloat c = FABSF(fogCoord) / w; \ 00113 GLfloat f, oneMinusF; \ 00114 FOG_FUNC(f, c); \ 00115 f = CLAMP(f, 0.0F, 1.0F); \ 00116 oneMinusF = 1.0F - f; \ 00117 rgba[i][RCOMP] = (TYPE) (f * rgba[i][RCOMP] + oneMinusF * rFog); \ 00118 rgba[i][GCOMP] = (TYPE) (f * rgba[i][GCOMP] + oneMinusF * gFog); \ 00119 rgba[i][BCOMP] = (TYPE) (f * rgba[i][BCOMP] + oneMinusF * bFog); \ 00120 fogCoord += fogStep; \ 00121 w += wStep; \ 00122 } \ 00123 } 00124 00125 /* As above, but CI mode (XXX try to merge someday) */ 00126 #define FOG_LOOP_CI(FOG_FUNC) \ 00127 if (span->arrayAttribs & FRAG_BIT_FOGC) { \ 00128 GLuint i; \ 00129 for (i = 0; i < span->end; i++) { \ 00130 const GLfloat fogCoord = span->array->attribs[FRAG_ATTRIB_FOGC][i][0]; \ 00131 const GLfloat c = FABSF(fogCoord); \ 00132 GLfloat f; \ 00133 FOG_FUNC(f, c); \ 00134 f = CLAMP(f, 0.0F, 1.0F); \ 00135 index[i] = (GLuint) ((GLfloat) index[i] + (1.0F - f) * fogIndex); \ 00136 } \ 00137 } \ 00138 else { \ 00139 const GLfloat fogStep = span->attrStepX[FRAG_ATTRIB_FOGC][0]; \ 00140 GLfloat fogCoord = span->attrStart[FRAG_ATTRIB_FOGC][0]; \ 00141 const GLfloat wStep = span->attrStepX[FRAG_ATTRIB_WPOS][3]; \ 00142 GLfloat w = span->attrStart[FRAG_ATTRIB_WPOS][3]; \ 00143 GLuint i; \ 00144 for (i = 0; i < span->end; i++) { \ 00145 const GLfloat c = FABSF(fogCoord) / w; \ 00146 GLfloat f; \ 00147 FOG_FUNC(f, c); \ 00148 f = CLAMP(f, 0.0F, 1.0F); \ 00149 index[i] = (GLuint) ((GLfloat) index[i] + (1.0F - f) * fogIndex); \ 00150 fogCoord += fogStep; \ 00151 w += wStep; \ 00152 } \ 00153 } 00154 00155 00156 00164 void 00165 _swrast_fog_rgba_span( const GLcontext *ctx, SWspan *span ) 00166 { 00167 const SWcontext *swrast = SWRAST_CONTEXT(ctx); 00168 GLfloat rFog, gFog, bFog; 00169 00170 ASSERT(swrast->_FogEnabled); 00171 ASSERT(span->arrayMask & SPAN_RGBA); 00172 00173 /* compute (scaled) fog color */ 00174 if (span->array->ChanType == GL_UNSIGNED_BYTE) { 00175 rFog = ctx->Fog.Color[RCOMP] * 255.0; 00176 gFog = ctx->Fog.Color[GCOMP] * 255.0; 00177 bFog = ctx->Fog.Color[BCOMP] * 255.0; 00178 } 00179 else if (span->array->ChanType == GL_UNSIGNED_SHORT) { 00180 rFog = ctx->Fog.Color[RCOMP] * 65535.0; 00181 gFog = ctx->Fog.Color[GCOMP] * 65535.0; 00182 bFog = ctx->Fog.Color[BCOMP] * 65535.0; 00183 } 00184 else { 00185 rFog = ctx->Fog.Color[RCOMP]; 00186 gFog = ctx->Fog.Color[GCOMP]; 00187 bFog = ctx->Fog.Color[BCOMP]; 00188 } 00189 00190 if (swrast->_PreferPixelFog) { 00191 /* The span's fog values are fog coordinates, now compute blend factors 00192 * and blend the fragment colors with the fog color. 00193 */ 00194 switch (swrast->_FogMode) { 00195 case GL_LINEAR: 00196 { 00197 const GLfloat fogEnd = ctx->Fog.End; 00198 const GLfloat fogScale = (ctx->Fog.Start == ctx->Fog.End) 00199 ? 1.0F : 1.0F / (ctx->Fog.End - ctx->Fog.Start); 00200 if (span->array->ChanType == GL_UNSIGNED_BYTE) { 00201 GLubyte (*rgba)[4] = span->array->rgba8; 00202 FOG_LOOP(GLubyte, LINEAR_FOG); 00203 } 00204 else if (span->array->ChanType == GL_UNSIGNED_SHORT) { 00205 GLushort (*rgba)[4] = span->array->rgba16; 00206 FOG_LOOP(GLushort, LINEAR_FOG); 00207 } 00208 else { 00209 GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0]; 00210 ASSERT(span->array->ChanType == GL_FLOAT); 00211 FOG_LOOP(GLfloat, LINEAR_FOG); 00212 } 00213 } 00214 break; 00215 00216 case GL_EXP: 00217 { 00218 const GLfloat density = -ctx->Fog.Density; 00219 if (span->array->ChanType == GL_UNSIGNED_BYTE) { 00220 GLubyte (*rgba)[4] = span->array->rgba8; 00221 FOG_LOOP(GLubyte, EXP_FOG); 00222 } 00223 else if (span->array->ChanType == GL_UNSIGNED_SHORT) { 00224 GLushort (*rgba)[4] = span->array->rgba16; 00225 FOG_LOOP(GLushort, EXP_FOG); 00226 } 00227 else { 00228 GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0]; 00229 ASSERT(span->array->ChanType == GL_FLOAT); 00230 FOG_LOOP(GLfloat, EXP_FOG); 00231 } 00232 } 00233 break; 00234 00235 case GL_EXP2: 00236 { 00237 const GLfloat negDensitySquared = -ctx->Fog.Density * ctx->Fog.Density; 00238 if (span->array->ChanType == GL_UNSIGNED_BYTE) { 00239 GLubyte (*rgba)[4] = span->array->rgba8; 00240 FOG_LOOP(GLubyte, EXP2_FOG); 00241 } 00242 else if (span->array->ChanType == GL_UNSIGNED_SHORT) { 00243 GLushort (*rgba)[4] = span->array->rgba16; 00244 FOG_LOOP(GLushort, EXP2_FOG); 00245 } 00246 else { 00247 GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0]; 00248 ASSERT(span->array->ChanType == GL_FLOAT); 00249 FOG_LOOP(GLfloat, EXP2_FOG); 00250 } 00251 } 00252 break; 00253 00254 default: 00255 _mesa_problem(ctx, "Bad fog mode in _swrast_fog_rgba_span"); 00256 return; 00257 } 00258 } 00259 else { 00260 /* The span's fog start/step/array values are blend factors in [0,1]. 00261 * They were previously computed per-vertex. 00262 */ 00263 if (span->array->ChanType == GL_UNSIGNED_BYTE) { 00264 GLubyte (*rgba)[4] = span->array->rgba8; 00265 FOG_LOOP(GLubyte, BLEND_FOG); 00266 } 00267 else if (span->array->ChanType == GL_UNSIGNED_SHORT) { 00268 GLushort (*rgba)[4] = span->array->rgba16; 00269 FOG_LOOP(GLushort, BLEND_FOG); 00270 } 00271 else { 00272 GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0]; 00273 ASSERT(span->array->ChanType == GL_FLOAT); 00274 FOG_LOOP(GLfloat, BLEND_FOG); 00275 } 00276 } 00277 } 00278 00279 00283 void 00284 _swrast_fog_ci_span( const GLcontext *ctx, SWspan *span ) 00285 { 00286 const SWcontext *swrast = SWRAST_CONTEXT(ctx); 00287 const GLuint fogIndex = (GLuint) ctx->Fog.Index; 00288 GLuint *index = span->array->index; 00289 00290 ASSERT(swrast->_FogEnabled); 00291 ASSERT(span->arrayMask & SPAN_INDEX); 00292 00293 /* we need to compute fog blend factors */ 00294 if (swrast->_PreferPixelFog) { 00295 /* The span's fog values are fog coordinates, now compute blend factors 00296 * and blend the fragment colors with the fog color. 00297 */ 00298 switch (ctx->Fog.Mode) { 00299 case GL_LINEAR: 00300 { 00301 const GLfloat fogEnd = ctx->Fog.End; 00302 const GLfloat fogScale = (ctx->Fog.Start == ctx->Fog.End) 00303 ? 1.0F : 1.0F / (ctx->Fog.End - ctx->Fog.Start); 00304 FOG_LOOP_CI(LINEAR_FOG); 00305 } 00306 break; 00307 case GL_EXP: 00308 { 00309 const GLfloat density = -ctx->Fog.Density; 00310 FOG_LOOP_CI(EXP_FOG); 00311 } 00312 break; 00313 case GL_EXP2: 00314 { 00315 const GLfloat negDensitySquared = -ctx->Fog.Density * ctx->Fog.Density; 00316 FOG_LOOP_CI(EXP2_FOG); 00317 } 00318 break; 00319 default: 00320 _mesa_problem(ctx, "Bad fog mode in _swrast_fog_ci_span"); 00321 return; 00322 } 00323 } 00324 else { 00325 /* The span's fog start/step/array values are blend factors in [0,1]. 00326 * They were previously computed per-vertex. 00327 */ 00328 FOG_LOOP_CI(BLEND_FOG); 00329 } 00330 } Generated on Sun May 27 2012 04:20:43 for ReactOS by
1.7.6.1
|