📄 prog_statevars.c
字号:
/* * Mesa 3-D graphics library * Version: 7.1 * * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *//** * \file prog_statevars.c * Program state variable management. * \author Brian Paul */#include "glheader.h"#include "context.h"#include "hash.h"#include "imports.h"#include "macros.h"#include "mtypes.h"#include "prog_statevars.h"#include "prog_parameter.h"#include "nvvertparse.h"/** * Use the list of tokens in the state[] array to find global GL state * and return it in <value>. Usually, four values are returned in <value> * but matrix queries may return as many as 16 values. * This function is used for ARB vertex/fragment programs. * The program parser will produce the state[] values. */static void_mesa_fetch_state(GLcontext *ctx, const gl_state_index state[], GLfloat *value){ switch (state[0]) { case STATE_MATERIAL: { /* state[1] is either 0=front or 1=back side */ const GLuint face = (GLuint) state[1]; const struct gl_material *mat = &ctx->Light.Material; ASSERT(face == 0 || face == 1); /* we rely on tokens numbered so that _BACK_ == _FRONT_+ 1 */ ASSERT(MAT_ATTRIB_FRONT_AMBIENT + 1 == MAT_ATTRIB_BACK_AMBIENT); /* XXX we could get rid of this switch entirely with a little * work in arbprogparse.c's parse_state_single_item(). */ /* state[2] is the material attribute */ switch (state[2]) { case STATE_AMBIENT: COPY_4V(value, mat->Attrib[MAT_ATTRIB_FRONT_AMBIENT + face]); return; case STATE_DIFFUSE: COPY_4V(value, mat->Attrib[MAT_ATTRIB_FRONT_DIFFUSE + face]); return; case STATE_SPECULAR: COPY_4V(value, mat->Attrib[MAT_ATTRIB_FRONT_SPECULAR + face]); return; case STATE_EMISSION: COPY_4V(value, mat->Attrib[MAT_ATTRIB_FRONT_EMISSION + face]); return; case STATE_SHININESS: value[0] = mat->Attrib[MAT_ATTRIB_FRONT_SHININESS + face][0]; value[1] = 0.0F; value[2] = 0.0F; value[3] = 1.0F; return; default: _mesa_problem(ctx, "Invalid material state in fetch_state"); return; } } case STATE_LIGHT: { /* state[1] is the light number */ const GLuint ln = (GLuint) state[1]; /* state[2] is the light attribute */ switch (state[2]) { case STATE_AMBIENT: COPY_4V(value, ctx->Light.Light[ln].Ambient); return; case STATE_DIFFUSE: COPY_4V(value, ctx->Light.Light[ln].Diffuse); return; case STATE_SPECULAR: COPY_4V(value, ctx->Light.Light[ln].Specular); return; case STATE_POSITION: COPY_4V(value, ctx->Light.Light[ln].EyePosition); return; case STATE_ATTENUATION: value[0] = ctx->Light.Light[ln].ConstantAttenuation; value[1] = ctx->Light.Light[ln].LinearAttenuation; value[2] = ctx->Light.Light[ln].QuadraticAttenuation; value[3] = ctx->Light.Light[ln].SpotExponent; return; case STATE_SPOT_DIRECTION: COPY_3V(value, ctx->Light.Light[ln].EyeDirection); value[3] = ctx->Light.Light[ln]._CosCutoff; return; case STATE_SPOT_CUTOFF: value[0] = ctx->Light.Light[ln].SpotCutoff; return; case STATE_HALF_VECTOR: { static const GLfloat eye_z[] = {0, 0, 1}; GLfloat p[3]; /* Compute infinite half angle vector: * halfVector = normalize(normalize(lightPos) + (0, 0, 1)) * light.EyePosition.w should be 0 for infinite lights. */ COPY_3V(p, ctx->Light.Light[ln].EyePosition); NORMALIZE_3FV(p); ADD_3V(value, p, eye_z); NORMALIZE_3FV(value); value[3] = 1.0; } return; case STATE_POSITION_NORMALIZED: COPY_4V(value, ctx->Light.Light[ln].EyePosition); NORMALIZE_3FV( value ); return; default: _mesa_problem(ctx, "Invalid light state in fetch_state"); return; } } case STATE_LIGHTMODEL_AMBIENT: COPY_4V(value, ctx->Light.Model.Ambient); return; case STATE_LIGHTMODEL_SCENECOLOR: if (state[1] == 0) { /* front */ GLint i; for (i = 0; i < 3; i++) { value[i] = ctx->Light.Model.Ambient[i] * ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_AMBIENT][i] + ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_EMISSION][i]; } value[3] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE][3]; } else { /* back */ GLint i; for (i = 0; i < 3; i++) { value[i] = ctx->Light.Model.Ambient[i] * ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_AMBIENT][i] + ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_EMISSION][i]; } value[3] = ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_DIFFUSE][3]; } return; case STATE_LIGHTPROD: { const GLuint ln = (GLuint) state[1]; const GLuint face = (GLuint) state[2]; GLint i; ASSERT(face == 0 || face == 1); switch (state[3]) { case STATE_AMBIENT: for (i = 0; i < 3; i++) { value[i] = ctx->Light.Light[ln].Ambient[i] * ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_AMBIENT+face][i]; } /* [3] = material alpha */ value[3] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_AMBIENT+face][3]; return; case STATE_DIFFUSE: for (i = 0; i < 3; i++) { value[i] = ctx->Light.Light[ln].Diffuse[i] * ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE+face][i]; } /* [3] = material alpha */ value[3] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE+face][3]; return; case STATE_SPECULAR: for (i = 0; i < 3; i++) { value[i] = ctx->Light.Light[ln].Specular[i] * ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_SPECULAR+face][i]; } /* [3] = material alpha */ value[3] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_SPECULAR+face][3]; return; default: _mesa_problem(ctx, "Invalid lightprod state in fetch_state"); return; } } case STATE_TEXGEN: { /* state[1] is the texture unit */ const GLuint unit = (GLuint) state[1]; /* state[2] is the texgen attribute */ switch (state[2]) { case STATE_TEXGEN_EYE_S: COPY_4V(value, ctx->Texture.Unit[unit].EyePlaneS); return; case STATE_TEXGEN_EYE_T: COPY_4V(value, ctx->Texture.Unit[unit].EyePlaneT); return; case STATE_TEXGEN_EYE_R: COPY_4V(value, ctx->Texture.Unit[unit].EyePlaneR); return; case STATE_TEXGEN_EYE_Q: COPY_4V(value, ctx->Texture.Unit[unit].EyePlaneQ); return; case STATE_TEXGEN_OBJECT_S: COPY_4V(value, ctx->Texture.Unit[unit].ObjectPlaneS); return; case STATE_TEXGEN_OBJECT_T: COPY_4V(value, ctx->Texture.Unit[unit].ObjectPlaneT); return; case STATE_TEXGEN_OBJECT_R: COPY_4V(value, ctx->Texture.Unit[unit].ObjectPlaneR); return; case STATE_TEXGEN_OBJECT_Q: COPY_4V(value, ctx->Texture.Unit[unit].ObjectPlaneQ); return; default: _mesa_problem(ctx, "Invalid texgen state in fetch_state"); return; } } case STATE_TEXENV_COLOR: { /* state[1] is the texture unit */ const GLuint unit = (GLuint) state[1]; COPY_4V(value, ctx->Texture.Unit[unit].EnvColor); } return; case STATE_FOG_COLOR: COPY_4V(value, ctx->Fog.Color); return; case STATE_FOG_PARAMS: value[0] = ctx->Fog.Density; value[1] = ctx->Fog.Start; value[2] = ctx->Fog.End; value[3] = (ctx->Fog.End == ctx->Fog.Start) ? 1.0f : (GLfloat)(1.0 / (ctx->Fog.End - ctx->Fog.Start)); return; case STATE_CLIPPLANE: { const GLuint plane = (GLuint) state[1]; COPY_4V(value, ctx->Transform.EyeUserPlane[plane]); } return; case STATE_POINT_SIZE: value[0] = ctx->Point.Size; value[1] = ctx->Point.MinSize; value[2] = ctx->Point.MaxSize; value[3] = ctx->Point.Threshold; return; case STATE_POINT_ATTENUATION: value[0] = ctx->Point.Params[0]; value[1] = ctx->Point.Params[1]; value[2] = ctx->Point.Params[2]; value[3] = 1.0F; return; case STATE_MODELVIEW_MATRIX: case STATE_PROJECTION_MATRIX: case STATE_MVP_MATRIX: case STATE_TEXTURE_MATRIX: case STATE_PROGRAM_MATRIX: case STATE_COLOR_MATRIX: { /* state[0] = modelview, projection, texture, etc. */ /* state[1] = which texture matrix or program matrix */ /* state[2] = first row to fetch */ /* state[3] = last row to fetch */ /* state[4] = transpose, inverse or invtrans */ const GLmatrix *matrix; const gl_state_index mat = state[0]; const GLuint index = (GLuint) state[1]; const GLuint firstRow = (GLuint) state[2]; const GLuint lastRow = (GLuint) state[3]; const gl_state_index modifier = state[4]; const GLfloat *m; GLuint row, i; ASSERT(firstRow >= 0); ASSERT(firstRow < 4); ASSERT(lastRow >= 0); ASSERT(lastRow < 4); if (mat == STATE_MODELVIEW_MATRIX) { matrix = ctx->ModelviewMatrixStack.Top; } else if (mat == STATE_PROJECTION_MATRIX) { matrix = ctx->ProjectionMatrixStack.Top; } else if (mat == STATE_MVP_MATRIX) { matrix = &ctx->_ModelProjectMatrix; } else if (mat == STATE_TEXTURE_MATRIX) { matrix = ctx->TextureMatrixStack[index].Top; } else if (mat == STATE_PROGRAM_MATRIX) { matrix = ctx->ProgramMatrixStack[index].Top; } else if (mat == STATE_COLOR_MATRIX) { matrix = ctx->ColorMatrixStack.Top; } else { _mesa_problem(ctx, "Bad matrix name in _mesa_fetch_state()"); return; } if (modifier == STATE_MATRIX_INVERSE || modifier == STATE_MATRIX_INVTRANS) { /* Be sure inverse is up to date: */ _math_matrix_alloc_inv( (GLmatrix *) matrix );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -