⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 arbprogparse.c

📁 Mesa is an open-source implementation of the OpenGL specification - a system for rendering interacti
💻 C
📖 第 1 页 / 共 5 页
字号:
         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 + -