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

📄 arbprogparse.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 5 页
字号:
               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;
               }
            }
            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;
               }
            }
         }
         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;
         state_tokens[1] = parse_integer (inst, Program);
         if (parse_clipplane_num (ctx, inst, Program, &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:
         state_tokens[0] = STATE_MATRIX;
         if (parse_matrix
             (ctx, inst, Program, &state_tokens[1], &state_tokens[2],
              &state_tokens[5]))
            return 1;

         state_tokens[3] = parse_integer (inst, Program);       /* The first row to grab */

         if ((**inst) != 0) {                                   /* Either the last row, 0 */
            state_tokens[4] = parse_integer (inst, Program);
            if (state_tokens[4] < state_tokens[3]) {
               _mesa_set_program_error (ctx, Program->Position,
                     "Second matrix index less than the first");
               _mesa_error (ctx, GL_INVALID_OPERATION,
                     "Second matrix index (%d) less than the first (%d)",
                     state_tokens[4], state_tokens[3]);
               return 1;
            }
         }
         else {
            state_tokens[4] = state_tokens[3];
            (*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 GLuint
parse_program_single_item (GLcontext * ctx, GLubyte ** inst,
                           struct arb_program *Program, GLint * state_tokens)
{
   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.MaxFragmentProgramEnvParams))
             ||
             ((Program->Base.Target == GL_VERTEX_PROGRAM_ARB) &&
              (state_tokens[2] >= (GLint) ctx->Const.MaxVertexProgramEnvParams))) {
            _mesa_set_program_error (ctx, Program->Position,
                                     "Invalid Program Env Parameter");
            _mesa_error (ctx, GL_INVALID_OPERATION,
                         "Invalid Program Env Parameter: %d",
                         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.MaxFragmentProgramLocalParams))
             ||
             ((Program->Base.Target == GL_VERTEX_PROGRAM_ARB) &&
              (state_tokens[2] >= (GLint) ctx->Const.MaxVertexProgramLocalParams))) {
            _mesa_set_program_error (ctx, Program->Position,
                                     "Invalid Program Local Parameter");
            _mesa_error (ctx, GL_INVALID_OPERATION,
                         "Invalid Program Local Parameter: %d",
                         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 GLuint
generic_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_idx ] = GL_TRUE;
         else
            explicitAttrib[ curr->attrib_binding_idx ] = 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 binding     - the fragment input register state, defined in nvfragprog.h
 * \param binding_idx - the index in the attrib register file that binding is associated with
 * \return returns 0 on sucess, 1 on error
 *
 * See nvfragparse.c for attrib register file layout
 */
static GLuint
parse_attrib_binding (GLcontext * ctx, GLubyte ** inst,
                      struct arb_program *Program, GLuint * binding,
                      GLuint * binding_idx, GLuint *is_generic)
{
   GLuint texcoord;
   GLint coord;
   GLint err = 0;

   *is_generic = 0;
   if (Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) {
      switch (*(*inst)++) {
         case FRAGMENT_ATTRIB_COLOR:
            err = parse_color_type (ctx, inst, Program, &coord);
            *binding = FRAG_ATTRIB_COL0 + coord;
            *binding_idx = 1 + coord;
            break;

         case FRAGMENT_ATTRIB_TEXCOORD:
            err = parse_texcoord_num (ctx, inst, Program, &texcoord);
            *binding = FRAG_ATTRIB_TEX0 + texcoord;
            *binding_idx = 4 + texcoord;
            break;

         case FRAGMENT_ATTRIB_FOGCOORD:
            *binding = FRAG_ATTRIB_FOGC;
            *binding_idx = 3;
            break;

         case FRAGMENT_ATTRIB_POSITION:
            *binding = FRAG_ATTRIB_WPOS;
            *binding_idx = 0;
            break;

         default:
            err = 1;
            break;
      }
   }
   else {
      switch (*(*inst)++) {
         case VERTEX_ATTRIB_POSITION:
            *binding = VERT_ATTRIB_POS;
            *binding_idx = 0;
            break;

         case VERTEX_ATTRIB_WEIGHT:
            {
               GLint weight;

               err = parse_weight_num (ctx, inst, Program, &weight);
               *binding = VERT_ATTRIB_WEIGHT;
               *binding_idx = 1;
            }
            _mesa_set_program_error (ctx, Program->Position,
                 "ARB_vertex_blend not supported\n");
            _mesa_error (ctx, GL_INVALID_OPERATION,
                 "ARB_vertex_blend not supported\n");
            return 1;
            break;

         case VERTEX_ATTRIB_NORMAL:
            *binding = VERT_ATTRIB_NORMAL;
            *binding_idx = 2;
            break;

         case VERTEX_ATTRIB_COLOR:
            {
               GLint color;

               err = parse_color_type (ctx, inst, Program, &color);
               if (color) {
                  *binding = VERT_ATTRIB_COLOR1;
                  *binding_idx = 4;
               }
               else {
                  *binding = VERT_ATTRIB_COLOR0;
                  *binding_idx = 3;
               }
            }
            break;

         case VERTEX_ATTRIB_FOGCOORD:
            *binding = VERT_ATTRIB_FOG;
            *binding_idx = 5;
            break;

         case VERTEX_ATTRIB_TEXCOORD:
            {
               GLuint unit;

               err = parse_texcoord_num (ctx, inst, Program, &unit);
               *binding = VERT_ATTRIB_TEX0 + unit;
               *binding_idx = 8 + unit;
            }
            break;

            /* It looks like we don't support this at all, atm */
         case VERTEX_ATTRIB_MATRIXINDEX:
            parse_integer (inst, Program);
            _mesa_set_program_error (ctx, Program->Position,
                  "ARB_palette_matrix not supported");
            _mesa_error (ctx, GL_INVALID_OPERATION,
                  "ARB_palette_matrix not supported");
            return 1;
            break;

         case VERTEX_ATTRIB_GENERIC:
            {
               GLuint attrib;

               if (!parse_generic_attrib_num(ctx, inst, Program, &attrib)) {
                  *is_generic = 1;
                  switch (attrib) {
                     case 0:
                        *binding = VERT_ATTRIB_POS;
                        break;
                     case 1:
                        *binding = VERT_ATTRIB_WEIGHT;
                        break;
                     case 2:
                        *binding = VERT_ATTRIB_NORMAL;
                        break;
                     case 3:
                        *binding = VERT_ATTRIB_COLOR0;
                        break;
                     case 4:
                        *binding = VERT_ATTRIB_COLOR1;
                        break;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -