示例#1
0
/*
 * Check if the global material has to be updated with info that was
 * associated with a vertex via glMaterial.
 * This function is used when any material values get changed between
 * glBegin/glEnd either by calling glMaterial() or by calling glColor()
 * when GL_COLOR_MATERIAL is enabled.
 *
 * src[0] is front material, src[1] is back material
 *
 * Additionally keeps the precomputed lighting state uptodate.
 */
void _mesa_update_material( GLcontext *ctx,
			 const struct gl_material src[2],
			 GLuint bitmask )
{
   struct gl_light *light, *list = &ctx->Light.EnabledList;

   if (ctx->Light.ColorMaterialEnabled)
      bitmask &= ~ctx->Light.ColorMaterialBitmask;

   if (MESA_VERBOSE&VERBOSE_IMMEDIATE)
      fprintf(stderr, "_mesa_update_material, mask 0x%x\n", bitmask);

   if (!bitmask)
      return;

   /* update material emission */
   if (bitmask & FRONT_EMISSION_BIT) {
      struct gl_material *mat = &ctx->Light.Material[0];
      COPY_4FV( mat->Emission, src[0].Emission );
   }
   if (bitmask & BACK_EMISSION_BIT) {
      struct gl_material *mat = &ctx->Light.Material[1];
      COPY_4FV( mat->Emission, src[1].Emission );
   }

   /* update material ambience */
   if (bitmask & FRONT_AMBIENT_BIT) {
      struct gl_material *mat = &ctx->Light.Material[0];
      COPY_4FV( mat->Ambient, src[0].Ambient );
      foreach (light, list) {
         SCALE_3V( light->_MatAmbient[0], light->Ambient, src[0].Ambient);
      }
   }
示例#2
0
void GLAPIENTRY 
_mesa_CullParameterfvEXT (GLenum cap, GLfloat *v)
{
   GET_CURRENT_CONTEXT(ctx);
   ASSERT_OUTSIDE_BEGIN_END(ctx);

   switch (cap) {
   case GL_CULL_VERTEX_EYE_POSITION_EXT:
      FLUSH_VERTICES(ctx, _NEW_TRANSFORM);
      COPY_4FV(ctx->Transform.CullEyePos, v);
      
      _mesa_transform_vector( ctx->Transform.CullObjPos, 
			      ctx->Transform.CullEyePos,
			      ctx->ModelviewMatrixStack.Top->inv );
      break;

   case GL_CULL_VERTEX_OBJECT_POSITION_EXT:
      FLUSH_VERTICES(ctx, _NEW_TRANSFORM);
      COPY_4FV(ctx->Transform.CullObjPos, v);

      _mesa_transform_vector( ctx->Transform.CullEyePos, 
			      ctx->Transform.CullObjPos,
			      ctx->ModelviewMatrixStack.Top->m );
     break;
   default:
      _mesa_error( ctx, GL_INVALID_ENUM, "glCullParameterfvEXT" );
   }
}
示例#3
0
文件: blend.c 项目: etnaviv/mesa
/**
 * Set the blending color.
 *
 * \param red red color component.
 * \param green green color component.
 * \param blue blue color component.
 * \param alpha alpha color component.
 *
 * \sa glBlendColor().
 *
 * Clamps the parameters and updates gl_colorbuffer_attrib::BlendColor.  On a
 * change, flushes the vertices and notifies the driver via
 * dd_function_table::BlendColor callback.
 */
void GLAPIENTRY
_mesa_BlendColor( GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha )
{
   GLfloat tmp[4];
   GET_CURRENT_CONTEXT(ctx);

   tmp[0] = red;
   tmp[1] = green;
   tmp[2] = blue;
   tmp[3] = alpha;

   if (TEST_EQ_4V(tmp, ctx->Color.BlendColorUnclamped))
      return;

   FLUSH_VERTICES(ctx, _NEW_COLOR);
   COPY_4FV( ctx->Color.BlendColorUnclamped, tmp );

   ctx->Color.BlendColor[0] = CLAMP(tmp[0], 0.0F, 1.0F);
   ctx->Color.BlendColor[1] = CLAMP(tmp[1], 0.0F, 1.0F);
   ctx->Color.BlendColor[2] = CLAMP(tmp[2], 0.0F, 1.0F);
   ctx->Color.BlendColor[3] = CLAMP(tmp[3], 0.0F, 1.0F);

   if (ctx->Driver.BlendColor)
      ctx->Driver.BlendColor(ctx, ctx->Color.BlendColor);
}
示例#4
0
文件: st_cb_bitmap.c 项目: iquiw/xsrc
/**
 * Try to accumulate this glBitmap call in the bitmap cache.
 * \return  GL_TRUE for success, GL_FALSE if bitmap is too large, etc.
 */
static GLboolean
accum_bitmap(struct st_context *st,
             GLint x, GLint y, GLsizei width, GLsizei height,
             const struct gl_pixelstore_attrib *unpack,
             const GLubyte *bitmap )
{
   struct bitmap_cache *cache = st->bitmap.cache;
   int px = -999, py = -999;
   const GLfloat z = st->ctx->Current.RasterPos[2];

   if (width > BITMAP_CACHE_WIDTH ||
       height > BITMAP_CACHE_HEIGHT)
      return GL_FALSE; /* too big to cache */

   if (!cache->empty) {
      px = x - cache->xpos;  /* pos in buffer */
      py = y - cache->ypos;
      if (px < 0 || px + width > BITMAP_CACHE_WIDTH ||
          py < 0 || py + height > BITMAP_CACHE_HEIGHT ||
          !TEST_EQ_4V(st->ctx->Current.RasterColor, cache->color) ||
          ((fabs(z - cache->zpos) > Z_EPSILON))) {
         /* This bitmap would extend beyond cache bounds, or the bitmap
          * color is changing
          * so flush and continue.
          */
         st_flush_bitmap_cache(st);
      }
   }

   if (cache->empty) {
      /* Initialize.  Center bitmap vertically in the buffer. */
      px = 0;
      py = (BITMAP_CACHE_HEIGHT - height) / 2;
      cache->xpos = x;
      cache->ypos = y - py;
      cache->zpos = z;
      cache->empty = GL_FALSE;
      COPY_4FV(cache->color, st->ctx->Current.RasterColor);
   }

   assert(px != -999);
   assert(py != -999);

   if (x < cache->xmin)
      cache->xmin = x;
   if (y < cache->ymin)
      cache->ymin = y;
   if (x + width > cache->xmax)
      cache->xmax = x + width;
   if (y + height > cache->ymax)
      cache->ymax = y + height;

   /* create the transfer if needed */
   create_cache_trans(st);

   unpack_bitmap(st, px, py, width, height, unpack, bitmap,
                 cache->buffer, BITMAP_CACHE_WIDTH);

   return GL_TRUE; /* accumulated */
}
示例#5
0
void GLAPIENTRY
_mesa_TexBumpParameterfvATI( GLenum pname, const GLfloat *param )
{
   struct gl_texture_unit *texUnit;
   GET_CURRENT_CONTEXT(ctx);
   ASSERT_OUTSIDE_BEGIN_END(ctx);

   if (!ctx->Extensions.ATI_envmap_bumpmap) {
      _mesa_error(ctx, GL_INVALID_OPERATION, "glTexBumpParameterfvATI");
      return;
   }

   texUnit = _mesa_get_current_tex_unit(ctx);

   if (pname == GL_BUMP_ROT_MATRIX_ATI) {
      if (TEST_EQ_4V(param, texUnit->RotMatrix))
         return;
      FLUSH_VERTICES(ctx, _NEW_TEXTURE);
      COPY_4FV(texUnit->RotMatrix, param);
   }
   else {
      _mesa_error( ctx, GL_INVALID_ENUM, "glTexBumpParameter(pname)" );
      return;
   }
   /* Drivers might want to know about this, instead of dedicated function
      just shove it into TexEnv where it really belongs anyway */
   if (ctx->Driver.TexEnv) {
      (*ctx->Driver.TexEnv)( ctx, 0, pname, param );
   }
}
/**
 * All glWindowPosMESA and glWindowPosARB commands call this function to
 * update the current raster position.
 */
static void
window_pos3f(GLfloat x, GLfloat y, GLfloat z)
{
   GET_CURRENT_CONTEXT(ctx);
   GLfloat z2;

   FLUSH_VERTICES(ctx, 0);
   FLUSH_CURRENT(ctx, 0);

   z2 = CLAMP(z, 0.0F, 1.0F)
      * (ctx->ViewportArray[0].Far - ctx->ViewportArray[0].Near)
      + ctx->ViewportArray[0].Near;

   /* set raster position */
   ctx->Current.RasterPos[0] = x;
   ctx->Current.RasterPos[1] = y;
   ctx->Current.RasterPos[2] = z2;
   ctx->Current.RasterPos[3] = 1.0F;

   ctx->Current.RasterPosValid = GL_TRUE;

   if (ctx->Fog.FogCoordinateSource == GL_FOG_COORDINATE_EXT)
      ctx->Current.RasterDistance = ctx->Current.Attrib[VERT_ATTRIB_FOG][0];
   else
      ctx->Current.RasterDistance = 0.0;

   /* raster color = current color or index */
   ctx->Current.RasterColor[0]
      = CLAMP(ctx->Current.Attrib[VERT_ATTRIB_COLOR0][0], 0.0F, 1.0F);
   ctx->Current.RasterColor[1]
      = CLAMP(ctx->Current.Attrib[VERT_ATTRIB_COLOR0][1], 0.0F, 1.0F);
   ctx->Current.RasterColor[2]
      = CLAMP(ctx->Current.Attrib[VERT_ATTRIB_COLOR0][2], 0.0F, 1.0F);
   ctx->Current.RasterColor[3]
      = CLAMP(ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3], 0.0F, 1.0F);
   ctx->Current.RasterSecondaryColor[0]
      = CLAMP(ctx->Current.Attrib[VERT_ATTRIB_COLOR1][0], 0.0F, 1.0F);
   ctx->Current.RasterSecondaryColor[1]
      = CLAMP(ctx->Current.Attrib[VERT_ATTRIB_COLOR1][1], 0.0F, 1.0F);
   ctx->Current.RasterSecondaryColor[2]
      = CLAMP(ctx->Current.Attrib[VERT_ATTRIB_COLOR1][2], 0.0F, 1.0F);
   ctx->Current.RasterSecondaryColor[3]
      = CLAMP(ctx->Current.Attrib[VERT_ATTRIB_COLOR1][3], 0.0F, 1.0F);

   /* raster texcoord = current texcoord */
   {
      GLuint texSet;
      for (texSet = 0; texSet < ctx->Const.MaxTextureCoordUnits; texSet++) {
         assert(texSet < ARRAY_SIZE(ctx->Current.RasterTexCoords));
         COPY_4FV( ctx->Current.RasterTexCoords[texSet],
                  ctx->Current.Attrib[VERT_ATTRIB_TEX0 + texSet] );
      }
   }

   if (ctx->RenderMode==GL_SELECT) {
      _mesa_update_hitflag( ctx, ctx->Current.RasterPos[2] );
   }
}
INTERP_QUALIFIER void TAG(copy_pv_extras)( GLcontext *ctx, 
					   GLuint dst, GLuint src )
{
   LOCALVARS
      struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;

   if (VB->ColorPtr[1]) {
      COPY_4FV( GET_COLOR(VB->ColorPtr[1], dst), 
		GET_COLOR(VB->ColorPtr[1], src) );

      if (VB->SecondaryColorPtr[1]) {
	 COPY_4FV( GET_COLOR(VB->SecondaryColorPtr[1], dst), 
		   GET_COLOR(VB->SecondaryColorPtr[1], src) );
      }
   }

   COPY_PV_VERTEX(ctx, dst, src);
}
示例#8
0
/**
 * Copy back color(s) to front color(s).
 */
static INLINE struct vertex_header *
copy_bfc( struct twoside_stage *twoside, 
          const struct vertex_header *v,
          unsigned idx )
{   
   struct vertex_header *tmp = dup_vert( &twoside->stage, v, idx );
   
   if (twoside->attrib_back0) {
      COPY_4FV(tmp->data[twoside->attrib_front0],
               tmp->data[twoside->attrib_back0]);
   }
   if (twoside->attrib_back1) {
      COPY_4FV(tmp->data[twoside->attrib_front1],
               tmp->data[twoside->attrib_back1]);
   }

   return tmp;
}
示例#9
0
文件: api_eval.c 项目: aosm/X11
void _mesa_EvalCoord2f( GLfloat u, GLfloat v )
{
   GET_CURRENT_CONTEXT( ctx );
   GLfloat normal[3], texcoord[4], color[4];
   GLuint index;

   COPY_3FV( normal, ctx->Current.Attrib[VERT_ATTRIB_NORMAL] );
   COPY_4FV( texcoord, ctx->Current.Attrib[VERT_ATTRIB_TEX0] );
   COPY_4FV( color, ctx->Current.Attrib[VERT_ATTRIB_COLOR0] );
   index = ctx->Current.Index;

   do_EvalCoord2f( ctx, u, v );

   COPY_3FV( ctx->Current.Attrib[VERT_ATTRIB_NORMAL], normal );
   COPY_4FV( ctx->Current.Attrib[VERT_ATTRIB_TEX0], texcoord );
   COPY_4FV( ctx->Current.Attrib[VERT_ATTRIB_COLOR0], color );
   ctx->Current.Index = index;
}
/** Copy all the color attributes from src vertex to dst0 & dst1 vertices */
static INLINE void copy_colors2( struct draw_stage *stage,
                                 struct vertex_header *dst0,
                                 struct vertex_header *dst1,
                                 const struct vertex_header *src )
{
   const struct flat_stage *flat = flat_stage(stage);
   uint i;
   for (i = 0; i < flat->num_color_attribs; i++) {
      const uint attr = flat->color_attribs[i];
      COPY_4FV(dst0->data[attr], src->data[attr]);
      COPY_4FV(dst1->data[attr], src->data[attr]);
   }

   for (i = 0; i < flat->num_spec_attribs; i++) {
      const uint attr = flat->spec_attribs[i];
      COPY_3FV(dst0->data[attr], src->data[attr]);
      COPY_3FV(dst1->data[attr], src->data[attr]);
   }
}
示例#11
0
void GLAPIENTRY
_mesa_ClipPlane( GLenum plane, const GLdouble *eq )
{
   GET_CURRENT_CONTEXT(ctx);
   GLint p;
   GLfloat equation[4];
   ASSERT_OUTSIDE_BEGIN_END(ctx);

   p = (GLint) plane - (GLint) GL_CLIP_PLANE0;
   if (p < 0 || p >= (GLint) ctx->Const.MaxClipPlanes) {
      _mesa_error( ctx, GL_INVALID_ENUM, "glClipPlane" );
      return;
   }

   equation[0] = (GLfloat) eq[0];
   equation[1] = (GLfloat) eq[1];
   equation[2] = (GLfloat) eq[2];
   equation[3] = (GLfloat) eq[3];

   /*
    * The equation is transformed by the transpose of the inverse of the
    * current modelview matrix and stored in the resulting eye coordinates.
    *
    * KW: Eqn is then transformed to the current clip space, where user
    * clipping now takes place.  The clip-space equations are recalculated
    * whenever the projection matrix changes.
    */
   if (_math_matrix_is_dirty(ctx->ModelviewMatrixStack.Top))
      _math_matrix_analyse( ctx->ModelviewMatrixStack.Top );

   _mesa_transform_vector( equation, equation,
                           ctx->ModelviewMatrixStack.Top->inv );

   if (TEST_EQ_4V(ctx->Transform.EyeUserPlane[p], equation))
      return;

   FLUSH_VERTICES(ctx, _NEW_TRANSFORM);
   COPY_4FV(ctx->Transform.EyeUserPlane[p], equation);

   /* Update derived state.  This state also depends on the projection
    * matrix, and is recalculated on changes to the projection matrix by
    * code in _mesa_update_state().
    */
   if (ctx->Transform.ClipPlanesEnabled & (1 << p)) {
      if (_math_matrix_is_dirty(ctx->ProjectionMatrixStack.Top))
         _math_matrix_analyse( ctx->ProjectionMatrixStack.Top );

      _mesa_transform_vector( ctx->Transform._ClipUserPlane[p],
			   ctx->Transform.EyeUserPlane[p],
			   ctx->ProjectionMatrixStack.Top->inv );
   }

   if (ctx->Driver.ClipPlane)
      ctx->Driver.ClipPlane( ctx, plane, equation );
}
示例#12
0
static void copy_pv_extras( GLcontext *ctx, GLuint dst, GLuint src )
{
    struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;

    if (VB->ColorPtr[1]) {
        COPY_4FV( GET_COLOR(VB->ColorPtr[1], dst),
                  GET_COLOR(VB->ColorPtr[1], src) );
    }

    setup_tab[TDFX_CONTEXT(ctx)->SetupIndex].copy_pv(ctx, dst, src);
}
示例#13
0
static void generic_copy_pv_extras( GLcontext *ctx, 
				    GLuint dst, GLuint src )
{
   struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;

   if (VB->ColorPtr[1]) {
      COPY_4FV( VB->ColorPtr[1]->data[dst], 
		VB->ColorPtr[1]->data[src] );

      if (VB->SecondaryColorPtr[1]) {
	 COPY_4FV( VB->SecondaryColorPtr[1]->data[dst], 
		   VB->SecondaryColorPtr[1]->data[src] );
      }
   }
   else if (VB->IndexPtr[1]) {
      VB->IndexPtr[1]->data[dst][0] = VB->IndexPtr[1]->data[src][0];
   }

   generic_copy_pv(ctx, dst, src);
}
示例#14
0
/**
 * Copy front/back, primary/secondary colors from src vertex to dst vertex.
 * Used when flat shading.
 */
