📄 arbprogparse.c
字号:
#define MATRIX_TEXTURE 0x04#define MATRIX_PALETTE 0x05#define MATRIX_PROGRAM 0x06/* matrix modifier */#define MATRIX_MODIFIER_IDENTITY 0x00#define MATRIX_MODIFIER_INVERSE 0x01#define MATRIX_MODIFIER_TRANSPOSE 0x02#define MATRIX_MODIFIER_INVTRANS 0x03/* constant type */#define CONSTANT_SCALAR 0x01#define CONSTANT_VECTOR 0x02/* program param type */#define PROGRAM_PARAM_ENV 0x01#define PROGRAM_PARAM_LOCAL 0x02/* register type */#define REGISTER_ATTRIB 0x01#define REGISTER_PARAM 0x02#define REGISTER_RESULT 0x03#define REGISTER_ESTABLISHED_NAME 0x04/* param binding */#define PARAM_NULL 0x00#define PARAM_ARRAY_ELEMENT 0x01#define PARAM_STATE_ELEMENT 0x02#define PARAM_PROGRAM_ELEMENT 0x03#define PARAM_PROGRAM_ELEMENTS 0x04#define PARAM_CONSTANT 0x05/* param state property */#define STATE_MATERIAL_PARSER 0x01#define STATE_LIGHT_PARSER 0x02#define STATE_LIGHT_MODEL 0x03#define STATE_LIGHT_PROD 0x04#define STATE_FOG 0x05#define STATE_MATRIX_ROWS 0x06/* GL_ARB_fragment_program */#define STATE_TEX_ENV 0x07#define STATE_DEPTH 0x08/* GL_ARB_vertex_program */#define STATE_TEX_GEN 0x09#define STATE_CLIP_PLANE 0x0A#define STATE_POINT 0x0B/* state material property */#define MATERIAL_AMBIENT 0x01#define MATERIAL_DIFFUSE 0x02#define MATERIAL_SPECULAR 0x03#define MATERIAL_EMISSION 0x04#define MATERIAL_SHININESS 0x05/* state light property */#define LIGHT_AMBIENT 0x01#define LIGHT_DIFFUSE 0x02#define LIGHT_SPECULAR 0x03#define LIGHT_POSITION 0x04#define LIGHT_ATTENUATION 0x05#define LIGHT_HALF 0x06#define LIGHT_SPOT_DIRECTION 0x07/* state light model property */#define LIGHT_MODEL_AMBIENT 0x01#define LIGHT_MODEL_SCENECOLOR 0x02/* state light product property */#define LIGHT_PROD_AMBIENT 0x01#define LIGHT_PROD_DIFFUSE 0x02#define LIGHT_PROD_SPECULAR 0x03/* state texture environment property */#define TEX_ENV_COLOR 0x01/* state texture generation coord property */#define TEX_GEN_EYE 0x01#define TEX_GEN_OBJECT 0x02/* state fog property */#define FOG_COLOR 0x01#define FOG_PARAMS 0x02/* state depth property */#define DEPTH_RANGE 0x01/* state point parameters property */#define POINT_SIZE 0x01#define POINT_ATTENUATION 0x02/* declaration */#define ATTRIB 0x01#define PARAM 0x02#define TEMP 0x03#define OUTPUT 0x04#define ALIAS 0x05/* GL_ARB_vertex_program */#define ADDRESS 0x06/*----------------------------------------------------------------------- * From here on down is the semantic checking portion * *//** * Variable Table Handling functions */typedef enum{ vt_none, vt_address, vt_attrib, vt_param, vt_temp, vt_output, vt_alias} var_type;/** * Setting an explicit field for each of the binding properties is a bit * wasteful of space, but it should be much more clear when reading later on.. */struct var_cache{ const GLubyte *name; /* don't free() - no need */ var_type type; GLuint address_binding; /* The index of the address register we should * be using */ GLuint attrib_binding; /* For type vt_attrib, see nvfragprog.h for values */ GLuint attrib_is_generic; /* If the attrib was specified through a generic * vertex attrib */ GLuint temp_binding; /* The index of the temp register we are to use */ GLuint output_binding; /* Output/result register number */ struct var_cache *alias_binding; /* For type vt_alias, points to the var_cache entry * that this is aliased to */ GLuint param_binding_type; /* {PROGRAM_STATE_VAR, PROGRAM_LOCAL_PARAM, * PROGRAM_ENV_PARAM} */ GLuint param_binding_begin; /* This is the offset into the program_parameter_list where * the tokens representing our bound state (or constants) * start */ GLuint param_binding_length; /* This is how many entries in the the program_parameter_list * we take up with our state tokens or constants. Note that * this is _not_ the same as the number of param registers * we eventually use */ struct var_cache *next;};static GLvoidvar_cache_create (struct var_cache **va){ *va = (struct var_cache *) _mesa_malloc (sizeof (struct var_cache)); if (*va) { (**va).name = NULL; (**va).type = vt_none; (**va).attrib_binding = ~0; (**va).attrib_is_generic = 0; (**va).temp_binding = ~0; (**va).output_binding = ~0; (**va).param_binding_type = ~0; (**va).param_binding_begin = ~0; (**va).param_binding_length = ~0; (**va).alias_binding = NULL; (**va).next = NULL; }}static GLvoidvar_cache_destroy (struct var_cache **va){ if (*va) { var_cache_destroy (&(**va).next); _mesa_free (*va); *va = NULL; }}static GLvoidvar_cache_append (struct var_cache **va, struct var_cache *nv){ if (*va) var_cache_append (&(**va).next, nv); else *va = nv;}static struct var_cache *var_cache_find (struct var_cache *va, const GLubyte * name){ /*struct var_cache *first = va;*/ while (va) { if (!_mesa_strcmp ( (const char*) name, (const char*) va->name)) { if (va->type == vt_alias) return va->alias_binding; return va; } va = va->next; } return NULL;}/** * Called when an error is detected while parsing/compiling a program. * Sets the ctx->Program.ErrorString field to descript and records a * GL_INVALID_OPERATION error. * \param position position of error in program string * \param descrip verbose error description */static voidprogram_error(GLcontext *ctx, GLint position, const char *descrip){ if (descrip) { const char *prefix = "glProgramString(", *suffix = ")"; char *str = (char *) _mesa_malloc(_mesa_strlen(descrip) + _mesa_strlen(prefix) + _mesa_strlen(suffix) + 1); if (str) { _mesa_sprintf(str, "%s%s%s", prefix, descrip, suffix); _mesa_error(ctx, GL_INVALID_OPERATION, str); _mesa_free(str); } } _mesa_set_program_error(ctx, position, descrip);}/** * As above, but with an extra string parameter for more info. */static voidprogram_error2(GLcontext *ctx, GLint position, const char *descrip, const char *var){ if (descrip) { const char *prefix = "glProgramString(", *suffix = ")"; char *str = (char *) _mesa_malloc(_mesa_strlen(descrip) + _mesa_strlen(": ") + _mesa_strlen(var) + _mesa_strlen(prefix) + _mesa_strlen(suffix) + 1); if (str) { _mesa_sprintf(str, "%s%s: %s%s", prefix, descrip, var, suffix); _mesa_error(ctx, GL_INVALID_OPERATION, str); _mesa_free(str); } } { char *str = (char *) _mesa_malloc(_mesa_strlen(descrip) + _mesa_strlen(": ") + _mesa_strlen(var) + 1); if (str) { _mesa_sprintf(str, "%s: %s", descrip, var); } _mesa_set_program_error(ctx, position, str); if (str) { _mesa_free(str); } }}/** * constructs an integer from 4 GLubytes in LE format */static GLuintparse_position (const GLubyte ** inst){ GLuint value; value = (GLuint) (*(*inst)++); value += (GLuint) (*(*inst)++) * 0x100; value += (GLuint) (*(*inst)++) * 0x10000; value += (GLuint) (*(*inst)++) * 0x1000000; return value;}/** * This will, given a string, lookup the string as a variable name in the * var cache. If the name is found, the var cache node corresponding to the * var name is returned. If it is not found, a new entry is allocated * * \param I Points into the binary array where the string identifier begins * \param found 1 if the string was found in the var_cache, 0 if it was allocated * \return The location on the var_cache corresponding the the string starting at I */static struct var_cache *parse_string (const GLubyte ** inst, struct var_cache **vc_head, struct arb_program *Program, GLuint * found){ const GLubyte *i = *inst; struct var_cache *va = NULL; (void) Program; *inst += _mesa_strlen ((char *) i) + 1; va = var_cache_find (*vc_head, i); if (va) { *found = 1; return va; } *found = 0; var_cache_create (&va); va->name = (const GLubyte *) i; var_cache_append (vc_head, va); return va;}static char *parse_string_without_adding (const GLubyte ** inst, struct arb_program *Program){ const GLubyte *i = *inst; (void) Program; *inst += _mesa_strlen ((char *) i) + 1; return (char *) i;}/** * \return -1 if we parse '-', return 1 otherwise */static GLintparse_sign (const GLubyte ** inst){ /*return *(*inst)++ != '+'; */ if (**inst == '-') { (*inst)++; return -1; } else if (**inst == '+') { (*inst)++; return 1; } return 1;}/** * parses and returns signed integer */static GLintparse_integer (const GLubyte ** inst, struct arb_program *Program){ GLint sign; GLint value; /* check if *inst points to '+' or '-' * if yes, grab the sign and increment *inst */ sign = parse_sign (inst); /* now check if *inst points to 0 * if yes, increment the *inst and return the default value */ if (**inst == 0) { (*inst)++; return 0; } /* parse the integer as you normally would do it */ value = _mesa_atoi (parse_string_without_adding (inst, Program)); /* now, after terminating 0 there is a position * to parse it - parse_position() */ Program->Position = parse_position (inst); return value * sign;}/** Accumulate this string of digits, and return them as a large integer represented in floating point (for range). If scale is not NULL, also accumulates a power-of-ten integer scale factor that represents the number of digits in the string.*/static GLdoubleparse_float_string(const GLubyte ** inst, struct arb_program *Program, GLdouble *scale){ GLdouble value = 0.0; GLdouble oscale = 1.0; if (**inst == 0) { /* this string of digits is empty-- do nothing */ (*inst)++; } else { /* nonempty string-- parse out the digits */ while (**inst >= '0' && **inst <= '9') { GLubyte digit = *((*inst)++); value = value * 10.0 + (GLint) (digit - '0'); oscale *= 10.0; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -