Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygent_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
1.7.6.1
|