static void copy_colors( struct draw_stage *stage,
			 struct vertex_header *dst,
			 const struct vertex_header *src )
{
   const struct clip_stage *clipper = clip_stage(stage);
   uint i;
   for (i = 0; i < clipper->num_color_attribs; i++) {
      const uint attr = clipper->color_attribs[i];
      COPY_4FV(dst->data[attr], src->data[attr]);
   }
}
示例#15
0
文件: t_imm_exec.c 项目: aosm/X11
/**
 * Copy the last specified normal, color, texcoord, edge flag, etc
 * from the immediate struct into the ctx->Current attribute group.
 */
void _tnl_copy_to_current( GLcontext *ctx, struct immediate *IM,
			   GLuint flag, GLuint count )
{
   if (MESA_VERBOSE&VERBOSE_IMMEDIATE)
      _tnl_print_vert_flags("copy to current", flag);

   /* XXX should be able to replace these conditions with a loop over
    * the 16 vertex attributes.
    */
   if (flag & VERT_BIT_NORMAL)
      COPY_4FV( ctx->Current.Attrib[VERT_ATTRIB_NORMAL],
                IM->Attrib[VERT_ATTRIB_NORMAL][count]);

   if (flag & VERT_BIT_COLOR0) {
      COPY_4FV(ctx->Current.Attrib[VERT_ATTRIB_COLOR0],
               IM->Attrib[VERT_ATTRIB_COLOR0][count]);
      if (ctx->Light.ColorMaterialEnabled) {
	 _mesa_update_color_material( ctx,
                                   ctx->Current.Attrib[VERT_ATTRIB_COLOR0] );
 	 TNL_CONTEXT(ctx)->Driver.NotifyMaterialChange( ctx );
      }
   }

   if (flag & VERT_BIT_COLOR1)
      COPY_4FV(ctx->Current.Attrib[VERT_ATTRIB_COLOR1],
               IM->Attrib[VERT_ATTRIB_COLOR1][count]);

   if (flag & VERT_BIT_FOG)
      ctx->Current.Attrib[VERT_ATTRIB_FOG][0] = IM->Attrib[VERT_ATTRIB_FOG][count][0];

   if (flag & VERT_BIT_SIX)
      COPY_4FV(ctx->Current.Attrib[VERT_ATTRIB_SIX], IM->Attrib[VERT_ATTRIB_SIX][count]);

   if (flag & VERT_BIT_SEVEN)
      COPY_4FV(ctx->Current.Attrib[VERT_ATTRIB_SEVEN], IM->Attrib[VERT_ATTRIB_SEVEN][count]);

   if (flag & VERT_BITS_TEX_ANY) {
      GLuint i;
      for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++) {
	 if (flag & VERT_BIT_TEX(i)) {
	    COPY_4FV( ctx->Current.Attrib[VERT_ATTRIB_TEX0 + i],
                      IM->Attrib[VERT_ATTRIB_TEX0 + i][count]);
	 }
      }
   }

   if (flag & VERT_BIT_INDEX)
      ctx->Current.Index = IM->Index[count];

   if (flag & VERT_BIT_EDGEFLAG)
      ctx->Current.EdgeFlag = IM->EdgeFlag[count];

   if (flag & VERT_BIT_MATERIAL) {
      _mesa_update_material( ctx,
			  IM->Material[IM->LastMaterial],
			  IM->MaterialOrMask );

      TNL_CONTEXT(ctx)->Driver.NotifyMaterialChange( ctx );
   }
}
示例#16
0
/**
 * All glWindowPosMESA and glWindowPosARB commands call this function to
 * update the current raster position.
 */
