prog_statevars.c revision 707f0679157f83ac45127e41647b96ed924d45c9
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Mesa 3-D graphics library 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Version: 7.1 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 5f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Permission is hereby granted, free of charge, to any person obtaining a 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * copy of this software and associated documentation files (the "Software"), 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * to deal in the Software without restriction, including without limitation 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the rights to use, copy, modify, merge, publish, distribute, sublicense, 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * and/or sell copies of the Software, and to permit persons to whom the 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Software is furnished to do so, subject to the following conditions: 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * The above copyright notice and this permission notice shall be included 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * in all copies or substantial portions of the Software. 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 17116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 21d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * \file prog_statevars.c 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Program state variable management. 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * \author Brian Paul 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "main/glheader.h" 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "main/context.h" 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "main/imports.h" 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "main/macros.h" 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "main/mtypes.h" 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "main/fbobject.h" 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "prog_statevars.h" 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "prog_parameter.h" 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "main/samplerobj.h" 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Use the list of tokens in the state[] array to find global GL state 45010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) * and return it in <value>. Usually, four values are returned in <value> 46d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) * but matrix queries may return as many as 16 values. 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * This function is used for ARB vertex/fragment programs. 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * The program parser will produce the state[] values. 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)_mesa_fetch_state(struct gl_context *ctx, const gl_state_index state[], 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLfloat *value) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (state[0]) { 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATE_MATERIAL: 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* state[1] is either 0=front or 1=back side */ 581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const GLuint face = (GLuint) state[1]; 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const struct gl_material *mat = &ctx->Light.Material; 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT(face == 0 || face == 1); 611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci /* we rely on tokens numbered so that _BACK_ == _FRONT_+ 1 */ 621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ASSERT(MAT_ATTRIB_FRONT_AMBIENT + 1 == MAT_ATTRIB_BACK_AMBIENT); 631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci /* XXX we could get rid of this switch entirely with a little 641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * work in arbprogparse.c's parse_state_single_item(). 651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci */ 661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci /* state[2] is the material attribute */ 671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci switch (state[2]) { 681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci case STATE_AMBIENT: 691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci COPY_4V(value, mat->Attrib[MAT_ATTRIB_FRONT_AMBIENT + face]); 701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci case STATE_DIFFUSE: 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) COPY_4V(value, mat->Attrib[MAT_ATTRIB_FRONT_DIFFUSE + face]); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATE_SPECULAR: 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) COPY_4V(value, mat->Attrib[MAT_ATTRIB_FRONT_SPECULAR + face]); 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATE_EMISSION: 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) COPY_4V(value, mat->Attrib[MAT_ATTRIB_FRONT_EMISSION + face]); 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 80f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) case STATE_SHININESS: 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value[0] = mat->Attrib[MAT_ATTRIB_FRONT_SHININESS + face][0]; 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value[1] = 0.0F; 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value[2] = 0.0F; 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value[3] = 1.0F; 857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return; 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) _mesa_problem(ctx, "Invalid material state in fetch_state"); 88f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return; 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATE_LIGHT: 92f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) { 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* state[1] is the light number */ 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GLuint ln = (GLuint) state[1]; 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* state[2] is the light attribute */ 96116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch switch (state[2]) { 97116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch case STATE_AMBIENT: 98116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch COPY_4V(value, ctx->Light.Light[ln].Ambient); 99116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return; 100116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch case STATE_DIFFUSE: 101116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch COPY_4V(value, ctx->Light.Light[ln].Diffuse); 102116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return; 103116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch case STATE_SPECULAR: 104116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch COPY_4V(value, ctx->Light.Light[ln].Specular); 105ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return; 106ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch case STATE_POSITION: 107a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) COPY_4V(value, ctx->Light.Light[ln].EyePosition); 108a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return; 109a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) case STATE_ATTENUATION: 110ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch value[0] = ctx->Light.Light[ln].ConstantAttenuation; 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value[1] = ctx->Light.Light[ln].LinearAttenuation; 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value[2] = ctx->Light.Light[ln].QuadraticAttenuation; 113f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) value[3] = ctx->Light.Light[ln].SpotExponent; 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATE_SPOT_DIRECTION: 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) COPY_3V(value, ctx->Light.Light[ln].SpotDirection); 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value[3] = ctx->Light.Light[ln]._CosCutoff; 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATE_SPOT_CUTOFF: 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value[0] = ctx->Light.Light[ln].SpotCutoff; 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATE_HALF_VECTOR: 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 12490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) static const GLfloat eye_z[] = {0, 0, 1}; 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLfloat p[3]; 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Compute infinite half angle vector: 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * halfVector = normalize(normalize(lightPos) + (0, 0, 1)) 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * light.EyePosition.w should be 0 for infinite lights. 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) COPY_3V(p, ctx->Light.Light[ln].EyePosition); 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NORMALIZE_3FV(p); 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ADD_3V(value, p, eye_z); 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NORMALIZE_3FV(value); 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value[3] = 1.0; 1357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) _mesa_problem(ctx, "Invalid light state in fetch_state"); 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 142f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) case STATE_LIGHTMODEL_AMBIENT: 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) COPY_4V(value, ctx->Light.Model.Ambient); 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATE_LIGHTMODEL_SCENECOLOR: 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (state[1] == 0) { 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* front */ 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLint i; 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < 3; i++) { 150d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) value[i] = ctx->Light.Model.Ambient[i] 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_AMBIENT][i] 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) + ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_EMISSION][i]; 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value[3] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE][3]; 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else { 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* back */ 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLint i; 159f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) for (i = 0; i < 3; i++) { 1600f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) value[i] = ctx->Light.Model.Ambient[i] 1610f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) * ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_AMBIENT][i] 1620f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) + ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_EMISSION][i]; 1630f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) } 164f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) value[3] = ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_DIFFUSE][3]; 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATE_LIGHTPROD: 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GLuint ln = (GLuint) state[1]; 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GLuint face = (GLuint) state[2]; 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLint i; 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT(face == 0 || face == 1); 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (state[3]) { 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATE_AMBIENT: 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < 3; i++) { 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value[i] = ctx->Light.Light[ln].Ambient[i] * 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_AMBIENT+face][i]; 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* [3] = material alpha */ 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value[3] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_AMBIENT+face][3]; 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATE_DIFFUSE: 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < 3; i++) { 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value[i] = ctx->Light.Light[ln].Diffuse[i] * 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE+face][i]; 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* [3] = material alpha */ 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value[3] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE+face][3]; 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATE_SPECULAR: 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < 3; i++) { 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value[i] = ctx->Light.Light[ln].Specular[i] * 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_SPECULAR+face][i]; 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* [3] = material alpha */ 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value[3] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_SPECULAR+face][3]; 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) _mesa_problem(ctx, "Invalid lightprod state in fetch_state"); 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATE_TEXGEN: 204f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) { 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* state[1] is the texture unit */ 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GLuint unit = (GLuint) state[1]; 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* state[2] is the texgen attribute */ 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (state[2]) { 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATE_TEXGEN_EYE_S: 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) COPY_4V(value, ctx->Texture.Unit[unit].GenS.EyePlane); 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATE_TEXGEN_EYE_T: 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) COPY_4V(value, ctx->Texture.Unit[unit].GenT.EyePlane); 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATE_TEXGEN_EYE_R: 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) COPY_4V(value, ctx->Texture.Unit[unit].GenR.EyePlane); 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATE_TEXGEN_EYE_Q: 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) COPY_4V(value, ctx->Texture.Unit[unit].GenQ.EyePlane); 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATE_TEXGEN_OBJECT_S: 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) COPY_4V(value, ctx->Texture.Unit[unit].GenS.ObjectPlane); 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATE_TEXGEN_OBJECT_T: 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) COPY_4V(value, ctx->Texture.Unit[unit].GenT.ObjectPlane); 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATE_TEXGEN_OBJECT_R: 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) COPY_4V(value, ctx->Texture.Unit[unit].GenR.ObjectPlane); 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATE_TEXGEN_OBJECT_Q: 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) COPY_4V(value, ctx->Texture.Unit[unit].GenQ.ObjectPlane); 232f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return; 233a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) default: 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) _mesa_problem(ctx, "Invalid texgen state in fetch_state"); 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 237d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATE_TEXENV_COLOR: 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 240f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) /* state[1] is the texture unit */ 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GLuint unit = (GLuint) state[1]; 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if(ctx->Color._ClampFragmentColor) 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) COPY_4V(value, ctx->Texture.Unit[unit].EnvColor); 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) COPY_4V(value, ctx->Texture.Unit[unit].EnvColorUnclamped); 246c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 247c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 248c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case STATE_FOG_COLOR: 249c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if(ctx->Color._ClampFragmentColor) 250c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) COPY_4V(value, ctx->Fog.Color); 251c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) else 252c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) COPY_4V(value, ctx->Fog.ColorUnclamped); 253c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 254a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) case STATE_FOG_PARAMS: 255c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) value[0] = ctx->Fog.Density; 256c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) value[1] = ctx->Fog.Start; 257c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) value[2] = ctx->Fog.End; 258c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) value[3] = (ctx->Fog.End == ctx->Fog.Start) 259c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ? 1.0f : (GLfloat)(1.0 / (ctx->Fog.End - ctx->Fog.Start)); 260c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 26190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) case STATE_CLIPPLANE: 262c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) { 263c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const GLuint plane = (GLuint) state[1]; 264c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) COPY_4V(value, ctx->Transform.EyeUserPlane[plane]); 265c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 266c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATE_POINT_SIZE: 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value[0] = ctx->Point.Size; 269f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) value[1] = ctx->Point.MinSize; 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value[2] = ctx->Point.MaxSize; 271010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) value[3] = ctx->Point.Threshold; 2727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return; 2737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch case STATE_POINT_ATTENUATION: 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value[0] = ctx->Point.Params[0]; 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value[1] = ctx->Point.Params[1]; 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value[2] = ctx->Point.Params[2]; 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value[3] = 1.0F; 278f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return; 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATE_MODELVIEW_MATRIX: 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATE_PROJECTION_MATRIX: 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATE_MVP_MATRIX: 282010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) case STATE_TEXTURE_MATRIX: 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATE_PROGRAM_MATRIX: 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 285010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) /* state[0] = modelview, projection, texture, etc. */ 286010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) /* state[1] = which texture matrix or program matrix */ 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* state[2] = first row to fetch */ 288010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) /* state[3] = last row to fetch */ 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* state[4] = transpose, inverse or invtrans */ 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GLmatrix *matrix; 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gl_state_index mat = state[0]; 292010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const GLuint index = (GLuint) state[1]; 293010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const GLuint firstRow = (GLuint) state[2]; 294010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const GLuint lastRow = (GLuint) state[3]; 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gl_state_index modifier = state[4]; 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GLfloat *m; 297f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) GLuint row, i; 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT(firstRow >= 0); 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT(firstRow < 4); 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT(lastRow >= 0); 30168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ASSERT(lastRow < 4); 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (mat == STATE_MODELVIEW_MATRIX) { 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) matrix = ctx->ModelviewMatrixStack.Top; 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (mat == STATE_PROJECTION_MATRIX) { 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) matrix = ctx->ProjectionMatrixStack.Top; 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (mat == STATE_MVP_MATRIX) { 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) matrix = &ctx->_ModelProjectMatrix; 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (mat == STATE_TEXTURE_MATRIX) { 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT(index < Elements(ctx->TextureMatrixStack)); 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) matrix = ctx->TextureMatrixStack[index].Top; 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (mat == STATE_PROGRAM_MATRIX) { 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT(index < Elements(ctx->ProgramMatrixStack)); 317f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) matrix = ctx->ProgramMatrixStack[index].Top; 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else { 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) _mesa_problem(ctx, "Bad matrix name in _mesa_fetch_state()"); 32168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return; 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 32368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (modifier == STATE_MATRIX_INVERSE || 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) modifier == STATE_MATRIX_INVTRANS) { 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Be sure inverse is up to date: 32668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) */ 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) _math_matrix_analyse( (GLmatrix*) matrix ); 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m = matrix->inv; 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 330116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch else { 331116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch m = matrix->m; 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (modifier == STATE_MATRIX_TRANSPOSE || 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) modifier == STATE_MATRIX_INVTRANS) { 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0, row = firstRow; row <= lastRow; row++) { 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value[i++] = m[row * 4 + 0]; 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value[i++] = m[row * 4 + 1]; 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value[i++] = m[row * 4 + 2]; 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value[i++] = m[row * 4 + 3]; 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else { 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0, row = firstRow; row <= lastRow; row++) { 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value[i++] = m[row + 0]; 34568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) value[i++] = m[row + 4]; 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value[i++] = m[row + 8]; 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value[i++] = m[row + 12]; 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 352f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) case STATE_DEPTH_RANGE: 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value[0] = ctx->Viewport.Near; /* near */ 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value[1] = ctx->Viewport.Far; /* far */ 3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) value[2] = ctx->Viewport.Far - ctx->Viewport.Near; /* far - near */ 3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) value[3] = 1.0; 3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case STATE_FRAGMENT_PROGRAM: 3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /* state[1] = {STATE_ENV, STATE_LOCAL} */ 3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /* state[2] = parameter index */ 3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const int idx = (int) state[2]; 3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switch (state[1]) { 3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case STATE_ENV: 3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) COPY_4V(value, ctx->FragmentProgram.Parameters[idx]); 3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 3675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case STATE_LOCAL: 3685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) COPY_4V(value, ctx->FragmentProgram.Current->Base.LocalParams[idx]); 3695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 3705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) default: 3715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) _mesa_problem(ctx, "Bad state switch in _mesa_fetch_state()"); 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATE_VERTEX_PROGRAM: 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /* state[1] = {STATE_ENV, STATE_LOCAL} */ 3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /* state[2] = parameter index */ 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int idx = (int) state[2]; 3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switch (state[1]) { 3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case STATE_ENV: 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) COPY_4V(value, ctx->VertexProgram.Parameters[idx]); 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATE_LOCAL: 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) COPY_4V(value, ctx->VertexProgram.Current->Base.LocalParams[idx]); 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 389f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) default: 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) _mesa_problem(ctx, "Bad state switch in _mesa_fetch_state()"); 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3930f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) } 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATE_NORMAL_SCALE: 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSIGN_4V(value, ctx->_ModelViewInvScale, 0, 0, 1); 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATE_INTERNAL: 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (state[1]) { 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATE_CURRENT_ATTRIB: 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 404116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const GLuint idx = (GLuint) state[2]; 405116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch COPY_4V(value, ctx->Current.Attrib[idx]); 406116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case STATE_CURRENT_ATTRIB_MAYBE_VP_CLAMPED: 4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GLuint idx = (GLuint) state[2]; 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if(ctx->Light._ClampVertexColor && 4131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci (idx == VERT_ATTRIB_COLOR0 || 4141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci idx == VERT_ATTRIB_COLOR1)) { 4151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci value[0] = CLAMP(ctx->Current.Attrib[idx][0], 0.0f, 1.0f); 4161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci value[1] = CLAMP(ctx->Current.Attrib[idx][1], 0.0f, 1.0f); 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value[2] = CLAMP(ctx->Current.Attrib[idx][2], 0.0f, 1.0f); 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value[3] = CLAMP(ctx->Current.Attrib[idx][3], 0.0f, 1.0f); 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) COPY_4V(value, ctx->Current.Attrib[idx]); 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATE_NORMAL_SCALE: 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSIGN_4V(value, 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctx->_ModelViewInvScale, 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctx->_ModelViewInvScale, 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctx->_ModelViewInvScale, 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1); 4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case STATE_TEXRECT_SCALE: 4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /* Value = { 1/texWidth, 1/texHeight, 0, 1 }. 4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * Used to convert unnormalized texcoords to normalized texcoords. 4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */ 4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const int unit = (int) state[2]; 4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const struct gl_texture_object *texObj 440d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) = ctx->Texture.Unit[unit]._Current; 4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (texObj) { 4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) struct gl_texture_image *texImage = texObj->Image[0][0]; 4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSIGN_4V(value, 4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (GLfloat) (1.0 / texImage->Width), 4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (GLfloat) (1.0 / texImage->Height), 4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 0.0f, 1.0f); 4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case STATE_FOG_PARAMS_OPTIMIZED: 4521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci /* for simpler per-vertex/pixel fog calcs. POW (for EXP/EXP2 fog) 4531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * might be more expensive than EX2 on some hw, plus it needs 4541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * another constant (e) anyway. Linear fog can now be done with a 4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * single MAD. 4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * linear: fogcoord * -1/(end-start) + end/(end-start) 4571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * exp: 2^-(density/ln(2) * fogcoord) 4581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * exp2: 2^-((density/(ln(2)^2) * fogcoord)^2) 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value[0] = (ctx->Fog.End == ctx->Fog.Start) 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ? 1.0f : (GLfloat)(-1.0F / (ctx->Fog.End - ctx->Fog.Start)); 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value[1] = ctx->Fog.End * -value[0]; 4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) value[2] = (GLfloat)(ctx->Fog.Density * M_LOG2E); /* M_LOG2E == 1/ln(2) */ 4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) value[3] = (GLfloat)(ctx->Fog.Density * ONE_DIV_SQRT_LN2); 4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case STATE_POINT_SIZE_CLAMPED: 4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /* this includes implementation dependent limits, to avoid 4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * another potentially necessary clamp. 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Note: for sprites, point smooth (point AA) is ignored 4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * and we'll clamp to MinPointSizeAA and MaxPointSize, because we 4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * expect drivers will want to say their minimum for AA size is 0.0 4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * but for non-AA it's 1.0 (because normal points with size below 1.0 4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * need to get rounded up to 1.0, hence never disappear). GL does 4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * not specify max clamp size for sprites, other than it needs to be 4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * at least as large as max AA size, hence use non-AA size there. 4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */ 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLfloat minImplSize; 4801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci GLfloat maxImplSize; 4811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (ctx->Point.PointSprite) { 4821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci minImplSize = ctx->Const.MinPointSizeAA; 4831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci maxImplSize = ctx->Const.MaxPointSize; 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else if (ctx->Point.SmoothFlag || ctx->Multisample._Enabled) { 486effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch minImplSize = ctx->Const.MinPointSizeAA; 487effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch maxImplSize = ctx->Const.MaxPointSizeAA; 4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else { 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) minImplSize = ctx->Const.MinPointSize; 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) maxImplSize = ctx->Const.MaxPointSize; 492f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value[0] = ctx->Point.Size; 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value[1] = ctx->Point.MinSize >= minImplSize ? ctx->Point.MinSize : minImplSize; 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value[2] = ctx->Point.MaxSize <= maxImplSize ? ctx->Point.MaxSize : maxImplSize; 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value[3] = ctx->Point.Threshold; 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 499d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) case STATE_LIGHT_SPOT_DIR_NORMALIZED: 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* here, state[2] is the light number */ 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* pre-normalize spot dir */ 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GLuint ln = (GLuint) state[2]; 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) COPY_3V(value, ctx->Light.Light[ln]._NormSpotDirection); 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value[3] = ctx->Light.Light[ln]._CosCutoff; 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 507f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return; 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATE_LIGHT_POSITION: 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GLuint ln = (GLuint) state[2]; 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) COPY_4V(value, ctx->Light.Light[ln]._Position); 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 514f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return; 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATE_LIGHT_POSITION_NORMALIZED: 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GLuint ln = (GLuint) state[2]; 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) COPY_4V(value, ctx->Light.Light[ln]._Position); 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NORMALIZE_3FV( value ); 521f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case STATE_LIGHT_HALF_VECTOR: 5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GLuint ln = (GLuint) state[2]; 527cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) GLfloat p[3]; 528f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) /* Compute infinite half angle vector: 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * halfVector = normalize(normalize(lightPos) + (0, 0, 1)) 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * light.EyePosition.w should be 0 for infinite lights. 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 532 COPY_3V(p, ctx->Light.Light[ln]._Position); 533 NORMALIZE_3FV(p); 534 ADD_3V(value, p, ctx->_EyeZDir); 535 NORMALIZE_3FV(value); 536 value[3] = 1.0; 537 } 538 return; 539 540 case STATE_PT_SCALE: 541 value[0] = ctx->Pixel.RedScale; 542 value[1] = ctx->Pixel.GreenScale; 543 value[2] = ctx->Pixel.BlueScale; 544 value[3] = ctx->Pixel.AlphaScale; 545 return; 546 547 case STATE_PT_BIAS: 548 value[0] = ctx->Pixel.RedBias; 549 value[1] = ctx->Pixel.GreenBias; 550 value[2] = ctx->Pixel.BlueBias; 551 value[3] = ctx->Pixel.AlphaBias; 552 return; 553 554 case STATE_FB_SIZE: 555 value[0] = (GLfloat) (ctx->DrawBuffer->Width - 1); 556 value[1] = (GLfloat) (ctx->DrawBuffer->Height - 1); 557 value[2] = 0.0F; 558 value[3] = 0.0F; 559 return; 560 561 case STATE_FB_WPOS_Y_TRANSFORM: 562 /* A driver may negate this conditional by using ZW swizzle 563 * instead of XY (based on e.g. some other state). */ 564 if (_mesa_is_user_fbo(ctx->DrawBuffer)) { 565 /* Identity (XY) followed by flipping Y upside down (ZW). */ 566 value[0] = 1.0F; 567 value[1] = 0.0F; 568 value[2] = -1.0F; 569 value[3] = (GLfloat) ctx->DrawBuffer->Height; 570 } else { 571 /* Flipping Y upside down (XY) followed by identity (ZW). */ 572 value[0] = -1.0F; 573 value[1] = (GLfloat) ctx->DrawBuffer->Height; 574 value[2] = 1.0F; 575 value[3] = 0.0F; 576 } 577 return; 578 579 case STATE_ROT_MATRIX_0: 580 { 581 const int unit = (int) state[2]; 582 GLfloat *rotMat22 = ctx->Texture.Unit[unit].RotMatrix; 583 value[0] = rotMat22[0]; 584 value[1] = rotMat22[2]; 585 value[2] = 0.0; 586 value[3] = 0.0; 587 } 588 return; 589 590 case STATE_ROT_MATRIX_1: 591 { 592 const int unit = (int) state[2]; 593 GLfloat *rotMat22 = ctx->Texture.Unit[unit].RotMatrix; 594 value[0] = rotMat22[1]; 595 value[1] = rotMat22[3]; 596 value[2] = 0.0; 597 value[3] = 0.0; 598 } 599 return; 600 601 /* XXX: make sure new tokens added here are also handled in the 602 * _mesa_program_state_flags() switch, below. 603 */ 604 default: 605 /* Unknown state indexes are silently ignored here. 606 * Drivers may do something special. 607 */ 608 return; 609 } 610 return; 611 612 default: 613 _mesa_problem(ctx, "Invalid state in _mesa_fetch_state"); 614 return; 615 } 616} 617 618 619/** 620 * Return a bitmask of the Mesa state flags (_NEW_* values) which would 621 * indicate that the given context state may have changed. 622 * The bitmask is used during validation to determine if we need to update 623 * vertex/fragment program parameters (like "state.material.color") when 624 * some GL state has changed. 625 */ 626GLbitfield 627_mesa_program_state_flags(const gl_state_index state[STATE_LENGTH]) 628{ 629 switch (state[0]) { 630 case STATE_MATERIAL: 631 case STATE_LIGHTPROD: 632 case STATE_LIGHTMODEL_SCENECOLOR: 633 /* these can be effected by glColor when colormaterial mode is used */ 634 return _NEW_LIGHT | _NEW_CURRENT_ATTRIB; 635 636 case STATE_LIGHT: 637 case STATE_LIGHTMODEL_AMBIENT: 638 return _NEW_LIGHT; 639 640 case STATE_TEXGEN: 641 return _NEW_TEXTURE; 642 case STATE_TEXENV_COLOR: 643 return _NEW_TEXTURE | _NEW_BUFFERS | _NEW_FRAG_CLAMP; 644 645 case STATE_FOG_COLOR: 646 return _NEW_FOG | _NEW_BUFFERS | _NEW_FRAG_CLAMP; 647 case STATE_FOG_PARAMS: 648 return _NEW_FOG; 649 650 case STATE_CLIPPLANE: 651 return _NEW_TRANSFORM; 652 653 case STATE_POINT_SIZE: 654 case STATE_POINT_ATTENUATION: 655 return _NEW_POINT; 656 657 case STATE_MODELVIEW_MATRIX: 658 return _NEW_MODELVIEW; 659 case STATE_PROJECTION_MATRIX: 660 return _NEW_PROJECTION; 661 case STATE_MVP_MATRIX: 662 return _NEW_MODELVIEW | _NEW_PROJECTION; 663 case STATE_TEXTURE_MATRIX: 664 return _NEW_TEXTURE_MATRIX; 665 case STATE_PROGRAM_MATRIX: 666 return _NEW_TRACK_MATRIX; 667 668 case STATE_DEPTH_RANGE: 669 return _NEW_VIEWPORT; 670 671 case STATE_FRAGMENT_PROGRAM: 672 case STATE_VERTEX_PROGRAM: 673 return _NEW_PROGRAM; 674 675 case STATE_NORMAL_SCALE: 676 return _NEW_MODELVIEW; 677 678 case STATE_INTERNAL: 679 switch (state[1]) { 680 case STATE_CURRENT_ATTRIB: 681 return _NEW_CURRENT_ATTRIB; 682 case STATE_CURRENT_ATTRIB_MAYBE_VP_CLAMPED: 683 return _NEW_CURRENT_ATTRIB | _NEW_LIGHT | _NEW_BUFFERS; 684 685 case STATE_NORMAL_SCALE: 686 return _NEW_MODELVIEW; 687 688 case STATE_TEXRECT_SCALE: 689 case STATE_ROT_MATRIX_0: 690 case STATE_ROT_MATRIX_1: 691 return _NEW_TEXTURE; 692 case STATE_FOG_PARAMS_OPTIMIZED: 693 return _NEW_FOG; 694 case STATE_POINT_SIZE_CLAMPED: 695 return _NEW_POINT | _NEW_MULTISAMPLE; 696 case STATE_LIGHT_SPOT_DIR_NORMALIZED: 697 case STATE_LIGHT_POSITION: 698 case STATE_LIGHT_POSITION_NORMALIZED: 699 case STATE_LIGHT_HALF_VECTOR: 700 return _NEW_LIGHT; 701 702 case STATE_PT_SCALE: 703 case STATE_PT_BIAS: 704 return _NEW_PIXEL; 705 706 case STATE_FB_SIZE: 707 case STATE_FB_WPOS_Y_TRANSFORM: 708 return _NEW_BUFFERS; 709 710 default: 711 /* unknown state indexes are silently ignored and 712 * no flag set, since it is handled by the driver. 713 */ 714 return 0; 715 } 716 717 default: 718 _mesa_problem(NULL, "unexpected state[0] in make_state_flags()"); 719 return 0; 720 } 721} 722 723 724static void 725append(char *dst, const char *src) 726{ 727 while (*dst) 728 dst++; 729 while (*src) 730 *dst++ = *src++; 731 *dst = 0; 732} 733 734 735/** 736 * Convert token 'k' to a string, append it onto 'dst' string. 737 */ 738static void 739append_token(char *dst, gl_state_index k) 740{ 741 switch (k) { 742 case STATE_MATERIAL: 743 append(dst, "material"); 744 break; 745 case STATE_LIGHT: 746 append(dst, "light"); 747 break; 748 case STATE_LIGHTMODEL_AMBIENT: 749 append(dst, "lightmodel.ambient"); 750 break; 751 case STATE_LIGHTMODEL_SCENECOLOR: 752 break; 753 case STATE_LIGHTPROD: 754 append(dst, "lightprod"); 755 break; 756 case STATE_TEXGEN: 757 append(dst, "texgen"); 758 break; 759 case STATE_FOG_COLOR: 760 append(dst, "fog.color"); 761 break; 762 case STATE_FOG_PARAMS: 763 append(dst, "fog.params"); 764 break; 765 case STATE_CLIPPLANE: 766 append(dst, "clip"); 767 break; 768 case STATE_POINT_SIZE: 769 append(dst, "point.size"); 770 break; 771 case STATE_POINT_ATTENUATION: 772 append(dst, "point.attenuation"); 773 break; 774 case STATE_MODELVIEW_MATRIX: 775 append(dst, "matrix.modelview"); 776 break; 777 case STATE_PROJECTION_MATRIX: 778 append(dst, "matrix.projection"); 779 break; 780 case STATE_MVP_MATRIX: 781 append(dst, "matrix.mvp"); 782 break; 783 case STATE_TEXTURE_MATRIX: 784 append(dst, "matrix.texture"); 785 break; 786 case STATE_PROGRAM_MATRIX: 787 append(dst, "matrix.program"); 788 break; 789 case STATE_MATRIX_INVERSE: 790 append(dst, ".inverse"); 791 break; 792 case STATE_MATRIX_TRANSPOSE: 793 append(dst, ".transpose"); 794 break; 795 case STATE_MATRIX_INVTRANS: 796 append(dst, ".invtrans"); 797 break; 798 case STATE_AMBIENT: 799 append(dst, ".ambient"); 800 break; 801 case STATE_DIFFUSE: 802 append(dst, ".diffuse"); 803 break; 804 case STATE_SPECULAR: 805 append(dst, ".specular"); 806 break; 807 case STATE_EMISSION: 808 append(dst, ".emission"); 809 break; 810 case STATE_SHININESS: 811 append(dst, "lshininess"); 812 break; 813 case STATE_HALF_VECTOR: 814 append(dst, ".half"); 815 break; 816 case STATE_POSITION: 817 append(dst, ".position"); 818 break; 819 case STATE_ATTENUATION: 820 append(dst, ".attenuation"); 821 break; 822 case STATE_SPOT_DIRECTION: 823 append(dst, ".spot.direction"); 824 break; 825 case STATE_SPOT_CUTOFF: 826 append(dst, ".spot.cutoff"); 827 break; 828 case STATE_TEXGEN_EYE_S: 829 append(dst, ".eye.s"); 830 break; 831 case STATE_TEXGEN_EYE_T: 832 append(dst, ".eye.t"); 833 break; 834 case STATE_TEXGEN_EYE_R: 835 append(dst, ".eye.r"); 836 break; 837 case STATE_TEXGEN_EYE_Q: 838 append(dst, ".eye.q"); 839 break; 840 case STATE_TEXGEN_OBJECT_S: 841 append(dst, ".object.s"); 842 break; 843 case STATE_TEXGEN_OBJECT_T: 844 append(dst, ".object.t"); 845 break; 846 case STATE_TEXGEN_OBJECT_R: 847 append(dst, ".object.r"); 848 break; 849 case STATE_TEXGEN_OBJECT_Q: 850 append(dst, ".object.q"); 851 break; 852 case STATE_TEXENV_COLOR: 853 append(dst, "texenv"); 854 break; 855 case STATE_DEPTH_RANGE: 856 append(dst, "depth.range"); 857 break; 858 case STATE_VERTEX_PROGRAM: 859 case STATE_FRAGMENT_PROGRAM: 860 break; 861 case STATE_ENV: 862 append(dst, "env"); 863 break; 864 case STATE_LOCAL: 865 append(dst, "local"); 866 break; 867 /* BEGIN internal state vars */ 868 case STATE_INTERNAL: 869 append(dst, ".internal."); 870 break; 871 case STATE_CURRENT_ATTRIB: 872 append(dst, "current"); 873 break; 874 case STATE_NORMAL_SCALE: 875 append(dst, "normalScale"); 876 break; 877 case STATE_TEXRECT_SCALE: 878 append(dst, "texrectScale"); 879 break; 880 case STATE_FOG_PARAMS_OPTIMIZED: 881 append(dst, "fogParamsOptimized"); 882 break; 883 case STATE_POINT_SIZE_CLAMPED: 884 append(dst, "pointSizeClamped"); 885 break; 886 case STATE_LIGHT_SPOT_DIR_NORMALIZED: 887 append(dst, "lightSpotDirNormalized"); 888 break; 889 case STATE_LIGHT_POSITION: 890 append(dst, "lightPosition"); 891 break; 892 case STATE_LIGHT_POSITION_NORMALIZED: 893 append(dst, "light.position.normalized"); 894 break; 895 case STATE_LIGHT_HALF_VECTOR: 896 append(dst, "lightHalfVector"); 897 break; 898 case STATE_PT_SCALE: 899 append(dst, "PTscale"); 900 break; 901 case STATE_PT_BIAS: 902 append(dst, "PTbias"); 903 break; 904 case STATE_FB_SIZE: 905 append(dst, "FbSize"); 906 break; 907 case STATE_FB_WPOS_Y_TRANSFORM: 908 append(dst, "FbWposYTransform"); 909 break; 910 case STATE_ROT_MATRIX_0: 911 append(dst, "rotMatrixRow0"); 912 break; 913 case STATE_ROT_MATRIX_1: 914 append(dst, "rotMatrixRow1"); 915 break; 916 default: 917 /* probably STATE_INTERNAL_DRIVER+i (driver private state) */ 918 append(dst, "driverState"); 919 } 920} 921 922static void 923append_face(char *dst, GLint face) 924{ 925 if (face == 0) 926 append(dst, "front."); 927 else 928 append(dst, "back."); 929} 930 931static void 932append_index(char *dst, GLint index) 933{ 934 char s[20]; 935 sprintf(s, "[%d]", index); 936 append(dst, s); 937} 938 939/** 940 * Make a string from the given state vector. 941 * For example, return "state.matrix.texture[2].inverse". 942 * Use free() to deallocate the string. 943 */ 944char * 945_mesa_program_state_string(const gl_state_index state[STATE_LENGTH]) 946{ 947 char str[1000] = ""; 948 char tmp[30]; 949 950 append(str, "state."); 951 append_token(str, state[0]); 952 953 switch (state[0]) { 954 case STATE_MATERIAL: 955 append_face(str, state[1]); 956 append_token(str, state[2]); 957 break; 958 case STATE_LIGHT: 959 append_index(str, state[1]); /* light number [i]. */ 960 append_token(str, state[2]); /* coefficients */ 961 break; 962 case STATE_LIGHTMODEL_AMBIENT: 963 append(str, "lightmodel.ambient"); 964 break; 965 case STATE_LIGHTMODEL_SCENECOLOR: 966 if (state[1] == 0) { 967 append(str, "lightmodel.front.scenecolor"); 968 } 969 else { 970 append(str, "lightmodel.back.scenecolor"); 971 } 972 break; 973 case STATE_LIGHTPROD: 974 append_index(str, state[1]); /* light number [i]. */ 975 append_face(str, state[2]); 976 append_token(str, state[3]); 977 break; 978 case STATE_TEXGEN: 979 append_index(str, state[1]); /* tex unit [i] */ 980 append_token(str, state[2]); /* plane coef */ 981 break; 982 case STATE_TEXENV_COLOR: 983 append_index(str, state[1]); /* tex unit [i] */ 984 append(str, "color"); 985 break; 986 case STATE_CLIPPLANE: 987 append_index(str, state[1]); /* plane [i] */ 988 append(str, ".plane"); 989 break; 990 case STATE_MODELVIEW_MATRIX: 991 case STATE_PROJECTION_MATRIX: 992 case STATE_MVP_MATRIX: 993 case STATE_TEXTURE_MATRIX: 994 case STATE_PROGRAM_MATRIX: 995 { 996 /* state[0] = modelview, projection, texture, etc. */ 997 /* state[1] = which texture matrix or program matrix */ 998 /* state[2] = first row to fetch */ 999 /* state[3] = last row to fetch */ 1000 /* state[4] = transpose, inverse or invtrans */ 1001 const gl_state_index mat = state[0]; 1002 const GLuint index = (GLuint) state[1]; 1003 const GLuint firstRow = (GLuint) state[2]; 1004 const GLuint lastRow = (GLuint) state[3]; 1005 const gl_state_index modifier = state[4]; 1006 if (index || 1007 mat == STATE_TEXTURE_MATRIX || 1008 mat == STATE_PROGRAM_MATRIX) 1009 append_index(str, index); 1010 if (modifier) 1011 append_token(str, modifier); 1012 if (firstRow == lastRow) 1013 sprintf(tmp, ".row[%d]", firstRow); 1014 else 1015 sprintf(tmp, ".row[%d..%d]", firstRow, lastRow); 1016 append(str, tmp); 1017 } 1018 break; 1019 case STATE_POINT_SIZE: 1020 break; 1021 case STATE_POINT_ATTENUATION: 1022 break; 1023 case STATE_FOG_PARAMS: 1024 break; 1025 case STATE_FOG_COLOR: 1026 break; 1027 case STATE_DEPTH_RANGE: 1028 break; 1029 case STATE_FRAGMENT_PROGRAM: 1030 case STATE_VERTEX_PROGRAM: 1031 /* state[1] = {STATE_ENV, STATE_LOCAL} */ 1032 /* state[2] = parameter index */ 1033 append_token(str, state[1]); 1034 append_index(str, state[2]); 1035 break; 1036 case STATE_NORMAL_SCALE: 1037 break; 1038 case STATE_INTERNAL: 1039 append_token(str, state[1]); 1040 if (state[1] == STATE_CURRENT_ATTRIB) 1041 append_index(str, state[2]); 1042 break; 1043 default: 1044 _mesa_problem(NULL, "Invalid state in _mesa_program_state_string"); 1045 break; 1046 } 1047 1048 return _mesa_strdup(str); 1049} 1050 1051 1052/** 1053 * Loop over all the parameters in a parameter list. If the parameter 1054 * is a GL state reference, look up the current value of that state 1055 * variable and put it into the parameter's Value[4] array. 1056 * Other parameter types never change or are explicitly set by the user 1057 * with glUniform() or glProgramParameter(), etc. 1058 * This would be called at glBegin time. 1059 */ 1060void 1061_mesa_load_state_parameters(struct gl_context *ctx, 1062 struct gl_program_parameter_list *paramList) 1063{ 1064 GLuint i; 1065 1066 if (!paramList) 1067 return; 1068 1069 for (i = 0; i < paramList->NumParameters; i++) { 1070 if (paramList->Parameters[i].Type == PROGRAM_STATE_VAR) { 1071 _mesa_fetch_state(ctx, 1072 paramList->Parameters[i].StateIndexes, 1073 ¶mList->ParameterValues[i][0].f); 1074 } 1075 } 1076} 1077 1078 1079/** 1080 * Copy the 16 elements of a matrix into four consecutive program 1081 * registers starting at 'pos'. 1082 */ 1083static void 1084load_matrix(GLfloat registers[][4], GLuint pos, const GLfloat mat[16]) 1085{ 1086 GLuint i; 1087 for (i = 0; i < 4; i++) { 1088 registers[pos + i][0] = mat[0 + i]; 1089 registers[pos + i][1] = mat[4 + i]; 1090 registers[pos + i][2] = mat[8 + i]; 1091 registers[pos + i][3] = mat[12 + i]; 1092 } 1093} 1094 1095 1096/** 1097 * As above, but transpose the matrix. 1098 */ 1099static void 1100load_transpose_matrix(GLfloat registers[][4], GLuint pos, 1101 const GLfloat mat[16]) 1102{ 1103 memcpy(registers[pos], mat, 16 * sizeof(GLfloat)); 1104} 1105 1106 1107/** 1108 * Load current vertex program's parameter registers with tracked 1109 * matrices (if NV program). This only needs to be done per 1110 * glBegin/glEnd, not per-vertex. 1111 */ 1112void 1113_mesa_load_tracked_matrices(struct gl_context *ctx) 1114{ 1115 GLuint i; 1116 1117 for (i = 0; i < MAX_NV_VERTEX_PROGRAM_PARAMS / 4; i++) { 1118 /* point 'mat' at source matrix */ 1119 GLmatrix *mat; 1120 if (ctx->VertexProgram.TrackMatrix[i] == GL_MODELVIEW) { 1121 mat = ctx->ModelviewMatrixStack.Top; 1122 } 1123 else if (ctx->VertexProgram.TrackMatrix[i] == GL_PROJECTION) { 1124 mat = ctx->ProjectionMatrixStack.Top; 1125 } 1126 else if (ctx->VertexProgram.TrackMatrix[i] == GL_TEXTURE) { 1127 GLuint unit = MIN2(ctx->Texture.CurrentUnit, 1128 Elements(ctx->TextureMatrixStack) - 1); 1129 mat = ctx->TextureMatrixStack[unit].Top; 1130 } 1131 else if (ctx->VertexProgram.TrackMatrix[i]==GL_MODELVIEW_PROJECTION_NV) { 1132 /* XXX verify the combined matrix is up to date */ 1133 mat = &ctx->_ModelProjectMatrix; 1134 } 1135 else if (ctx->VertexProgram.TrackMatrix[i] >= GL_MATRIX0_NV && 1136 ctx->VertexProgram.TrackMatrix[i] <= GL_MATRIX7_NV) { 1137 GLuint n = ctx->VertexProgram.TrackMatrix[i] - GL_MATRIX0_NV; 1138 ASSERT(n < Elements(ctx->ProgramMatrixStack)); 1139 mat = ctx->ProgramMatrixStack[n].Top; 1140 } 1141 else { 1142 /* no matrix is tracked, but we leave the register values as-is */ 1143 assert(ctx->VertexProgram.TrackMatrix[i] == GL_NONE); 1144 continue; 1145 } 1146 1147 /* load the matrix values into sequential registers */ 1148 if (ctx->VertexProgram.TrackMatrixTransform[i] == GL_IDENTITY_NV) { 1149 load_matrix(ctx->VertexProgram.Parameters, i*4, mat->m); 1150 } 1151 else if (ctx->VertexProgram.TrackMatrixTransform[i] == GL_INVERSE_NV) { 1152 _math_matrix_analyse(mat); /* update the inverse */ 1153 ASSERT(!_math_matrix_is_dirty(mat)); 1154 load_matrix(ctx->VertexProgram.Parameters, i*4, mat->inv); 1155 } 1156 else if (ctx->VertexProgram.TrackMatrixTransform[i] == GL_TRANSPOSE_NV) { 1157 load_transpose_matrix(ctx->VertexProgram.Parameters, i*4, mat->m); 1158 } 1159 else { 1160 assert(ctx->VertexProgram.TrackMatrixTransform[i] 1161 == GL_INVERSE_TRANSPOSE_NV); 1162 _math_matrix_analyse(mat); /* update the inverse */ 1163 ASSERT(!_math_matrix_is_dirty(mat)); 1164 load_transpose_matrix(ctx->VertexProgram.Parameters, i*4, mat->inv); 1165 } 1166 } 1167} 1168