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

t_vb_fog.c
Go to the documentation of this file.
00001 /*
00002  * Mesa 3-D graphics library
00003  * Version:  6.5
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  * Authors:
00025  *    Keith Whitwell <keith@tungstengraphics.com>
00026  */
00027 
00028 
00029 #include "main/glheader.h"
00030 #include "main/colormac.h"
00031 #include "main/context.h"
00032 #include "main/macros.h"
00033 #include "main/imports.h"
00034 #include "main/mtypes.h"
00035 
00036 #include "math/m_xform.h"
00037 
00038 #include "t_context.h"
00039 #include "t_pipeline.h"
00040 
00041 
00042 struct fog_stage_data {
00043    GLvector4f fogcoord;     /* has actual storage allocated */
00044 };
00045 
00046 #define FOG_STAGE_DATA(stage) ((struct fog_stage_data *)stage->privatePtr)
00047 
00048 #define FOG_EXP_TABLE_SIZE 256
00049 #define FOG_MAX (10.0)
00050 #define EXP_FOG_MAX .0006595
00051 #define FOG_INCR (FOG_MAX/FOG_EXP_TABLE_SIZE)
00052 static GLfloat exp_table[FOG_EXP_TABLE_SIZE];
00053 static GLfloat inited = 0;
00054 
00055 #if 1
00056 #define NEG_EXP( result, narg )                     \
00057 do {                                    \
00058    GLfloat f = (GLfloat) (narg * (1.0/FOG_INCR));           \
00059    GLint k = (GLint) f;                         \
00060    if (k > FOG_EXP_TABLE_SIZE-2)                    \
00061       result = (GLfloat) EXP_FOG_MAX;                   \
00062    else                                 \
00063       result = exp_table[k] + (f-k)*(exp_table[k+1]-exp_table[k]);  \
00064 } while (0)
00065 #else
00066 #define NEG_EXP( result, narg )                 \
00067 do {                                \
00068    result = exp(-narg);                     \
00069 } while (0)
00070 #endif
00071 
00072 
00076 static void
00077 init_static_data( void )
00078 {
00079    GLfloat f = 0.0F;
00080    GLint i = 0;
00081    for ( ; i < FOG_EXP_TABLE_SIZE ; i++, f += FOG_INCR) {
00082       exp_table[i] = EXPF(-f);
00083    }
00084    inited = 1;
00085 }
00086 
00087 
00097 static void
00098 compute_fog_blend_factors(GLcontext *ctx, GLvector4f *out, const GLvector4f *in)
00099 {
00100    GLfloat end  = ctx->Fog.End;
00101    GLfloat *v = in->start;
00102    GLuint stride = in->stride;
00103    GLuint n = in->count;
00104    GLfloat (*data)[4] = out->data;
00105    GLfloat d;
00106    GLuint i;
00107 
00108    out->count = in->count;
00109 
00110    switch (ctx->Fog.Mode) {
00111    case GL_LINEAR:
00112       if (ctx->Fog.Start == ctx->Fog.End)
00113          d = 1.0F;
00114       else
00115          d = 1.0F / (ctx->Fog.End - ctx->Fog.Start);
00116       for ( i = 0 ; i < n ; i++, STRIDE_F(v, stride)) {
00117          const GLfloat z = *v;
00118          GLfloat f = (end - z) * d;
00119      data[i][0] = CLAMP(f, 0.0F, 1.0F);
00120       }
00121       break;
00122    case GL_EXP:
00123       d = ctx->Fog.Density;
00124       for ( i = 0 ; i < n ; i++, STRIDE_F(v,stride)) {
00125          const GLfloat z = *v;
00126          NEG_EXP( data[i][0], d * z );
00127       }
00128       break;
00129    case GL_EXP2:
00130       d = ctx->Fog.Density*ctx->Fog.Density;
00131       for ( i = 0 ; i < n ; i++, STRIDE_F(v, stride)) {
00132          const GLfloat z = *v;
00133          NEG_EXP( data[i][0], d * z * z );
00134       }
00135       break;
00136    default:
00137       _mesa_problem(ctx, "Bad fog mode in make_fog_coord");
00138       return;
00139    }
00140 }
00141 
00142 
00143 static GLboolean
00144 run_fog_stage(GLcontext *ctx, struct tnl_pipeline_stage *stage)
00145 {
00146    TNLcontext *tnl = TNL_CONTEXT(ctx);
00147    struct vertex_buffer *VB = &tnl->vb;
00148    struct fog_stage_data *store = FOG_STAGE_DATA(stage);
00149    GLvector4f *input;
00150 
00151 
00152    if (!ctx->Fog.Enabled)
00153       return GL_TRUE;
00154 
00155    if (ctx->Fog.FogCoordinateSource == GL_FRAGMENT_DEPTH_EXT && !ctx->VertexProgram._Current) {
00156       GLuint i;
00157       GLfloat *coord;
00158       /* Fog is computed from vertex or fragment Z values */
00159       /* source = VB->ObjPtr or VB->EyePtr coords */
00160       /* dest = VB->AttribPtr[_TNL_ATTRIB_FOG] = fog stage private storage */
00161       VB->AttribPtr[_TNL_ATTRIB_FOG] = &store->fogcoord;
00162 
00163       if (!ctx->_NeedEyeCoords) {
00164          /* compute fog coords from object coords */
00165      const GLfloat *m = ctx->ModelviewMatrixStack.Top->m;
00166      GLfloat plane[4];
00167 
00168      /* Use this to store calculated eye z values:
00169       */
00170      input = &store->fogcoord;
00171 
00172      plane[0] = m[2];
00173      plane[1] = m[6];
00174      plane[2] = m[10];
00175      plane[3] = m[14];
00176      /* Full eye coords weren't required, just calculate the
00177       * eye Z values.
00178       */
00179      _mesa_dotprod_tab[VB->ObjPtr->size]( (GLfloat *) input->data,
00180                           4 * sizeof(GLfloat),
00181                           VB->ObjPtr, plane );
00182 
00183      input->count = VB->ObjPtr->count;
00184 
00185      /* make sure coords are really positive
00186         NOTE should avoid going through array twice */
00187      coord = input->start;
00188      for (i = 0; i < input->count; i++) {
00189         *coord = FABSF(*coord);
00190         STRIDE_F(coord, input->stride);
00191      }
00192       }
00193       else {
00194          /* fog coordinates = eye Z coordinates - need to copy for ABS */
00195      input = &store->fogcoord;
00196 
00197      if (VB->EyePtr->size < 2)
00198         _mesa_vector4f_clean_elem( VB->EyePtr, VB->Count, 2 );
00199 
00200      input->stride = 4 * sizeof(GLfloat);
00201      input->count = VB->EyePtr->count;
00202      coord = VB->EyePtr->start;
00203      for (i = 0 ; i < VB->EyePtr->count; i++) {
00204         input->data[i][0] = FABSF(coord[2]);
00205         STRIDE_F(coord, VB->EyePtr->stride);
00206      }
00207       }
00208    }
00209    else {
00210       /* use glFogCoord() coordinates */
00211       input = VB->AttribPtr[_TNL_ATTRIB_FOG];  /* source data */
00212 
00213       /* input->count may be one if glFogCoord was only called once
00214        * before glBegin.  But we need to compute fog for all vertices.
00215        */
00216       input->count = VB->ObjPtr->count;
00217 
00218       VB->AttribPtr[_TNL_ATTRIB_FOG] = &store->fogcoord;  /* dest data */
00219    }
00220 
00221    if (tnl->_DoVertexFog) {
00222       /* compute blend factors from fog coordinates */
00223       compute_fog_blend_factors( ctx, VB->AttribPtr[_TNL_ATTRIB_FOG], input );
00224    }
00225    else {
00226       /* results = incoming fog coords (compute fog per-fragment later) */
00227       VB->AttribPtr[_TNL_ATTRIB_FOG] = input;
00228    }
00229 
00230    VB->FogCoordPtr = VB->AttribPtr[_TNL_ATTRIB_FOG];
00231    return GL_TRUE;
00232 }
00233 
00234 
00235 
00236 /* Called the first time stage->run() is invoked.
00237  */
00238 static GLboolean
00239 alloc_fog_data(GLcontext *ctx, struct tnl_pipeline_stage *stage)
00240 {
00241    TNLcontext *tnl = TNL_CONTEXT(ctx);
00242    struct fog_stage_data *store;
00243    stage->privatePtr = MALLOC(sizeof(*store));
00244    store = FOG_STAGE_DATA(stage);
00245    if (!store)
00246       return GL_FALSE;
00247 
00248    _mesa_vector4f_alloc( &store->fogcoord, 0, tnl->vb.Size, 32 );
00249 
00250    if (!inited)
00251       init_static_data();
00252 
00253    return GL_TRUE;
00254 }
00255 
00256 
00257 static void
00258 free_fog_data(struct tnl_pipeline_stage *stage)
00259 {
00260    struct fog_stage_data *store = FOG_STAGE_DATA(stage);
00261    if (store) {
00262       _mesa_vector4f_free( &store->fogcoord );
00263       FREE( store );
00264       stage->privatePtr = NULL;
00265    }
00266 }
00267 
00268 
00269 const struct tnl_pipeline_stage _tnl_fog_coordinate_stage =
00270 {
00271    "build fog coordinates", /* name */
00272    NULL,            /* private_data */
00273    alloc_fog_data,      /* dtr */
00274    free_fog_data,       /* dtr */
00275    NULL,        /* check */
00276    run_fog_stage        /* run -- initially set to init. */
00277 };

Generated on Thu May 24 2012 04:20:58 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.