static void
window_pos3f(GLfloat x, GLfloat y, GLfloat z)
{
   GET_CURRENT_CONTEXT(ctx);
   GLfloat z2;

   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
   FLUSH_CURRENT(ctx, 0);

   z2 = CLAMP(z, 0.0F, 1.0F) * (ctx->Viewport.Far - ctx->Viewport.Near)
      + ctx->Viewport.Near;

   /* set raster position */
   ctx->Current.RasterPos[0] = x;
   ctx->Current.RasterPos[1] = y;
   ctx->Current.RasterPos[2] = z2;
   ctx->Current.RasterPos[3] = 1.0F;

   ctx->Current.RasterPosValid = GL_TRUE;

   if (ctx->Fog.FogCoordinateSource == GL_FOG_COORDINATE_EXT)
      ctx->Current.RasterDistance = ctx->Current.Attrib[VERT_ATTRIB_FOG][0];
   else
      ctx->Current.RasterDistance = 0.0;

   /* raster color = current color or index */
   ctx->Current.RasterColor[0]
      = CLAMP(ctx->Current.Attrib[VERT_ATTRIB_COLOR0][0], 0.0F, 1.0F);
   ctx->Current.RasterColor[1]
      = CLAMP(ctx->Current.Attrib[VERT_ATTRIB_COLOR0][1], 0.0F, 1.0F);
   ctx->Current.RasterColor[2]
      = CLAMP(ctx->Current.Attrib[VERT_ATTRIB_COLOR0][2], 0.0F, 1.0F);
   ctx->Current.RasterColor[3]
      = CLAMP(ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3], 0.0F, 1.0F);
   ctx->Current.RasterSecondaryColor[0]
      = CLAMP(ctx->Current.Attrib[VERT_ATTRIB_COLOR1][0], 0.0F, 1.0F);
   ctx->Current.RasterSecondaryColor[1]
      = CLAMP(ctx->Current.Attrib[VERT_ATTRIB_COLOR1][1], 0.0F, 1.0F);
   ctx->Current.RasterSecondaryColor[2]
      = CLAMP(ctx->Current.Attrib[VERT_ATTRIB_COLOR1][2], 0.0F, 1.0F);
   ctx->Current.RasterSecondaryColor[3]
      = CLAMP(ctx->Current.Attrib[VERT_ATTRIB_COLOR1][3], 0.0F, 1.0F);

   /* raster texcoord = current texcoord */
   COPY_4FV( ctx->Current.RasterTexCoords, ctx->Current.Attrib[VERT_ATTRIB_TEX] );

   if (ctx->RenderMode==GL_SELECT) {
      _mesa_update_hitflag( ctx, ctx->Current.RasterPos[2] );
   }
}
示例#17
0
文件: texenv.c 项目: cpp3ds/gl3ds
static void
set_env_color(struct gl_context *ctx,
              struct gl_texture_unit *texUnit,
              const GLfloat *color)
{
   if (TEST_EQ_4V(color, texUnit->EnvColorUnclamped))
      return;
   FLUSH_VERTICES(ctx, _NEW_TEXTURE);
   COPY_4FV(texUnit->EnvColorUnclamped, color);
   texUnit->EnvColor[0] = CLAMP(color[0], 0.0F, 1.0F);
   texUnit->EnvColor[1] = CLAMP(color[1], 0.0F, 1.0F);
   texUnit->EnvColor[2] = CLAMP(color[2], 0.0F, 1.0F);
   texUnit->EnvColor[3] = CLAMP(color[3], 0.0F, 1.0F);
}
示例#18
0
void _tnl_generic_copy_pv_extras( struct gl_context *ctx,
                                  GLuint dst, GLuint src )
{
    struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;

    /* See above comment:
     */
    if (VB->BackfaceColorPtr && VB->BackfaceColorPtr->stride) {
        COPY_4FV( VB->BackfaceColorPtr->data[dst],
                  VB->BackfaceColorPtr->data[src] );
    }

    if (VB->BackfaceSecondaryColorPtr) {
        COPY_4FV( VB->BackfaceSecondaryColorPtr->data[dst],
                  VB->BackfaceSecondaryColorPtr->data[src] );
    }

    if (VB->BackfaceIndexPtr) {
        VB->BackfaceIndexPtr->data[dst][0] = VB->BackfaceIndexPtr->data[src][0];
    }

    _tnl_generic_copy_pv(ctx, dst, src);
}
示例#19
0
static void
set_env_color(GLcontext *ctx,
              struct gl_texture_unit *texUnit,
              const GLfloat *color)
{
   GLfloat tmp[4];
   tmp[0] = CLAMP(color[0], 0.0F, 1.0F);
   tmp[1] = CLAMP(color[1], 0.0F, 1.0F);
   tmp[2] = CLAMP(color[2], 0.0F, 1.0F);
   tmp[3] = CLAMP(color[3], 0.0F, 1.0F);
   if (TEST_EQ_4V(tmp, texUnit->EnvColor))
      return;
   FLUSH_VERTICES(ctx, _NEW_TEXTURE);
   COPY_4FV(texUnit->EnvColor, tmp);
}
示例#20
0
/* Perform a straight copy between pairs of materials.
 */
void _mesa_copy_material_pairs( struct gl_material dst[2],
			     const struct gl_material src[2],
			     GLuint bitmask )
{
   if (bitmask & FRONT_EMISSION_BIT) {
      COPY_4FV( dst[0].Emission, src[0].Emission );
   }
   if (bitmask & BACK_EMISSION_BIT) {
      COPY_4FV( dst[1].Emission, src[1].Emission );
   }
   if (bitmask & FRONT_AMBIENT_BIT) {
      COPY_4FV( dst[0].Ambient, src[0].Ambient );
   }
   if (bitmask & BACK_AMBIENT_BIT) {
      COPY_4FV( dst[1].Ambient, src[1].Ambient );
   }
   if (bitmask & FRONT_DIFFUSE_BIT) {
      COPY_4FV( dst[0].Diffuse, src[0].Diffuse );
   }
   if (bitmask & BACK_DIFFUSE_BIT) {
      COPY_4FV( dst[1].Diffuse, src[1].Diffuse );
   }
   if (bitmask & FRONT_SPECULAR_BIT) {
      COPY_4FV( dst[0].Specular, src[0].Specular );
   }
   if (bitmask & BACK_SPECULAR_BIT) {
      COPY_4FV( dst[1].Specular, src[1].Specular );
   }
   if (bitmask & FRONT_SHININESS_BIT) {
      dst[0].Shininess = src[0].Shininess;
   }
   if (bitmask & BACK_SHININESS_BIT) {
      dst[1].Shininess = src[1].Shininess;
   }
   if (bitmask & FRONT_INDEXES_BIT) {
      dst[0].AmbientIndex = src[0].AmbientIndex;
      dst[0].DiffuseIndex = src[0].DiffuseIndex;
      dst[0].SpecularIndex = src[0].SpecularIndex;
   }
   if (bitmask & BACK_INDEXES_BIT) {
      dst[1].AmbientIndex = src[1].AmbientIndex;
      dst[1].DiffuseIndex = src[1].DiffuseIndex;
      dst[1].SpecularIndex = src[1].SpecularIndex;
   }
}
示例#21
0
void GLAPIENTRY
_mesa_ClearAccum( GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha )
{
   GLfloat tmp[4];
   GET_CURRENT_CONTEXT(ctx);
   ASSERT_OUTSIDE_BEGIN_END(ctx);

   tmp[0] = CLAMP( red,   -1.0F, 1.0F );
   tmp[1] = CLAMP( green, -1.0F, 1.0F );
   tmp[2] = CLAMP( blue,  -1.0F, 1.0F );
   tmp[3] = CLAMP( alpha, -1.0F, 1.0F );

   if (TEST_EQ_4V(tmp, ctx->Accum.ClearColor))
      return;

   COPY_4FV( ctx->Accum.ClearColor, tmp );
}
示例#22
0
/**
 * Set the blending color.
 *
 * \param red red color component.
 * \param green green color component.
 * \param blue blue color component.
 * \param alpha alpha color component.
 *
 * \sa glBlendColor().
 *
 * Clamps the parameters and updates gl_colorbuffer_attrib::BlendColor.  On a
 * change, flushes the vertices and notifies the driver via
 * dd_function_table::BlendColor callback.
 */
