📄 arbprogparse.c
字号:
if (state_tokens[1] >= (GLint) ctx->Const.MaxLights) { program_error(ctx, Program->Position, "Invalid Light Number"); /* bad state_tokens[1] */ return 1; } state_tokens[2] = parse_face_type (inst); switch (*(*inst)++) { case LIGHT_PROD_AMBIENT: state_tokens[3] = STATE_AMBIENT; break; case LIGHT_PROD_DIFFUSE: state_tokens[3] = STATE_DIFFUSE; break; case LIGHT_PROD_SPECULAR: state_tokens[3] = STATE_SPECULAR; break; } break; case STATE_FOG: switch (*(*inst)++) { case FOG_COLOR: state_tokens[0] = STATE_FOG_COLOR; break; case FOG_PARAMS: state_tokens[0] = STATE_FOG_PARAMS; break; } break; case STATE_TEX_ENV: state_tokens[1] = parse_integer (inst, Program); switch (*(*inst)++) { case TEX_ENV_COLOR: state_tokens[0] = STATE_TEXENV_COLOR; break; } break; case STATE_TEX_GEN: { GLuint type, coord; state_tokens[0] = STATE_TEXGEN; /*state_tokens[1] = parse_integer (inst, Program);*/ /* Texture Unit */ if (parse_texcoord_num (ctx, inst, Program, &coord)) return 1; state_tokens[1] = coord; /* EYE or OBJECT */ type = *(*inst)++; /* 0 - s, 1 - t, 2 - r, 3 - q */ coord = *(*inst)++; if (type == TEX_GEN_EYE) { switch (coord) { case COMPONENT_X: state_tokens[2] = STATE_TEXGEN_EYE_S; break; case COMPONENT_Y: state_tokens[2] = STATE_TEXGEN_EYE_T; break; case COMPONENT_Z: state_tokens[2] = STATE_TEXGEN_EYE_R; break; case COMPONENT_W: state_tokens[2] = STATE_TEXGEN_EYE_Q; break; default: _mesa_problem(ctx, "bad texgen component in " "parse_state_single_item()"); } } else { switch (coord) { case COMPONENT_X: state_tokens[2] = STATE_TEXGEN_OBJECT_S; break; case COMPONENT_Y: state_tokens[2] = STATE_TEXGEN_OBJECT_T; break; case COMPONENT_Z: state_tokens[2] = STATE_TEXGEN_OBJECT_R; break; case COMPONENT_W: state_tokens[2] = STATE_TEXGEN_OBJECT_Q; break; default: _mesa_problem(ctx, "bad texgen component in " "parse_state_single_item()"); } } } break; case STATE_DEPTH: switch (*(*inst)++) { case DEPTH_RANGE: state_tokens[0] = STATE_DEPTH_RANGE; break; } break; case STATE_CLIP_PLANE: state_tokens[0] = STATE_CLIPPLANE; if (parse_clipplane_num (ctx, inst, Program, (GLint *) &state_tokens[1])) return 1; break; case STATE_POINT: switch (*(*inst)++) { case POINT_SIZE: state_tokens[0] = STATE_POINT_SIZE; break; case POINT_ATTENUATION: state_tokens[0] = STATE_POINT_ATTENUATION; break; } break; /* XXX: I think this is the correct format for a matrix row */ case STATE_MATRIX_ROWS: if (parse_matrix(ctx, inst, Program, (GLint *) &state_tokens[0], (GLint *) &state_tokens[1], (GLint *) &state_tokens[4])) return 1; state_tokens[2] = parse_integer (inst, Program); /* The first row to grab */ if ((**inst) != 0) { /* Either the last row, 0 */ state_tokens[3] = parse_integer (inst, Program); if (state_tokens[3] < state_tokens[2]) { program_error(ctx, Program->Position, "Second matrix index less than the first"); /* state_tokens[4] vs. state_tokens[3] */ return 1; } } else { state_tokens[3] = state_tokens[2]; (*inst)++; } break; } return 0;}/** * This parses a state string (rather, the binary version of it) into * a 6-token similar for the state fetching code in program.c * * One might ask, why fetch these parameters into just like you fetch * state when they are already stored in other places? * * Because of array offsets -> We can stick env/local parameters in the * middle of a parameter array and then index someplace into the array * when we execute. * * One optimization might be to only do this for the cases where the * env/local parameters end up inside of an array, and leave the * single parameters (or arrays of pure env/local pareameters) in their * respective register files. * * For ENV parameters, the format is: * state_tokens[0] = STATE_FRAGMENT_PROGRAM / STATE_VERTEX_PROGRAM * state_tokens[1] = STATE_ENV * state_tokens[2] = the parameter index * * for LOCAL parameters, the format is: * state_tokens[0] = STATE_FRAGMENT_PROGRAM / STATE_VERTEX_PROGRAM * state_tokens[1] = STATE_LOCAL * state_tokens[2] = the parameter index * * \param inst - the start in the binary arry to start working from * \param state_tokens - the storage for the 6-token state description * \return - 0 on sucess, 1 on failure */static GLuintparse_program_single_item (GLcontext * ctx, const GLubyte ** inst, struct arb_program *Program, gl_state_index state_tokens[STATE_LENGTH]){ if (Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) state_tokens[0] = STATE_FRAGMENT_PROGRAM; else state_tokens[0] = STATE_VERTEX_PROGRAM; switch (*(*inst)++) { case PROGRAM_PARAM_ENV: state_tokens[1] = STATE_ENV; state_tokens[2] = parse_integer (inst, Program); /* Check state_tokens[2] against the number of ENV parameters available */ if (((Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) && (state_tokens[2] >= (GLint) ctx->Const.FragmentProgram.MaxEnvParams)) || ((Program->Base.Target == GL_VERTEX_PROGRAM_ARB) && (state_tokens[2] >= (GLint) ctx->Const.VertexProgram.MaxEnvParams))) { program_error(ctx, Program->Position, "Invalid Program Env Parameter"); /* bad state_tokens[2] */ return 1; } break; case PROGRAM_PARAM_LOCAL: state_tokens[1] = STATE_LOCAL; state_tokens[2] = parse_integer (inst, Program); /* Check state_tokens[2] against the number of LOCAL parameters available */ if (((Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) && (state_tokens[2] >= (GLint) ctx->Const.FragmentProgram.MaxLocalParams)) || ((Program->Base.Target == GL_VERTEX_PROGRAM_ARB) && (state_tokens[2] >= (GLint) ctx->Const.VertexProgram.MaxLocalParams))) { program_error(ctx, Program->Position, "Invalid Program Local Parameter"); /* bad state_tokens[2] */ return 1; } break; } return 0;}/** * For ARB_vertex_program, programs are not allowed to use both an explicit * vertex attribute and a generic vertex attribute corresponding to the same * state. See section 2.14.3.1 of the GL_ARB_vertex_program spec. * * This will walk our var_cache and make sure that nobody does anything fishy. * * \return 0 on sucess, 1 on error */static GLuintgeneric_attrib_check(struct var_cache *vc_head){ int a; struct var_cache *curr; GLboolean explicitAttrib[MAX_VERTEX_PROGRAM_ATTRIBS], genericAttrib[MAX_VERTEX_PROGRAM_ATTRIBS]; for (a=0; a<MAX_VERTEX_PROGRAM_ATTRIBS; a++) { explicitAttrib[a] = GL_FALSE; genericAttrib[a] = GL_FALSE; } curr = vc_head; while (curr) { if (curr->type == vt_attrib) { if (curr->attrib_is_generic) genericAttrib[ curr->attrib_binding ] = GL_TRUE; else explicitAttrib[ curr->attrib_binding ] = GL_TRUE; } curr = curr->next; } for (a=0; a<MAX_VERTEX_PROGRAM_ATTRIBS; a++) { if ((explicitAttrib[a]) && (genericAttrib[a])) return 1; } return 0;}/** * This will handle the binding side of an ATTRIB var declaration * * \param inputReg returns the input register index, one of the * VERT_ATTRIB_* or FRAG_ATTRIB_* values. * \return returns 0 on success, 1 on error */static GLuintparse_attrib_binding(GLcontext * ctx, const GLubyte ** inst, struct arb_program *Program, GLuint *inputReg, GLuint *is_generic){ GLint err = 0; *is_generic = 0; if (Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) { switch (*(*inst)++) { case FRAGMENT_ATTRIB_COLOR: { GLint coord; err = parse_color_type (ctx, inst, Program, &coord); *inputReg = FRAG_ATTRIB_COL0 + coord; } break; case FRAGMENT_ATTRIB_TEXCOORD: { GLuint texcoord = 0; err = parse_texcoord_num (ctx, inst, Program, &texcoord); *inputReg = FRAG_ATTRIB_TEX0 + texcoord; } break; case FRAGMENT_ATTRIB_FOGCOORD: *inputReg = FRAG_ATTRIB_FOGC; break; case FRAGMENT_ATTRIB_POSITION: *inputReg = FRAG_ATTRIB_WPOS; break; default: err = 1; break; } } else { switch (*(*inst)++) { case VERTEX_ATTRIB_POSITION: *inputReg = VERT_ATTRIB_POS; break; case VERTEX_ATTRIB_WEIGHT: { GLint weight; err = parse_weight_num (ctx, inst, Program, &weight); *inputReg = VERT_ATTRIB_WEIGHT;#if 1 /* hack for Warcraft (see bug 8060) */ _mesa_warning(ctx, "Application error: vertex program uses 'vertex.weight' but GL_ARB_vertex_blend not supported."); break;#else program_error(ctx, Program->Position, "ARB_vertex_blend not supported"); return 1;#endif } case VERTEX_ATTRIB_NORMAL: *inputReg = VERT_ATTRIB_NORMAL; break; case VERTEX_ATTRIB_COLOR: { GLint color; err = parse_color_type (ctx, inst, Program, &color); if (color) { *inputReg = VERT_ATTRIB_COLOR1; } else { *inputReg = VERT_ATTRIB_COLOR0; } } break; case VERTEX_ATTRIB_FOGCOORD: *inputReg = VERT_ATTRIB_FOG; break; case VERTEX_ATTRIB_TEXCOORD: { GLuint unit = 0; err = parse_texcoord_num (ctx, inst, Program, &unit); *inputReg = VERT_ATTRIB_TEX0 + unit; } break; case VERTEX_ATTRIB_MATRIXINDEX: /* Not supported at this time */ { const char *msg = "ARB_palette_matrix not supported"; parse_integer (inst, Program); program_error(ctx, Program->Position, msg); } return 1; case VERTEX_ATTRIB_GENERIC: { GLuint attrib; err = parse_generic_attrib_num(ctx, inst, Program, &attrib); if (!err) { *is_generic = 1; /* Add VERT_ATTRIB_GENERIC0 here because ARB_vertex_program's * attributes do not alias the conventional vertex * attributes. */ if (attrib > 0) *inputReg = attrib + VERT_ATTRIB_GENERIC0; else *inputReg = 0; } } break; default: err = 1; break; } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -