ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

s_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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.