void GLAPIENTRY
_mesa_BlendColor( GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha )
{
   GLfloat tmp[4];
   GET_CURRENT_CONTEXT(ctx);
   ASSERT_OUTSIDE_BEGIN_END(ctx);

   tmp[0] = CLAMP( red,   0.0F, 1.0F );
   tmp[1] = CLAMP( green, 0.0F, 1.0F );
   tmp[2] = CLAMP( blue,  0.0F, 1.0F );
   tmp[3] = CLAMP( alpha, 0.0F, 1.0F );

   if (TEST_EQ_4V(tmp, ctx->Color.BlendColor))
      return;

   FLUSH_VERTICES(ctx, _NEW_COLOR);
   COPY_4FV( ctx->Color.BlendColor, tmp );

   if (ctx->Driver.BlendColor)
      (*ctx->Driver.BlendColor)(ctx, tmp);
}
示例#23
0
/**
 * Upload SAMPLER_BORDER_COLOR_STATE.
 */
void
upload_default_color(struct brw_context *brw,
                     struct gl_sampler_object *sampler,
                     int unit,
                     uint32_t *sdc_offset)
{
   struct gl_context *ctx = &brw->ctx;
   struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
   struct gl_texture_object *texObj = texUnit->_Current;
   struct gl_texture_image *firstImage = texObj->Image[0][texObj->BaseLevel];
   float color[4];

   switch (firstImage->_BaseFormat) {
   case GL_DEPTH_COMPONENT:
      /* GL specs that border color for depth textures is taken from the
       * R channel, while the hardware uses A.  Spam R into all the
       * channels for safety.
       */
      color[0] = sampler->BorderColor.f[0];
      color[1] = sampler->BorderColor.f[0];
      color[2] = sampler->BorderColor.f[0];
      color[3] = sampler->BorderColor.f[0];
      break;
   case GL_ALPHA:
      color[0] = 0.0;
      color[1] = 0.0;
      color[2] = 0.0;
      color[3] = sampler->BorderColor.f[3];
      break;
   case GL_INTENSITY:
      color[0] = sampler->BorderColor.f[0];
      color[1] = sampler->BorderColor.f[0];
      color[2] = sampler->BorderColor.f[0];
      color[3] = sampler->BorderColor.f[0];
      break;
   case GL_LUMINANCE:
      color[0] = sampler->BorderColor.f[0];
      color[1] = sampler->BorderColor.f[0];
      color[2] = sampler->BorderColor.f[0];
      color[3] = 1.0;
      break;
   case GL_LUMINANCE_ALPHA:
      color[0] = sampler->BorderColor.f[0];
      color[1] = sampler->BorderColor.f[0];
      color[2] = sampler->BorderColor.f[0];
      color[3] = sampler->BorderColor.f[3];
      break;
   default:
      color[0] = sampler->BorderColor.f[0];
      color[1] = sampler->BorderColor.f[1];
      color[2] = sampler->BorderColor.f[2];
      color[3] = sampler->BorderColor.f[3];
      break;
   }

   /* In some cases we use an RGBA surface format for GL RGB textures,
    * where we've initialized the A channel to 1.0.  We also have to set
    * the border color alpha to 1.0 in that case.
    */
   if (firstImage->_BaseFormat == GL_RGB)
      color[3] = 1.0;

   if (brw->gen >= 8) {
      /* On Broadwell, the border color is represented as four 32-bit floats,
       * integers, or unsigned values, interpreted according to the surface
       * format.  This matches the sampler->BorderColor union exactly.  Since
       * we use floats both here and in the above reswizzling code, we preserve
       * the original bit pattern.  So we actually handle all three formats.
       */
      float *sdc = brw_state_batch(brw, AUB_TRACE_SAMPLER_DEFAULT_COLOR,
                                   4 * 4, 64, sdc_offset);
      COPY_4FV(sdc, color);
   } else if (brw->gen == 5 || brw->gen == 6) {
      struct gen5_sampler_default_color *sdc;

      sdc = brw_state_batch(brw, AUB_TRACE_SAMPLER_DEFAULT_COLOR,
			    sizeof(*sdc), 32, sdc_offset);

      memset(sdc, 0, sizeof(*sdc));

      UNCLAMPED_FLOAT_TO_UBYTE(sdc->ub[0], color[0]);
      UNCLAMPED_FLOAT_TO_UBYTE(sdc->ub[1], color[1]);
      UNCLAMPED_FLOAT_TO_UBYTE(sdc->ub[2], color[2]);
      UNCLAMPED_FLOAT_TO_UBYTE(sdc->ub[3], color[3]);

      UNCLAMPED_FLOAT_TO_USHORT(sdc->us[0], color[0]);
      UNCLAMPED_FLOAT_TO_USHORT(sdc->us[1], color[1]);
      UNCLAMPED_FLOAT_TO_USHORT(sdc->us[2], color[2]);
      UNCLAMPED_FLOAT_TO_USHORT(sdc->us[3], color[3]);

      UNCLAMPED_FLOAT_TO_SHORT(sdc->s[0], color[0]);
      UNCLAMPED_FLOAT_TO_SHORT(sdc->s[1], color[1]);
      UNCLAMPED_FLOAT_TO_SHORT(sdc->s[2], color[2]);
      UNCLAMPED_FLOAT_TO_SHORT(sdc->s[3], color[3]);

      sdc->hf[0] = _mesa_float_to_half(color[0]);
      sdc->hf[1] = _mesa_float_to_half(color[1]);
      sdc->hf[2] = _mesa_float_to_half(color[2]);
      sdc->hf[3] = _mesa_float_to_half(color[3]);

      sdc->b[0] = sdc->s[0] >> 8;
      sdc->b[1] = sdc->s[1] >> 8;
      sdc->b[2] = sdc->s[2] >> 8;
      sdc->b[3] = sdc->s[3] >> 8;

      sdc->f[0] = color[0];
      sdc->f[1] = color[1];
      sdc->f[2] = color[2];
      sdc->f[3] = color[3];
   } else {
示例#24
0
文件: texenv.c 项目: mariuz/haiku
void GLAPIENTRY
_mesa_GetTexEnvfv( GLenum target, GLenum pname, GLfloat *params )
{
   GLuint maxUnit;
   const struct gl_texture_unit *texUnit;
   GET_CURRENT_CONTEXT(ctx);
   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, "glGetTexEnvfv(current unit)");
      return;
   }

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

   if (target == GL_TEXTURE_ENV) {
      if (pname == GL_TEXTURE_ENV_COLOR) {
         COPY_4FV( params, texUnit->EnvColor );
      }
      else {
         GLint val = get_texenvi(ctx, texUnit, pname);
         if (val >= 0) {
            *params = (GLfloat) val;
         }
      }
   }
   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, "glGetTexEnvfv(target)" );
	 return;
      }
      if (pname == GL_TEXTURE_LOD_BIAS_EXT) {
         *params = texUnit->LodBias;
      }
      else {
         _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnvfv(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, "glGetTexEnvfv(target)" );
         return;
      }
      if (pname == GL_COORD_REPLACE_NV) {
         *params = (GLfloat) ctx->Point.CoordReplace[ctx->Texture.CurrentUnit];
      }
      else {
         _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)" );
         return;
      }
   }
   else {
      _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnvfv(target)" );
      return;
   }
}
示例#25
0
文件: texenv.c 项目: mariuz/haiku
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 );
   }
}
示例#26
0
/**
 * Perform glClear where mask contains only color, depth, and/or stencil.
 *
 * The implementation is based on calling into Mesa to set GL state and
 * performing normal triangle rendering.  The intent of this path is to
 * have as generic a path as possible, so that any driver could make use of
 * it.
 */
