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_lighttmp.h
Go to the documentation of this file.
00001 /*
00002  * Mesa 3-D graphics library
00003  * Version:  5.1
00004  *
00005  * Copyright (C) 1999-2003  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  * Authors:
00026  *    Brian Paul
00027  *    Keith Whitwell <keith@tungstengraphics.com>
00028  */
00029 
00030 
00031 #if IDX & LIGHT_TWOSIDE
00032 #  define NR_SIDES 2
00033 #else
00034 #  define NR_SIDES 1
00035 #endif
00036 
00037 
00038 /* define TRACE to trace lighting code */
00039 /* #define TRACE 1 */
00040 
00041 /*
00042  * ctx is the current context
00043  * VB is the vertex buffer
00044  * stage is the lighting stage-private data
00045  * input is the vector of eye or object-space vertex coordinates
00046  */
00047 static void TAG(light_rgba_spec)( GLcontext *ctx,
00048                   struct vertex_buffer *VB,
00049                   struct tnl_pipeline_stage *stage,
00050                   GLvector4f *input )
00051 {
00052    struct light_stage_data *store = LIGHT_STAGE_DATA(stage);
00053    GLfloat (*base)[3] = ctx->Light._BaseColor;
00054    GLfloat sumA[2];
00055    GLuint j;
00056 
00057    const GLuint vstride = input->stride;
00058    const GLfloat *vertex = (GLfloat *)input->data;
00059    const GLuint nstride = VB->AttribPtr[_TNL_ATTRIB_NORMAL]->stride;
00060    const GLfloat *normal = (GLfloat *)VB->AttribPtr[_TNL_ATTRIB_NORMAL]->data;
00061 
00062    GLfloat (*Fcolor)[4] = (GLfloat (*)[4]) store->LitColor[0].data;
00063    GLfloat (*Fspec)[4] = (GLfloat (*)[4]) store->LitSecondary[0].data;
00064 #if IDX & LIGHT_TWOSIDE
00065    GLfloat (*Bcolor)[4] = (GLfloat (*)[4]) store->LitColor[1].data;
00066    GLfloat (*Bspec)[4] = (GLfloat (*)[4]) store->LitSecondary[1].data;
00067 #endif
00068 
00069    const GLuint nr = VB->Count;
00070 
00071 #ifdef TRACE
00072    fprintf(stderr, "%s\n", __FUNCTION__ );
00073 #endif
00074 
00075    VB->ColorPtr[0] = &store->LitColor[0];
00076    VB->SecondaryColorPtr[0] = &store->LitSecondary[0];
00077    sumA[0] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE][3];
00078 
00079 #if IDX & LIGHT_TWOSIDE
00080    VB->ColorPtr[1] = &store->LitColor[1];
00081    VB->SecondaryColorPtr[1] = &store->LitSecondary[1];
00082    sumA[1] = ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_DIFFUSE][3];
00083 #endif
00084 
00085 
00086    store->LitColor[0].stride = 16;
00087    store->LitColor[1].stride = 16;
00088 
00089    for (j = 0; j < nr; j++,STRIDE_F(vertex,vstride),STRIDE_F(normal,nstride)) {
00090       GLfloat sum[2][3], spec[2][3];
00091       struct gl_light *light;
00092 
00093 #if IDX & LIGHT_MATERIAL
00094       update_materials( ctx, store );
00095       sumA[0] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE][3];
00096 #if IDX & LIGHT_TWOSIDE
00097       sumA[1] = ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_DIFFUSE][3];
00098 #endif
00099 #endif
00100 
00101       COPY_3V(sum[0], base[0]);
00102       ZERO_3V(spec[0]);
00103 
00104 #if IDX & LIGHT_TWOSIDE
00105       COPY_3V(sum[1], base[1]);
00106       ZERO_3V(spec[1]);
00107 #endif
00108 
00109       /* Add contribution from each enabled light source */
00110       foreach (light, &ctx->Light.EnabledList) {
00111      GLfloat n_dot_h;
00112      GLfloat correction;
00113      GLint side;
00114      GLfloat contrib[3];
00115      GLfloat attenuation;
00116      GLfloat VP[3];  /* unit vector from vertex to light */
00117      GLfloat n_dot_VP;       /* n dot VP */
00118      GLfloat *h;
00119 
00120      /* compute VP and attenuation */
00121      if (!(light->_Flags & LIGHT_POSITIONAL)) {
00122         /* directional light */
00123         COPY_3V(VP, light->_VP_inf_norm);
00124         attenuation = light->_VP_inf_spot_attenuation;
00125      }
00126      else {
00127         GLfloat d;     /* distance from vertex to light */
00128 
00129         SUB_3V(VP, light->_Position, vertex);
00130 
00131         d = (GLfloat) LEN_3FV( VP );
00132 
00133         if (d > 1e-6) {
00134            GLfloat invd = 1.0F / d;
00135            SELF_SCALE_SCALAR_3V(VP, invd);
00136         }
00137 
00138         attenuation = 1.0F / (light->ConstantAttenuation + d *
00139                   (light->LinearAttenuation + d *
00140                    light->QuadraticAttenuation));
00141 
00142         /* spotlight attenuation */
00143         if (light->_Flags & LIGHT_SPOT) {
00144            GLfloat PV_dot_dir = - DOT3(VP, light->_NormDirection);
00145 
00146            if (PV_dot_dir<light->_CosCutoff) {
00147           continue; /* this light makes no contribution */
00148            }
00149            else {
00150           GLdouble x = PV_dot_dir * (EXP_TABLE_SIZE-1);
00151           GLint k = (GLint) x;
00152           GLfloat spot = (GLfloat) (light->_SpotExpTable[k][0]
00153                     + (x-k)*light->_SpotExpTable[k][1]);
00154           attenuation *= spot;
00155            }
00156         }
00157      }
00158 
00159      if (attenuation < 1e-3)
00160         continue;       /* this light makes no contribution */
00161 
00162      /* Compute dot product or normal and vector from V to light pos */
00163      n_dot_VP = DOT3( normal, VP );
00164 
00165      /* Which side gets the diffuse & specular terms? */
00166      if (n_dot_VP < 0.0F) {
00167         ACC_SCALE_SCALAR_3V(sum[0], attenuation, light->_MatAmbient[0]);
00168 #if IDX & LIGHT_TWOSIDE
00169         side = 1;
00170         correction = -1;
00171         n_dot_VP = -n_dot_VP;
00172 #else
00173             continue;
00174 #endif
00175      }
00176          else {
00177 #if IDX & LIGHT_TWOSIDE
00178             ACC_SCALE_SCALAR_3V( sum[1], attenuation, light->_MatAmbient[1]);
00179 #endif
00180         side = 0;
00181         correction = 1;
00182      }
00183 
00184      /* diffuse term */
00185      COPY_3V(contrib, light->_MatAmbient[side]);
00186      ACC_SCALE_SCALAR_3V(contrib, n_dot_VP, light->_MatDiffuse[side]);
00187      ACC_SCALE_SCALAR_3V(sum[side], attenuation, contrib );
00188 
00189      /* specular term - cannibalize VP... */
00190      if (ctx->Light.Model.LocalViewer) {
00191         GLfloat v[3];
00192         COPY_3V(v, vertex);
00193         NORMALIZE_3FV(v);
00194         SUB_3V(VP, VP, v);                /* h = VP + VPe */
00195         h = VP;
00196         NORMALIZE_3FV(h);
00197      }
00198      else if (light->_Flags & LIGHT_POSITIONAL) {
00199         h = VP;
00200         ACC_3V(h, ctx->_EyeZDir);
00201         NORMALIZE_3FV(h);
00202      }
00203          else {
00204         h = light->_h_inf_norm;
00205      }
00206 
00207      n_dot_h = correction * DOT3(normal, h);
00208 
00209      if (n_dot_h > 0.0F) {
00210         GLfloat spec_coef;
00211         struct gl_shine_tab *tab = ctx->_ShineTable[side];
00212         GET_SHINE_TAB_ENTRY( tab, n_dot_h, spec_coef );
00213 
00214         if (spec_coef > 1.0e-10) {
00215            spec_coef *= attenuation;
00216            ACC_SCALE_SCALAR_3V( spec[side], spec_coef,
00217                     light->_MatSpecular[side]);
00218         }
00219      }
00220       } /*loop over lights*/
00221 
00222       COPY_3V( Fcolor[j], sum[0] );
00223       COPY_3V( Fspec[j], spec[0] );
00224       Fcolor[j][3] = sumA[0];
00225 
00226 #if IDX & LIGHT_TWOSIDE
00227       COPY_3V( Bcolor[j], sum[1] );
00228       COPY_3V( Bspec[j], spec[1] );
00229       Bcolor[j][3] = sumA[1];
00230 #endif
00231    }
00232 }
00233 
00234 
00235 static void TAG(light_rgba)( GLcontext *ctx,
00236                  struct vertex_buffer *VB,
00237                  struct tnl_pipeline_stage *stage,
00238                  GLvector4f *input )
00239 {
00240    struct light_stage_data *store = LIGHT_STAGE_DATA(stage);
00241    GLuint j;
00242 
00243    GLfloat (*base)[3] = ctx->Light._BaseColor;
00244    GLfloat sumA[2];
00245 
00246    const GLuint vstride = input->stride;
00247    const GLfloat *vertex = (GLfloat *) input->data;
00248    const GLuint nstride = VB->AttribPtr[_TNL_ATTRIB_NORMAL]->stride;
00249    const GLfloat *normal = (GLfloat *)VB->AttribPtr[_TNL_ATTRIB_NORMAL]->data;
00250 
00251    GLfloat (*Fcolor)[4] = (GLfloat (*)[4]) store->LitColor[0].data;
00252 #if IDX & LIGHT_TWOSIDE
00253    GLfloat (*Bcolor)[4] = (GLfloat (*)[4]) store->LitColor[1].data;
00254 #endif
00255 
00256    const GLuint nr = VB->Count;
00257 
00258 #ifdef TRACE
00259    fprintf(stderr, "%s\n", __FUNCTION__ );
00260 #endif
00261 
00262    VB->ColorPtr[0] = &store->LitColor[0];
00263    sumA[0] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE][3];
00264 
00265 #if IDX & LIGHT_TWOSIDE
00266    VB->ColorPtr[1] = &store->LitColor[1];
00267    sumA[1] = ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_DIFFUSE][3];
00268 #endif
00269 
00270    store->LitColor[0].stride = 16;
00271    store->LitColor[1].stride = 16;
00272 
00273    for (j = 0; j < nr; j++,STRIDE_F(vertex,vstride),STRIDE_F(normal,nstride)) {
00274       GLfloat sum[2][3];
00275       struct gl_light *light;
00276 
00277 #if IDX & LIGHT_MATERIAL
00278       update_materials( ctx, store );
00279       sumA[0] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE][3];
00280 #if IDX & LIGHT_TWOSIDE
00281       sumA[1] = ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_DIFFUSE][3];
00282 #endif
00283 #endif
00284 
00285       COPY_3V(sum[0], base[0]);
00286 
00287 #if IDX & LIGHT_TWOSIDE
00288       COPY_3V(sum[1], base[1]);
00289 #endif
00290 
00291       /* Add contribution from each enabled light source */
00292       foreach (light, &ctx->Light.EnabledList) {
00293 
00294      GLfloat n_dot_h;
00295      GLfloat correction;
00296      GLint side;
00297      GLfloat contrib[3];
00298      GLfloat attenuation = 1.0;
00299      GLfloat VP[3];          /* unit vector from vertex to light */
00300      GLfloat n_dot_VP;       /* n dot VP */
00301      GLfloat *h;
00302 
00303      /* compute VP and attenuation */
00304      if (!(light->_Flags & LIGHT_POSITIONAL)) {
00305         /* directional light */
00306         COPY_3V(VP, light->_VP_inf_norm);
00307         attenuation = light->_VP_inf_spot_attenuation;
00308      }
00309      else {
00310         GLfloat d;     /* distance from vertex to light */
00311 
00312 
00313         SUB_3V(VP, light->_Position, vertex);
00314 
00315         d = (GLfloat) LEN_3FV( VP );
00316 
00317         if ( d > 1e-6) {
00318            GLfloat invd = 1.0F / d;
00319            SELF_SCALE_SCALAR_3V(VP, invd);
00320         }
00321 
00322             attenuation = 1.0F / (light->ConstantAttenuation + d *
00323                                   (light->LinearAttenuation + d *
00324                                    light->QuadraticAttenuation));
00325 
00326         /* spotlight attenuation */
00327         if (light->_Flags & LIGHT_SPOT) {
00328            GLfloat PV_dot_dir = - DOT3(VP, light->_NormDirection);
00329 
00330            if (PV_dot_dir<light->_CosCutoff) {
00331           continue; /* this light makes no contribution */
00332            }
00333            else {
00334           GLdouble x = PV_dot_dir * (EXP_TABLE_SIZE-1);
00335           GLint k = (GLint) x;
00336           GLfloat spot = (GLfloat) (light->_SpotExpTable[k][0]
00337                   + (x-k)*light->_SpotExpTable[k][1]);
00338           attenuation *= spot;
00339            }
00340         }
00341      }
00342 
00343      if (attenuation < 1e-3)
00344         continue;       /* this light makes no contribution */
00345 
00346      /* Compute dot product or normal and vector from V to light pos */
00347      n_dot_VP = DOT3( normal, VP );
00348 
00349      /* which side are we lighting? */
00350      if (n_dot_VP < 0.0F) {
00351         ACC_SCALE_SCALAR_3V(sum[0], attenuation, light->_MatAmbient[0]);
00352 #if IDX & LIGHT_TWOSIDE
00353         side = 1;
00354         correction = -1;
00355         n_dot_VP = -n_dot_VP;
00356 #else
00357             continue;
00358 #endif
00359      }
00360          else {
00361 #if IDX & LIGHT_TWOSIDE
00362             ACC_SCALE_SCALAR_3V( sum[1], attenuation, light->_MatAmbient[1]);
00363 #endif
00364         side = 0;
00365         correction = 1;
00366      }
00367 
00368      COPY_3V(contrib, light->_MatAmbient[side]);
00369 
00370      /* diffuse term */
00371      ACC_SCALE_SCALAR_3V(contrib, n_dot_VP, light->_MatDiffuse[side]);
00372 
00373      /* specular term - cannibalize VP... */
00374      {
00375         if (ctx->Light.Model.LocalViewer) {
00376            GLfloat v[3];
00377            COPY_3V(v, vertex);
00378            NORMALIZE_3FV(v);
00379            SUB_3V(VP, VP, v);                /* h = VP + VPe */
00380            h = VP;
00381            NORMALIZE_3FV(h);
00382         }
00383         else if (light->_Flags & LIGHT_POSITIONAL) {
00384            h = VP;
00385            ACC_3V(h, ctx->_EyeZDir);
00386            NORMALIZE_3FV(h);
00387         }
00388             else {
00389            h = light->_h_inf_norm;
00390         }
00391 
00392         n_dot_h = correction * DOT3(normal, h);
00393 
00394         if (n_dot_h > 0.0F)
00395         {
00396            GLfloat spec_coef;
00397            struct gl_shine_tab *tab = ctx->_ShineTable[side];
00398 
00399            GET_SHINE_TAB_ENTRY( tab, n_dot_h, spec_coef );
00400 
00401            ACC_SCALE_SCALAR_3V( contrib, spec_coef,
00402                     light->_MatSpecular[side]);
00403         }
00404      }
00405 
00406      ACC_SCALE_SCALAR_3V( sum[side], attenuation, contrib );
00407       }
00408 
00409       COPY_3V( Fcolor[j], sum[0] );
00410       Fcolor[j][3] = sumA[0];
00411 
00412 #if IDX & LIGHT_TWOSIDE
00413       COPY_3V( Bcolor[j], sum[1] );
00414       Bcolor[j][3] = sumA[1];
00415 #endif
00416    }
00417 }
00418 
00419 
00420 
00421 
00422 /* As below, but with just a single light.
00423  */
00424 static void TAG(light_fast_rgba_single)( GLcontext *ctx,
00425                      struct vertex_buffer *VB,
00426                      struct tnl_pipeline_stage *stage,
00427                      GLvector4f *input )
00428 
00429 {
00430    struct light_stage_data *store = LIGHT_STAGE_DATA(stage);
00431    const GLuint nstride = VB->AttribPtr[_TNL_ATTRIB_NORMAL]->stride;
00432    const GLfloat *normal = (GLfloat *)VB->AttribPtr[_TNL_ATTRIB_NORMAL]->data;
00433    GLfloat (*Fcolor)[4] = (GLfloat (*)[4]) store->LitColor[0].data;
00434 #if IDX & LIGHT_TWOSIDE
00435    GLfloat (*Bcolor)[4] = (GLfloat (*)[4]) store->LitColor[1].data;
00436 #endif
00437    const struct gl_light *light = ctx->Light.EnabledList.next;
00438    GLuint j = 0;
00439    GLfloat base[2][4];
00440 #if IDX & LIGHT_MATERIAL
00441    const GLuint nr = VB->Count;
00442 #else
00443    const GLuint nr = VB->AttribPtr[_TNL_ATTRIB_NORMAL]->count;
00444 #endif
00445 
00446 #ifdef TRACE
00447    fprintf(stderr, "%s\n", __FUNCTION__ );
00448 #endif
00449 
00450    (void) input;        /* doesn't refer to Eye or Obj */
00451 
00452    VB->ColorPtr[0] = &store->LitColor[0];
00453 #if IDX & LIGHT_TWOSIDE
00454    VB->ColorPtr[1] = &store->LitColor[1];
00455 #endif
00456 
00457    if (nr > 1) {
00458       store->LitColor[0].stride = 16;
00459       store->LitColor[1].stride = 16;
00460    }
00461    else {
00462       store->LitColor[0].stride = 0;
00463       store->LitColor[1].stride = 0;
00464    }
00465 
00466    for (j = 0; j < nr; j++, STRIDE_F(normal,nstride)) {
00467 
00468       GLfloat n_dot_VP;
00469 
00470 #if IDX & LIGHT_MATERIAL
00471       update_materials( ctx, store );
00472 #endif
00473 
00474       /* No attenuation, so incoporate _MatAmbient into base color.
00475        */
00476 #if !(IDX & LIGHT_MATERIAL)
00477       if ( j == 0 )
00478 #endif
00479       {
00480      COPY_3V(base[0], light->_MatAmbient[0]);
00481      ACC_3V(base[0], ctx->Light._BaseColor[0] );
00482      base[0][3] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE][3];
00483 
00484 #if IDX & LIGHT_TWOSIDE
00485          COPY_3V(base[1], light->_MatAmbient[1]);
00486          ACC_3V(base[1], ctx->Light._BaseColor[1]);
00487          base[1][3] = ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_DIFFUSE][3];
00488 #endif
00489       }
00490 
00491       n_dot_VP = DOT3(normal, light->_VP_inf_norm);
00492 
00493       if (n_dot_VP < 0.0F) {
00494 #if IDX & LIGHT_TWOSIDE
00495          GLfloat n_dot_h = -DOT3(normal, light->_h_inf_norm);
00496          GLfloat sum[3];
00497          COPY_3V(sum, base[1]);
00498          ACC_SCALE_SCALAR_3V(sum, -n_dot_VP, light->_MatDiffuse[1]);
00499          if (n_dot_h > 0.0F) {
00500             GLfloat spec;
00501             GET_SHINE_TAB_ENTRY( ctx->_ShineTable[1], n_dot_h, spec );
00502             ACC_SCALE_SCALAR_3V(sum, spec, light->_MatSpecular[1]);
00503          }
00504          COPY_3V(Bcolor[j], sum );
00505          Bcolor[j][3] = base[1][3];
00506 #endif
00507      COPY_4FV(Fcolor[j], base[0]);
00508       }
00509       else {
00510      GLfloat n_dot_h = DOT3(normal, light->_h_inf_norm);
00511      GLfloat sum[3];
00512      COPY_3V(sum, base[0]);
00513      ACC_SCALE_SCALAR_3V(sum, n_dot_VP, light->_MatDiffuse[0]);
00514      if (n_dot_h > 0.0F) {
00515         GLfloat spec;
00516         GET_SHINE_TAB_ENTRY( ctx->_ShineTable[0], n_dot_h, spec );
00517         ACC_SCALE_SCALAR_3V(sum, spec, light->_MatSpecular[0]);
00518 
00519      }
00520      COPY_3V(Fcolor[j], sum );
00521      Fcolor[j][3] = base[0][3];
00522 #if IDX & LIGHT_TWOSIDE
00523          COPY_4FV(Bcolor[j], base[1]);
00524 #endif
00525       }
00526    }
00527 }
00528 
00529 
00530 /* Light infinite lights
00531  */
00532 static void TAG(light_fast_rgba)( GLcontext *ctx,
00533                   struct vertex_buffer *VB,
00534                   struct tnl_pipeline_stage *stage,
00535                   GLvector4f *input )
00536 {
00537    struct light_stage_data *store = LIGHT_STAGE_DATA(stage);
00538    GLfloat sumA[2];
00539    const GLuint nstride = VB->AttribPtr[_TNL_ATTRIB_NORMAL]->stride;
00540    const GLfloat *normal = (GLfloat *)VB->AttribPtr[_TNL_ATTRIB_NORMAL]->data;
00541    GLfloat (*Fcolor)[4] = (GLfloat (*)[4]) store->LitColor[0].data;
00542 #if IDX & LIGHT_TWOSIDE
00543    GLfloat (*Bcolor)[4] = (GLfloat (*)[4]) store->LitColor[1].data;
00544 #endif
00545    GLuint j = 0;
00546 #if IDX & LIGHT_MATERIAL
00547    const GLuint nr = VB->Count;
00548 #else
00549    const GLuint nr = VB->AttribPtr[_TNL_ATTRIB_NORMAL]->count;
00550 #endif
00551    const struct gl_light *light;
00552 
00553 #ifdef TRACE
00554    fprintf(stderr, "%s %d\n", __FUNCTION__, nr );
00555 #endif
00556 
00557    (void) input;
00558 
00559    sumA[0] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE][3];
00560    sumA[1] = ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_DIFFUSE][3];
00561 
00562    VB->ColorPtr[0] = &store->LitColor[0];
00563 #if IDX & LIGHT_TWOSIDE
00564    VB->ColorPtr[1] = &store->LitColor[1];
00565 #endif
00566 
00567    if (nr > 1) {
00568       store->LitColor[0].stride = 16;
00569       store->LitColor[1].stride = 16;
00570    }
00571    else {
00572       store->LitColor[0].stride = 0;
00573       store->LitColor[1].stride = 0;
00574    }
00575 
00576    for (j = 0; j < nr; j++, STRIDE_F(normal,nstride)) {
00577 
00578       GLfloat sum[2][3];
00579 
00580 #if IDX & LIGHT_MATERIAL
00581       update_materials( ctx, store );
00582 
00583       sumA[0] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE][3];
00584 #if IDX & LIGHT_TWOSIDE
00585       sumA[1] = ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_DIFFUSE][3];
00586 #endif
00587 #endif
00588 
00589 
00590       COPY_3V(sum[0], ctx->Light._BaseColor[0]);
00591 #if IDX & LIGHT_TWOSIDE
00592       COPY_3V(sum[1], ctx->Light._BaseColor[1]);
00593 #endif
00594 
00595       foreach (light, &ctx->Light.EnabledList) {
00596      GLfloat n_dot_h, n_dot_VP, spec;
00597 
00598      ACC_3V(sum[0], light->_MatAmbient[0]);
00599 #if IDX & LIGHT_TWOSIDE
00600          ACC_3V(sum[1], light->_MatAmbient[1]);
00601 #endif
00602 
00603      n_dot_VP = DOT3(normal, light->_VP_inf_norm);
00604 
00605      if (n_dot_VP > 0.0F) {
00606         ACC_SCALE_SCALAR_3V(sum[0], n_dot_VP, light->_MatDiffuse[0]);
00607         n_dot_h = DOT3(normal, light->_h_inf_norm);
00608         if (n_dot_h > 0.0F) {
00609            struct gl_shine_tab *tab = ctx->_ShineTable[0];
00610            GET_SHINE_TAB_ENTRY( tab, n_dot_h, spec );
00611            ACC_SCALE_SCALAR_3V( sum[0], spec, light->_MatSpecular[0]);
00612         }
00613      }
00614 #if IDX & LIGHT_TWOSIDE
00615          else {
00616         ACC_SCALE_SCALAR_3V(sum[1], -n_dot_VP, light->_MatDiffuse[1]);
00617         n_dot_h = -DOT3(normal, light->_h_inf_norm);
00618         if (n_dot_h > 0.0F) {
00619            struct gl_shine_tab *tab = ctx->_ShineTable[1];
00620            GET_SHINE_TAB_ENTRY( tab, n_dot_h, spec );
00621            ACC_SCALE_SCALAR_3V( sum[1], spec, light->_MatSpecular[1]);
00622         }
00623      }
00624 #endif
00625       }
00626 
00627       COPY_3V( Fcolor[j], sum[0] );
00628       Fcolor[j][3] = sumA[0];
00629 
00630 #if IDX & LIGHT_TWOSIDE
00631       COPY_3V( Bcolor[j], sum[1] );
00632       Bcolor[j][3] = sumA[1];
00633 #endif
00634    }
00635 }
00636 
00637 
00638 
00639 
00640 
00641 /*
00642  * Use current lighting/material settings to compute the color indexes
00643  * for an array of vertices.
00644  * Input:  n - number of vertices to light
00645  *         side - 0=use front material, 1=use back material
00646  *         vertex - array of [n] vertex position in eye coordinates
00647  *         normal - array of [n] surface normal vector
00648  * Output:  indexResult - resulting array of [n] color indexes
00649  */
00650 static void TAG(light_ci)( GLcontext *ctx,
00651                struct vertex_buffer *VB,
00652                struct tnl_pipeline_stage *stage,
00653                GLvector4f *input )
00654 {
00655    struct light_stage_data *store = LIGHT_STAGE_DATA(stage);
00656    GLuint j;
00657    const GLuint vstride = input->stride;
00658    const GLfloat *vertex = (GLfloat *) input->data;
00659    const GLuint nstride = VB->AttribPtr[_TNL_ATTRIB_NORMAL]->stride;
00660    const GLfloat *normal = (GLfloat *)VB->AttribPtr[_TNL_ATTRIB_NORMAL]->data;
00661    GLfloat *indexResult[2];
00662    const GLuint nr = VB->Count;
00663 
00664 #ifdef TRACE
00665    fprintf(stderr, "%s\n", __FUNCTION__ );
00666 #endif
00667 
00668    VB->IndexPtr[0] = &store->LitIndex[0];
00669 #if IDX & LIGHT_TWOSIDE
00670    VB->IndexPtr[1] = &store->LitIndex[1];
00671 #endif
00672 
00673    indexResult[0] = (GLfloat *)VB->IndexPtr[0]->data;
00674 #if IDX & LIGHT_TWOSIDE
00675    indexResult[1] = (GLfloat *)VB->IndexPtr[1]->data;
00676 #endif
00677 
00678    /* loop over vertices */
00679    for (j=0; j<nr; j++,STRIDE_F(vertex,vstride),STRIDE_F(normal, nstride)) {
00680       GLfloat diffuse[2], specular[2];
00681       GLuint side = 0;
00682       struct gl_light *light;
00683 
00684 #if IDX & LIGHT_MATERIAL
00685       update_materials( ctx, store );
00686 #endif
00687 
00688       diffuse[0] = specular[0] = 0.0F;
00689 
00690 #if IDX & LIGHT_TWOSIDE
00691      diffuse[1] = specular[1] = 0.0F;
00692 #endif
00693 
00694       /* Accumulate diffuse and specular from each light source */
00695       foreach (light, &ctx->Light.EnabledList) {
00696 
00697      GLfloat attenuation = 1.0F;
00698      GLfloat VP[3];  /* unit vector from vertex to light */
00699      GLfloat n_dot_VP;  /* dot product of l and n */
00700      GLfloat *h, n_dot_h, correction = 1.0;
00701 
00702      /* compute l and attenuation */
00703      if (!(light->_Flags & LIGHT_POSITIONAL)) {
00704         /* directional light */
00705         COPY_3V(VP, light->_VP_inf_norm);
00706      }
00707      else {
00708         GLfloat d;     /* distance from vertex to light */
00709 
00710         SUB_3V(VP, light->_Position, vertex);
00711 
00712         d = (GLfloat) LEN_3FV( VP );
00713         if ( d > 1e-6) {
00714            GLfloat invd = 1.0F / d;
00715            SELF_SCALE_SCALAR_3V(VP, invd);
00716         }
00717 
00718         attenuation = 1.0F / (light->ConstantAttenuation + d *
00719                   (light->LinearAttenuation + d *
00720                    light->QuadraticAttenuation));
00721 
00722         /* spotlight attenuation */
00723         if (light->_Flags & LIGHT_SPOT) {
00724            GLfloat PV_dot_dir = - DOT3(VP, light->_NormDirection);
00725            if (PV_dot_dir < light->_CosCutoff) {
00726           continue; /* this light makes no contribution */
00727            }
00728            else {
00729           GLdouble x = PV_dot_dir * (EXP_TABLE_SIZE-1);
00730           GLint k = (GLint) x;
00731           GLfloat spot = (GLfloat) (light->_SpotExpTable[k][0]
00732                   + (x-k)*light->_SpotExpTable[k][1]);
00733           attenuation *= spot;
00734            }
00735         }
00736      }
00737 
00738      if (attenuation < 1e-3)
00739         continue;       /* this light makes no contribution */
00740 
00741      n_dot_VP = DOT3( normal, VP );
00742 
00743      /* which side are we lighting? */
00744      if (n_dot_VP < 0.0F) {
00745 #if IDX & LIGHT_TWOSIDE
00746         side = 1;
00747         correction = -1;
00748         n_dot_VP = -n_dot_VP;
00749 #else
00750             continue;
00751 #endif
00752      }
00753 
00754      /* accumulate diffuse term */
00755      diffuse[side] += n_dot_VP * light->_dli * attenuation;
00756 
00757      /* specular term */
00758      if (ctx->Light.Model.LocalViewer) {
00759         GLfloat v[3];
00760         COPY_3V(v, vertex);
00761         NORMALIZE_3FV(v);
00762         SUB_3V(VP, VP, v);                /* h = VP + VPe */
00763         h = VP;
00764         NORMALIZE_3FV(h);
00765      }
00766      else if (light->_Flags & LIGHT_POSITIONAL) {
00767         h = VP;
00768             /* Strangely, disabling this addition fixes a conformance
00769              * problem.  If this code is enabled, l_sed.c fails.
00770              */
00771         /*ACC_3V(h, ctx->_EyeZDir);*/
00772         NORMALIZE_3FV(h);
00773      }
00774          else {
00775         h = light->_h_inf_norm;
00776      }
00777 
00778      n_dot_h = correction * DOT3(normal, h);
00779      if (n_dot_h > 0.0F) {
00780         GLfloat spec_coef;
00781         struct gl_shine_tab *tab = ctx->_ShineTable[side];
00782         GET_SHINE_TAB_ENTRY( tab, n_dot_h, spec_coef);
00783         specular[side] += spec_coef * light->_sli * attenuation;
00784      }
00785       } /*loop over lights*/
00786 
00787       /* Now compute final color index */
00788       for (side = 0 ; side < NR_SIDES ; side++) {
00789      const GLfloat *ind = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_INDEXES + side];
00790      GLfloat index;
00791 
00792      if (specular[side] > 1.0F) {
00793         index = ind[MAT_INDEX_SPECULAR];
00794      }
00795      else {
00796         GLfloat d_a = ind[MAT_INDEX_DIFFUSE] - ind[MAT_INDEX_AMBIENT];
00797         GLfloat s_a = ind[MAT_INDEX_SPECULAR] - ind[MAT_INDEX_AMBIENT];
00798         index = (ind[MAT_INDEX_AMBIENT]
00799              + diffuse[side] * (1.0F-specular[side]) * d_a
00800              + specular[side] * s_a);
00801         if (index > ind[MAT_INDEX_SPECULAR]) {
00802            index = ind[MAT_INDEX_SPECULAR];
00803         }
00804      }
00805      indexResult[side][j] = index;
00806       }
00807    } /*for vertex*/
00808 }
00809 
00810 
00811 
00812 static void TAG(init_light_tab)( void )
00813 {
00814    _tnl_light_tab[IDX] = TAG(light_rgba);
00815    _tnl_light_fast_tab[IDX] = TAG(light_fast_rgba);
00816    _tnl_light_fast_single_tab[IDX] = TAG(light_fast_rgba_single);
00817    _tnl_light_spec_tab[IDX] = TAG(light_rgba_spec);
00818    _tnl_light_ci_tab[IDX] = TAG(light_ci);
00819 }
00820 
00821 
00822 #undef TAG
00823 #undef IDX
00824 #undef NR_SIDES

Generated on Sun May 27 2012 04:20:46 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.