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

📄 arbprogparse.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 5 页
字号:
#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
{
   GLubyte *name;
   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_binding_idx;   /* The index into the attrib register file corresponding
                                 * to the state in attrib_binding                  */
   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;       /* For type vt_output, see nvfragprog.h for values */
   GLuint output_binding_idx;   /* This is the index into the result register file
                                 * corresponding to the bound result state         */
   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 GLvoid
var_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).output_binding_idx = ~0;
      (**va).param_binding_type = ~0;
      (**va).param_binding_begin = ~0;
      (**va).param_binding_length = ~0;
      (**va).alias_binding = NULL;
      (**va).next = NULL;
   }
}

static GLvoid
var_cache_destroy (struct var_cache **va)
{
   if (*va) {
      var_cache_destroy (&(**va).next);
      _mesa_free (*va);
      *va = NULL;
   }
}

static GLvoid
var_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, GLubyte * name)
{
   /*struct var_cache *first = va;*/

   while (va) {
      if (!strcmp ( (const char*) name, (const char*) va->name)) {
         if (va->type == vt_alias)
            return va->alias_binding;
         return va;
      }

      va = va->next;
   }

   return NULL;
}

/**
 * constructs an integer from 4 GLubytes in LE format
 */
static GLuint
parse_position (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 (GLubyte ** inst, struct var_cache **vc_head,
              struct arb_program *Program, GLuint * found)
{
   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 = i;

   var_cache_append (vc_head, va);

   return va;
}

static char *
parse_string_without_adding (GLubyte ** inst, struct arb_program *Program)
{
   GLubyte *i = *inst;
   (void) Program;
   
   *inst += _mesa_strlen ((char *) i) + 1;

   return (char *) i;
}

/**
 * \return -1 if we parse '-', return 1 otherwise
 */
static GLint
parse_sign (GLubyte ** inst)
{
   /*return *(*inst)++ != '+'; */

   if (**inst == '-') {
      (*inst)++;
      return -1;
   }
   else if (**inst == '+') {
      (*inst)++;
      return 1;
   }

   return 1;
}

/**
 * parses and returns signed integer
 */
static GLint
parse_integer (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 GLdouble
parse_float_string(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;
      }
      assert(**inst == 0); /* integer string should end with 0 */
      (*inst)++; /* skip over terminating 0 */
      Program->Position = parse_position(inst); /* skip position (from integer) */
   }
   if (scale)
      *scale = oscale;
   return value;
}

/**
  Parse an unsigned floating-point number from this stream of tokenized
  characters.  Example floating-point formats supported:
     12.34
     12
     0.34
     .34
     12.34e-4
 */
static GLfloat
parse_float (GLubyte ** inst, struct arb_program *Program)
{
   GLint exponent;
   GLdouble whole, fraction, fracScale = 1.0;

   whole = parse_float_string(inst, Program, 0);
   fraction = parse_float_string(inst, Program, &fracScale);
   
   /* Parse signed exponent */
   exponent = parse_integer(inst, Program);   /* This is the exponent */

   /* Assemble parts of floating-point number: */
   return (GLfloat) ((whole + fraction / fracScale) *
                     _mesa_pow(10.0, (GLfloat) exponent));
}


/**
 */
static GLfloat
parse_signed_float (GLubyte ** inst, struct arb_program *Program)
{
   GLint sign = parse_sign (inst);
   GLfloat value = parse_float (inst, Program);
   return value * sign;
}

/**
 * This picks out a constant value from the parsed array. The constant vector is r
 * returned in the *values array, which should be of length 4.
 *
 * \param values - The 4 component vector with the constant value in it
 */
static GLvoid
parse_constant (GLubyte ** inst, GLfloat *values, struct arb_program *Program,
                GLboolean use)
{
   GLuint components, i;


   switch (*(*inst)++) {
      case CONSTANT_SCALAR:
         if (use == GL_TRUE) {
            values[0] =

⌨️ 快捷键说明

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