void
intel_clear_tris(GLcontext *ctx, GLbitfield mask)
{
   struct intel_context *intel = intel_context(ctx);
   GLfloat dst_z;
   struct gl_framebuffer *fb = ctx->DrawBuffer;
   int i;
   GLboolean saved_fp_enable = GL_FALSE, saved_vp_enable = GL_FALSE;
   GLuint saved_shader_program = 0;
   unsigned int saved_active_texture;
   struct gl_array_object *arraySave = NULL;

   if (!intel->clear.arrayObj)
      init_clear(ctx);

   assert((mask & ~(TRI_CLEAR_COLOR_BITS | BUFFER_BIT_DEPTH |
		    BUFFER_BIT_STENCIL)) == 0);

   _mesa_PushAttrib(GL_COLOR_BUFFER_BIT |
		    GL_CURRENT_BIT |
		    GL_DEPTH_BUFFER_BIT |
		    GL_ENABLE_BIT |
		    GL_POLYGON_BIT |
		    GL_STENCIL_BUFFER_BIT |
		    GL_TRANSFORM_BIT |
		    GL_CURRENT_BIT);
   saved_active_texture = ctx->Texture.CurrentUnit;

   /* Disable existing GL state we don't want to apply to a clear. */
   _mesa_Disable(GL_ALPHA_TEST);
   _mesa_Disable(GL_BLEND);
   _mesa_Disable(GL_CULL_FACE);
   _mesa_Disable(GL_FOG);
   _mesa_Disable(GL_POLYGON_SMOOTH);
   _mesa_Disable(GL_POLYGON_STIPPLE);
   _mesa_Disable(GL_POLYGON_OFFSET_FILL);
   _mesa_Disable(GL_LIGHTING);
   _mesa_Disable(GL_CLIP_PLANE0);
   _mesa_Disable(GL_CLIP_PLANE1);
   _mesa_Disable(GL_CLIP_PLANE2);
   _mesa_Disable(GL_CLIP_PLANE3);
   _mesa_Disable(GL_CLIP_PLANE4);
   _mesa_Disable(GL_CLIP_PLANE5);
   _mesa_PolygonMode(GL_FRONT_AND_BACK, GL_FILL);
   if (ctx->Extensions.ARB_fragment_program && ctx->FragmentProgram.Enabled) {
      saved_fp_enable = GL_TRUE;
      _mesa_Disable(GL_FRAGMENT_PROGRAM_ARB);
   }
   if (ctx->Extensions.ARB_vertex_program && ctx->VertexProgram.Enabled) {
      saved_vp_enable = GL_TRUE;
      _mesa_Disable(GL_VERTEX_PROGRAM_ARB);
   }
   if (ctx->Extensions.ARB_shader_objects && ctx->Shader.CurrentProgram) {
      saved_shader_program = ctx->Shader.CurrentProgram->Name;
      _mesa_UseProgramObjectARB(0);
   }

   if (ctx->Texture._EnabledUnits != 0) {
      int i;

      for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
	 _mesa_ActiveTextureARB(GL_TEXTURE0 + i);
	 _mesa_Disable(GL_TEXTURE_1D);
	 _mesa_Disable(GL_TEXTURE_2D);
	 _mesa_Disable(GL_TEXTURE_3D);
	 if (ctx->Extensions.ARB_texture_cube_map)
	    _mesa_Disable(GL_TEXTURE_CUBE_MAP_ARB);
	 if (ctx->Extensions.NV_texture_rectangle)
	    _mesa_Disable(GL_TEXTURE_RECTANGLE_NV);
	 if (ctx->Extensions.MESA_texture_array) {
	    _mesa_Disable(GL_TEXTURE_1D_ARRAY_EXT);
	    _mesa_Disable(GL_TEXTURE_2D_ARRAY_EXT);
	 }
      }
   }

   /* save current array object, bind our private one */
   _mesa_reference_array_object(ctx, &arraySave, ctx->Array.ArrayObj);
   _mesa_reference_array_object(ctx, &ctx->Array.ArrayObj, intel->clear.arrayObj);

   intel_meta_set_passthrough_transform(intel);

   for (i = 0; i < 4; i++) {
      COPY_4FV(intel->clear.color[i], ctx->Color.ClearColor);
   }

   /* convert clear Z from [0,1] to NDC coord in [-1,1] */
   dst_z = -1.0 + 2.0 * ctx->Depth.Clear;

   /* Prepare the vertices, which are the same regardless of which buffer we're
    * drawing to.
    */
   intel->clear.vertices[0][0] = fb->_Xmin;
   intel->clear.vertices[0][1] = fb->_Ymin;
   intel->clear.vertices[0][2] = dst_z;
   intel->clear.vertices[1][0] = fb->_Xmax;
   intel->clear.vertices[1][1] = fb->_Ymin;
   intel->clear.vertices[1][2] = dst_z;
   intel->clear.vertices[2][0] = fb->_Xmax;
   intel->clear.vertices[2][1] = fb->_Ymax;
   intel->clear.vertices[2][2] = dst_z;
   intel->clear.vertices[3][0] = fb->_Xmin;
   intel->clear.vertices[3][1] = fb->_Ymax;
   intel->clear.vertices[3][2] = dst_z;

   while (mask != 0) {
      GLuint this_mask = 0;
      GLuint color_bit;

      color_bit = _mesa_ffs(mask & TRI_CLEAR_COLOR_BITS);
      if (color_bit != 0)
	 this_mask |= (1 << (color_bit - 1));

      /* Clear depth/stencil in the same pass as color. */
      this_mask |= (mask & (BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL));

      /* Select the current color buffer and use the color write mask if
       * we have one, otherwise don't write any color channels.
       */
      if (this_mask & BUFFER_BIT_FRONT_LEFT)
	 _mesa_DrawBuffer(GL_FRONT_LEFT);
      else if (this_mask & BUFFER_BIT_BACK_LEFT)
	 _mesa_DrawBuffer(GL_BACK_LEFT);
      else if (color_bit != 0)
	 _mesa_DrawBuffer(GL_COLOR_ATTACHMENT0 +
			  (color_bit - BUFFER_COLOR0 - 1));
      else
	 _mesa_ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);

      /* Control writing of the depth clear value to depth. */
      if (this_mask & BUFFER_BIT_DEPTH) {
	 _mesa_DepthFunc(GL_ALWAYS);
	 _mesa_Enable(GL_DEPTH_TEST);
      } else {
	 _mesa_Disable(GL_DEPTH_TEST);
	 _mesa_DepthMask(GL_FALSE);
      }

      /* Control writing of the stencil clear value to stencil. */
      if (this_mask & BUFFER_BIT_STENCIL) {
	 _mesa_Enable(GL_STENCIL_TEST);
	 _mesa_StencilOpSeparate(GL_FRONT_AND_BACK,
				 GL_REPLACE, GL_REPLACE, GL_REPLACE);
	 _mesa_StencilFuncSeparate(GL_FRONT_AND_BACK, GL_ALWAYS,
				   ctx->Stencil.Clear,
				   ctx->Stencil.WriteMask[0]);
      } else {
	 _mesa_Disable(GL_STENCIL_TEST);
      }

      _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);

      mask &= ~this_mask;
   }

   intel_meta_restore_transform(intel);

   _mesa_ActiveTextureARB(GL_TEXTURE0 + saved_active_texture);
   if (saved_fp_enable)
      _mesa_Enable(GL_FRAGMENT_PROGRAM_ARB);
   if (saved_vp_enable)
      _mesa_Enable(GL_VERTEX_PROGRAM_ARB);

   if (saved_shader_program)
      _mesa_UseProgramObjectARB(saved_shader_program);

   _mesa_PopAttrib();

   /* restore current array object */
   _mesa_reference_array_object(ctx, &ctx->Array.ArrayObj, arraySave);
   _mesa_reference_array_object(ctx, &arraySave, NULL);
}
示例#27
0
文件: texenv.c 项目: cpp3ds/gl3ds
void glGetTexEnvfv( GLenum target, GLenum pname, GLfloat *params )
{
   GLuint maxUnit;
   const struct gl_texture_unit *texUnit;
   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, "glGetTexEnvfv(current unit)");
      return;
   }

   texUnit = _mesa_get_current_tex_unit(ctx);

   if (target == GL_TEXTURE_ENV) {
      if (pname == GL_TEXTURE_ENV_COLOR) {
         if(ctx->NewState & (_NEW_BUFFERS | _NEW_FRAG_CLAMP))
            _mesa_update_state(ctx);
         if (_mesa_get_clamp_fragment_color(ctx, ctx->DrawBuffer))
            COPY_4FV( params, texUnit->EnvColor );
         else
            COPY_4FV( params, texUnit->EnvColorUnclamped );
      }
      else {
         GLint val = get_texenvi(ctx, texUnit, pname);
         if (val >= 0) {
            *params = (GLfloat) val;
         }
      }
   }
   else if (target == GL_TEXTURE_FILTER_CONTROL) {
      if (pname == GL_TEXTURE_LOD_BIAS) {
         *params = texUnit->LodBias;
      }
      else {
         _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnvfv(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, "glGetTexEnvfv(target)" );
//         return;
//      }
//      if (pname == GL_COORD_REPLACE_NV) {
//         *params = (GLfloat) ctx->Point.CoordReplace[ctx->Texture.CurrentUnit];
//      }
//      else {
//         _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)" );
//         return;
//      }
//   }
   else {
      _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnvfv(target)" );
      return;
   }
}
示例#28
0
static void
_tnl_Materialfv( GLenum face, GLenum pname, const GLfloat *params )
{
   GET_CURRENT_CONTEXT(ctx);
   TNLcontext *tnl = TNL_CONTEXT(ctx);
   struct immediate *IM = TNL_CURRENT_IM(ctx);
   GLuint count = IM->Count;
   struct gl_material *mat;
   GLuint bitmask = _mesa_material_bitmask(ctx, face, pname, ~0, "Materialfv");

   if (bitmask == 0)
      return;
   
   if (MESA_VERBOSE & VERBOSE_API)
      fprintf(stderr, "_tnl_Materialfv\n");

   if (tnl->IsolateMaterials &&
       !(IM->BeginState & VERT_BEGIN_1)) /* heuristic */
   {
      _tnl_flush_immediate( IM );      
      IM = TNL_CURRENT_IM(ctx);
      count = IM->Count;
   }

   if (!(IM->Flag[count] & VERT_MATERIAL)) {
      if (!IM->Material) {
	 IM->Material = (GLmaterial (*)[2]) MALLOC( sizeof(GLmaterial) *
						    IMM_SIZE * 2 );
	 IM->MaterialMask = (GLuint *) MALLOC( sizeof(GLuint) * IMM_SIZE );
	 IM->MaterialMask[IM->LastMaterial] = 0;
      }
      else if (IM->MaterialOrMask & ~bitmask) {
	 _mesa_copy_material_pairs( IM->Material[count],
				    IM->Material[IM->LastMaterial],
				    IM->MaterialOrMask & ~bitmask );
      }

      IM->Flag[count] |= VERT_MATERIAL;
      IM->MaterialMask[count] = 0;
      IM->MaterialAndMask &= IM->MaterialMask[IM->LastMaterial];
      IM->LastMaterial = count;
   }

   IM->MaterialOrMask |= bitmask;
   IM->MaterialMask[count] |= bitmask;
   mat = IM->Material[count];

   if (bitmask & FRONT_AMBIENT_BIT) {
      COPY_4FV( mat[0].Ambient, params );
   }
   if (bitmask & BACK_AMBIENT_BIT) {
      COPY_4FV( mat[1].Ambient, params );
   }
   if (bitmask & FRONT_DIFFUSE_BIT) {
      COPY_4FV( mat[0].Diffuse, params );
   }
   if (bitmask & BACK_DIFFUSE_BIT) {
      COPY_4FV( mat[1].Diffuse, params );
   }
   if (bitmask & FRONT_SPECULAR_BIT) {
      COPY_4FV( mat[0].Specular, params );
   }
   if (bitmask & BACK_SPECULAR_BIT) {
      COPY_4FV( mat[1].Specular, params );
   }
   if (bitmask & FRONT_EMISSION_BIT) {
      COPY_4FV( mat[0].Emission, params );
   }
   if (bitmask & BACK_EMISSION_BIT) {
      COPY_4FV( mat[1].Emission, params );
   }
   if (bitmask & FRONT_SHININESS_BIT) {
      GLfloat shininess = CLAMP( params[0], 0.0F, 128.0F );
      mat[0].Shininess = shininess;
   }
   if (bitmask & BACK_SHININESS_BIT) {
      GLfloat shininess = CLAMP( params[0], 0.0F, 128.0F );
      mat[1].Shininess = shininess;
   }
   if (bitmask & FRONT_INDEXES_BIT) {
      mat[0].AmbientIndex = params[0];
      mat[0].DiffuseIndex = params[1];
      mat[0].SpecularIndex = params[2];
   }
   if (bitmask & BACK_INDEXES_BIT) {
      mat[1].AmbientIndex = params[0];
      mat[1].DiffuseIndex = params[1];
      mat[1].SpecularIndex = params[2];
   }

   if (tnl->IsolateMaterials && 
       !(IM->BeginState & VERT_BEGIN_1)) /* heuristic */
   {
      _tnl_flush_immediate( IM );
   }
}
/**
 * glRasterPos transformation.  Typically called via ctx->Driver.RasterPos().
 *
 * \param vObj  vertex position in object space
 */
void
_mesa_RasterPos(struct gl_context *ctx, const GLfloat vObj[4])
{
   if (_mesa_arb_vertex_program_enabled(ctx)) {
      /* XXX implement this */
      _mesa_problem(ctx, "Vertex programs not implemented for glRasterPos");
      return;
   }
   else {
      GLfloat eye[4], clip[4], ndc[3], d;
      GLfloat *norm, eyenorm[3];
      GLfloat *objnorm = ctx->Current.Attrib[VERT_ATTRIB_NORMAL];
      float scale[3], translate[3];

      /* apply modelview matrix:  eye = MV * obj */
      TRANSFORM_POINT( eye, ctx->ModelviewMatrixStack.Top->m, vObj );
      /* apply projection matrix:  clip = Proj * eye */
      TRANSFORM_POINT( clip, ctx->ProjectionMatrixStack.Top->m, eye );

      /* clip to view volume. */
      if (!ctx->Transform.DepthClamp) {
         if (viewclip_point_z(clip) == 0) {
            ctx->Current.RasterPosValid = GL_FALSE;
            return;
         }
      }
      if (!ctx->Transform.RasterPositionUnclipped) {
         if (viewclip_point_xy(clip) == 0) {
            ctx->Current.RasterPosValid = GL_FALSE;
            return;
         }
      }

      /* clip to user clipping planes */
      if (ctx->Transform.ClipPlanesEnabled && !userclip_point(ctx, clip)) {
         ctx->Current.RasterPosValid = GL_FALSE;
         return;
      }

      /* ndc = clip / W */
      d = (clip[3] == 0.0F) ? 1.0F : 1.0F / clip[3];
      ndc[0] = clip[0] * d;
      ndc[1] = clip[1] * d;
      ndc[2] = clip[2] * d;
      /* wincoord = viewport_mapping(ndc) */
      _mesa_get_viewport_xform(ctx, 0, scale, translate);
      ctx->Current.RasterPos[0] = ndc[0] * scale[0] + translate[0];
      ctx->Current.RasterPos[1] = ndc[1] * scale[1] + translate[1];
      ctx->Current.RasterPos[2] = ndc[2] * scale[2] + translate[2];
      ctx->Current.RasterPos[3] = clip[3];

      if (ctx->Transform.DepthClamp) {
	 ctx->Current.RasterPos[3] = CLAMP(ctx->Current.RasterPos[3],
					   ctx->ViewportArray[0].Near,
					   ctx->ViewportArray[0].Far);
      }

      /* compute raster distance */
      if (ctx->Fog.FogCoordinateSource == GL_FOG_COORDINATE_EXT)
         ctx->Current.RasterDistance = ctx->Current.Attrib[VERT_ATTRIB_FOG][0];
      else
         ctx->Current.RasterDistance =
                        sqrtf( eye[0]*eye[0] + eye[1]*eye[1] + eye[2]*eye[2] );

      /* compute transformed normal vector (for lighting or texgen) */
      if (ctx->_NeedEyeCoords) {
         const GLfloat *inv = ctx->ModelviewMatrixStack.Top->inv;
         TRANSFORM_NORMAL( eyenorm, objnorm, inv );
         norm = eyenorm;
      }
      else {
         norm = objnorm;
      }

      /* update raster color */
      if (ctx->Light.Enabled) {
         /* lighting */
         shade_rastpos( ctx, vObj, norm,
                        ctx->Current.RasterColor,
                        ctx->Current.RasterSecondaryColor );
      }
      else {
         /* use current color */
	 COPY_4FV(ctx->Current.RasterColor,
		  ctx->Current.Attrib[VERT_ATTRIB_COLOR0]);
	 COPY_4FV(ctx->Current.RasterSecondaryColor,
		  ctx->Current.Attrib[VERT_ATTRIB_COLOR1]);
      }

      /* texture coords */
      {
         GLuint u;
         for (u = 0; u < ctx->Const.MaxTextureCoordUnits; u++) {
            GLfloat tc[4];
            COPY_4V(tc, ctx->Current.Attrib[VERT_ATTRIB_TEX0 + u]);
            if (ctx->Texture.Unit[u].TexGenEnabled) {
               compute_texgen(ctx, vObj, eye, norm, u, tc);
            }
            TRANSFORM_POINT(ctx->Current.RasterTexCoords[u],
                            ctx->TextureMatrixStack[u].Top->m, tc);
         }
      }

      ctx->Current.RasterPosValid = GL_TRUE;
   }

   if (ctx->RenderMode == GL_SELECT) {
      _mesa_update_hitflag( ctx, ctx->Current.RasterPos[2] );
   }
}
示例#30
0
void GLAPIENTRY
_mesa_TexGenfv( GLenum coord, GLenum pname, const GLfloat *params )
{
   struct gl_texture_unit *texUnit;
   struct gl_texgen *texgen;
   GET_CURRENT_CONTEXT(ctx);
   ASSERT_OUTSIDE_BEGIN_END(ctx);

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

   if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureCoordUnits) {
      _mesa_error(ctx, GL_INVALID_OPERATION, "glTexGen(current unit)");
      return;
   }

   texUnit = _mesa_get_current_tex_unit(ctx);

   texgen = get_texgen(texUnit, coord);
   if (!texgen) {
      _mesa_error(ctx, GL_INVALID_ENUM, "glTexGen(coord)");
      return;
   }

   switch (pname) {
   case GL_TEXTURE_GEN_MODE:
      {
         GLenum mode = (GLenum) (GLint) params[0];
         GLbitfield bit = 0x0;
         if (texgen->Mode == mode)
            return;
         switch (mode) {
         case GL_OBJECT_LINEAR:
            bit = TEXGEN_OBJ_LINEAR;
            break;
         case GL_EYE_LINEAR:
            bit = TEXGEN_EYE_LINEAR;
            break;
         case GL_SPHERE_MAP:
            if (coord == GL_S || coord == GL_T)
               bit = TEXGEN_SPHERE_MAP;
            break;
         case GL_REFLECTION_MAP_NV:
            if (coord != GL_Q)
               bit = TEXGEN_REFLECTION_MAP_NV;
            break;
         case GL_NORMAL_MAP_NV:
            if (coord != GL_Q)
               bit = TEXGEN_NORMAL_MAP_NV;
            break;
         default:
            ; /* nop */
         }
         if (!bit) {
            _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(param)" );
            return;
         }
         FLUSH_VERTICES(ctx, _NEW_TEXTURE);
         texgen->Mode = mode;
         texgen->_ModeBit = bit;
      }
      break;

   case GL_OBJECT_PLANE:
      {
         if (TEST_EQ_4V(texgen->ObjectPlane, params))
            return;
         FLUSH_VERTICES(ctx, _NEW_TEXTURE);
         COPY_4FV(texgen->ObjectPlane, params);
      }
      break;

   case GL_EYE_PLANE:
      {
         GLfloat tmp[4];
         /* Transform plane equation by the inverse modelview matrix */
         if (_math_matrix_is_dirty(ctx->ModelviewMatrixStack.Top)) {
            _math_matrix_analyse(ctx->ModelviewMatrixStack.Top);
         }
         _mesa_transform_vector(tmp, params,
                                ctx->ModelviewMatrixStack.Top->inv);
         if (TEST_EQ_4V(texgen->EyePlane, tmp))
            return;
         FLUSH_VERTICES(ctx, _NEW_TEXTURE);
         COPY_4FV(texgen->EyePlane, tmp);
      }
      break;

   default:
      _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(pname)" );
      return;
   }

   if (ctx->Driver.TexGen)
      ctx->Driver.TexGen( ctx, coord, pname, params );
}