Example #1
0
/** Set an RGB or A combiner mode/function */
static void
set_combiner_mode(struct gl_context *ctx,
                  struct gl_texture_unit *texUnit,
                  GLenum pname, GLenum mode)
{
   GLboolean legal;

   switch (mode) {
   case GL_REPLACE:
   case GL_MODULATE:
   case GL_ADD:
   case GL_ADD_SIGNED:
   case GL_INTERPOLATE:
      legal = GL_TRUE;
      break;
   case GL_SUBTRACT:
      legal = ctx->Extensions.ARB_texture_env_combine;
      break;
   case GL_DOT3_RGB:
//   case GL_DOT3_RGBA:
      legal = (ctx->Extensions.EXT_texture_env_dot3 &&
               pname == GL_COMBINE_RGB);
      break;
//   case GL_MODULATE_ADD_ATI:
//   case GL_MODULATE_SIGNED_ADD_ATI:
//   case GL_MODULATE_SUBTRACT_ATI:
//      legal = (ctx->API == API_OPENGL_COMPAT &&
//               ctx->Extensions.ATI_texture_env_combine3);
//      break;
   default:
      legal = GL_FALSE;
   }

   if (!legal) {
      TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
      return;
   }

   switch (pname) {
   case GL_COMBINE_RGB:
      if (texUnit->Combine.ModeRGB == mode)
         return;
      FLUSH_VERTICES(ctx, _NEW_TEXTURE);
      texUnit->Combine.ModeRGB = mode;
      break;

   case GL_COMBINE_ALPHA:
      if (texUnit->Combine.ModeA == mode)
         return;
      FLUSH_VERTICES(ctx, _NEW_TEXTURE);
      texUnit->Combine.ModeA = mode;
      break;
   default:
      TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
   }
}
Example #2
0
static void
set_combiner_scale(GLcontext *ctx,
                   struct gl_texture_unit *texUnit,
                   GLenum pname, GLfloat scale)
{
   GLuint shift;

   if (!ctx->Extensions.EXT_texture_env_combine &&
       !ctx->Extensions.ARB_texture_env_combine) {
      _mesa_error(ctx, GL_INVALID_ENUM, "glTexEnv(pname)");
      return;
   }

   if (scale == 1.0F) {
      shift = 0;
   }
   else if (scale == 2.0F) {
      shift = 1;
   }
   else if (scale == 4.0F) {
      shift = 2;
   }
   else {
      _mesa_error( ctx, GL_INVALID_VALUE,
                   "glTexEnv(GL_RGB_SCALE not 1, 2 or 4)" );
      return;
   }

   switch (pname) {
   case GL_RGB_SCALE:
      if (texUnit->Combine.ScaleShiftRGB == shift)
         return;
      FLUSH_VERTICES(ctx, _NEW_TEXTURE);
      texUnit->Combine.ScaleShiftRGB = shift;
      break;
   case GL_ALPHA_SCALE:
      if (texUnit->Combine.ScaleShiftA == shift)
         return;
      FLUSH_VERTICES(ctx, _NEW_TEXTURE);
      texUnit->Combine.ScaleShiftA = shift;
      break;
   default:
      TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
   }
}
Example #3
0
/** Set texture env mode */
static void
set_env_mode(GLcontext *ctx,
             struct gl_texture_unit *texUnit,
             GLenum mode)
{
   GLboolean legal;

   if (texUnit->EnvMode == mode)
      return;

   switch (mode) {
   case GL_MODULATE:
   case GL_BLEND:
   case GL_DECAL:
   case GL_REPLACE:
      legal = GL_TRUE;
      break;
   case GL_REPLACE_EXT:
      mode = GL_REPLACE; /* GL_REPLACE_EXT != GL_REPLACE */
      legal = GL_TRUE;
      break;
   case GL_ADD:
      legal = ctx->Extensions.EXT_texture_env_add;
      break;
   case GL_COMBINE:
      legal = (ctx->Extensions.EXT_texture_env_combine ||
               ctx->Extensions.ARB_texture_env_combine);
      break;
   case GL_COMBINE4_NV:
      legal = ctx->Extensions.NV_texture_env_combine4;
      break;
   default:
      legal = GL_FALSE;
   }

   if (legal) {
      FLUSH_VERTICES(ctx, _NEW_TEXTURE);
      texUnit->EnvMode = mode;
   }
   else {
      TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
   }
}
Example #4
0
void GLAPIENTRY
_mesa_TexEnvfv( GLenum target, GLenum pname, const GLfloat *param )
{
   GLuint maxUnit;
   GET_CURRENT_CONTEXT(ctx);
   struct gl_texture_unit *texUnit;
   ASSERT_OUTSIDE_BEGIN_END(ctx);

   maxUnit = (target == GL_POINT_SPRITE_NV && pname == GL_COORD_REPLACE_NV)
      ? ctx->Const.MaxTextureCoordUnits : ctx->Const.MaxTextureImageUnits;
   if (ctx->Texture.CurrentUnit >= maxUnit) {
      _mesa_error(ctx, GL_INVALID_OPERATION, "glTexEnvfv(current unit)");
      return;
   }

   texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];

