📄 t_vb_lighttmp.h
字号:
Bcolor[j][3] = sumA[1];#endif }}/* As below, but with just a single light. */static void TAG(light_fast_rgba_single)( GLcontext *ctx, struct vertex_buffer *VB, struct tnl_pipeline_stage *stage, GLvector4f *input ){ struct light_stage_data *store = LIGHT_STAGE_DATA(stage); const GLuint nstride = VB->AttribPtr[_TNL_ATTRIB_NORMAL]->stride; const GLfloat *normal = (GLfloat *)VB->AttribPtr[_TNL_ATTRIB_NORMAL]->data; GLfloat (*Fcolor)[4] = (GLfloat (*)[4]) store->LitColor[0].data;#if IDX & LIGHT_TWOSIDE GLfloat (*Bcolor)[4] = (GLfloat (*)[4]) store->LitColor[1].data;#endif const struct gl_light *light = ctx->Light.EnabledList.next; GLuint j = 0; GLfloat base[2][4];#if IDX & LIGHT_MATERIAL const GLuint nr = VB->Count;#else const GLuint nr = VB->AttribPtr[_TNL_ATTRIB_NORMAL]->count;#endif#ifdef TRACE fprintf(stderr, "%s\n", __FUNCTION__ );#endif (void) input; /* doesn't refer to Eye or Obj */ VB->ColorPtr[0] = &store->LitColor[0];#if IDX & LIGHT_TWOSIDE VB->ColorPtr[1] = &store->LitColor[1];#endif if (nr > 1) { store->LitColor[0].stride = 16; store->LitColor[1].stride = 16; } else { store->LitColor[0].stride = 0; store->LitColor[1].stride = 0; } for (j = 0; j < nr; j++, STRIDE_F(normal,nstride)) { GLfloat n_dot_VP;#if IDX & LIGHT_MATERIAL update_materials( ctx, store );#endif /* No attenuation, so incoporate _MatAmbient into base color. */#if !(IDX & LIGHT_MATERIAL) if ( j == 0 )#endif { COPY_3V(base[0], light->_MatAmbient[0]); ACC_3V(base[0], ctx->Light._BaseColor[0] ); base[0][3] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE][3];#if IDX & LIGHT_TWOSIDE COPY_3V(base[1], light->_MatAmbient[1]); ACC_3V(base[1], ctx->Light._BaseColor[1]); base[1][3] = ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_DIFFUSE][3];#endif } n_dot_VP = DOT3(normal, light->_VP_inf_norm); if (n_dot_VP < 0.0F) {#if IDX & LIGHT_TWOSIDE GLfloat n_dot_h = -DOT3(normal, light->_h_inf_norm); GLfloat sum[3]; COPY_3V(sum, base[1]); ACC_SCALE_SCALAR_3V(sum, -n_dot_VP, light->_MatDiffuse[1]); if (n_dot_h > 0.0F) { GLfloat spec; GET_SHINE_TAB_ENTRY( ctx->_ShineTable[1], n_dot_h, spec ); ACC_SCALE_SCALAR_3V(sum, spec, light->_MatSpecular[1]); } COPY_3V(Bcolor[j], sum ); Bcolor[j][3] = base[1][3];#endif COPY_4FV(Fcolor[j], base[0]); } else { GLfloat n_dot_h = DOT3(normal, light->_h_inf_norm); GLfloat sum[3]; COPY_3V(sum, base[0]); ACC_SCALE_SCALAR_3V(sum, n_dot_VP, light->_MatDiffuse[0]); if (n_dot_h > 0.0F) { GLfloat spec; GET_SHINE_TAB_ENTRY( ctx->_ShineTable[0], n_dot_h, spec ); ACC_SCALE_SCALAR_3V(sum, spec, light->_MatSpecular[0]); } COPY_3V(Fcolor[j], sum ); Fcolor[j][3] = base[0][3];#if IDX & LIGHT_TWOSIDE COPY_4FV(Bcolor[j], base[1]);#endif } }}/* Light infinite lights */static void TAG(light_fast_rgba)( GLcontext *ctx, struct vertex_buffer *VB, struct tnl_pipeline_stage *stage, GLvector4f *input ){ struct light_stage_data *store = LIGHT_STAGE_DATA(stage); GLfloat sumA[2]; const GLuint nstride = VB->AttribPtr[_TNL_ATTRIB_NORMAL]->stride; const GLfloat *normal = (GLfloat *)VB->AttribPtr[_TNL_ATTRIB_NORMAL]->data; GLfloat (*Fcolor)[4] = (GLfloat (*)[4]) store->LitColor[0].data;#if IDX & LIGHT_TWOSIDE GLfloat (*Bcolor)[4] = (GLfloat (*)[4]) store->LitColor[1].data;#endif GLuint j = 0;#if IDX & LIGHT_MATERIAL const GLuint nr = VB->Count;#else const GLuint nr = VB->AttribPtr[_TNL_ATTRIB_NORMAL]->count;#endif const struct gl_light *light;#ifdef TRACE fprintf(stderr, "%s %d\n", __FUNCTION__, nr );#endif (void) input; sumA[0] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE][3]; sumA[1] = ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_DIFFUSE][3]; VB->ColorPtr[0] = &store->LitColor[0];#if IDX & LIGHT_TWOSIDE VB->ColorPtr[1] = &store->LitColor[1];#endif if (nr > 1) { store->LitColor[0].stride = 16; store->LitColor[1].stride = 16; } else { store->LitColor[0].stride = 0; store->LitColor[1].stride = 0; } for (j = 0; j < nr; j++, STRIDE_F(normal,nstride)) { GLfloat sum[2][3];#if IDX & LIGHT_MATERIAL update_materials( ctx, store ); sumA[0] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE][3];#if IDX & LIGHT_TWOSIDE sumA[1] = ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_DIFFUSE][3];#endif#endif COPY_3V(sum[0], ctx->Light._BaseColor[0]);#if IDX & LIGHT_TWOSIDE COPY_3V(sum[1], ctx->Light._BaseColor[1]);#endif foreach (light, &ctx->Light.EnabledList) { GLfloat n_dot_h, n_dot_VP, spec; ACC_3V(sum[0], light->_MatAmbient[0]);#if IDX & LIGHT_TWOSIDE ACC_3V(sum[1], light->_MatAmbient[1]);#endif n_dot_VP = DOT3(normal, light->_VP_inf_norm); if (n_dot_VP > 0.0F) { ACC_SCALE_SCALAR_3V(sum[0], n_dot_VP, light->_MatDiffuse[0]); n_dot_h = DOT3(normal, light->_h_inf_norm); if (n_dot_h > 0.0F) { struct gl_shine_tab *tab = ctx->_ShineTable[0]; GET_SHINE_TAB_ENTRY( tab, n_dot_h, spec ); ACC_SCALE_SCALAR_3V( sum[0], spec, light->_MatSpecular[0]); } }#if IDX & LIGHT_TWOSIDE else { ACC_SCALE_SCALAR_3V(sum[1], -n_dot_VP, light->_MatDiffuse[1]); n_dot_h = -DOT3(normal, light->_h_inf_norm); if (n_dot_h > 0.0F) { struct gl_shine_tab *tab = ctx->_ShineTable[1]; GET_SHINE_TAB_ENTRY( tab, n_dot_h, spec ); ACC_SCALE_SCALAR_3V( sum[1], spec, light->_MatSpecular[1]); } }#endif } COPY_3V( Fcolor[j], sum[0] ); Fcolor[j][3] = sumA[0];#if IDX & LIGHT_TWOSIDE COPY_3V( Bcolor[j], sum[1] ); Bcolor[j][3] = sumA[1];#endif }}/* * Use current lighting/material settings to compute the color indexes * for an array of vertices. * Input: n - number of vertices to light * side - 0=use front material, 1=use back material * vertex - array of [n] vertex position in eye coordinates * normal - array of [n] surface normal vector * Output: indexResult - resulting array of [n] color indexes */static void TAG(light_ci)( GLcontext *ctx, struct vertex_buffer *VB, struct tnl_pipeline_stage *stage, GLvector4f *input ){ struct light_stage_data *store = LIGHT_STAGE_DATA(stage); GLuint j; const GLuint vstride = input->stride; const GLfloat *vertex = (GLfloat *) input->data; const GLuint nstride = VB->AttribPtr[_TNL_ATTRIB_NORMAL]->stride; const GLfloat *normal = (GLfloat *)VB->AttribPtr[_TNL_ATTRIB_NORMAL]->data; GLfloat *indexResult[2]; const GLuint nr = VB->Count;#ifdef TRACE fprintf(stderr, "%s\n", __FUNCTION__ );#endif VB->IndexPtr[0] = &store->LitIndex[0];#if IDX & LIGHT_TWOSIDE VB->IndexPtr[1] = &store->LitIndex[1];#endif indexResult[0] = (GLfloat *)VB->IndexPtr[0]->data;#if IDX & LIGHT_TWOSIDE indexResult[1] = (GLfloat *)VB->IndexPtr[1]->data;#endif /* loop over vertices */ for (j=0; j<nr; j++,STRIDE_F(vertex,vstride),STRIDE_F(normal, nstride)) { GLfloat diffuse[2], specular[2]; GLuint side = 0; struct gl_light *light;#if IDX & LIGHT_MATERIAL update_materials( ctx, store );#endif diffuse[0] = specular[0] = 0.0F;#if IDX & LIGHT_TWOSIDE diffuse[1] = specular[1] = 0.0F;#endif /* Accumulate diffuse and specular from each light source */ foreach (light, &ctx->Light.EnabledList) { GLfloat attenuation = 1.0F; GLfloat VP[3]; /* unit vector from vertex to light */ GLfloat n_dot_VP; /* dot product of l and n */ GLfloat *h, n_dot_h, correction = 1.0; /* compute l and attenuation */ if (!(light->_Flags & LIGHT_POSITIONAL)) { /* directional light */ COPY_3V(VP, light->_VP_inf_norm); } else { GLfloat d; /* distance from vertex to light */ SUB_3V(VP, light->_Position, vertex); d = (GLfloat) LEN_3FV( VP ); if ( d > 1e-6) { GLfloat invd = 1.0F / d; SELF_SCALE_SCALAR_3V(VP, invd); } attenuation = 1.0F / (light->ConstantAttenuation + d * (light->LinearAttenuation + d * light->QuadraticAttenuation)); /* spotlight attenuation */ if (light->_Flags & LIGHT_SPOT) { GLfloat PV_dot_dir = - DOT3(VP, light->_NormDirection); if (PV_dot_dir < light->_CosCutoff) { continue; /* this light makes no contribution */ } else { GLdouble x = PV_dot_dir * (EXP_TABLE_SIZE-1); GLint k = (GLint) x; GLfloat spot = (GLfloat) (light->_SpotExpTable[k][0] + (x-k)*light->_SpotExpTable[k][1]); attenuation *= spot; } } } if (attenuation < 1e-3) continue; /* this light makes no contribution */ n_dot_VP = DOT3( normal, VP ); /* which side are we lighting? */ if (n_dot_VP < 0.0F) {#if IDX & LIGHT_TWOSIDE side = 1; correction = -1; n_dot_VP = -n_dot_VP;#else continue;#endif } /* accumulate diffuse term */ diffuse[side] += n_dot_VP * light->_dli * attenuation; /* specular term */ if (ctx->Light.Model.LocalViewer) { GLfloat v[3]; COPY_3V(v, vertex); NORMALIZE_3FV(v); SUB_3V(VP, VP, v); /* h = VP + VPe */ h = VP; NORMALIZE_3FV(h); } else if (light->_Flags & LIGHT_POSITIONAL) { h = VP; /* Strangely, disabling this addition fixes a conformance * problem. If this code is enabled, l_sed.c fails. */ /*ACC_3V(h, ctx->_EyeZDir);*/ NORMALIZE_3FV(h); } else { h = light->_h_inf_norm; } n_dot_h = correction * DOT3(normal, h); if (n_dot_h > 0.0F) { GLfloat spec_coef; struct gl_shine_tab *tab = ctx->_ShineTable[side]; GET_SHINE_TAB_ENTRY( tab, n_dot_h, spec_coef); specular[side] += spec_coef * light->_sli * attenuation; } } /*loop over lights*/ /* Now compute final color index */ for (side = 0 ; side < NR_SIDES ; side++) { const GLfloat *ind = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_INDEXES + side]; GLfloat index; if (specular[side] > 1.0F) { index = ind[MAT_INDEX_SPECULAR]; } else { GLfloat d_a = ind[MAT_INDEX_DIFFUSE] - ind[MAT_INDEX_AMBIENT]; GLfloat s_a = ind[MAT_INDEX_SPECULAR] - ind[MAT_INDEX_AMBIENT]; index = (ind[MAT_INDEX_AMBIENT] + diffuse[side] * (1.0F-specular[side]) * d_a + specular[side] * s_a); if (index > ind[MAT_INDEX_SPECULAR]) { index = ind[MAT_INDEX_SPECULAR]; } } indexResult[side][j] = index; } } /*for vertex*/}static void TAG(init_light_tab)( void ){ _tnl_light_tab[IDX] = TAG(light_rgba); _tnl_light_fast_tab[IDX] = TAG(light_fast_rgba); _tnl_light_fast_single_tab[IDX] = TAG(light_fast_rgba_single); _tnl_light_spec_tab[IDX] = TAG(light_rgba_spec); _tnl_light_ci_tab[IDX] = TAG(light_ci);}#undef TAG#undef IDX#undef NR_SIDES
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -