t_vb_lighttmp.h revision b305028464f02947c0cce0476af0e35f4ed1fafa
1d02174c1f22974a1f0e2334e393f8345c6d11302Zhongxing Xu/* 28958fff8aad09f317a51b2d4cda3d7b126a530a4Zhongxing Xu * Mesa 3-D graphics library 38958fff8aad09f317a51b2d4cda3d7b126a530a4Zhongxing Xu * Version: 5.1 48958fff8aad09f317a51b2d4cda3d7b126a530a4Zhongxing Xu * 58958fff8aad09f317a51b2d4cda3d7b126a530a4Zhongxing Xu * Copyright (C) 1999-2003 Brian Paul All Rights Reserved. 68958fff8aad09f317a51b2d4cda3d7b126a530a4Zhongxing Xu * 78958fff8aad09f317a51b2d4cda3d7b126a530a4Zhongxing Xu * Permission is hereby granted, free of charge, to any person obtaining a 88958fff8aad09f317a51b2d4cda3d7b126a530a4Zhongxing Xu * copy of this software and associated documentation files (the "Software"), 98958fff8aad09f317a51b2d4cda3d7b126a530a4Zhongxing Xu * to deal in the Software without restriction, including without limitation 10d02174c1f22974a1f0e2334e393f8345c6d11302Zhongxing Xu * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11d02174c1f22974a1f0e2334e393f8345c6d11302Zhongxing Xu * and/or sell copies of the Software, and to permit persons to whom the 128958fff8aad09f317a51b2d4cda3d7b126a530a4Zhongxing Xu * Software is furnished to do so, subject to the following conditions: 138958fff8aad09f317a51b2d4cda3d7b126a530a4Zhongxing Xu * 148958fff8aad09f317a51b2d4cda3d7b126a530a4Zhongxing Xu * The above copyright notice and this permission notice shall be included 15d84f422ebfde2145bce79a8fa823e3393b392994Argyrios Kyrtzidis * in all copies or substantial portions of the Software. 1655fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth * 1755fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 1855fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19ec8605f1d7ec846dbf51047bfd5c56d32d1ff91cArgyrios Kyrtzidis * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20d84f422ebfde2145bce79a8fa823e3393b392994Argyrios Kyrtzidis * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 21f540c54701e3eeb34cb619a3a4eb18f1ac70ef2dJordan Rose * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22d84f422ebfde2145bce79a8fa823e3393b392994Argyrios Kyrtzidis * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 238fe83e1df954d72c0f4ffc15d20a5222ec151c21Benjamin Kramer * 24a93d0f280693b8418bc88cf7a8c93325f7fcf4c6Benjamin Kramer * 258958fff8aad09f317a51b2d4cda3d7b126a530a4Zhongxing Xu * Authors: 268958fff8aad09f317a51b2d4cda3d7b126a530a4Zhongxing Xu * Brian Paul 279ef6537a894c33003359b1f9b9676e9178e028b7Ted Kremenek * Keith Whitwell <keith@tungstengraphics.com> 288958fff8aad09f317a51b2d4cda3d7b126a530a4Zhongxing Xu */ 29f493f49fae3ab242ae055ae00b24fa5512655e15Ted Kremenek 30651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 31651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#if (IDX & LIGHT_TWOSIDE) 32651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines# define NR_SIDES 2 33651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#else 34651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines# define NR_SIDES 1 35651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#endif 36651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 37651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 38651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/* define TRACE to trace lighting code */ 39ba5fb5a955c896815c439289fc51c03cf0635129Kovarththanan Rajaratnam/* #define TRACE 1 */ 40fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose 41fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose/* 42fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose * ctx is the current context 43fe6a011a113b3ddcb32f42af152d7476054e7f79Jordan Rose * VB is the vertex buffer 44651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines * stage is the lighting stage-private data 45651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines * input is the vector of eye or object-space vertex coordinates 46651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines */ 47651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstatic void TAG(light_rgba_spec)( GLcontext *ctx, 48651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines struct vertex_buffer *VB, 49651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines struct tnl_pipeline_stage *stage, 50651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines GLvector4f *input ) 51651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines{ 52651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines struct light_stage_data *store = LIGHT_STAGE_DATA(stage); 53651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines GLfloat (*base)[3] = ctx->Light._BaseColor; 54651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines GLfloat sumA[2]; 55651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines GLuint j; 56651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 57f493f49fae3ab242ae055ae00b24fa5512655e15Ted Kremenek const GLuint vstride = input->stride; 58651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const GLfloat *vertex = (GLfloat *)input->data; 59fee96e043108b6e24e7d4c5464bf89ac970a7f81Ted Kremenek const GLuint nstride = VB->NormalPtr->stride; 60d84f422ebfde2145bce79a8fa823e3393b392994Argyrios Kyrtzidis const GLfloat *normal = (GLfloat *)VB->NormalPtr->data; 61fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose 62de507eaf3cb54d3cb234dc14499c10ab3373d15fJordan Rose GLfloat (*Fcolor)[4] = (GLfloat (*)[4]) store->LitColor[0].data; 63fe6a011a113b3ddcb32f42af152d7476054e7f79Jordan Rose GLfloat (*Fspec)[4] = (GLfloat (*)[4]) store->LitSecondary[0].data; 64fee96e043108b6e24e7d4c5464bf89ac970a7f81Ted Kremenek#if IDX & LIGHT_TWOSIDE 65c79d7d49c5ec42e8bb6ac34350ebb5bc24ca663dTed Kremenek GLfloat (*Bcolor)[4] = (GLfloat (*)[4]) store->LitColor[1].data; 66651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines GLfloat (*Bspec)[4] = (GLfloat (*)[4]) store->LitSecondary[1].data; 67651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#endif 68651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 69651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const GLuint nr = VB->Count; 70651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 718133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek (void) nstride; 729da59a67a27a4d3fc9d59552f07808a32f85e9d3Jordan Rose (void) vstride; 73de507eaf3cb54d3cb234dc14499c10ab3373d15fJordan Rose 74d84f422ebfde2145bce79a8fa823e3393b392994Argyrios Kyrtzidis#ifdef TRACE 75091b588f09401f2ec20cabffe57d9e09962970abTed Kremenek fprintf(stderr, "%s\n", __FUNCTION__ ); 7618c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek#endif 778bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek 78de507eaf3cb54d3cb234dc14499c10ab3373d15fJordan Rose VB->ColorPtr[0] = &store->LitColor[0]; 79091b588f09401f2ec20cabffe57d9e09962970abTed Kremenek VB->SecondaryColorPtr[0] = &store->LitSecondary[0]; 80651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines sumA[0] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE][3]; 818133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek 82651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#if IDX & LIGHT_TWOSIDE 83091b588f09401f2ec20cabffe57d9e09962970abTed Kremenek VB->ColorPtr[1] = &store->LitColor[1]; 84651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines VB->SecondaryColorPtr[1] = &store->LitSecondary[1]; 85651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines sumA[1] = ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_DIFFUSE][3]; 86651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#endif 87651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 88f493f49fae3ab242ae055ae00b24fa5512655e15Ted Kremenek /* Side-effects done, can we finish now? 89f493f49fae3ab242ae055ae00b24fa5512655e15Ted Kremenek */ 90f493f49fae3ab242ae055ae00b24fa5512655e15Ted Kremenek if (stage->changed_inputs == 0) 919da59a67a27a4d3fc9d59552f07808a32f85e9d3Jordan Rose return; 929da59a67a27a4d3fc9d59552f07808a32f85e9d3Jordan Rose 93d048c6ef5b6cfaa0cecb8cc1d4bdace32ed21d07Ted Kremenek for (j = 0; j < nr; j++,STRIDE_F(vertex,vstride),STRIDE_F(normal,nstride)) { 94c79d7d49c5ec42e8bb6ac34350ebb5bc24ca663dTed Kremenek GLfloat sum[2][3], spec[2][3]; 95c79d7d49c5ec42e8bb6ac34350ebb5bc24ca663dTed Kremenek struct gl_light *light; 96091b588f09401f2ec20cabffe57d9e09962970abTed Kremenek 97e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks#if IDX & LIGHT_MATERIAL 989da59a67a27a4d3fc9d59552f07808a32f85e9d3Jordan Rose update_materials( ctx, store ); 999da59a67a27a4d3fc9d59552f07808a32f85e9d3Jordan Rose sumA[0] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE][3]; 10044ec3f00e64199667edf9f12c0f31f66916c95feJordan Rose#if IDX & LIGHT_TWOSIDE 10144ec3f00e64199667edf9f12c0f31f66916c95feJordan Rose sumA[1] = ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_DIFFUSE][3]; 102a1f81bb0e55749a1414b1b5124bb83b9052ff2acJordan Rose#endif 1039da59a67a27a4d3fc9d59552f07808a32f85e9d3Jordan Rose#endif 104785950e59424dca7ce0081bebf13c0acd2c4fff6Jordan Rose 105c79d7d49c5ec42e8bb6ac34350ebb5bc24ca663dTed Kremenek COPY_3V(sum[0], base[0]); 106c79d7d49c5ec42e8bb6ac34350ebb5bc24ca663dTed Kremenek ZERO_3V(spec[0]); 107da88536ed2c2755873a0db72656e443b95068d45Benjamin Kramer 108da88536ed2c2755873a0db72656e443b95068d45Benjamin Kramer#if IDX & LIGHT_TWOSIDE 1098919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose COPY_3V(sum[1], base[1]); 1108919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose ZERO_3V(spec[1]); 1118919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose#endif 1128919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose 1138919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose /* Add contribution from each enabled light source */ 1148919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose foreach (light, &ctx->Light.EnabledList) { 1158919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose GLfloat n_dot_h; 1168919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose GLfloat correction; 1178919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose GLint side; 1188919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose GLfloat contrib[3]; 1198919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose GLfloat attenuation; 1208919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose GLfloat VP[3]; /* unit vector from vertex to light */ 1218919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose GLfloat n_dot_VP; /* n dot VP */ 1228919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose GLfloat *h; 1238919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose 1248919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose /* compute VP and attenuation */ 1258919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose if (!(light->_Flags & LIGHT_POSITIONAL)) { 1268919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose /* directional light */ 1278919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose COPY_3V(VP, light->_VP_inf_norm); 1288919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose attenuation = light->_VP_inf_spot_attenuation; 1298919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose } 1308919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose else { 1318919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose GLfloat d; /* distance from vertex to light */ 132651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 133651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines SUB_3V(VP, light->_Position, vertex); 134651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 135651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines d = (GLfloat) LEN_3FV( VP ); 136651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 137651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (d > 1e-6) { 138651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines GLfloat invd = 1.0F / d; 139651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines SELF_SCALE_SCALAR_3V(VP, invd); 140651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 141651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 142651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines attenuation = 1.0F / (light->ConstantAttenuation + d * 143651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines (light->LinearAttenuation + d * 144651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines light->QuadraticAttenuation)); 145651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 146651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /* spotlight attenuation */ 147651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (light->_Flags & LIGHT_SPOT) { 148651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines GLfloat PV_dot_dir = - DOT3(VP, light->_NormDirection); 149651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 150651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (PV_dot_dir<light->_CosCutoff) { 151651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines continue; /* this light makes no contribution */ 152651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 153651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines else { 154651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines GLdouble x = PV_dot_dir * (EXP_TABLE_SIZE-1); 155651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines GLint k = (GLint) x; 156651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines GLfloat spot = (GLfloat) (light->_SpotExpTable[k][0] 157651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines + (x-k)*light->_SpotExpTable[k][1]); 158651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines attenuation *= spot; 159651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 160651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 161651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 162651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 163651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (attenuation < 1e-3) 164651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines continue; /* this light makes no contribution */ 165651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 166651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /* Compute dot product or normal and vector from V to light pos */ 167651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines n_dot_VP = DOT3( normal, VP ); 168651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 169651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /* Which side gets the diffuse & specular terms? */ 170651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (n_dot_VP < 0.0F) { 171651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ACC_SCALE_SCALAR_3V(sum[0], attenuation, light->_MatAmbient[0]); 172651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#if IDX & LIGHT_TWOSIDE 173651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines side = 1; 174651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines correction = -1; 175651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines n_dot_VP = -n_dot_VP; 176651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#else 177651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines continue; 178651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#endif 179651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 1808133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek else { 181651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#if IDX & LIGHT_TWOSIDE 182651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ACC_SCALE_SCALAR_3V( sum[1], attenuation, light->_MatAmbient[1]); 183651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#endif 1848919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose side = 0; 185651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines correction = 1; 1868919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose } 187651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 188651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /* diffuse term */ 189651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines COPY_3V(contrib, light->_MatAmbient[side]); 190651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ACC_SCALE_SCALAR_3V(contrib, n_dot_VP, light->_MatDiffuse[side]); 191651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ACC_SCALE_SCALAR_3V(sum[side], attenuation, contrib ); 192651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 193651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /* specular term - cannibalize VP... */ 194651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (ctx->Light.Model.LocalViewer) { 1958133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek GLfloat v[3]; 196d048c6ef5b6cfaa0cecb8cc1d4bdace32ed21d07Ted Kremenek COPY_3V(v, vertex); 197651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines NORMALIZE_3FV(v); 1988133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek SUB_3V(VP, VP, v); /* h = VP + VPe */ 1998133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek h = VP; 200651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines NORMALIZE_3FV(h); 201651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 2028919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose else if (light->_Flags & LIGHT_POSITIONAL) { 203651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines h = VP; 204651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ACC_3V(h, ctx->_EyeZDir); 205651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines NORMALIZE_3FV(h); 206785950e59424dca7ce0081bebf13c0acd2c4fff6Jordan Rose } 2078133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek else { 2088133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek h = light->_h_inf_norm; 2098133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek } 2108133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek 211651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines n_dot_h = correction * DOT3(normal, h); 212e4d653b5a4cba281502177f6ef03d43e3ebb2b6aTed Kremenek 2135251abea41b446c26e3239c8dd6c7edea6fc335dDavid Blaikie if (n_dot_h > 0.0F) { 214dc84cd5efdd3430efb22546b4ac656aa0540b210David Blaikie GLfloat spec_coef; 2155251abea41b446c26e3239c8dd6c7edea6fc335dDavid Blaikie struct gl_shine_tab *tab = ctx->_ShineTable[side]; 2168133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek GET_SHINE_TAB_ENTRY( tab, n_dot_h, spec_coef ); 2178133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek 2188133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek if (spec_coef > 1.0e-10) { 2195f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner spec_coef *= attenuation; 2208133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek ACC_SCALE_SCALAR_3V( spec[side], spec_coef, 2218133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek light->_MatSpecular[side]); 2228133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek } 2238133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek } 2248133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek } /*loop over lights*/ 225facde171ae4b8926622a1bffa833732a06f1875bBenjamin Kramer 2268133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek COPY_3V( Fcolor[j], sum[0] ); 227facde171ae4b8926622a1bffa833732a06f1875bBenjamin Kramer COPY_3V( Fspec[j], spec[0] ); 2288133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek Fcolor[j][3] = sumA[0]; 2299697934650354bed2e509d8e7e44f21a1fb00f76Ted Kremenek 230018220c343c103b7dfaa117a7a474c7a7fd6d068Zhongxing Xu#if IDX & LIGHT_TWOSIDE 2318133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek COPY_3V( Bcolor[j], sum[1] ); 2328133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek COPY_3V( Bspec[j], spec[1] ); 2338133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek Bcolor[j][3] = sumA[1]; 234651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#endif 235651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 236651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 237262bc18e32500558af7cb0afa205b34bd37bafedDavid Blaikie 2388133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek 2398133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenekstatic void TAG(light_rgba)( GLcontext *ctx, 2408133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek struct vertex_buffer *VB, 2418133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek struct tnl_pipeline_stage *stage, 2428133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek GLvector4f *input ) 2431437425a62dbf7bdb0a855d3ed3b05ed2019ec1eAnna Zaks{ 2448133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek struct light_stage_data *store = LIGHT_STAGE_DATA(stage); 2458133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek GLuint j; 2468133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek 2478133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek GLfloat (*base)[3] = ctx->Light._BaseColor; 2488133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek GLfloat sumA[2]; 2498133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek 2508133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek const GLuint vstride = input->stride; 2518133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek const GLfloat *vertex = (GLfloat *) input->data; 2528133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek const GLuint nstride = VB->NormalPtr->stride; 2538133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek const GLfloat *normal = (GLfloat *)VB->NormalPtr->data; 2548133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek 2558133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek GLfloat (*Fcolor)[4] = (GLfloat (*)[4]) store->LitColor[0].data; 256facde171ae4b8926622a1bffa833732a06f1875bBenjamin Kramer GLfloat (*Bcolor)[4] = (GLfloat (*)[4]) store->LitColor[1].data; 257c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek GLfloat (*color[2])[4]; 2588133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek 2598133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek const GLuint nr = VB->Count; 2608133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek 261d048c6ef5b6cfaa0cecb8cc1d4bdace32ed21d07Ted Kremenek#ifdef TRACE 262651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines fprintf(stderr, "%s\n", __FUNCTION__ ); 263f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith#endif 2648133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek 2658133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek (void) nstride; 2668133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek (void) vstride; 2678133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek 268b8989f27f116ff2400e92a52c067a69846119eb5Benjamin Kramer color[0] = Fcolor; 2698133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek color[1] = Bcolor; 2708133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek 2718133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek VB->ColorPtr[0] = &store->LitColor[0]; 2725f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner sumA[0] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE][3]; 2738133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek 2748133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek#if IDX & LIGHT_TWOSIDE 2758133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek VB->ColorPtr[1] = &store->LitColor[1]; 2768133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek sumA[1] = ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_DIFFUSE][3]; 2778133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek#endif 278b8989f27f116ff2400e92a52c067a69846119eb5Benjamin Kramer 2798133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek if (stage->changed_inputs == 0) 2808133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek return; 2818133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek 2828133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek for (j = 0; j < nr; j++,STRIDE_F(vertex,vstride),STRIDE_F(normal,nstride)) { 2838133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek GLfloat sum[2][3]; 284e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks struct gl_light *light; 285651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 2868133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek if ( IDX & LIGHT_MATERIAL ) { 2878133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek update_materials( ctx, store ); 2888133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek sumA[0] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE][3]; 289785950e59424dca7ce0081bebf13c0acd2c4fff6Jordan Rose#if IDX & LIGHT_TWOSIDE 2908133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek sumA[1] = ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_DIFFUSE][3]; 2918133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek#endif 2928133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek } 2938133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek 2948133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek COPY_3V(sum[0], base[0]); 2958133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek 2968133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek if ( IDX & LIGHT_TWOSIDE ) 2978133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek COPY_3V(sum[1], base[1]); 298d84f422ebfde2145bce79a8fa823e3393b392994Argyrios Kyrtzidis 299d84f422ebfde2145bce79a8fa823e3393b392994Argyrios Kyrtzidis /* Add contribution from each enabled light source */ 300091b588f09401f2ec20cabffe57d9e09962970abTed Kremenek foreach (light, &ctx->Light.EnabledList) { 301c79d7d49c5ec42e8bb6ac34350ebb5bc24ca663dTed Kremenek 30255037cdc2e29b70df2fd1ca0ba9d4c36da1049e8Jordan Rose GLfloat n_dot_h; 3035eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek GLfloat correction; 30455037cdc2e29b70df2fd1ca0ba9d4c36da1049e8Jordan Rose GLint side; 305091b588f09401f2ec20cabffe57d9e09962970abTed Kremenek GLfloat contrib[3]; 306c79d7d49c5ec42e8bb6ac34350ebb5bc24ca663dTed Kremenek GLfloat attenuation = 1.0; 307c79d7d49c5ec42e8bb6ac34350ebb5bc24ca663dTed Kremenek GLfloat VP[3]; /* unit vector from vertex to light */ 308651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines GLfloat n_dot_VP; /* n dot VP */ 309651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines GLfloat *h; 3109da59a67a27a4d3fc9d59552f07808a32f85e9d3Jordan Rose 311c79d7d49c5ec42e8bb6ac34350ebb5bc24ca663dTed Kremenek /* compute VP and attenuation */ 312c79d7d49c5ec42e8bb6ac34350ebb5bc24ca663dTed Kremenek if (!(light->_Flags & LIGHT_POSITIONAL)) { 313091b588f09401f2ec20cabffe57d9e09962970abTed Kremenek /* directional light */ 314a8695180217806bb421cfc6700bec76fc0b1ae56Jordan Rose COPY_3V(VP, light->_VP_inf_norm); 315651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines attenuation = light->_VP_inf_spot_attenuation; 316a8695180217806bb421cfc6700bec76fc0b1ae56Jordan Rose } 317a8695180217806bb421cfc6700bec76fc0b1ae56Jordan Rose else { 318c79d7d49c5ec42e8bb6ac34350ebb5bc24ca663dTed Kremenek GLfloat d; /* distance from vertex to light */ 319651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 320651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 3219da59a67a27a4d3fc9d59552f07808a32f85e9d3Jordan Rose SUB_3V(VP, light->_Position, vertex); 3227453624b98817f06d28ed2abe39c98805cfec623Jordan Rose 323091b588f09401f2ec20cabffe57d9e09962970abTed Kremenek d = (GLfloat) LEN_3FV( VP ); 3247f660857309a14c036a80ef90b40bf8f68fda9daJordan Rose 3257f660857309a14c036a80ef90b40bf8f68fda9daJordan Rose if ( d > 1e-6) { 326fe6a011a113b3ddcb32f42af152d7476054e7f79Jordan Rose GLfloat invd = 1.0F / d; 327091b588f09401f2ec20cabffe57d9e09962970abTed Kremenek SELF_SCALE_SCALAR_3V(VP, invd); 328fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose } 329fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose 330fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose attenuation = 1.0F / (light->ConstantAttenuation + d * 331fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose (light->LinearAttenuation + d * 332fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose light->QuadraticAttenuation)); 333fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose 334fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose /* spotlight attenuation */ 335fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose if (light->_Flags & LIGHT_SPOT) { 336fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose GLfloat PV_dot_dir = - DOT3(VP, light->_NormDirection); 337fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose 338651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (PV_dot_dir<light->_CosCutoff) { 339651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines continue; /* this light makes no contribution */ 340fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose } 341fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose else { 342fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose GLdouble x = PV_dot_dir * (EXP_TABLE_SIZE-1); 343fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose GLint k = (GLint) x; 344fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose GLfloat spot = (GLfloat) (light->_SpotExpTable[k][0] 345fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose + (x-k)*light->_SpotExpTable[k][1]); 346fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose attenuation *= spot; 347fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose } 348fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose } 349fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose } 350fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose 351fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose if (attenuation < 1e-3) 352fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose continue; /* this light makes no contribution */ 353fe6a011a113b3ddcb32f42af152d7476054e7f79Jordan Rose 354fe6a011a113b3ddcb32f42af152d7476054e7f79Jordan Rose /* Compute dot product or normal and vector from V to light pos */ 3557f660857309a14c036a80ef90b40bf8f68fda9daJordan Rose n_dot_VP = DOT3( normal, VP ); 3567f660857309a14c036a80ef90b40bf8f68fda9daJordan Rose 357fc999ac663eca933359047c88dc4a1ef6e579e8aTed Kremenek /* which side are we lighting? */ 358fc999ac663eca933359047c88dc4a1ef6e579e8aTed Kremenek if (n_dot_VP < 0.0F) { 3599da59a67a27a4d3fc9d59552f07808a32f85e9d3Jordan Rose ACC_SCALE_SCALAR_3V(sum[0], attenuation, light->_MatAmbient[0]); 360fc999ac663eca933359047c88dc4a1ef6e579e8aTed Kremenek#if IDX & LIGHT_TWOSIDE 361fc999ac663eca933359047c88dc4a1ef6e579e8aTed Kremenek side = 1; 362fc999ac663eca933359047c88dc4a1ef6e579e8aTed Kremenek correction = -1; 363651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines n_dot_VP = -n_dot_VP; 364651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#else 3659da59a67a27a4d3fc9d59552f07808a32f85e9d3Jordan Rose continue; 366fc999ac663eca933359047c88dc4a1ef6e579e8aTed Kremenek#endif 367fc999ac663eca933359047c88dc4a1ef6e579e8aTed Kremenek } 368a8695180217806bb421cfc6700bec76fc0b1ae56Jordan Rose else { 369a8695180217806bb421cfc6700bec76fc0b1ae56Jordan Rose#if IDX & LIGHT_TWOSIDE 370651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ACC_SCALE_SCALAR_3V( sum[1], attenuation, light->_MatAmbient[1]); 3715251abea41b446c26e3239c8dd6c7edea6fc335dDavid Blaikie#endif 372a8695180217806bb421cfc6700bec76fc0b1ae56Jordan Rose side = 0; 373a8695180217806bb421cfc6700bec76fc0b1ae56Jordan Rose correction = 1; 374fc999ac663eca933359047c88dc4a1ef6e579e8aTed Kremenek } 375651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 376651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines COPY_3V(contrib, light->_MatAmbient[side]); 3779da59a67a27a4d3fc9d59552f07808a32f85e9d3Jordan Rose 378fc999ac663eca933359047c88dc4a1ef6e579e8aTed Kremenek /* diffuse term */ 379fc999ac663eca933359047c88dc4a1ef6e579e8aTed Kremenek ACC_SCALE_SCALAR_3V(contrib, n_dot_VP, light->_MatDiffuse[side]); 3807f660857309a14c036a80ef90b40bf8f68fda9daJordan Rose 3817f660857309a14c036a80ef90b40bf8f68fda9daJordan Rose /* specular term - cannibalize VP... */ 382fc999ac663eca933359047c88dc4a1ef6e579e8aTed Kremenek { 383fc999ac663eca933359047c88dc4a1ef6e579e8aTed Kremenek if (ctx->Light.Model.LocalViewer) { 38437926da411d5a0047240b3ffd4dad0c4838aac57Pavel Labath GLfloat v[3]; 385651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines COPY_3V(v, vertex); 386651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines NORMALIZE_3FV(v); 38737926da411d5a0047240b3ffd4dad0c4838aac57Pavel Labath SUB_3V(VP, VP, v); /* h = VP + VPe */ 38837926da411d5a0047240b3ffd4dad0c4838aac57Pavel Labath h = VP; 38937926da411d5a0047240b3ffd4dad0c4838aac57Pavel Labath NORMALIZE_3FV(h); 39037926da411d5a0047240b3ffd4dad0c4838aac57Pavel Labath } 39137926da411d5a0047240b3ffd4dad0c4838aac57Pavel Labath else if (light->_Flags & LIGHT_POSITIONAL) { 39237926da411d5a0047240b3ffd4dad0c4838aac57Pavel Labath h = VP; 39337926da411d5a0047240b3ffd4dad0c4838aac57Pavel Labath ACC_3V(h, ctx->_EyeZDir); 39437926da411d5a0047240b3ffd4dad0c4838aac57Pavel Labath NORMALIZE_3FV(h); 39537926da411d5a0047240b3ffd4dad0c4838aac57Pavel Labath } 39637926da411d5a0047240b3ffd4dad0c4838aac57Pavel Labath else { 39737926da411d5a0047240b3ffd4dad0c4838aac57Pavel Labath h = light->_h_inf_norm; 39837926da411d5a0047240b3ffd4dad0c4838aac57Pavel Labath } 39937926da411d5a0047240b3ffd4dad0c4838aac57Pavel Labath 40037926da411d5a0047240b3ffd4dad0c4838aac57Pavel Labath n_dot_h = correction * DOT3(normal, h); 40137926da411d5a0047240b3ffd4dad0c4838aac57Pavel Labath 40237926da411d5a0047240b3ffd4dad0c4838aac57Pavel Labath if (n_dot_h > 0.0F) 40337926da411d5a0047240b3ffd4dad0c4838aac57Pavel Labath { 40437926da411d5a0047240b3ffd4dad0c4838aac57Pavel Labath GLfloat spec_coef; 40537926da411d5a0047240b3ffd4dad0c4838aac57Pavel Labath struct gl_shine_tab *tab = ctx->_ShineTable[side]; 40637926da411d5a0047240b3ffd4dad0c4838aac57Pavel Labath 40737926da411d5a0047240b3ffd4dad0c4838aac57Pavel Labath GET_SHINE_TAB_ENTRY( tab, n_dot_h, spec_coef ); 408fe6a011a113b3ddcb32f42af152d7476054e7f79Jordan Rose 409fe6a011a113b3ddcb32f42af152d7476054e7f79Jordan Rose ACC_SCALE_SCALAR_3V( contrib, spec_coef, 410fe6a011a113b3ddcb32f42af152d7476054e7f79Jordan Rose light->_MatSpecular[side]); 411fe6a011a113b3ddcb32f42af152d7476054e7f79Jordan Rose } 412fe6a011a113b3ddcb32f42af152d7476054e7f79Jordan Rose } 413fc999ac663eca933359047c88dc4a1ef6e579e8aTed Kremenek 414fe6a011a113b3ddcb32f42af152d7476054e7f79Jordan Rose ACC_SCALE_SCALAR_3V( sum[side], attenuation, contrib ); 415651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 4168919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose 417fe6a011a113b3ddcb32f42af152d7476054e7f79Jordan Rose COPY_3V( Fcolor[j], sum[0] ); 4188919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose Fcolor[j][3] = sumA[0]; 419fe6a011a113b3ddcb32f42af152d7476054e7f79Jordan Rose 420fe6a011a113b3ddcb32f42af152d7476054e7f79Jordan Rose#if IDX & LIGHT_TWOSIDE 421651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines COPY_3V( Bcolor[j], sum[1] ); 4226bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Bcolor[j][3] = sumA[1]; 423651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#endif 424651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 4258919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose} 4268919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose 427651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 428fe6a011a113b3ddcb32f42af152d7476054e7f79Jordan Rose 429651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 4307f660857309a14c036a80ef90b40bf8f68fda9daJordan Rose/* As below, but with just a single light. 4317f660857309a14c036a80ef90b40bf8f68fda9daJordan Rose */ 4327f660857309a14c036a80ef90b40bf8f68fda9daJordan Rosestatic void TAG(light_fast_rgba_single)( GLcontext *ctx, 43364fa85855638d69e56ed1b2fad7ed65deb3ecdfdTed Kremenek struct vertex_buffer *VB, 43464fa85855638d69e56ed1b2fad7ed65deb3ecdfdTed Kremenek struct tnl_pipeline_stage *stage, 435de507eaf3cb54d3cb234dc14499c10ab3373d15fJordan Rose GLvector4f *input ) 436d84f422ebfde2145bce79a8fa823e3393b392994Argyrios Kyrtzidis 437de507eaf3cb54d3cb234dc14499c10ab3373d15fJordan Rose{ 438de507eaf3cb54d3cb234dc14499c10ab3373d15fJordan Rose struct light_stage_data *store = LIGHT_STAGE_DATA(stage); 439de507eaf3cb54d3cb234dc14499c10ab3373d15fJordan Rose const GLuint nstride = VB->NormalPtr->stride; 4406bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const GLfloat *normal = (GLfloat *)VB->NormalPtr->data; 4418919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose GLfloat (*Fcolor)[4] = (GLfloat (*)[4]) store->LitColor[0].data; 4428919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose#if IDX & LIGHT_TWOSIDE 443de507eaf3cb54d3cb234dc14499c10ab3373d15fJordan Rose GLfloat (*Bcolor)[4] = (GLfloat (*)[4]) store->LitColor[1].data; 444651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#endif 445651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const struct gl_light *light = ctx->Light.EnabledList.next; 446de507eaf3cb54d3cb234dc14499c10ab3373d15fJordan Rose GLuint j = 0; 447de507eaf3cb54d3cb234dc14499c10ab3373d15fJordan Rose GLfloat base[2][3]; 4488919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose const GLuint nr = VB->Count; 4498919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose 4508919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose#ifdef TRACE 451651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines fprintf(stderr, "%s\n", __FUNCTION__ ); 452651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#endif 4538919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose 4548919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose (void) input; /* doesn't refer to Eye or Obj */ 4558919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose (void) nr; 4568919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose (void) nstride; 457651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 458651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines VB->ColorPtr[0] = &store->LitColor[0]; 4598919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose#if IDX & LIGHT_TWOSIDE 4608919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose VB->ColorPtr[1] = &store->LitColor[1]; 461de507eaf3cb54d3cb234dc14499c10ab3373d15fJordan Rose#endif 4628919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose 4638919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose if (stage->changed_inputs == 0) 464de507eaf3cb54d3cb234dc14499c10ab3373d15fJordan Rose return; 4658919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose 4668919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose for (j = 0; j < nr; j++, STRIDE_F(normal,nstride)) { 46764fa85855638d69e56ed1b2fad7ed65deb3ecdfdTed Kremenek 468de507eaf3cb54d3cb234dc14499c10ab3373d15fJordan Rose GLfloat n_dot_VP; 4698919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose 470a1f81bb0e55749a1414b1b5124bb83b9052ff2acJordan Rose if ( IDX & LIGHT_MATERIAL ) 471785950e59424dca7ce0081bebf13c0acd2c4fff6Jordan Rose update_materials( ctx, store ); 472de507eaf3cb54d3cb234dc14499c10ab3373d15fJordan Rose 473de507eaf3cb54d3cb234dc14499c10ab3373d15fJordan Rose /* No attenuation, so incoporate _MatAmbient into base color. 474de507eaf3cb54d3cb234dc14499c10ab3373d15fJordan Rose */ 475de507eaf3cb54d3cb234dc14499c10ab3373d15fJordan Rose if ( j == 0 || (IDX & LIGHT_MATERIAL) ) { 4765251abea41b446c26e3239c8dd6c7edea6fc335dDavid Blaikie COPY_3V(base[0], light->_MatAmbient[0]); 477de507eaf3cb54d3cb234dc14499c10ab3373d15fJordan Rose ACC_3V(base[0], ctx->Light._BaseColor[0] ); 478de507eaf3cb54d3cb234dc14499c10ab3373d15fJordan Rose base[0][3] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE][3]; 479de507eaf3cb54d3cb234dc14499c10ab3373d15fJordan Rose 480651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#if IDX & LIGHT_TWOSIDE 481de507eaf3cb54d3cb234dc14499c10ab3373d15fJordan Rose COPY_3V(base[1], light->_MatAmbient[1]); 482de507eaf3cb54d3cb234dc14499c10ab3373d15fJordan Rose ACC_3V(base[1], ctx->Light._BaseColor[1]); 483de507eaf3cb54d3cb234dc14499c10ab3373d15fJordan Rose base[1][3] = ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_DIFFUSE][3]; 484de507eaf3cb54d3cb234dc14499c10ab3373d15fJordan Rose#endif 485c79d7d49c5ec42e8bb6ac34350ebb5bc24ca663dTed Kremenek } 486c79d7d49c5ec42e8bb6ac34350ebb5bc24ca663dTed Kremenek 487d84f422ebfde2145bce79a8fa823e3393b392994Argyrios Kyrtzidis n_dot_VP = DOT3(normal, light->_VP_inf_norm); 488a46e4d91d8f3eb341f2387768db66dcfe8dd0afaZhongxing Xu 4892055effed54d614b51e3501a174c9b1fe92e4de4Zhongxing Xu if (n_dot_VP < 0.0F) { 490c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek#if IDX & LIGHT_TWOSIDE 491de507eaf3cb54d3cb234dc14499c10ab3373d15fJordan Rose GLfloat n_dot_h = -DOT3(normal, light->_h_inf_norm); 492d84f422ebfde2145bce79a8fa823e3393b392994Argyrios Kyrtzidis GLfloat sum[3]; 493091b588f09401f2ec20cabffe57d9e09962970abTed Kremenek COPY_3V(sum, base[1]); 494fee96e043108b6e24e7d4c5464bf89ac970a7f81Ted Kremenek ACC_SCALE_SCALAR_3V(sum, -n_dot_VP, light->_MatDiffuse[1]); 495d84f422ebfde2145bce79a8fa823e3393b392994Argyrios Kyrtzidis if (n_dot_h > 0.0F) { 496651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines GLfloat spec; 497091b588f09401f2ec20cabffe57d9e09962970abTed Kremenek GET_SHINE_TAB_ENTRY( ctx->_ShineTable[1], n_dot_h, spec ); 4988919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose ACC_SCALE_SCALAR_3V(sum, spec, light->_MatSpecular[1]); 4998919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose } 500841f16846e17f625874ecfe9c6dba822d29a2b95Anna Zaks COPY_3V(Bcolor[j], sum ); 501841f16846e17f625874ecfe9c6dba822d29a2b95Anna Zaks Bcolor[j][3] = base[1][3]; 502f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith#endif 503fee96e043108b6e24e7d4c5464bf89ac970a7f81Ted Kremenek COPY_4FV(Fcolor[j], base[0]); 504651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 505651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines else { 506651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines GLfloat n_dot_h = DOT3(normal, light->_h_inf_norm); 507841f16846e17f625874ecfe9c6dba822d29a2b95Anna Zaks GLfloat sum[3]; 508841f16846e17f625874ecfe9c6dba822d29a2b95Anna Zaks COPY_3V(sum, base[0]); 509841f16846e17f625874ecfe9c6dba822d29a2b95Anna Zaks ACC_SCALE_SCALAR_3V(sum, n_dot_VP, light->_MatDiffuse[0]); 510841f16846e17f625874ecfe9c6dba822d29a2b95Anna Zaks if (n_dot_h > 0.0F) { 511841f16846e17f625874ecfe9c6dba822d29a2b95Anna Zaks GLfloat spec; 512841f16846e17f625874ecfe9c6dba822d29a2b95Anna Zaks GET_SHINE_TAB_ENTRY( ctx->_ShineTable[0], n_dot_h, spec ); 513841f16846e17f625874ecfe9c6dba822d29a2b95Anna Zaks ACC_SCALE_SCALAR_3V(sum, spec, light->_MatSpecular[0]); 514091b588f09401f2ec20cabffe57d9e09962970abTed Kremenek 515e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks } 5168919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose COPY_3V(Fcolor[j], sum ); 517de507eaf3cb54d3cb234dc14499c10ab3373d15fJordan Rose Fcolor[j][3] = base[0][3]; 5188919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose#if IDX & LIGHT_TWOSIDE 519a1f81bb0e55749a1414b1b5124bb83b9052ff2acJordan Rose COPY_4FV(Bcolor[j], base[1]); 52004badcf84c8d504d8491c7c7e29b58f52cb16640Douglas Gregor#endif 521785950e59424dca7ce0081bebf13c0acd2c4fff6Jordan Rose } 522fee96e043108b6e24e7d4c5464bf89ac970a7f81Ted Kremenek } 523fee96e043108b6e24e7d4c5464bf89ac970a7f81Ted Kremenek} 524c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek 5258f1e65617844d315dd19b6cf9bfc437fd4902ed8Bob Wilson 52657b1da1588a3f5785ad8bd5d9f2d795d685e1058Cameron Esfahani/* Light infinite lights 527f81330c741e0f70b227f113d2e5a84948d1a5752Ted Kremenek */ 528f81330c741e0f70b227f113d2e5a84948d1a5752Ted Kremenekstatic void TAG(light_fast_rgba)( GLcontext *ctx, 529fee96e043108b6e24e7d4c5464bf89ac970a7f81Ted Kremenek struct vertex_buffer *VB, 5308bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek struct tnl_pipeline_stage *stage, 531de507eaf3cb54d3cb234dc14499c10ab3373d15fJordan Rose GLvector4f *input ) 532432424d67641d609e4990d791baa782fc161027eArgyrios Kyrtzidis{ 533651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines struct light_stage_data *store = LIGHT_STAGE_DATA(stage); 534091b588f09401f2ec20cabffe57d9e09962970abTed Kremenek GLfloat sumA[2]; 535fee96e043108b6e24e7d4c5464bf89ac970a7f81Ted Kremenek const GLuint nstride = VB->NormalPtr->stride; 536fee96e043108b6e24e7d4c5464bf89ac970a7f81Ted Kremenek const GLfloat *normal = (GLfloat *)VB->NormalPtr->data; 537de507eaf3cb54d3cb234dc14499c10ab3373d15fJordan Rose GLfloat (*Fcolor)[4] = (GLfloat (*)[4]) store->LitColor[0].data; 538f81330c741e0f70b227f113d2e5a84948d1a5752Ted Kremenek#if IDX & LIGHT_TWOSIDE 5395eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek GLfloat (*Bcolor)[4] = (GLfloat (*)[4]) store->LitColor[1].data; 540fee96e043108b6e24e7d4c5464bf89ac970a7f81Ted Kremenek#endif 541fb87b89fc9eb103e19fb8e4b925c23f0bd091b99Douglas Gregor GLuint j = 0; 5424a037c70fdaefafb9c635fedb7035ad462a2742cTed Kremenek const GLuint nr = VB->Count; 543de507eaf3cb54d3cb234dc14499c10ab3373d15fJordan Rose const struct gl_light *light; 5444a49df3be929d442535d6721ab8a2bbc8a7cd528Anna Zaks 545fee96e043108b6e24e7d4c5464bf89ac970a7f81Ted Kremenek#ifdef TRACE 546fee96e043108b6e24e7d4c5464bf89ac970a7f81Ted Kremenek fprintf(stderr, "%s %d\n", __FUNCTION__, nr ); 547fee96e043108b6e24e7d4c5464bf89ac970a7f81Ted Kremenek#endif 5484a037c70fdaefafb9c635fedb7035ad462a2742cTed Kremenek 549a2a860306e3697fcf7a12c5ba59551ca60578968Anna Zaks (void) input; 550de507eaf3cb54d3cb234dc14499c10ab3373d15fJordan Rose (void) nr; 551fee96e043108b6e24e7d4c5464bf89ac970a7f81Ted Kremenek (void) nstride; 552091b588f09401f2ec20cabffe57d9e09962970abTed Kremenek 553f81330c741e0f70b227f113d2e5a84948d1a5752Ted Kremenek sumA[0] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE][3]; 554fee96e043108b6e24e7d4c5464bf89ac970a7f81Ted Kremenek sumA[1] = ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_DIFFUSE][3]; 555841f16846e17f625874ecfe9c6dba822d29a2b95Anna Zaks 556841f16846e17f625874ecfe9c6dba822d29a2b95Anna Zaks VB->ColorPtr[0] = &store->LitColor[0]; 557841f16846e17f625874ecfe9c6dba822d29a2b95Anna Zaks#if IDX & LIGHT_TWOSIDE 558841f16846e17f625874ecfe9c6dba822d29a2b95Anna Zaks VB->ColorPtr[1] = &store->LitColor[1]; 559841f16846e17f625874ecfe9c6dba822d29a2b95Anna Zaks#endif 560841f16846e17f625874ecfe9c6dba822d29a2b95Anna Zaks 561841f16846e17f625874ecfe9c6dba822d29a2b95Anna Zaks if (stage->changed_inputs == 0) 562841f16846e17f625874ecfe9c6dba822d29a2b95Anna Zaks return; 5636bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 564de507eaf3cb54d3cb234dc14499c10ab3373d15fJordan Rose for (j = 0; j < nr; j++, STRIDE_F(normal,nstride)) { 565fee96e043108b6e24e7d4c5464bf89ac970a7f81Ted Kremenek 566fee96e043108b6e24e7d4c5464bf89ac970a7f81Ted Kremenek GLfloat sum[2][3]; 567fee96e043108b6e24e7d4c5464bf89ac970a7f81Ted Kremenek 568fee96e043108b6e24e7d4c5464bf89ac970a7f81Ted Kremenek if ( IDX & LIGHT_MATERIAL ) { 569fee96e043108b6e24e7d4c5464bf89ac970a7f81Ted Kremenek update_materials( ctx, store ); 570fee96e043108b6e24e7d4c5464bf89ac970a7f81Ted Kremenek 571fee96e043108b6e24e7d4c5464bf89ac970a7f81Ted Kremenek sumA[0] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE][3]; 572fee96e043108b6e24e7d4c5464bf89ac970a7f81Ted Kremenek#if IDX & LIGHT_TWOSIDE 573fee96e043108b6e24e7d4c5464bf89ac970a7f81Ted Kremenek sumA[1] = ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_DIFFUSE][3]; 574fee96e043108b6e24e7d4c5464bf89ac970a7f81Ted Kremenek#endif 575fee96e043108b6e24e7d4c5464bf89ac970a7f81Ted Kremenek } 576fee96e043108b6e24e7d4c5464bf89ac970a7f81Ted Kremenek 577fee96e043108b6e24e7d4c5464bf89ac970a7f81Ted Kremenek 578fee96e043108b6e24e7d4c5464bf89ac970a7f81Ted Kremenek COPY_3V(sum[0], ctx->Light._BaseColor[0]); 579fee96e043108b6e24e7d4c5464bf89ac970a7f81Ted Kremenek#if IDX & LIGHT_TWOSIDE 580fee96e043108b6e24e7d4c5464bf89ac970a7f81Ted Kremenek COPY_3V(sum[1], ctx->Light._BaseColor[1]); 581de507eaf3cb54d3cb234dc14499c10ab3373d15fJordan Rose#endif 5824a49df3be929d442535d6721ab8a2bbc8a7cd528Anna Zaks 583fee96e043108b6e24e7d4c5464bf89ac970a7f81Ted Kremenek foreach (light, &ctx->Light.EnabledList) { 584fee96e043108b6e24e7d4c5464bf89ac970a7f81Ted Kremenek GLfloat n_dot_h, n_dot_VP, spec; 585091b588f09401f2ec20cabffe57d9e09962970abTed Kremenek 5860bd6b110e908892d4b5c8671a9f435a1d72ad16aAnna Zaks ACC_3V(sum[0], light->_MatAmbient[0]); 5878958fff8aad09f317a51b2d4cda3d7b126a530a4Zhongxing Xu#if IDX & LIGHT_TWOSIDE 588d84f422ebfde2145bce79a8fa823e3393b392994Argyrios Kyrtzidis ACC_3V(sum[1], light->_MatAmbient[1]); 589651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#endif 590651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 591651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines n_dot_VP = DOT3(normal, light->_VP_inf_norm); 592651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 593651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (n_dot_VP > 0.0F) { 594651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ACC_SCALE_SCALAR_3V(sum[0], n_dot_VP, light->_MatDiffuse[0]); 595651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines n_dot_h = DOT3(normal, light->_h_inf_norm); 596651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (n_dot_h > 0.0F) { 597651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines struct gl_shine_tab *tab = ctx->_ShineTable[0]; 598651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines GET_SHINE_TAB_ENTRY( tab, n_dot_h, spec ); 599 ACC_SCALE_SCALAR_3V( sum[0], spec, light->_MatSpecular[0]); 600 } 601 } 602#if IDX & LIGHT_TWOSIDE 603 else { 604 ACC_SCALE_SCALAR_3V(sum[1], -n_dot_VP, light->_MatDiffuse[1]); 605 n_dot_h = -DOT3(normal, light->_h_inf_norm); 606 if (n_dot_h > 0.0F) { 607 struct gl_shine_tab *tab = ctx->_ShineTable[1]; 608 GET_SHINE_TAB_ENTRY( tab, n_dot_h, spec ); 609 ACC_SCALE_SCALAR_3V( sum[1], spec, light->_MatSpecular[1]); 610 } 611 } 612#endif 613 } 614 615 COPY_3V( Fcolor[j], sum[0] ); 616 Fcolor[j][3] = sumA[0]; 617 618#if IDX & LIGHT_TWOSIDE 619 COPY_3V( Bcolor[j], sum[1] ); 620 Bcolor[j][3] = sumA[1]; 621#endif 622 } 623} 624 625 626 627 628 629/* 630 * Use current lighting/material settings to compute the color indexes 631 * for an array of vertices. 632 * Input: n - number of vertices to light 633 * side - 0=use front material, 1=use back material 634 * vertex - array of [n] vertex position in eye coordinates 635 * normal - array of [n] surface normal vector 636 * Output: indexResult - resulting array of [n] color indexes 637 */ 638static void TAG(light_ci)( GLcontext *ctx, 639 struct vertex_buffer *VB, 640 struct tnl_pipeline_stage *stage, 641 GLvector4f *input ) 642{ 643 struct light_stage_data *store = LIGHT_STAGE_DATA(stage); 644 GLuint j; 645 const GLuint vstride = input->stride; 646 const GLfloat *vertex = (GLfloat *) input->data; 647 const GLuint nstride = VB->NormalPtr->stride; 648 const GLfloat *normal = (GLfloat *)VB->NormalPtr->data; 649 GLfloat *indexResult[2]; 650 const GLuint nr = VB->Count; 651 652#ifdef TRACE 653 fprintf(stderr, "%s\n", __FUNCTION__ ); 654#endif 655 656 (void) nstride; 657 (void) vstride; 658 659 VB->IndexPtr[0] = &store->LitIndex[0]; 660#if IDX & LIGHT_TWOSIDE 661 VB->IndexPtr[1] = &store->LitIndex[1]; 662#endif 663 664 if (stage->changed_inputs == 0) 665 return; 666 667 indexResult[0] = (GLfloat *)VB->IndexPtr[0]->data; 668#if IDX & LIGHT_TWOSIDE 669 indexResult[1] = (GLfloat *)VB->IndexPtr[1]->data; 670#endif 671 672 /* loop over vertices */ 673 for (j=0; j<nr; j++,STRIDE_F(vertex,vstride),STRIDE_F(normal, nstride)) { 674 GLfloat diffuse[2], specular[2]; 675 GLuint side = 0; 676 struct gl_light *light; 677 678 if ( IDX & LIGHT_MATERIAL ) 679 update_materials( ctx, store ); 680 681 diffuse[0] = specular[0] = 0.0F; 682 683 if ( IDX & LIGHT_TWOSIDE ) { 684 diffuse[1] = specular[1] = 0.0F; 685 } 686 687 /* Accumulate diffuse and specular from each light source */ 688 foreach (light, &ctx->Light.EnabledList) { 689 690 GLfloat attenuation = 1.0F; 691 GLfloat VP[3]; /* unit vector from vertex to light */ 692 GLfloat n_dot_VP; /* dot product of l and n */ 693 GLfloat *h, n_dot_h, correction = 1.0; 694 695 /* compute l and attenuation */ 696 if (!(light->_Flags & LIGHT_POSITIONAL)) { 697 /* directional light */ 698 COPY_3V(VP, light->_VP_inf_norm); 699 } 700 else { 701 GLfloat d; /* distance from vertex to light */ 702 703 SUB_3V(VP, light->_Position, vertex); 704 705 d = (GLfloat) LEN_3FV( VP ); 706 if ( d > 1e-6) { 707 GLfloat invd = 1.0F / d; 708 SELF_SCALE_SCALAR_3V(VP, invd); 709 } 710 711 attenuation = 1.0F / (light->ConstantAttenuation + d * 712 (light->LinearAttenuation + d * 713 light->QuadraticAttenuation)); 714 715 /* spotlight attenuation */ 716 if (light->_Flags & LIGHT_SPOT) { 717 GLfloat PV_dot_dir = - DOT3(VP, light->_NormDirection); 718 if (PV_dot_dir < light->_CosCutoff) { 719 continue; /* this light makes no contribution */ 720 } 721 else { 722 GLdouble x = PV_dot_dir * (EXP_TABLE_SIZE-1); 723 GLint k = (GLint) x; 724 GLfloat spot = (GLfloat) (light->_SpotExpTable[k][0] 725 + (x-k)*light->_SpotExpTable[k][1]); 726 attenuation *= spot; 727 } 728 } 729 } 730 731 if (attenuation < 1e-3) 732 continue; /* this light makes no contribution */ 733 734 n_dot_VP = DOT3( normal, VP ); 735 736 /* which side are we lighting? */ 737 if (n_dot_VP < 0.0F) { 738#if IDX & LIGHT_TWOSIDE 739 side = 1; 740 correction = -1; 741 n_dot_VP = -n_dot_VP; 742#else 743 continue; 744#endif 745 } 746 747 /* accumulate diffuse term */ 748 diffuse[side] += n_dot_VP * light->_dli * attenuation; 749 750 /* specular term */ 751 if (ctx->Light.Model.LocalViewer) { 752 GLfloat v[3]; 753 COPY_3V(v, vertex); 754 NORMALIZE_3FV(v); 755 SUB_3V(VP, VP, v); /* h = VP + VPe */ 756 h = VP; 757 NORMALIZE_3FV(h); 758 } 759 else if (light->_Flags & LIGHT_POSITIONAL) { 760 h = VP; 761 /* Strangely, disabling this addition fixes a conformance 762 * problem. If this code is enabled, l_sed.c fails. 763 */ 764 /*ACC_3V(h, ctx->_EyeZDir);*/ 765 NORMALIZE_3FV(h); 766 } 767 else { 768 h = light->_h_inf_norm; 769 } 770 771 n_dot_h = correction * DOT3(normal, h); 772 if (n_dot_h > 0.0F) { 773 GLfloat spec_coef; 774 struct gl_shine_tab *tab = ctx->_ShineTable[side]; 775 GET_SHINE_TAB_ENTRY( tab, n_dot_h, spec_coef); 776 specular[side] += spec_coef * light->_sli * attenuation; 777 } 778 } /*loop over lights*/ 779 780 /* Now compute final color index */ 781 for (side = 0 ; side < NR_SIDES ; side++) { 782 const GLfloat *ind = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_INDEXES + side]; 783 GLfloat index; 784 785 if (specular[side] > 1.0F) { 786 index = ind[MAT_INDEX_SPECULAR]; 787 } 788 else { 789 GLfloat d_a = ind[MAT_INDEX_DIFFUSE] - ind[MAT_INDEX_AMBIENT]; 790 GLfloat s_a = ind[MAT_INDEX_SPECULAR] - ind[MAT_INDEX_AMBIENT]; 791 index = (ind[MAT_INDEX_AMBIENT] 792 + diffuse[side] * (1.0F-specular[side]) * d_a 793 + specular[side] * s_a); 794 if (index > ind[MAT_INDEX_SPECULAR]) { 795 index = ind[MAT_INDEX_SPECULAR]; 796 } 797 } 798 indexResult[side][j] = index; 799 } 800 } /*for vertex*/ 801} 802 803 804 805static void TAG(init_light_tab)( void ) 806{ 807 _tnl_light_tab[IDX] = TAG(light_rgba); 808 _tnl_light_fast_tab[IDX] = TAG(light_fast_rgba); 809 _tnl_light_fast_single_tab[IDX] = TAG(light_fast_rgba_single); 810 _tnl_light_spec_tab[IDX] = TAG(light_rgba_spec); 811 _tnl_light_ci_tab[IDX] = TAG(light_ci); 812} 813 814 815#undef TAG 816#undef IDX 817#undef NR_SIDES 818