#define TE_ERROR(errCode, msg, value)				\
   _mesa_error(ctx, errCode, msg, _mesa_lookup_enum_by_nr(value));

   if (target == GL_TEXTURE_ENV) {
      switch (pname) {
      case GL_TEXTURE_ENV_MODE:
         {
            GLenum mode = (GLenum) (GLint) *param;
            if (mode == GL_REPLACE_EXT)
               mode = GL_REPLACE;
	    if (texUnit->EnvMode == mode)
	       return;
            if (mode == GL_MODULATE ||
                mode == GL_BLEND ||
                mode == GL_DECAL ||
                mode == GL_REPLACE ||
                (mode == GL_ADD && ctx->Extensions.EXT_texture_env_add) ||
                (mode == GL_COMBINE &&
                 (ctx->Extensions.EXT_texture_env_combine ||
                  ctx->Extensions.ARB_texture_env_combine))) {
               /* legal */
               FLUSH_VERTICES(ctx, _NEW_TEXTURE);
               texUnit->EnvMode = mode;
            }
            else {
               TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
               return;
            }
         }
         break;
      case GL_TEXTURE_ENV_COLOR:
         {
            GLfloat tmp[4];
            tmp[0] = CLAMP( param[0], 0.0F, 1.0F );
            tmp[1] = CLAMP( param[1], 0.0F, 1.0F );
            tmp[2] = CLAMP( param[2], 0.0F, 1.0F );
            tmp[3] = CLAMP( param[3], 0.0F, 1.0F );
            if (TEST_EQ_4V(tmp, texUnit->EnvColor))
               return;
            FLUSH_VERTICES(ctx, _NEW_TEXTURE);
            COPY_4FV(texUnit->EnvColor, tmp);
         }
         break;
      case GL_COMBINE_RGB:
	 if (ctx->Extensions.EXT_texture_env_combine ||
             ctx->Extensions.ARB_texture_env_combine) {
	    const GLenum mode = (GLenum) (GLint) *param;
	    if (texUnit->Combine.ModeRGB == mode)
	       return;
	    switch (mode) {
	    case GL_REPLACE:
	    case GL_MODULATE:
	    case GL_ADD:
	    case GL_ADD_SIGNED:
	    case GL_INTERPOLATE:
               /* OK */
	       break;
            case GL_SUBTRACT:
               if (!ctx->Extensions.ARB_texture_env_combine) {
                  TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
                  return;
               }
               break;
	    case GL_DOT3_RGB_EXT:
	    case GL_DOT3_RGBA_EXT:
	       if (!ctx->Extensions.EXT_texture_env_dot3) {
                  TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
		  return;
	       }
	       break;
	    case GL_DOT3_RGB:
	    case GL_DOT3_RGBA:
	       if (!ctx->Extensions.ARB_texture_env_dot3) {
                  TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
		  return;
	       }
	       break;
	    case GL_MODULATE_ADD_ATI:
	    case GL_MODULATE_SIGNED_ADD_ATI:
	    case GL_MODULATE_SUBTRACT_ATI:
	       if (!ctx->Extensions.ATI_texture_env_combine3) {
                  TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
		  return;
	       }
	       break;
	    default:
               TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
	       return;
	    }
	    FLUSH_VERTICES(ctx, _NEW_TEXTURE);
	    texUnit->Combine.ModeRGB = mode;
	 }
	 else {
            TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
	    return;
	 }
         break;
      case GL_COMBINE_ALPHA:
	 if (ctx->Extensions.EXT_texture_env_combine ||
             ctx->Extensions.ARB_texture_env_combine) {
	    const GLenum mode = (GLenum) (GLint) *param;
	    if (texUnit->Combine.ModeA == mode)
	       return;
            switch (mode) {
	    case GL_REPLACE:
	    case GL_MODULATE:
	    case GL_ADD:
	    case GL_ADD_SIGNED:
	    case GL_INTERPOLATE:
	       /* OK */
	       break;
	    case GL_SUBTRACT:
	       if (!ctx->Extensions.ARB_texture_env_combine) {
		  TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
		  return;
	       }
	       break;
	    case GL_MODULATE_ADD_ATI:
	    case GL_MODULATE_SIGNED_ADD_ATI:
	    case GL_MODULATE_SUBTRACT_ATI:
	       if (!ctx->Extensions.ATI_texture_env_combine3) {
                  TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
		  return;
	       }
	       break;
	    default:
	       TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
	       return;
	    }
	    FLUSH_VERTICES(ctx, _NEW_TEXTURE);
	    texUnit->Combine.ModeA = mode;
	 }
	 else {
            TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
	    return;
	 }
	 break;
      case GL_SOURCE0_RGB:
      case GL_SOURCE1_RGB:
      case GL_SOURCE2_RGB:
	 if (ctx->Extensions.EXT_texture_env_combine ||
	     ctx->Extensions.ARB_texture_env_combine) {
	    const GLenum source = (GLenum) (GLint) *param;
	    const GLuint s = pname - GL_SOURCE0_RGB;
	    if (texUnit->Combine.SourceRGB[s] == source)
	       return;
            if (source == GL_TEXTURE ||
                source == GL_CONSTANT ||
                source == GL_PRIMARY_COLOR ||
                source == GL_PREVIOUS ||
                (ctx->Extensions.ARB_texture_env_crossbar &&
                 source >= GL_TEXTURE0 &&
                 source < GL_TEXTURE0 + ctx->Const.MaxTextureUnits) ||
                (ctx->Extensions.ATI_texture_env_combine3 &&
                 (source == GL_ZERO || source == GL_ONE))) {
               /* legal */
	       FLUSH_VERTICES(ctx, _NEW_TEXTURE);
	       texUnit->Combine.SourceRGB[s] = source;
            }
            else {
               TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", source);
	       return;
	    }
	 }
	 else {
            TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
	    return;
	 }
	 break;
      case GL_SOURCE0_ALPHA:
      case GL_SOURCE1_ALPHA:
      case GL_SOURCE2_ALPHA:
	 if (ctx->Extensions.EXT_texture_env_combine ||
             ctx->Extensions.ARB_texture_env_combine) {
	    const GLenum source = (GLenum) (GLint) *param;
	    const GLuint s = pname - GL_SOURCE0_ALPHA;
	    if (texUnit->Combine.SourceA[s] == source)
	       return;
            if (source == GL_TEXTURE ||
                source == GL_CONSTANT ||
                source == GL_PRIMARY_COLOR ||
                source == GL_PREVIOUS ||
                (ctx->Extensions.ARB_texture_env_crossbar &&
                 source >= GL_TEXTURE0 &&
                 source < GL_TEXTURE0 + ctx->Const.MaxTextureUnits) ||
		(ctx->Extensions.ATI_texture_env_combine3 &&
                 (source == GL_ZERO || source == GL_ONE))) {
               /* legal */
	       FLUSH_VERTICES(ctx, _NEW_TEXTURE);
	       texUnit->Combine.SourceA[s] = source;
            }
            else {
               TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", source);
	       return;
	    }
	 }
	 else {
            TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
	    return;
	 }
	 break;
      case GL_OPERAND0_RGB:
      case GL_OPERAND1_RGB:
	 if (ctx->Extensions.EXT_texture_env_combine ||
	     ctx->Extensions.ARB_texture_env_combine) {
	    const GLenum operand = (GLenum) (GLint) *param;
	    const GLuint s = pname - GL_OPERAND0_RGB;
	    if (texUnit->Combine.OperandRGB[s] == operand)
	       return;
	    switch (operand) {
	    case GL_SRC_COLOR:
	    case GL_ONE_MINUS_SRC_COLOR:
	    case GL_SRC_ALPHA:
	    case GL_ONE_MINUS_SRC_ALPHA:
	       FLUSH_VERTICES(ctx, _NEW_TEXTURE);
	       texUnit->Combine.OperandRGB[s] = operand;
	       break;
	    default:
               TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", operand);
	       return;
	    }
	 }
	 else {
            TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
	    return;
	 }
	 break;
      case GL_OPERAND0_ALPHA:
      case GL_OPERAND1_ALPHA:
	 if (ctx->Extensions.EXT_texture_env_combine ||
             ctx->Extensions.ARB_texture_env_combine) {
	    const GLenum operand = (GLenum) (GLint) *param;
	    if (texUnit->Combine.OperandA[pname-GL_OPERAND0_ALPHA] == operand)
	       return;
	    switch (operand) {
	    case GL_SRC_ALPHA:
	    case GL_ONE_MINUS_SRC_ALPHA:
	       FLUSH_VERTICES(ctx, _NEW_TEXTURE);
	       texUnit->Combine.OperandA[pname-GL_OPERAND0_ALPHA] = operand;
	       break;
	    default:
               TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", operand);
	       return;
	    }
	 }
	 else {
            TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
	    return;
	 }
	 break;
      case GL_OPERAND2_RGB:
	 if (ctx->Extensions.ARB_texture_env_combine) {
	    const GLenum operand = (GLenum) (GLint) *param;
	    if (texUnit->Combine.OperandRGB[2] == operand)
	       return;
	    switch (operand) {
	    case GL_SRC_COLOR:           /* ARB combine only */
	    case GL_ONE_MINUS_SRC_COLOR: /* ARB combine only */
	    case GL_SRC_ALPHA:
	    case GL_ONE_MINUS_SRC_ALPHA: /* ARB combine only */
	       FLUSH_VERTICES(ctx, _NEW_TEXTURE);
	       texUnit->Combine.OperandRGB[2] = operand;
               break;
	    default:
               TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", operand);
	       return;
	    }
	 }
	 else if (ctx->Extensions.EXT_texture_env_combine) {
	    const GLenum operand = (GLenum) (GLint) *param;
	    if (texUnit->Combine.OperandRGB[2] == operand)
	       return;
	    /* operand must be GL_SRC_ALPHA which is the initial value - thus
	       don't need to actually compare the operand to the possible value */
	    else {
               TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", operand);
	       return;
	    }
	 }
	 else {
            TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
	    return;
	 }
	 break;
      case GL_OPERAND2_ALPHA:
	 if (ctx->Extensions.ARB_texture_env_combine) {
	    const GLenum operand = (GLenum) (GLint) *param;
	    if (texUnit->Combine.OperandA[2] == operand)
	       return;
	    switch (operand) {
	    case GL_SRC_ALPHA:
	    case GL_ONE_MINUS_SRC_ALPHA: /* ARB combine only */
	       FLUSH_VERTICES(ctx, _NEW_TEXTURE);
	       texUnit->Combine.OperandA[2] = operand;
	       break;
	    default:
               TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", operand);
	       return;
	    }
	 }
	 else if (ctx->Extensions.EXT_texture_env_combine) {
	    const GLenum operand = (GLenum) (GLint) *param;
	    if (texUnit->Combine.OperandA[2] == operand)
	       return;
	    /* operand must be GL_SRC_ALPHA which is the initial value - thus
	       don't need to actually compare the operand to the possible value */
	    else {
               TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", operand);
	       return;
	    }
	 }
	 else {
            TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
	    return;
	 }
	 break;
      case GL_RGB_SCALE:
	 if (ctx->Extensions.EXT_texture_env_combine ||
             ctx->Extensions.ARB_texture_env_combine) {
	    GLuint newshift;
	    if (*param == 1.0) {
	       newshift = 0;
	    }
	    else if (*param == 2.0) {
	       newshift = 1;
	    }
	    else if (*param == 4.0) {
	       newshift = 2;
	    }
	    else {
	       _mesa_error( ctx, GL_INVALID_VALUE,
                            "glTexEnv(GL_RGB_SCALE not 1, 2 or 4)" );
	       return;
	    }
	    if (texUnit->Combine.ScaleShiftRGB == newshift)
	       return;
	    FLUSH_VERTICES(ctx, _NEW_TEXTURE);
	    texUnit->Combine.ScaleShiftRGB = newshift;
	 }
	 else {
            TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
	    return;
	 }
	 break;
      case GL_ALPHA_SCALE:
	 if (ctx->Extensions.EXT_texture_env_combine ||
             ctx->Extensions.ARB_texture_env_combine) {
	    GLuint newshift;
	    if (*param == 1.0) {
	       newshift = 0;
	    }
	    else if (*param == 2.0) {
	       newshift = 1;
	    }
	    else if (*param == 4.0) {
	       newshift = 2;
	    }
	    else {
	       _mesa_error( ctx, GL_INVALID_VALUE,
                            "glTexEnv(GL_ALPHA_SCALE not 1, 2 or 4)" );
	       return;
	    }
	    if (texUnit->Combine.ScaleShiftA == newshift)
	       return;
	    FLUSH_VERTICES(ctx, _NEW_TEXTURE);
	    texUnit->Combine.ScaleShiftA = newshift;
	 }
	 else {
            TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
	    return;
	 }
	 break;
      default:
	 _mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(pname)" );
	 return;
      }
   }
   else if (target == GL_TEXTURE_FILTER_CONTROL_EXT) {
      /* GL_EXT_texture_lod_bias */
      if (!ctx->Extensions.EXT_texture_lod_bias) {
	 _mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(target=0x%x)", target );
	 return;
      }
      if (pname == GL_TEXTURE_LOD_BIAS_EXT) {
	 if (texUnit->LodBias == param[0])
	    return;
	 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
         texUnit->LodBias = param[0];
      }
      else {
         TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
	 return;
      }
   }
   else if (target == GL_POINT_SPRITE_NV) {
      /* GL_ARB_point_sprite / GL_NV_point_sprite */
      if (!ctx->Extensions.NV_point_sprite
	  && !ctx->Extensions.ARB_point_sprite) {
	 _mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(target=0x%x)", target );
	 return;
      }
      if (pname == GL_COORD_REPLACE_NV) {
         const GLenum value = (GLenum) param[0];
         if (value == GL_TRUE || value == GL_FALSE) {
            /* It's kind of weird to set point state via glTexEnv,
             * but that's what the spec calls for.
             */
            const GLboolean state = (GLboolean) value;
            if (ctx->Point.CoordReplace[ctx->Texture.CurrentUnit] == state)
               return;
            FLUSH_VERTICES(ctx, _NEW_POINT);
            ctx->Point.CoordReplace[ctx->Texture.CurrentUnit] = state;
         }
         else {
            _mesa_error( ctx, GL_INVALID_VALUE, "glTexEnv(param=0x%x)", value);
            return;
         }
      }
      else {
         _mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(pname=0x%x)", pname );
         return;
      }
   }
   else {
      _mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(target=0x%x)",target );
      return;
   }

   if (MESA_VERBOSE&(VERBOSE_API|VERBOSE_TEXTURE))
      _mesa_debug(ctx, "glTexEnv %s %s %.1f(%s) ...\n",
                  _mesa_lookup_enum_by_nr(target),
                  _mesa_lookup_enum_by_nr(pname),
                  *param,
                  _mesa_lookup_enum_by_nr((GLenum) (GLint) *param));

   /* Tell device driver about the new texture environment */
   if (ctx->Driver.TexEnv) {
      (*ctx->Driver.TexEnv)( ctx, target, pname, param );
   }
}
Example #5
0
void GLAPIENTRY
_mesa_TexEnvfv( GLenum target, GLenum pname, const GLfloat *param )
{
   GLuint maxUnit;
   GET_CURRENT_CONTEXT(ctx);
   struct gl_texture_unit *texUnit;
   ASSERT_OUTSIDE_BEGIN_END(ctx);

   maxUnit = (target == GL_POINT_SPRITE_NV && pname == GL_COORD_REPLACE_NV)
      ? ctx->Const.MaxTextureCoordUnits : ctx->Const.MaxTextureImageUnits;
   if (ctx->Texture.CurrentUnit >= maxUnit) {
      _mesa_error(ctx, GL_INVALID_OPERATION, "glTexEnvfv(current unit)");
      return;
   }

   texUnit = _mesa_get_current_tex_unit(ctx);

   if (target == GL_TEXTURE_ENV) {
      switch (pname) {
      case GL_TEXTURE_ENV_MODE:
         set_env_mode(ctx, texUnit, (GLenum) (GLint) param[0]);
         break;
      case GL_TEXTURE_ENV_COLOR:
         set_env_color(ctx, texUnit, param);
         break;
      case GL_COMBINE_RGB:
      case GL_COMBINE_ALPHA:
         set_combiner_mode(ctx, texUnit, pname, (GLenum) (GLint) param[0]);
	 break;
      case GL_SOURCE0_RGB:
      case GL_SOURCE1_RGB:
      case GL_SOURCE2_RGB:
      case GL_SOURCE3_RGB_NV:
      case GL_SOURCE0_ALPHA:
      case GL_SOURCE1_ALPHA:
      case GL_SOURCE2_ALPHA:
      case GL_SOURCE3_ALPHA_NV:
         set_combiner_source(ctx, texUnit, pname, (GLenum) (GLint) param[0]);
	 break;
      case GL_OPERAND0_RGB:
      case GL_OPERAND1_RGB:
      case GL_OPERAND2_RGB:
      case GL_OPERAND3_RGB_NV:
      case GL_OPERAND0_ALPHA:
      case GL_OPERAND1_ALPHA:
      case GL_OPERAND2_ALPHA:
      case GL_OPERAND3_ALPHA_NV:
         set_combiner_operand(ctx, texUnit, pname, (GLenum) (GLint) param[0]);
	 break;
      case GL_RGB_SCALE:
      case GL_ALPHA_SCALE:
         set_combiner_scale(ctx, texUnit, pname, param[0]);
	 break;
      case GL_BUMP_TARGET_ATI:
         if (!ctx->Extensions.ATI_envmap_bumpmap) {
	    _mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(pname=0x%x)", pname );
	    return;
	 }
	 if (((GLenum) (GLint) param[0] < GL_TEXTURE0) ||
	 ((GLenum) (GLint) param[0] > GL_TEXTURE31)) {
	    /* spec doesn't say this but it seems logical */
	    _mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(param=0x%x)", (GLenum) (GLint) param[0]);
	    return;
	 }
	 if (!((1 << ((GLenum) (GLint) param[0] - GL_TEXTURE0)) & ctx->Const.SupportedBumpUnits)) {
	    _mesa_error( ctx, GL_INVALID_VALUE, "glTexEnv(param=0x%x)", (GLenum) (GLint) param[0]);
	    return;
	 }
	 else {
	    FLUSH_VERTICES(ctx, _NEW_TEXTURE);
	    texUnit->BumpTarget = (GLenum) (GLint) param[0];
	 }
	 break;
      default:
	 _mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(pname)" );
	 return;
      }
   }
   else if (target == GL_TEXTURE_FILTER_CONTROL_EXT) {
      /* GL_EXT_texture_lod_bias */
      if (!ctx->Extensions.EXT_texture_lod_bias) {
	 _mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(target=0x%x)", target );
	 return;
      }
      if (pname == GL_TEXTURE_LOD_BIAS_EXT) {
	 if (texUnit->LodBias == param[0])
	    return;
	 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
         texUnit->LodBias = param[0];
      }
      else {
         TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
	 return;
      }
   }
   else if (target == GL_POINT_SPRITE_NV) {
      /* GL_ARB_point_sprite / GL_NV_point_sprite */
      if (!ctx->Extensions.NV_point_sprite
	  && !ctx->Extensions.ARB_point_sprite) {
	 _mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(target=0x%x)", target );
	 return;
      }
      if (pname == GL_COORD_REPLACE_NV) {
         const GLenum value = (GLenum) param[0];
         if (value == GL_TRUE || value == GL_FALSE) {
            /* It's kind of weird to set point state via glTexEnv,
             * but that's what the spec calls for.
             */
            const GLboolean state = (GLboolean) value;
            if (ctx->Point.CoordReplace[ctx->Texture.CurrentUnit] == state)
               return;
            FLUSH_VERTICES(ctx, _NEW_POINT);
            ctx->Point.CoordReplace[ctx->Texture.CurrentUnit] = state;
         }
         else {
            _mesa_error( ctx, GL_INVALID_VALUE, "glTexEnv(param=0x%x)", value);
            return;
         }
      }
      else {
         _mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(pname=0x%x)", pname );
         return;
      }
   }
   else {
      _mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(target=0x%x)",target );
      return;
   }

   if (MESA_VERBOSE&(VERBOSE_API|VERBOSE_TEXTURE))
      _mesa_debug(ctx, "glTexEnv %s %s %.1f(%s) ...\n",
                  _mesa_lookup_enum_by_nr(target),
                  _mesa_lookup_enum_by_nr(pname),
                  *param,
                  _mesa_lookup_enum_by_nr((GLenum) (GLint) *param));

   /* Tell device driver about the new texture environment */
   if (ctx->Driver.TexEnv) {
      (*ctx->Driver.TexEnv)( ctx, target, pname, param );
   }
}
Example #6
0
/** Set an RGB or A combiner operand term */
static void
set_combiner_operand(GLcontext *ctx,
                     struct gl_texture_unit *texUnit,
                     GLenum pname, GLenum param)
{
   GLuint term;
   GLboolean alpha, legal;

   if (!ctx->Extensions.EXT_texture_env_combine &&
       !ctx->Extensions.ARB_texture_env_combine) {
      _mesa_error(ctx, GL_INVALID_ENUM, "glTexEnv(pname)");
      return;
   }

   /* The enums were given sequential values for a reason.
    */
   switch (pname) {
   case GL_OPERAND0_RGB:
   case GL_OPERAND1_RGB:
   case GL_OPERAND2_RGB:
   case GL_OPERAND3_RGB_NV:
      term = pname - GL_OPERAND0_RGB;
      alpha = GL_FALSE;
      break;
   case GL_OPERAND0_ALPHA:
   case GL_OPERAND1_ALPHA:
   case GL_OPERAND2_ALPHA:
   case GL_OPERAND3_ALPHA_NV:
      term = pname - GL_OPERAND0_ALPHA;
      alpha = GL_TRUE;
      break;
   default:
      TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
      return;
   }

   if ((term == 3) && !ctx->Extensions.NV_texture_env_combine4) {
      TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
      return;
   }

   assert(term < MAX_COMBINER_TERMS);

   /*
    * Error-check param (the source operand)
    */
   switch (param) {
   case GL_SRC_COLOR:
   case GL_ONE_MINUS_SRC_COLOR:
      /* The color input can only be used with GL_OPERAND[01]_RGB in the EXT
       * version.  In the ARB and NV versions they can be used for any RGB
       * operand.
       */
      legal = !alpha
	 && ((term < 2) || ctx->Extensions.ARB_texture_env_combine
	     || ctx->Extensions.NV_texture_env_combine4);
      break;
   case GL_ONE_MINUS_SRC_ALPHA:
      /* GL_ONE_MINUS_SRC_ALPHA can only be used with
       * GL_OPERAND[01]_(RGB|ALPHA) in the EXT version.  In the ARB and NV
       * versions it can be used for any operand.
       */
      legal = (term < 2) || ctx->Extensions.ARB_texture_env_combine
	 || ctx->Extensions.NV_texture_env_combine4;
      break;
   case GL_SRC_ALPHA:
      legal = GL_TRUE;
      break;
   default:
      legal = GL_FALSE;
   }

   if (!legal) {
      TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", param);
      return;
   }

   FLUSH_VERTICES(ctx, _NEW_TEXTURE);

   if (alpha)
      texUnit->Combine.OperandA[term] = param;
   else
      texUnit->Combine.OperandRGB[term] = param;
}
Example #7
0
/** Set an RGB or A combiner source term */
static void
set_combiner_source(GLcontext *ctx,
                    struct gl_texture_unit *texUnit,
                    GLenum pname, GLenum param)
{
   GLuint term;
   GLboolean alpha, legal;

   if (!ctx->Extensions.EXT_texture_env_combine &&
       !ctx->Extensions.ARB_texture_env_combine) {
      _mesa_error(ctx, GL_INVALID_ENUM, "glTexEnv(pname)");
      return;
   }

   /*
    * Translate pname to (term, alpha).
    *
    * The enums were given sequential values for a reason.
    */
   switch (pname) {
   case GL_SOURCE0_RGB:
   case GL_SOURCE1_RGB:
   case GL_SOURCE2_RGB:
   case GL_SOURCE3_RGB_NV:
      term = pname - GL_SOURCE0_RGB;
      alpha = GL_FALSE;
      break;
   case GL_SOURCE0_ALPHA:
   case GL_SOURCE1_ALPHA:
   case GL_SOURCE2_ALPHA:
   case GL_SOURCE3_ALPHA_NV:
      term = pname - GL_SOURCE0_ALPHA;
      alpha = GL_TRUE;
      break;
   default:
      TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
      return;
   }

   if ((term == 3) && !ctx->Extensions.NV_texture_env_combine4) {
      TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
      return;
   }

   assert(term < MAX_COMBINER_TERMS);

   /*
    * Error-check param (the source term)
    */
   switch (param) {
   case GL_TEXTURE:
   case GL_CONSTANT:
   case GL_PRIMARY_COLOR:
   case GL_PREVIOUS:
      legal = GL_TRUE;
      break;
   case GL_TEXTURE0:
   case GL_TEXTURE1:
   case GL_TEXTURE2:
   case GL_TEXTURE3:
   case GL_TEXTURE4:
   case GL_TEXTURE5:
   case GL_TEXTURE6:
   case GL_TEXTURE7:
      legal = (ctx->Extensions.ARB_texture_env_crossbar &&
               param - GL_TEXTURE0 < ctx->Const.MaxTextureUnits);
      break;
   case GL_ZERO:
      legal = (ctx->Extensions.ATI_texture_env_combine3 ||
               ctx->Extensions.NV_texture_env_combine4);
      break;
   case GL_ONE:
      legal = ctx->Extensions.ATI_texture_env_combine3;
      break;
   default:
      legal = GL_FALSE;
   }

   if (!legal) {
      TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", param);
      return;
   }

   FLUSH_VERTICES(ctx, _NEW_TEXTURE);

   if (alpha)
      texUnit->Combine.SourceA[term] = param;
   else
      texUnit->Combine.SourceRGB[term] = param;
}
Example #8
0
/** Set an RGB or A combiner mode/function */
static void
set_combiner_mode(GLcontext *ctx,
                  struct gl_texture_unit *texUnit,
                  GLenum pname, GLenum mode)
{
   GLboolean legal;

   if (!ctx->Extensions.EXT_texture_env_combine &&
       !ctx->Extensions.ARB_texture_env_combine) {
      _mesa_error(ctx, GL_INVALID_ENUM, "glTexEnv(pname)");
      return;
   }

   switch (mode) {
   case GL_REPLACE:
   case GL_MODULATE:
   case GL_ADD:
   case GL_ADD_SIGNED:
   case GL_INTERPOLATE:
      legal = GL_TRUE;
      break;
   case GL_SUBTRACT:
      legal = ctx->Extensions.ARB_texture_env_combine;
      break;
   case GL_DOT3_RGB_EXT:
   case GL_DOT3_RGBA_EXT:
      legal = (ctx->Extensions.EXT_texture_env_dot3 &&
               pname == GL_COMBINE_RGB);
      break;
   case GL_DOT3_RGB:
   case GL_DOT3_RGBA:
      legal = (ctx->Extensions.ARB_texture_env_dot3 &&
               pname == GL_COMBINE_RGB);
      break;
   case GL_MODULATE_ADD_ATI:
   case GL_MODULATE_SIGNED_ADD_ATI:
   case GL_MODULATE_SUBTRACT_ATI:
      legal = ctx->Extensions.ATI_texture_env_combine3;
      break;
   case GL_BUMP_ENVMAP_ATI:
      legal = (ctx->Extensions.ATI_envmap_bumpmap &&
               pname == GL_COMBINE_RGB);
      break;
   default:
      legal = GL_FALSE;
   }

   if (!legal) {
      TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
      return;
   }

   switch (pname) {
   case GL_COMBINE_RGB:
      if (texUnit->Combine.ModeRGB == mode)
         return;
      FLUSH_VERTICES(ctx, _NEW_TEXTURE);
      texUnit->Combine.ModeRGB = mode;
      break;

   case GL_COMBINE_ALPHA:
      if (texUnit->Combine.ModeA == mode)
         return;
      FLUSH_VERTICES(ctx, _NEW_TEXTURE);
      texUnit->Combine.ModeA = mode;
      break;
   default:
      TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
   }
}
Example #9
0
void glTexEnvfv( GLenum target, GLenum pname, const GLfloat *param )
{
   const GLint iparam0 = (GLint) param[0];
   struct gl_texture_unit *texUnit;
   GLuint maxUnit;
   GET_CURRENT_CONTEXT(ctx);

   maxUnit = ctx->Const.MaxCombinedTextureImageUnits;
//   maxUnit = (target == GL_POINT_SPRITE_NV && pname == GL_COORD_REPLACE_NV)
//      ? ctx->Const.MaxTextureCoordUnits : ctx->Const.MaxCombinedTextureImageUnits;
   if (ctx->Texture.CurrentUnit >= maxUnit) {
      _mesa_error(ctx, GL_INVALID_OPERATION, "glTexEnvfv(current unit)");
      return;
   }

   texUnit = _mesa_get_current_tex_unit(ctx);

   if (target == GL_TEXTURE_ENV) {
      switch (pname) {
      case GL_TEXTURE_ENV_MODE:
         set_env_mode(ctx, texUnit, (GLenum) iparam0);
         break;
      case GL_TEXTURE_ENV_COLOR:
         set_env_color(ctx, texUnit, param);
         break;
      case GL_COMBINE_RGB:
      case GL_COMBINE_ALPHA:
         set_combiner_mode(ctx, texUnit, pname, (GLenum) iparam0);
	 break;
      case GL_SOURCE0_RGB:
      case GL_SOURCE1_RGB:
      case GL_SOURCE2_RGB:
//      case GL_SOURCE3_RGB_NV:
      case GL_SOURCE0_ALPHA:
      case GL_SOURCE1_ALPHA:
      case GL_SOURCE2_ALPHA:
//      case GL_SOURCE3_ALPHA_NV:
         set_combiner_source(ctx, texUnit, pname, (GLenum) iparam0);
	 break;
      case GL_OPERAND0_RGB:
      case GL_OPERAND1_RGB:
      case GL_OPERAND2_RGB:
//      case GL_OPERAND3_RGB_NV:
      case GL_OPERAND0_ALPHA:
      case GL_OPERAND1_ALPHA:
      case GL_OPERAND2_ALPHA:
//      case GL_OPERAND3_ALPHA_NV:
         set_combiner_operand(ctx, texUnit, pname, (GLenum) iparam0);
	 break;
      case GL_RGB_SCALE:
      case GL_ALPHA_SCALE:
         set_combiner_scale(ctx, texUnit, pname, param[0]);
	 break;
      default:
	 _mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(pname)" );
	 return;
      }
   }
   else if (target == GL_TEXTURE_FILTER_CONTROL) {
      if (pname == GL_TEXTURE_LOD_BIAS) {
	 if (texUnit->LodBias == param[0])
	    return;
	 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
         texUnit->LodBias = param[0];
      }
      else {
         TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
	 return;
      }
   }
//   else if (target == GL_POINT_SPRITE_NV) {
//      /* GL_ARB_point_sprite / GL_NV_point_sprite */
//      if (!ctx->Extensions.NV_point_sprite
//	  && !ctx->Extensions.ARB_point_sprite) {
//	 _mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(target=0x%x)", target );
//	 return;
//      }
//      if (pname == GL_COORD_REPLACE_NV) {
//         if (iparam0 == GL_TRUE || iparam0 == GL_FALSE) {
//            /* It's kind of weird to set point state via glTexEnv,
//             * but that's what the spec calls for.
//             */
//            const GLboolean state = (GLboolean) iparam0;
//            if (ctx->Point.CoordReplace[ctx->Texture.CurrentUnit] == state)
//               return;
//            FLUSH_VERTICES(ctx, _NEW_POINT);
//            ctx->Point.CoordReplace[ctx->Texture.CurrentUnit] = state;
//         }
//         else {
//            _mesa_error( ctx, GL_INVALID_VALUE, "glTexEnv(param=0x%x)", iparam0);
//            return;
//         }
//      }
//      else {
//         _mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(pname=0x%x)", pname );
//         return;
//      }
//   }
   else {
      _mesa_error(ctx, GL_INVALID_ENUM, "glTexEnv(target=%s)",
                  _mesa_lookup_enum_by_nr(target));
      return;
   }

   if (MESA_VERBOSE&(VERBOSE_API|VERBOSE_TEXTURE))
      _mesa_debug(ctx, "glTexEnv %s %s %.1f(%s) ...\n",
                  _mesa_lookup_enum_by_nr(target),
                  _mesa_lookup_enum_by_nr(pname),
                  *param,
                  _mesa_lookup_enum_by_nr((GLenum) iparam0));

   /* Tell device driver about the new texture environment */
   if (ctx->Driver.TexEnv) {
      (*ctx->Driver.TexEnv)( ctx, target, pname, param );
   }
}