1e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell/*
2e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Mesa 3-D graphics library
3a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul * Version:  6.5.2
422144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes *
5a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul * Copyright (C) 1999-2006  Brian Paul   All Rights Reserved.
622144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes *
7e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Permission is hereby granted, free of charge, to any person obtaining a
8e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * copy of this software and associated documentation files (the "Software"),
9e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * to deal in the Software without restriction, including without limitation
10e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * and/or sell copies of the Software, and to permit persons to whom the
12e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Software is furnished to do so, subject to the following conditions:
1322144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes *
14e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * The above copyright notice and this permission notice shall be included
15e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * in all copies or substantial portions of the Software.
1622144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes *
17e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
24e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
25e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
26bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/glheader.h"
27bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/colormac.h"
28bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/macros.h"
29e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
30cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell#include "s_context.h"
31e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_fog.h"
32a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul
33a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul
342ef866d1fc0a5cc5ef8543d65744dfd4da4dbbafBrian Paul/**
35af197f5f8f182c04ab29cd3c7a18a0cb95a1d9b7Brian Paul * Used to convert current raster distance to a fog factor in [0,1].
36af197f5f8f182c04ab29cd3c7a18a0cb95a1d9b7Brian Paul */
37af197f5f8f182c04ab29cd3c7a18a0cb95a1d9b7Brian PaulGLfloat
38f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg_swrast_z_to_fogfactor(struct gl_context *ctx, GLfloat z)
39af197f5f8f182c04ab29cd3c7a18a0cb95a1d9b7Brian Paul{
40af197f5f8f182c04ab29cd3c7a18a0cb95a1d9b7Brian Paul   GLfloat d, f;
41af197f5f8f182c04ab29cd3c7a18a0cb95a1d9b7Brian Paul
42af197f5f8f182c04ab29cd3c7a18a0cb95a1d9b7Brian Paul   switch (ctx->Fog.Mode) {
43af197f5f8f182c04ab29cd3c7a18a0cb95a1d9b7Brian Paul   case GL_LINEAR:
44af197f5f8f182c04ab29cd3c7a18a0cb95a1d9b7Brian Paul      if (ctx->Fog.Start == ctx->Fog.End)
45af197f5f8f182c04ab29cd3c7a18a0cb95a1d9b7Brian Paul         d = 1.0F;
46af197f5f8f182c04ab29cd3c7a18a0cb95a1d9b7Brian Paul      else
47af197f5f8f182c04ab29cd3c7a18a0cb95a1d9b7Brian Paul         d = 1.0F / (ctx->Fog.End - ctx->Fog.Start);
48af197f5f8f182c04ab29cd3c7a18a0cb95a1d9b7Brian Paul      f = (ctx->Fog.End - z) * d;
49af197f5f8f182c04ab29cd3c7a18a0cb95a1d9b7Brian Paul      return CLAMP(f, 0.0F, 1.0F);
50af197f5f8f182c04ab29cd3c7a18a0cb95a1d9b7Brian Paul   case GL_EXP:
51af197f5f8f182c04ab29cd3c7a18a0cb95a1d9b7Brian Paul      d = ctx->Fog.Density;
52b3aefd1cfb6aacd1695c52911dd39da50d893eceBrian Paul      f = EXPF(-d * z);
530733dbb0110583894b9df028e48ffd074cfd5380Brian Paul      f = CLAMP(f, 0.0F, 1.0F);
54af197f5f8f182c04ab29cd3c7a18a0cb95a1d9b7Brian Paul      return f;
55af197f5f8f182c04ab29cd3c7a18a0cb95a1d9b7Brian Paul   case GL_EXP2:
56af197f5f8f182c04ab29cd3c7a18a0cb95a1d9b7Brian Paul      d = ctx->Fog.Density;
57b3aefd1cfb6aacd1695c52911dd39da50d893eceBrian Paul      f = EXPF(-(d * d * z * z));
580733dbb0110583894b9df028e48ffd074cfd5380Brian Paul      f = CLAMP(f, 0.0F, 1.0F);
59af197f5f8f182c04ab29cd3c7a18a0cb95a1d9b7Brian Paul      return f;
60af197f5f8f182c04ab29cd3c7a18a0cb95a1d9b7Brian Paul   default:
6145bc887da226403f2c41077e40ca38b6f60f1359Brian Paul      _mesa_problem(ctx, "Bad fog mode in _swrast_z_to_fogfactor");
62af197f5f8f182c04ab29cd3c7a18a0cb95a1d9b7Brian Paul      return 0.0;
63af197f5f8f182c04ab29cd3c7a18a0cb95a1d9b7Brian Paul   }
64af197f5f8f182c04ab29cd3c7a18a0cb95a1d9b7Brian Paul}
65af197f5f8f182c04ab29cd3c7a18a0cb95a1d9b7Brian Paul
66af197f5f8f182c04ab29cd3c7a18a0cb95a1d9b7Brian Paul
679e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian#define LINEAR_FOG(f, coord)  f = (fogEnd - coord) * fogScale
689e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian
699e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian#define EXP_FOG(f, coord)  f = EXPF(density * coord)
709e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian
719e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian#define EXP2_FOG(f, coord)				\
729e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBriando {							\
739e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian   GLfloat tmp = negDensitySquared * coord * coord;	\
749e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian   if (tmp < FLT_MIN_10_EXP)				\
759e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian      tmp = FLT_MIN_10_EXP;				\
769e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian   f = EXPF(tmp);					\
779e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian } while(0)
789e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian
799e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian
809e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian#define BLEND_FOG(f, coord)  f = coord
819e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian
829e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian
839e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian
842ef866d1fc0a5cc5ef8543d65744dfd4da4dbbafBrian Paul/**
85a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul * Template code for computing fog blend factor and applying it to colors.
86a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul * \param TYPE  either GLubyte, GLushort or GLfloat.
87a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul * \param COMPUTE_F  code to compute the fog blend factor, f.
88a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul */
899e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian#define FOG_LOOP(TYPE, FOG_FUNC)						\
909e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrianif (span->arrayAttribs & FRAG_BIT_FOGC) {					\
919e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian   GLuint i;									\
929e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian   for (i = 0; i < span->end; i++) {						\
939e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian      const GLfloat fogCoord = span->array->attribs[FRAG_ATTRIB_FOGC][i][0];	\
949e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian      const GLfloat c = FABSF(fogCoord);					\
959e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian      GLfloat f, oneMinusF;							\
969e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian      FOG_FUNC(f, c);								\
979e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian      f = CLAMP(f, 0.0F, 1.0F);							\
989e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian      oneMinusF = 1.0F - f;							\
999e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian      rgba[i][RCOMP] = (TYPE) (f * rgba[i][RCOMP] + oneMinusF * rFog);		\
1009e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian      rgba[i][GCOMP] = (TYPE) (f * rgba[i][GCOMP] + oneMinusF * gFog);		\
1019e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian      rgba[i][BCOMP] = (TYPE) (f * rgba[i][BCOMP] + oneMinusF * bFog);		\
1029e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian   }										\
1039e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian}										\
1049e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrianelse {										\
1059e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian   const GLfloat fogStep = span->attrStepX[FRAG_ATTRIB_FOGC][0];		\
1069e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian   GLfloat fogCoord = span->attrStart[FRAG_ATTRIB_FOGC][0];			\
1079e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian   const GLfloat wStep = span->attrStepX[FRAG_ATTRIB_WPOS][3];			\
1089e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian   GLfloat w = span->attrStart[FRAG_ATTRIB_WPOS][3];				\
1099e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian   GLuint i;									\
1109e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian   for (i = 0; i < span->end; i++) {						\
1119e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian      const GLfloat c = FABSF(fogCoord) / w;					\
1129e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian      GLfloat f, oneMinusF;							\
1139e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian      FOG_FUNC(f, c);								\
1149e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian      f = CLAMP(f, 0.0F, 1.0F);							\
1159e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian      oneMinusF = 1.0F - f;							\
1169e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian      rgba[i][RCOMP] = (TYPE) (f * rgba[i][RCOMP] + oneMinusF * rFog);		\
1179e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian      rgba[i][GCOMP] = (TYPE) (f * rgba[i][GCOMP] + oneMinusF * gFog);		\
1189e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian      rgba[i][BCOMP] = (TYPE) (f * rgba[i][BCOMP] + oneMinusF * bFog);		\
1199e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian      fogCoord += fogStep;							\
1209e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian      w += wStep;								\
1219e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian   }										\
1229e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian}
1239e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian
124a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul/**
12509da0b8e6621a831e3eeb9381430f2bed18a22adBrian Paul * Apply fog to a span of RGBA pixels.
12609da0b8e6621a831e3eeb9381430f2bed18a22adBrian Paul * The fog value are either in the span->array->fog array or interpolated from
12709da0b8e6621a831e3eeb9381430f2bed18a22adBrian Paul * the fog/fogStep values.
12809da0b8e6621a831e3eeb9381430f2bed18a22adBrian Paul * They fog values are either fog coordinates (Z) or fog blend factors.
12909da0b8e6621a831e3eeb9381430f2bed18a22adBrian Paul * _PreferPixelFog should be in sync with that state!
130e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
13109da0b8e6621a831e3eeb9381430f2bed18a22adBrian Paulvoid
132f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg_swrast_fog_rgba_span( const struct gl_context *ctx, SWspan *span )
133e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{
13481ca8b93f212d1946c70660041ce97d98f352608Brian Paul   const SWcontext *swrast = CONST_SWRAST_CONTEXT(ctx);
13532c3243e4d8237ecfeccd5a554abefaa0679e94bBrian Paul   GLfloat rFog, gFog, bFog;
136e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
13709da0b8e6621a831e3eeb9381430f2bed18a22adBrian Paul   ASSERT(swrast->_FogEnabled);
13809da0b8e6621a831e3eeb9381430f2bed18a22adBrian Paul   ASSERT(span->arrayMask & SPAN_RGBA);
139d14fce03f0b5db720cfc52a3c81f407626e28111Brian Paul
1409e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian   /* compute (scaled) fog color */
14132c3243e4d8237ecfeccd5a554abefaa0679e94bBrian Paul   if (span->array->ChanType == GL_UNSIGNED_BYTE) {
142880411c72aee7c0ec81366bdf6ab8cf25bebb9d5Brian Paul      rFog = ctx->Fog.Color[RCOMP] * 255.0F;
143880411c72aee7c0ec81366bdf6ab8cf25bebb9d5Brian Paul      gFog = ctx->Fog.Color[GCOMP] * 255.0F;
144880411c72aee7c0ec81366bdf6ab8cf25bebb9d5Brian Paul      bFog = ctx->Fog.Color[BCOMP] * 255.0F;
14532c3243e4d8237ecfeccd5a554abefaa0679e94bBrian Paul   }
14632c3243e4d8237ecfeccd5a554abefaa0679e94bBrian Paul   else if (span->array->ChanType == GL_UNSIGNED_SHORT) {
147880411c72aee7c0ec81366bdf6ab8cf25bebb9d5Brian Paul      rFog = ctx->Fog.Color[RCOMP] * 65535.0F;
148880411c72aee7c0ec81366bdf6ab8cf25bebb9d5Brian Paul      gFog = ctx->Fog.Color[GCOMP] * 65535.0F;
149880411c72aee7c0ec81366bdf6ab8cf25bebb9d5Brian Paul      bFog = ctx->Fog.Color[BCOMP] * 65535.0F;
15032c3243e4d8237ecfeccd5a554abefaa0679e94bBrian Paul   }
15132c3243e4d8237ecfeccd5a554abefaa0679e94bBrian Paul   else {
15232c3243e4d8237ecfeccd5a554abefaa0679e94bBrian Paul      rFog = ctx->Fog.Color[RCOMP];
15332c3243e4d8237ecfeccd5a554abefaa0679e94bBrian Paul      gFog = ctx->Fog.Color[GCOMP];
15432c3243e4d8237ecfeccd5a554abefaa0679e94bBrian Paul      bFog = ctx->Fog.Color[BCOMP];
15532c3243e4d8237ecfeccd5a554abefaa0679e94bBrian Paul   }
15632c3243e4d8237ecfeccd5a554abefaa0679e94bBrian Paul
15709da0b8e6621a831e3eeb9381430f2bed18a22adBrian Paul   if (swrast->_PreferPixelFog) {
15809da0b8e6621a831e3eeb9381430f2bed18a22adBrian Paul      /* The span's fog values are fog coordinates, now compute blend factors
15909da0b8e6621a831e3eeb9381430f2bed18a22adBrian Paul       * and blend the fragment colors with the fog color.
16009da0b8e6621a831e3eeb9381430f2bed18a22adBrian Paul       */
161cd354b4eb84839837a9349bd91e89b55d06e5837Ian Romanick      switch (ctx->Fog.Mode) {
162e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      case GL_LINEAR:
1639e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian         {
1649e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian            const GLfloat fogEnd = ctx->Fog.End;
1659e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian            const GLfloat fogScale = (ctx->Fog.Start == ctx->Fog.End)
1669e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian               ? 1.0F : 1.0F / (ctx->Fog.End - ctx->Fog.Start);
1679e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian            if (span->array->ChanType == GL_UNSIGNED_BYTE) {
1689e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian               GLubyte (*rgba)[4] = span->array->rgba8;
1699e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian               FOG_LOOP(GLubyte, LINEAR_FOG);
1709e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian            }
1719e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian            else if (span->array->ChanType == GL_UNSIGNED_SHORT) {
1729e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian               GLushort (*rgba)[4] = span->array->rgba16;
1739e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian               FOG_LOOP(GLushort, LINEAR_FOG);
1749e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian            }
1759e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian            else {
1769e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian               GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0];
1779e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian               ASSERT(span->array->ChanType == GL_FLOAT);
1789e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian               FOG_LOOP(GLfloat, LINEAR_FOG);
1799e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian            }
180e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         }
18109da0b8e6621a831e3eeb9381430f2bed18a22adBrian Paul         break;
182a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul
183e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      case GL_EXP:
1849e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian         {
1859e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian            const GLfloat density = -ctx->Fog.Density;
1869e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian            if (span->array->ChanType == GL_UNSIGNED_BYTE) {
1879e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian               GLubyte (*rgba)[4] = span->array->rgba8;
1889e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian               FOG_LOOP(GLubyte, EXP_FOG);
1899e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian            }
1909e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian            else if (span->array->ChanType == GL_UNSIGNED_SHORT) {
1919e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian               GLushort (*rgba)[4] = span->array->rgba16;
1929e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian               FOG_LOOP(GLushort, EXP_FOG);
1939e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian            }
1949e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian            else {
1959e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian               GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0];
1969e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian               ASSERT(span->array->ChanType == GL_FLOAT);
1979e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian               FOG_LOOP(GLfloat, EXP_FOG);
1989e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian            }
19930971cd098d147a4363df0dec0c338587dc1478fBrian Paul         }
20009da0b8e6621a831e3eeb9381430f2bed18a22adBrian Paul         break;
201a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul
202e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      case GL_EXP2:
2039e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian         {
2049e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian            const GLfloat negDensitySquared = -ctx->Fog.Density * ctx->Fog.Density;
2059e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian            if (span->array->ChanType == GL_UNSIGNED_BYTE) {
2069e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian               GLubyte (*rgba)[4] = span->array->rgba8;
2079e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian               FOG_LOOP(GLubyte, EXP2_FOG);
2089e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian            }
2099e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian            else if (span->array->ChanType == GL_UNSIGNED_SHORT) {
2109e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian               GLushort (*rgba)[4] = span->array->rgba16;
2119e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian               FOG_LOOP(GLushort, EXP2_FOG);
2129e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian            }
2139e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian            else {
2149e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian               GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0];
2159e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian               ASSERT(span->array->ChanType == GL_FLOAT);
2169e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian               FOG_LOOP(GLfloat, EXP2_FOG);
2179e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian            }
218a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         }
21909da0b8e6621a831e3eeb9381430f2bed18a22adBrian Paul         break;
220a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul
221e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      default:
22209da0b8e6621a831e3eeb9381430f2bed18a22adBrian Paul         _mesa_problem(ctx, "Bad fog mode in _swrast_fog_rgba_span");
223e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         return;
22409da0b8e6621a831e3eeb9381430f2bed18a22adBrian Paul      }
225e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
226711e27fda27e4235b20a4cf73c2767c984ab2b81Brian Paul   else {
2279e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian      /* The span's fog start/step/array values are blend factors in [0,1].
22809da0b8e6621a831e3eeb9381430f2bed18a22adBrian Paul       * They were previously computed per-vertex.
22909da0b8e6621a831e3eeb9381430f2bed18a22adBrian Paul       */
230a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul      if (span->array->ChanType == GL_UNSIGNED_BYTE) {
2319e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian         GLubyte (*rgba)[4] = span->array->rgba8;
2329e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian         FOG_LOOP(GLubyte, BLEND_FOG);
233a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul      }
234a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul      else if (span->array->ChanType == GL_UNSIGNED_SHORT) {
2359e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian         GLushort (*rgba)[4] = span->array->rgba16;
2369e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian         FOG_LOOP(GLushort, BLEND_FOG);
237a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul      }
238a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul      else {
239f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian         GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0];
240a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         ASSERT(span->array->ChanType == GL_FLOAT);
2419e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian         FOG_LOOP(GLfloat, BLEND_FOG);
242711e27fda27e4235b20a4cf73c2767c984ab2b81Brian Paul      }
243711e27fda27e4235b20a4cf73c2767c984ab2b81Brian Paul   }
24410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul}
245