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_light.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 
00025 
00026 
00027 #include "main/glheader.h"
00028 #include "main/colormac.h"
00029 #include "main/light.h"
00030 #include "main/macros.h"
00031 #include "main/imports.h"
00032 #include "main/simple_list.h"
00033 #include "main/mtypes.h"
00034 
00035 #include "math/m_translate.h"
00036 
00037 #include "t_context.h"
00038 #include "t_pipeline.h"
00039 
00040 #define LIGHT_TWOSIDE       0x1
00041 #define LIGHT_MATERIAL      0x2
00042 #define MAX_LIGHT_FUNC      0x4
00043 
00044 typedef void (*light_func)( GLcontext *ctx,
00045                 struct vertex_buffer *VB,
00046                 struct tnl_pipeline_stage *stage,
00047                 GLvector4f *input );
00048 
00053 struct material_cursor {
00054    const GLfloat *ptr;    /* points to src vertex color (in VB array) */
00055    GLuint stride;         /* stride to next vertex color (bytes) */
00056    GLfloat *current;      /* points to material attribute to update */
00057    GLuint size;           /* vertex/color size: 1, 2, 3 or 4 */
00058 };
00059 
00063 struct light_stage_data {
00064    GLvector4f Input;
00065    GLvector4f LitColor[2];
00066    GLvector4f LitSecondary[2];
00067    GLvector4f LitIndex[2];
00068    light_func *light_func_tab;
00069 
00070    struct material_cursor mat[MAT_ATTRIB_MAX];
00071    GLuint mat_count;
00072    GLuint mat_bitmask;
00073 };
00074 
00075 
00076 #define LIGHT_STAGE_DATA(stage) ((struct light_stage_data *)(stage->privatePtr))
00077 
00078 
00079 
00088 static void
00089 update_materials(GLcontext *ctx, struct light_stage_data *store)
00090 {
00091    GLuint i;
00092 
00093    for (i = 0 ; i < store->mat_count ; i++) {
00094       /* update the material */
00095       COPY_CLEAN_4V(store->mat[i].current, store->mat[i].size, store->mat[i].ptr);
00096       /* increment src vertex color pointer */
00097       STRIDE_F(store->mat[i].ptr, store->mat[i].stride);
00098    }
00099       
00100    /* recompute derived light/material values */
00101    _mesa_update_material( ctx, store->mat_bitmask );
00102    /* XXX we should only call this if we're tracking/changing the specular
00103     * exponent.
00104     */
00105    _mesa_validate_all_lighting_tables( ctx );
00106 }
00107 
00108 
00113 static GLuint
00114 prepare_materials(GLcontext *ctx,
00115                   struct vertex_buffer *VB, struct light_stage_data *store)
00116 {
00117    GLuint i;
00118    
00119    store->mat_count = 0;
00120    store->mat_bitmask = 0;
00121 
00122    /* Examine the ColorMaterialBitmask to determine which materials
00123     * track vertex color.  Override the material attribute's pointer
00124     * with the color pointer for each one.
00125     */
00126    if (ctx->Light.ColorMaterialEnabled) {
00127       const GLuint bitmask = ctx->Light.ColorMaterialBitmask;
00128       for (i = 0 ; i < MAT_ATTRIB_MAX ; i++)
00129      if (bitmask & (1<<i))
00130         VB->AttribPtr[_TNL_ATTRIB_MAT_FRONT_AMBIENT + i] = VB->ColorPtr[0];
00131    }
00132 
00133    /* Now, for each material attribute that's tracking vertex color, save
00134     * some values (ptr, stride, size, current) that we'll need in
00135     * update_materials(), above, that'll actually copy the vertex color to
00136     * the material attribute(s).
00137     */
00138    for (i = _TNL_FIRST_MAT; i <= _TNL_LAST_MAT; i++) {
00139       if (VB->AttribPtr[i]->stride) {
00140      const GLuint j = store->mat_count++;
00141      const GLuint attr = i - _TNL_ATTRIB_MAT_FRONT_AMBIENT;
00142      store->mat[j].ptr    = VB->AttribPtr[i]->start;
00143      store->mat[j].stride = VB->AttribPtr[i]->stride;
00144      store->mat[j].size   = VB->AttribPtr[i]->size;
00145      store->mat[j].current = ctx->Light.Material.Attrib[attr];
00146      store->mat_bitmask |= (1<<attr);
00147       }
00148    }
00149 
00150    /* FIXME: Is this already done?
00151     */
00152    _mesa_update_material( ctx, ~0 );
00153    _mesa_validate_all_lighting_tables( ctx );
00154 
00155    return store->mat_count;
00156 }
00157 
00158 /* Tables for all the shading functions.
00159  */
00160 static light_func _tnl_light_tab[MAX_LIGHT_FUNC];
00161 static light_func _tnl_light_fast_tab[MAX_LIGHT_FUNC];
00162 static light_func _tnl_light_fast_single_tab[MAX_LIGHT_FUNC];
00163 static light_func _tnl_light_spec_tab[MAX_LIGHT_FUNC];
00164 static light_func _tnl_light_ci_tab[MAX_LIGHT_FUNC];
00165 
00166 #define TAG(x)           x
00167 #define IDX              (0)
00168 #include "t_vb_lighttmp.h"
00169 
00170 #define TAG(x)           x##_twoside
00171 #define IDX              (LIGHT_TWOSIDE)
00172 #include "t_vb_lighttmp.h"
00173 
00174 #define TAG(x)           x##_material
00175 #define IDX              (LIGHT_MATERIAL)
00176 #include "t_vb_lighttmp.h"
00177 
00178 #define TAG(x)           x##_twoside_material
00179 #define IDX              (LIGHT_TWOSIDE|LIGHT_MATERIAL)
00180 #include "t_vb_lighttmp.h"
00181 
00182 
00183 static void init_lighting_tables( void )
00184 {
00185    static int done;
00186 
00187    if (!done) {
00188       init_light_tab();
00189       init_light_tab_twoside();
00190       init_light_tab_material();
00191       init_light_tab_twoside_material();
00192       done = 1;
00193    }
00194 }
00195 
00196 
00197 static GLboolean run_lighting( GLcontext *ctx, 
00198                    struct tnl_pipeline_stage *stage )
00199 {
00200    struct light_stage_data *store = LIGHT_STAGE_DATA(stage);
00201    TNLcontext *tnl = TNL_CONTEXT(ctx);
00202    struct vertex_buffer *VB = &tnl->vb;
00203    GLvector4f *input = ctx->_NeedEyeCoords ? VB->EyePtr : VB->ObjPtr;
00204    GLuint idx;
00205 
00206    if (!ctx->Light.Enabled || ctx->VertexProgram._Current)
00207       return GL_TRUE;
00208 
00209    /* Make sure we can talk about position x,y and z:
00210     */
00211    if (input->size <= 2 && input == VB->ObjPtr) {
00212 
00213       _math_trans_4f( store->Input.data,
00214               VB->ObjPtr->data,
00215               VB->ObjPtr->stride,
00216               GL_FLOAT,
00217               VB->ObjPtr->size,
00218               0,
00219               VB->Count );
00220 
00221       if (input->size <= 2) {
00222      /* Clean z.
00223       */
00224      _mesa_vector4f_clean_elem(&store->Input, VB->Count, 2);
00225       }
00226      
00227       if (input->size <= 1) {
00228      /* Clean y.
00229       */
00230      _mesa_vector4f_clean_elem(&store->Input, VB->Count, 1);
00231       }
00232 
00233       input = &store->Input;
00234    }
00235    
00236    idx = 0;
00237 
00238    if (prepare_materials( ctx, VB, store ))
00239       idx |= LIGHT_MATERIAL;
00240 
00241    if (ctx->Light.Model.TwoSide)
00242       idx |= LIGHT_TWOSIDE;
00243 
00244    /* The individual functions know about replaying side-effects
00245     * vs. full re-execution. 
00246     */
00247    store->light_func_tab[idx]( ctx, VB, stage, input );
00248 
00249    VB->AttribPtr[_TNL_ATTRIB_COLOR0] = VB->ColorPtr[0];
00250    VB->AttribPtr[_TNL_ATTRIB_COLOR1] = VB->SecondaryColorPtr[0];
00251    VB->AttribPtr[_TNL_ATTRIB_COLOR_INDEX] = VB->IndexPtr[0];
00252 
00253    return GL_TRUE;
00254 }
00255 
00256 
00257 /* Called in place of do_lighting when the light table may have changed.
00258  */
00259 static void validate_lighting( GLcontext *ctx,
00260                     struct tnl_pipeline_stage *stage )
00261 {
00262    light_func *tab;
00263 
00264    if (!ctx->Light.Enabled || ctx->VertexProgram._Current)
00265       return;
00266 
00267    if (ctx->Visual.rgbMode) {
00268       if (ctx->Light._NeedVertices) {
00269      if (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)
00270         tab = _tnl_light_spec_tab;
00271      else
00272         tab = _tnl_light_tab;
00273       }
00274       else {
00275      if (ctx->Light.EnabledList.next == ctx->Light.EnabledList.prev)
00276         tab = _tnl_light_fast_single_tab;
00277      else
00278         tab = _tnl_light_fast_tab;
00279       }
00280    }
00281    else
00282       tab = _tnl_light_ci_tab;
00283 
00284 
00285    LIGHT_STAGE_DATA(stage)->light_func_tab = tab;
00286 
00287    /* This and the above should only be done on _NEW_LIGHT:
00288     */
00289    TNL_CONTEXT(ctx)->Driver.NotifyMaterialChange( ctx );
00290 }
00291 
00292 
00293 
00294 /* Called the first time stage->run is called.  In effect, don't
00295  * allocate data until the first time the stage is run.
00296  */
00297 static GLboolean init_lighting( GLcontext *ctx,
00298                 struct tnl_pipeline_stage *stage )
00299 {
00300    TNLcontext *tnl = TNL_CONTEXT(ctx);
00301    struct light_stage_data *store;
00302    GLuint size = tnl->vb.Size;
00303 
00304    stage->privatePtr = MALLOC(sizeof(*store));
00305    store = LIGHT_STAGE_DATA(stage);
00306    if (!store)
00307       return GL_FALSE;
00308 
00309    /* Do onetime init.
00310     */
00311    init_lighting_tables();
00312 
00313    _mesa_vector4f_alloc( &store->Input, 0, size, 32 );
00314    _mesa_vector4f_alloc( &store->LitColor[0], 0, size, 32 );
00315    _mesa_vector4f_alloc( &store->LitColor[1], 0, size, 32 );
00316    _mesa_vector4f_alloc( &store->LitSecondary[0], 0, size, 32 );
00317    _mesa_vector4f_alloc( &store->LitSecondary[1], 0, size, 32 );
00318    _mesa_vector4f_alloc( &store->LitIndex[0], 0, size, 32 );
00319    _mesa_vector4f_alloc( &store->LitIndex[1], 0, size, 32 );
00320 
00321    store->LitColor[0].size = 4;
00322    store->LitColor[1].size = 4;
00323    store->LitSecondary[0].size = 3;
00324    store->LitSecondary[1].size = 3;
00325 
00326    store->LitIndex[0].size = 1;
00327    store->LitIndex[0].stride = sizeof(GLfloat);
00328    store->LitIndex[1].size = 1;
00329    store->LitIndex[1].stride = sizeof(GLfloat);
00330 
00331    return GL_TRUE;
00332 }
00333 
00334 
00335 
00336 
00337 static void dtr( struct tnl_pipeline_stage *stage )
00338 {
00339    struct light_stage_data *store = LIGHT_STAGE_DATA(stage);
00340 
00341    if (store) {
00342       _mesa_vector4f_free( &store->Input );
00343       _mesa_vector4f_free( &store->LitColor[0] );
00344       _mesa_vector4f_free( &store->LitColor[1] );
00345       _mesa_vector4f_free( &store->LitSecondary[0] );
00346       _mesa_vector4f_free( &store->LitSecondary[1] );
00347       _mesa_vector4f_free( &store->LitIndex[0] );
00348       _mesa_vector4f_free( &store->LitIndex[1] );
00349       FREE( store );
00350       stage->privatePtr = NULL;
00351    }
00352 }
00353 
00354 const struct tnl_pipeline_stage _tnl_lighting_stage =
00355 {
00356    "lighting",          /* name */
00357    NULL,            /* private_data */
00358    init_lighting,
00359    dtr,             /* destroy */
00360    validate_lighting,
00361    run_lighting
00362 };

Generated on Sat May 26 2012 04:19:35 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.