示例#1
0
文件: s_fragprog.c 项目: mariuz/haiku
/**
 * Fetch a texel with given lod.
 * Called via machine->FetchTexelLod()
 */
static void
fetch_texel_lod( GLcontext *ctx, const GLfloat texcoord[4], GLfloat lambda,
                 GLuint unit, GLfloat color[4] )
{
   const struct gl_texture_object *texObj = ctx->Texture.Unit[unit]._Current;

   if (texObj) {
      SWcontext *swrast = SWRAST_CONTEXT(ctx);
      GLchan rgba[4];

      lambda = CLAMP(lambda, texObj->MinLod, texObj->MaxLod);

      /* XXX use a float-valued TextureSample routine here!!! */
      swrast->TextureSample[unit](ctx, texObj, 1,
                                  (const GLfloat (*)[4]) texcoord,
                                  &lambda, &rgba);
      color[0] = CHAN_TO_FLOAT(rgba[0]);
      color[1] = CHAN_TO_FLOAT(rgba[1]);
      color[2] = CHAN_TO_FLOAT(rgba[2]);
      color[3] = CHAN_TO_FLOAT(rgba[3]);
   }
   else {
      color[0] = color[1] = color[2] = 0.0F;
      color[3] = 1.0F;
   }
}
示例#2
0
static void feedback_vertex( GLcontext *ctx,
                             const SWvertex *v, const SWvertex *pv )
{
    const GLuint texUnit = 0;  /* See section 5.3 of 1.2.1 spec */
    GLfloat win[4];
    GLfloat color[4];
    GLfloat tc[4];

    win[0] = v->win[0];
    win[1] = v->win[1];
    win[2] = v->win[2] / ctx->DepthMaxF;
    win[3] = 1.0F / v->win[3];

    color[0] = CHAN_TO_FLOAT(pv->color[0]);
    color[1] = CHAN_TO_FLOAT(pv->color[1]);
    color[2] = CHAN_TO_FLOAT(pv->color[2]);
    color[3] = CHAN_TO_FLOAT(pv->color[3]);

    if (v->texcoord[texUnit][3] != 1.0 &&
            v->texcoord[texUnit][3] != 0.0) {
        GLfloat invq = 1.0F / v->texcoord[texUnit][3];
        tc[0] = v->texcoord[texUnit][0] * invq;
        tc[1] = v->texcoord[texUnit][1] * invq;
        tc[2] = v->texcoord[texUnit][2] * invq;
        tc[3] = v->texcoord[texUnit][3];
    }
    else {
        COPY_4V(tc, v->texcoord[texUnit]);
    }

    _mesa_feedback_vertex( ctx, win, color, (GLfloat) v->index, tc );
}
示例#3
0
/**
 * Fetch a texel with the given partial derivatives to compute a level
 * of detail in the mipmap.
 */
static void
fetch_texel_deriv( GLcontext *ctx, const GLfloat texcoord[4],
                   const GLfloat texdx[4], const GLfloat texdy[4],
                   GLfloat lodBias, GLuint unit, GLfloat color[4] )
{
   SWcontext *swrast = SWRAST_CONTEXT(ctx);
   const struct gl_texture_object *texObj = ctx->Texture.Unit[unit]._Current;
   GLfloat lambda;
   GLchan rgba[4];

   if (texObj) {
      const struct gl_texture_image *texImg = texObj->Image[0][texObj->BaseLevel];
      const GLfloat texW = (GLfloat) texImg->WidthScale;
      const GLfloat texH = (GLfloat) texImg->HeightScale;

      lambda = _swrast_compute_lambda(texdx[0], texdy[0], /* ds/dx, ds/dy */
                                      texdx[1], texdy[1], /* dt/dx, dt/dy */
                                      texdx[3], texdy[2], /* dq/dx, dq/dy */
                                      texW, texH,
                                      texcoord[0], texcoord[1], texcoord[3],
                                      1.0F / texcoord[3]) + lodBias;

      lambda = CLAMP(lambda, texObj->MinLod, texObj->MaxLod);
   }

   swrast->TextureSample[unit](ctx, texObj, 1, (const GLfloat (*)[4]) texcoord,
                               &lambda, &rgba);
   color[0] = CHAN_TO_FLOAT(rgba[0]);
   color[1] = CHAN_TO_FLOAT(rgba[1]);
   color[2] = CHAN_TO_FLOAT(rgba[2]);
   color[3] = CHAN_TO_FLOAT(rgba[3]);
}
示例#4
0
/**
 * Convert GLchan[n][4] colors to GLfloat[n][4].
 * XXX maybe move into image.c
 */
static void
chan_span_to_float(GLuint n, CONST GLchan in[][4], GLfloat out[][4])
{
   GLuint i;
   for (i = 0; i < n; i++) {
      out[i][RCOMP] = CHAN_TO_FLOAT(in[i][RCOMP]);
      out[i][GCOMP] = CHAN_TO_FLOAT(in[i][GCOMP]);
      out[i][BCOMP] = CHAN_TO_FLOAT(in[i][BCOMP]);
      out[i][ACOMP] = CHAN_TO_FLOAT(in[i][ACOMP]);
   }
}
示例#5
0
static void extract_4chan_4f_rgba( const struct tnl_clipspace_attr *a, GLfloat *out, 
				 const GLubyte *v )
{
   GLchan *c = (GLchan *)v;
   (void) a;

   out[0] = CHAN_TO_FLOAT(c[0]);
   out[1] = CHAN_TO_FLOAT(c[1]);
   out[2] = CHAN_TO_FLOAT(c[2]);
   out[3] = CHAN_TO_FLOAT(c[3]);
}
示例#6
0
void
_mesa_fetch_texel_2d_f_rgba_dxt5(const struct gl_texture_image *texImage,
                                 GLint i, GLint j, GLint k, GLfloat *texel)
{
   /* just sample as GLchan and convert to float here */
   GLchan rgba[4];
   fetch_texel_2d_rgba_dxt5(texImage, i, j, k, rgba);
   texel[RCOMP] = CHAN_TO_FLOAT(rgba[RCOMP]);
   texel[GCOMP] = CHAN_TO_FLOAT(rgba[GCOMP]);
   texel[BCOMP] = CHAN_TO_FLOAT(rgba[BCOMP]);
   texel[ACOMP] = CHAN_TO_FLOAT(rgba[ACOMP]);
}
示例#7
0
static void
init_machine(GLcontext * ctx, struct atifs_machine *machine,
	     const struct ati_fragment_shader *shader,
	     const struct sw_span *span, GLuint col)
{
   GLint i, j;

   for (i = 0; i < 6; i++) {
      for (j = 0; j < 4; j++)
	 ctx->ATIFragmentShader.Machine.Registers[i][j] = 0.0;

   }

   ctx->ATIFragmentShader.Machine.Inputs[ATI_FS_INPUT_PRIMARY][0] =
      CHAN_TO_FLOAT(span->array->rgba[col][0]);
   ctx->ATIFragmentShader.Machine.Inputs[ATI_FS_INPUT_PRIMARY][1] =
      CHAN_TO_FLOAT(span->array->rgba[col][1]);
   ctx->ATIFragmentShader.Machine.Inputs[ATI_FS_INPUT_PRIMARY][2] =
      CHAN_TO_FLOAT(span->array->rgba[col][2]);
   ctx->ATIFragmentShader.Machine.Inputs[ATI_FS_INPUT_PRIMARY][3] =
      CHAN_TO_FLOAT(span->array->rgba[col][3]);

   ctx->ATIFragmentShader.Machine.Inputs[ATI_FS_INPUT_SECONDARY][0] =
      CHAN_TO_FLOAT(span->array->spec[col][0]);
   ctx->ATIFragmentShader.Machine.Inputs[ATI_FS_INPUT_SECONDARY][1] =
      CHAN_TO_FLOAT(span->array->spec[col][1]);
   ctx->ATIFragmentShader.Machine.Inputs[ATI_FS_INPUT_SECONDARY][2] =
      CHAN_TO_FLOAT(span->array->spec[col][2]);
   ctx->ATIFragmentShader.Machine.Inputs[ATI_FS_INPUT_SECONDARY][3] =
      CHAN_TO_FLOAT(span->array->spec[col][3]);

   ctx->ATIFragmentShader.Machine.pass = 0;
}
示例#8
0
文件: s_tcc.c 项目: Ionic/nx-libs
static void TEX( void *cc, const float *texcoord, int unit, float *result )
{
   GLcontext *ctx = (GLcontext *)cc;
   SWcontext *swrast = SWRAST_CONTEXT(ctx);
   GLfloat lambda = 1.0;	/* hack */
   GLchan rgba[4];

   swrast->TextureSample[unit](ctx, unit, ctx->Texture.Unit[unit]._Current,
                               1, (const GLfloat (*)[4]) texcoord,
                               &lambda, &rgba);

   result[0] = CHAN_TO_FLOAT(rgba[0]);
   result[1] = CHAN_TO_FLOAT(rgba[1]);
   result[2] = CHAN_TO_FLOAT(rgba[2]);
   result[3] = CHAN_TO_FLOAT(rgba[3]);
}
示例#9
0
/**
 * Fetch a texel.
 */
static void
fetch_texel(GLcontext * ctx, const GLfloat texcoord[4], GLfloat lambda,
	    GLuint unit, GLfloat color[4])
{
   GLchan rgba[4];
   SWcontext *swrast = SWRAST_CONTEXT(ctx);

   /* XXX use a float-valued TextureSample routine here!!! */
   swrast->TextureSample[unit] (ctx, unit, ctx->Texture.Unit[unit]._Current,
				1, (const GLfloat(*)[4]) texcoord,
				&lambda, &rgba);
   color[0] = CHAN_TO_FLOAT(rgba[0]);
   color[1] = CHAN_TO_FLOAT(rgba[1]);
   color[2] = CHAN_TO_FLOAT(rgba[2]);
   color[3] = CHAN_TO_FLOAT(rgba[3]);
}
示例#10
0
/**
 * Add specular color to primary color, draw point, restore original
 * primary color.
 */
void
_swrast_add_spec_terms_point(GLcontext *ctx, const SWvertex *v0)
{
   SWvertex *ncv0 = (SWvertex *) v0; /* cast away const */
   GLfloat rSum, gSum, bSum;
   GLchan cSave[4];

   /* save */
   COPY_CHAN4(cSave, ncv0->color);
   /* sum */
   rSum = CHAN_TO_FLOAT(ncv0->color[0]) + ncv0->attrib[FRAG_ATTRIB_COL1][0];
   gSum = CHAN_TO_FLOAT(ncv0->color[1]) + ncv0->attrib[FRAG_ATTRIB_COL1][1];
   bSum = CHAN_TO_FLOAT(ncv0->color[2]) + ncv0->attrib[FRAG_ATTRIB_COL1][2];
   UNCLAMPED_FLOAT_TO_CHAN(ncv0->color[0], rSum);
   UNCLAMPED_FLOAT_TO_CHAN(ncv0->color[1], gSum);
   UNCLAMPED_FLOAT_TO_CHAN(ncv0->color[2], bSum);
   /* draw */
   SWRAST_CONTEXT(ctx)->SpecPoint(ctx, ncv0);
   /* restore */
   COPY_CHAN4(ncv0->color, cSave);
}
示例#11
0
void
_swrast_add_spec_terms_line(struct gl_context *ctx,
                            const SWvertex *v0, const SWvertex *v1)
{
   SWvertex *ncv0 = (SWvertex *)v0;
   SWvertex *ncv1 = (SWvertex *)v1;
   GLfloat rSum, gSum, bSum;
   GLchan cSave[2][4];

   /* save original colors */
   COPY_CHAN4(cSave[0], ncv0->color);
   COPY_CHAN4(cSave[1], ncv1->color);
   /* sum v0 */
   rSum = CHAN_TO_FLOAT(ncv0->color[0]) + ncv0->attrib[FRAG_ATTRIB_COL1][0];
   gSum = CHAN_TO_FLOAT(ncv0->color[1]) + ncv0->attrib[FRAG_ATTRIB_COL1][1];
   bSum = CHAN_TO_FLOAT(ncv0->color[2]) + ncv0->attrib[FRAG_ATTRIB_COL1][2];
   UNCLAMPED_FLOAT_TO_CHAN(ncv0->color[0], rSum);
   UNCLAMPED_FLOAT_TO_CHAN(ncv0->color[1], gSum);
   UNCLAMPED_FLOAT_TO_CHAN(ncv0->color[2], bSum);
   /* sum v1 */
   rSum = CHAN_TO_FLOAT(ncv1->color[0]) + ncv1->attrib[FRAG_ATTRIB_COL1][0];
   gSum = CHAN_TO_FLOAT(ncv1->color[1]) + ncv1->attrib[FRAG_ATTRIB_COL1][1];
   bSum = CHAN_TO_FLOAT(ncv1->color[2]) + ncv1->attrib[FRAG_ATTRIB_COL1][2];
   UNCLAMPED_FLOAT_TO_CHAN(ncv1->color[0], rSum);
   UNCLAMPED_FLOAT_TO_CHAN(ncv1->color[1], gSum);
   UNCLAMPED_FLOAT_TO_CHAN(ncv1->color[2], bSum);
   /* draw */
   SWRAST_CONTEXT(ctx)->SpecLine( ctx, ncv0, ncv1 );
   /* restore original colors */
   COPY_CHAN4( ncv0->attrib[FRAG_ATTRIB_COL0], cSave[0] );
   COPY_CHAN4( ncv1->attrib[FRAG_ATTRIB_COL0], cSave[1] );
}
示例#12
0
/**
 * Adaptor for fetching a float texel from a GLchan-valued texture.
 */
static void
fetch_texel_chan_to_float(const struct gl_texture_image *texImage,
                          GLint i, GLint j, GLint k, GLfloat *texelOut)
{
   GLchan temp[4];
   GLenum baseFormat = _mesa_get_format_base_format(texImage->TexFormat);

   ASSERT(texImage->FetchTexelc);
   texImage->FetchTexelc(texImage, i, j, k, temp);
   if (baseFormat == GL_DEPTH_COMPONENT ||
       baseFormat == GL_DEPTH_STENCIL_EXT) {
      /* just one channel */
      texelOut[0] = CHAN_TO_FLOAT(temp[0]);
   }
   else {
      /* four channels */
      texelOut[0] = CHAN_TO_FLOAT(temp[0]);
      texelOut[1] = CHAN_TO_FLOAT(temp[1]);
      texelOut[2] = CHAN_TO_FLOAT(temp[2]);
      texelOut[3] = CHAN_TO_FLOAT(temp[3]);
   }
}
示例#13
0
文件: s_tcc.c 项目: Ionic/nx-libs
static void TXB( void *cc, const float *texcoord, int unit, float *result )
{
   GLcontext *ctx = (GLcontext *)cc;
   SWcontext *swrast = SWRAST_CONTEXT(ctx);
   GLfloat lambda = 1.0;	/* hack */
   GLchan rgba[4];

   /* texcoord[3] is the bias to add to lambda */
   lambda += texcoord[3];


   /* Is it necessary to reset texcoord[3] to 1 at this point?
    */
   swrast->TextureSample[unit](ctx, unit, ctx->Texture.Unit[unit]._Current,
                               1, (const GLfloat (*)[4]) texcoord,
                               &lambda, &rgba);

   result[0] = CHAN_TO_FLOAT(rgba[0]);
   result[1] = CHAN_TO_FLOAT(rgba[1]);
   result[2] = CHAN_TO_FLOAT(rgba[2]);
   result[3] = CHAN_TO_FLOAT(rgba[3]);
}
示例#14
0
/*
 * Convert RGBA values into strq texture coordinates.
 */
void
_mesa_pixeltexgen(GLcontext *ctx, GLuint n, const GLchan rgba[][4],
                  GLfloat s[], GLfloat t[], GLfloat r[], GLfloat q[])
{
   if (ctx->Pixel.FragmentRgbSource == GL_CURRENT_RASTER_COLOR) {
      GLuint i;
      for (i = 0; i < n; i++) {
         s[i] = ctx->Current.RasterColor[RCOMP];
         t[i] = ctx->Current.RasterColor[GCOMP];
         r[i] = ctx->Current.RasterColor[BCOMP];
      }
   }
   else {
      GLuint i;
      ASSERT(ctx->Pixel.FragmentRgbSource == GL_PIXEL_GROUP_COLOR_SGIS);
      for (i = 0; i < n; i++) {
         s[i] = CHAN_TO_FLOAT(rgba[i][RCOMP]);
         t[i] = CHAN_TO_FLOAT(rgba[i][GCOMP]);
         r[i] = CHAN_TO_FLOAT(rgba[i][BCOMP]);
      }
   }

   if (ctx->Pixel.FragmentAlphaSource == GL_CURRENT_RASTER_COLOR) {
      GLuint i;
      for (i = 0; i < n; i++) {
         q[i] = ctx->Current.RasterColor[ACOMP];
      }
   }
   else {
      GLuint i;
      ASSERT(ctx->Pixel.FragmentAlphaSource == GL_PIXEL_GROUP_COLOR_SGIS);
      for (i = 0; i < n; i++) {
         q[i] = CHAN_TO_FLOAT(rgba[i][ACOMP]);
      }
   }
}
示例#15
0
/**
 * Apply texture mapping to a span of fragments.
 */
void
_swrast_texture_span( GLcontext *ctx, SWspan *span )
{
   SWcontext *swrast = SWRAST_CONTEXT(ctx);
   GLfloat primary_rgba[MAX_WIDTH][4];
   GLuint unit;

   ASSERT(span->end <= MAX_WIDTH);

   /*
    * Save copy of the incoming fragment colors (the GL_PRIMARY_COLOR)
    */
   if (swrast->_TextureCombinePrimary) {
      GLuint i;
      for (i = 0; i < span->end; i++) {
         primary_rgba[i][RCOMP] = CHAN_TO_FLOAT(span->array->rgba[i][RCOMP]);
         primary_rgba[i][GCOMP] = CHAN_TO_FLOAT(span->array->rgba[i][GCOMP]);
         primary_rgba[i][BCOMP] = CHAN_TO_FLOAT(span->array->rgba[i][BCOMP]);
         primary_rgba[i][ACOMP] = CHAN_TO_FLOAT(span->array->rgba[i][ACOMP]);
      }
   }

   /* First must sample all bump maps */
   for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) {
      const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];

      if (texUnit->_ReallyEnabled &&
         texUnit->_CurrentCombine->ModeRGB == GL_BUMP_ENVMAP_ATI) {
         const GLfloat (*texcoords)[4] = (const GLfloat (*)[4])
            span->array->attribs[FRAG_ATTRIB_TEX0 + unit];
         float4_array targetcoords =
            span->array->attribs[FRAG_ATTRIB_TEX0 +
               ctx->Texture.Unit[unit].BumpTarget - GL_TEXTURE0];

         const struct gl_texture_object *curObj = texUnit->_Current;
         GLfloat *lambda = span->array->lambda[unit];
         float4_array texels = get_texel_array(swrast, unit);
         GLuint i;
         GLfloat rotMatrix00 = ctx->Texture.Unit[unit].RotMatrix[0];
         GLfloat rotMatrix01 = ctx->Texture.Unit[unit].RotMatrix[1];
         GLfloat rotMatrix10 = ctx->Texture.Unit[unit].RotMatrix[2];
         GLfloat rotMatrix11 = ctx->Texture.Unit[unit].RotMatrix[3];

         /* adjust texture lod (lambda) */
         if (span->arrayMask & SPAN_LAMBDA) {
            if (texUnit->LodBias + curObj->LodBias != 0.0F) {
               /* apply LOD bias, but don't clamp yet */
               const GLfloat bias = CLAMP(texUnit->LodBias + curObj->LodBias,
                                          -ctx->Const.MaxTextureLodBias,
                                          ctx->Const.MaxTextureLodBias);
               GLuint i;
               for (i = 0; i < span->end; i++) {
                  lambda[i] += bias;
               }
            }

            if (curObj->MinLod != -1000.0 || curObj->MaxLod != 1000.0) {
               /* apply LOD clamping to lambda */
               const GLfloat min = curObj->MinLod;
               const GLfloat max = curObj->MaxLod;
               GLuint i;
               for (i = 0; i < span->end; i++) {
                  GLfloat l = lambda[i];
                  lambda[i] = CLAMP(l, min, max);
               }
            }
         }

         /* Sample the texture (span->end = number of fragments) */
         swrast->TextureSample[unit]( ctx, texUnit->_Current, span->end,
                                      texcoords, lambda, texels );

         /* manipulate the span values of the bump target
            not sure this can work correctly even ignoring
            the problem that channel is unsigned */
         for (i = 0; i < span->end; i++) {
            targetcoords[i][0] += (texels[i][0] * rotMatrix00 + texels[i][1] *
                                  rotMatrix01) / targetcoords[i][3];
            targetcoords[i][1] += (texels[i][0] * rotMatrix10 + texels[i][1] *
                                  rotMatrix11) / targetcoords[i][3];
         }
      }
   }

   /*
    * Must do all texture sampling before combining in order to
    * accomodate GL_ARB_texture_env_crossbar.
    */
   for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) {
      const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
      if (texUnit->_ReallyEnabled &&
          texUnit->_CurrentCombine->ModeRGB != GL_BUMP_ENVMAP_ATI) {
         const GLfloat (*texcoords)[4] = (const GLfloat (*)[4])
            span->array->attribs[FRAG_ATTRIB_TEX0 + unit];
         const struct gl_texture_object *curObj = texUnit->_Current;
         GLfloat *lambda = span->array->lambda[unit];
         float4_array texels = get_texel_array(swrast, unit);

         /* adjust texture lod (lambda) */
         if (span->arrayMask & SPAN_LAMBDA) {
            if (texUnit->LodBias + curObj->LodBias != 0.0F) {
               /* apply LOD bias, but don't clamp yet */
               const GLfloat bias = CLAMP(texUnit->LodBias + curObj->LodBias,
                                          -ctx->Const.MaxTextureLodBias,
                                          ctx->Const.MaxTextureLodBias);
               GLuint i;
               for (i = 0; i < span->end; i++) {
                  lambda[i] += bias;
               }
            }

            if (curObj->MinLod != -1000.0 || curObj->MaxLod != 1000.0) {
               /* apply LOD clamping to lambda */
               const GLfloat min = curObj->MinLod;
               const GLfloat max = curObj->MaxLod;
               GLuint i;
               for (i = 0; i < span->end; i++) {
                  GLfloat l = lambda[i];
                  lambda[i] = CLAMP(l, min, max);
               }
            }
         }

         /* Sample the texture (span->end = number of fragments) */
         swrast->TextureSample[unit]( ctx, texUnit->_Current, span->end,
                                      texcoords, lambda, texels );

         /* GL_SGI_texture_color_table */
         if (texUnit->ColorTableEnabled) {
            _mesa_lookup_rgba_float(&texUnit->ColorTable, span->end, texels);
         }

         /* GL_EXT_texture_swizzle */
         if (curObj->_Swizzle != SWIZZLE_NOOP) {
            swizzle_texels(curObj->_Swizzle, span->end, texels);
         }
      }
   }

   /*
    * OK, now apply the texture (aka texture combine/blend).
    * We modify the span->color.rgba values.
    */
   for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) {
      if (ctx->Texture.Unit[unit]._ReallyEnabled) {
         texture_combine( ctx, unit, span->end,
                          primary_rgba,
                          swrast->TexelBuffer,
                          span->array->rgba );
      }
   }
}
示例#16
0
/**
 * Do texture application for:
 *  GL_EXT_texture_env_combine
 *  GL_ARB_texture_env_combine
 *  GL_EXT_texture_env_dot3
 *  GL_ARB_texture_env_dot3
 *  GL_ATI_texture_env_combine3
 *  GL_NV_texture_env_combine4
 *  conventional GL texture env modes
 *
 * \param ctx          rendering context
 * \param unit         the texture combiner unit
 * \param primary_rgba incoming fragment color array
 * \param texelBuffer  pointer to texel colors for all texture units
 * 
 * \param span         two fields are used in this function:
 *                       span->end: number of fragments to process
 *                       span->array->rgba: incoming/result fragment colors
 */
static void
texture_combine( struct gl_context *ctx, GLuint unit,
                 const float4_array primary_rgba,
                 const GLfloat *texelBuffer,
                 SWspan *span )
{
   SWcontext *swrast = SWRAST_CONTEXT(ctx);
   const struct gl_texture_unit *textureUnit = &(ctx->Texture.Unit[unit]);
   const struct gl_tex_env_combine_state *combine = textureUnit->_CurrentCombine;
   float4_array argRGB[MAX_COMBINER_TERMS];
   float4_array argA[MAX_COMBINER_TERMS];
   const GLfloat scaleRGB = (GLfloat) (1 << combine->ScaleShiftRGB);
   const GLfloat scaleA = (GLfloat) (1 << combine->ScaleShiftA);
   const GLuint numArgsRGB = combine->_NumArgsRGB;
   const GLuint numArgsA = combine->_NumArgsA;
   float4_array ccolor[4], rgba;
   GLuint i, term;
   GLuint n = span->end;
   GLchan (*rgbaChan)[4] = span->array->rgba;

   /* alloc temp pixel buffers */
   rgba = malloc(4 * n * sizeof(GLfloat));
   if (!rgba) {
      _mesa_error(ctx, GL_OUT_OF_MEMORY, "texture_combine");
      return;
   }

   for (i = 0; i < numArgsRGB || i < numArgsA; i++) {
      ccolor[i] = malloc(4 * n * sizeof(GLfloat));
      if (!ccolor[i]) {
         while (i) {
            free(ccolor[i]);
            i--;
         }
         _mesa_error(ctx, GL_OUT_OF_MEMORY, "texture_combine");
         free(rgba);
         return;
      }
   }

   for (i = 0; i < n; i++) {
      rgba[i][RCOMP] = CHAN_TO_FLOAT(rgbaChan[i][RCOMP]);
      rgba[i][GCOMP] = CHAN_TO_FLOAT(rgbaChan[i][GCOMP]);
      rgba[i][BCOMP] = CHAN_TO_FLOAT(rgbaChan[i][BCOMP]);
      rgba[i][ACOMP] = CHAN_TO_FLOAT(rgbaChan[i][ACOMP]);
   }

   /*
   printf("modeRGB 0x%x  modeA 0x%x  srcRGB1 0x%x  srcA1 0x%x  srcRGB2 0x%x  srcA2 0x%x\n",
          combine->ModeRGB,
          combine->ModeA,
          combine->SourceRGB[0],
          combine->SourceA[0],
          combine->SourceRGB[1],
          combine->SourceA[1]);
   */

   /*
    * Do operand setup for up to 4 operands.  Loop over the terms.
    */
   for (term = 0; term < numArgsRGB; term++) {
      const GLenum srcRGB = combine->SourceRGB[term];
      const GLenum operandRGB = combine->OperandRGB[term];

      switch (srcRGB) {
         case GL_TEXTURE:
            argRGB[term] = get_texel_array(swrast, unit);
            break;
         case GL_PRIMARY_COLOR:
            argRGB[term] = primary_rgba;
            break;
         case GL_PREVIOUS:
            argRGB[term] = rgba;
            break;
         case GL_CONSTANT:
            {
               float4_array c = ccolor[term];
               GLfloat red   = textureUnit->EnvColor[0];
               GLfloat green = textureUnit->EnvColor[1];
               GLfloat blue  = textureUnit->EnvColor[2];
               GLfloat alpha = textureUnit->EnvColor[3];
               for (i = 0; i < n; i++) {
                  ASSIGN_4V(c[i], red, green, blue, alpha);
               }
               argRGB[term] = ccolor[term];
            }
            break;
	 /* GL_ATI_texture_env_combine3 allows GL_ZERO & GL_ONE as sources.
	  */
	 case GL_ZERO:
            {
               float4_array c = ccolor[term];
               for (i = 0; i < n; i++) {
                  ASSIGN_4V(c[i], 0.0F, 0.0F, 0.0F, 0.0F);
               }
               argRGB[term] = ccolor[term];
            }
            break;
	 case GL_ONE:
            {
               float4_array c = ccolor[term];
               for (i = 0; i < n; i++) {
                  ASSIGN_4V(c[i], 1.0F, 1.0F, 1.0F, 1.0F);
               }
               argRGB[term] = ccolor[term];
            }
            break;
         default:
            /* ARB_texture_env_crossbar source */
            {
               const GLuint srcUnit = srcRGB - GL_TEXTURE0;
               ASSERT(srcUnit < ctx->Const.MaxTextureUnits);
               if (!ctx->Texture.Unit[srcUnit]._ReallyEnabled)
                  goto end;
               argRGB[term] = get_texel_array(swrast, srcUnit);
            }
      }

      if (operandRGB != GL_SRC_COLOR) {
         float4_array src = argRGB[term];
         float4_array dst = ccolor[term];

         /* point to new arg[term] storage */
         argRGB[term] = ccolor[term];

         switch (operandRGB) {
         case GL_ONE_MINUS_SRC_COLOR:
            for (i = 0; i < n; i++) {
               dst[i][RCOMP] = 1.0F - src[i][RCOMP];
               dst[i][GCOMP] = 1.0F - src[i][GCOMP];
               dst[i][BCOMP] = 1.0F - src[i][BCOMP];
            }
            break;
         case GL_SRC_ALPHA:
            for (i = 0; i < n; i++) {
               dst[i][RCOMP] =
               dst[i][GCOMP] =
               dst[i][BCOMP] = src[i][ACOMP];
            }
            break;
         case GL_ONE_MINUS_SRC_ALPHA:
            for (i = 0; i < n; i++) {
               dst[i][RCOMP] =
               dst[i][GCOMP] =
               dst[i][BCOMP] = 1.0F - src[i][ACOMP];
            }
            break;
         default:
            _mesa_problem(ctx, "Bad operandRGB");
         }
      }
   }

   /*
    * Set up the argA[term] pointers
    */
   for (term = 0; term < numArgsA; term++) {
      const GLenum srcA = combine->SourceA[term];
      const GLenum operandA = combine->OperandA[term];

      switch (srcA) {
         case GL_TEXTURE:
            argA[term] = get_texel_array(swrast, unit);
            break;
         case GL_PRIMARY_COLOR:
            argA[term] = primary_rgba;
            break;
         case GL_PREVIOUS:
            argA[term] = rgba;
            break;
         case GL_CONSTANT:
            {
               float4_array c = ccolor[term];
               GLfloat alpha = textureUnit->EnvColor[3];
               for (i = 0; i < n; i++)
                  c[i][ACOMP] = alpha;
               argA[term] = ccolor[term];
            }
            break;
	 /* GL_ATI_texture_env_combine3 allows GL_ZERO & GL_ONE as sources.
	  */
	 case GL_ZERO:
            {
               float4_array c = ccolor[term];
               for (i = 0; i < n; i++)
                  c[i][ACOMP] = 0.0F;
               argA[term] = ccolor[term];
            }
            break;
	 case GL_ONE:
            {
               float4_array c = ccolor[term];
               for (i = 0; i < n; i++)
                  c[i][ACOMP] = 1.0F;
               argA[term] = ccolor[term];
            }
            break;
         default:
            /* ARB_texture_env_crossbar source */
            {
               const GLuint srcUnit = srcA - GL_TEXTURE0;
               ASSERT(srcUnit < ctx->Const.MaxTextureUnits);
               if (!ctx->Texture.Unit[srcUnit]._ReallyEnabled)
                  goto end;
               argA[term] = get_texel_array(swrast, srcUnit);
            }
      }

      if (operandA == GL_ONE_MINUS_SRC_ALPHA) {
         float4_array src = argA[term];
         float4_array dst = ccolor[term];
         argA[term] = ccolor[term];
         for (i = 0; i < n; i++) {
            dst[i][ACOMP] = 1.0F - src[i][ACOMP];
         }
      }
   }

   /* RGB channel combine */
   {
      float4_array arg0 = argRGB[0];
      float4_array arg1 = argRGB[1];
      float4_array arg2 = argRGB[2];
      float4_array arg3 = argRGB[3];

      switch (combine->ModeRGB) {
      case GL_REPLACE:
         for (i = 0; i < n; i++) {
            rgba[i][RCOMP] = arg0[i][RCOMP] * scaleRGB;
            rgba[i][GCOMP] = arg0[i][GCOMP] * scaleRGB;
            rgba[i][BCOMP] = arg0[i][BCOMP] * scaleRGB;
         }
         break;
      case GL_MODULATE:
         for (i = 0; i < n; i++) {
            rgba[i][RCOMP] = arg0[i][RCOMP] * arg1[i][RCOMP] * scaleRGB;
            rgba[i][GCOMP] = arg0[i][GCOMP] * arg1[i][GCOMP] * scaleRGB;
            rgba[i][BCOMP] = arg0[i][BCOMP] * arg1[i][BCOMP] * scaleRGB;
         }
         break;
      case GL_ADD:
         if (textureUnit->EnvMode == GL_COMBINE4_NV) {
            /* (a * b) + (c * d) */
            for (i = 0; i < n; i++) {
               rgba[i][RCOMP] = (arg0[i][RCOMP] * arg1[i][RCOMP] +
                                 arg2[i][RCOMP] * arg3[i][RCOMP]) * scaleRGB;
               rgba[i][GCOMP] = (arg0[i][GCOMP] * arg1[i][GCOMP] +
                                 arg2[i][GCOMP] * arg3[i][GCOMP]) * scaleRGB;
               rgba[i][BCOMP] = (arg0[i][BCOMP] * arg1[i][BCOMP] +
                                 arg2[i][BCOMP] * arg3[i][BCOMP]) * scaleRGB;
            }
         }
         else {
            /* 2-term addition */
            for (i = 0; i < n; i++) {
               rgba[i][RCOMP] = (arg0[i][RCOMP] + arg1[i][RCOMP]) * scaleRGB;
               rgba[i][GCOMP] = (arg0[i][GCOMP] + arg1[i][GCOMP]) * scaleRGB;
               rgba[i][BCOMP] = (arg0[i][BCOMP] + arg1[i][BCOMP]) * scaleRGB;
            }
         }
         break;
      case GL_ADD_SIGNED:
         if (textureUnit->EnvMode == GL_COMBINE4_NV) {
            /* (a * b) + (c * d) - 0.5 */
            for (i = 0; i < n; i++) {
               rgba[i][RCOMP] = (arg0[i][RCOMP] * arg1[i][RCOMP] +
                                 arg2[i][RCOMP] * arg3[i][RCOMP] - 0.5F) * scaleRGB;
               rgba[i][GCOMP] = (arg0[i][GCOMP] * arg1[i][GCOMP] +
                                 arg2[i][GCOMP] * arg3[i][GCOMP] - 0.5F) * scaleRGB;
               rgba[i][BCOMP] = (arg0[i][BCOMP] * arg1[i][BCOMP] +
                                 arg2[i][BCOMP] * arg3[i][BCOMP] - 0.5F) * scaleRGB;
            }
         }
         else {
            for (i = 0; i < n; i++) {
               rgba[i][RCOMP] = (arg0[i][RCOMP] + arg1[i][RCOMP] - 0.5F) * scaleRGB;
               rgba[i][GCOMP] = (arg0[i][GCOMP] + arg1[i][GCOMP] - 0.5F) * scaleRGB;
               rgba[i][BCOMP] = (arg0[i][BCOMP] + arg1[i][BCOMP] - 0.5F) * scaleRGB;
            }
         }
         break;
      case GL_INTERPOLATE:
         for (i = 0; i < n; i++) {
            rgba[i][RCOMP] = (arg0[i][RCOMP] * arg2[i][RCOMP] +
                          arg1[i][RCOMP] * (1.0F - arg2[i][RCOMP])) * scaleRGB;
            rgba[i][GCOMP] = (arg0[i][GCOMP] * arg2[i][GCOMP] +
                          arg1[i][GCOMP] * (1.0F - arg2[i][GCOMP])) * scaleRGB;
            rgba[i][BCOMP] = (arg0[i][BCOMP] * arg2[i][BCOMP] +
                          arg1[i][BCOMP] * (1.0F - arg2[i][BCOMP])) * scaleRGB;
         }
         break;
      case GL_SUBTRACT:
         for (i = 0; i < n; i++) {
            rgba[i][RCOMP] = (arg0[i][RCOMP] - arg1[i][RCOMP]) * scaleRGB;
            rgba[i][GCOMP] = (arg0[i][GCOMP] - arg1[i][GCOMP]) * scaleRGB;
            rgba[i][BCOMP] = (arg0[i][BCOMP] - arg1[i][BCOMP]) * scaleRGB;
         }
         break;
      case GL_DOT3_RGB_EXT:
      case GL_DOT3_RGBA_EXT:
         /* Do not scale the result by 1 2 or 4 */
         for (i = 0; i < n; i++) {
            GLfloat dot = ((arg0[i][RCOMP] - 0.5F) * (arg1[i][RCOMP] - 0.5F) +
                           (arg0[i][GCOMP] - 0.5F) * (arg1[i][GCOMP] - 0.5F) +
                           (arg0[i][BCOMP] - 0.5F) * (arg1[i][BCOMP] - 0.5F))
               * 4.0F;
            dot = CLAMP(dot, 0.0F, 1.0F);
            rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = dot;
         }
         break;
      case GL_DOT3_RGB:
      case GL_DOT3_RGBA:
         /* DO scale the result by 1 2 or 4 */
         for (i = 0; i < n; i++) {
            GLfloat dot = ((arg0[i][RCOMP] - 0.5F) * (arg1[i][RCOMP] - 0.5F) +
                           (arg0[i][GCOMP] - 0.5F) * (arg1[i][GCOMP] - 0.5F) +
                           (arg0[i][BCOMP] - 0.5F) * (arg1[i][BCOMP] - 0.5F))
               * 4.0F * scaleRGB;
            dot = CLAMP(dot, 0.0F, 1.0F);
            rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = dot;
         }
         break;
      case GL_MODULATE_ADD_ATI:
         for (i = 0; i < n; i++) {
            rgba[i][RCOMP] = ((arg0[i][RCOMP] * arg2[i][RCOMP]) +
                              arg1[i][RCOMP]) * scaleRGB;
            rgba[i][GCOMP] = ((arg0[i][GCOMP] * arg2[i][GCOMP]) +
                              arg1[i][GCOMP]) * scaleRGB;
            rgba[i][BCOMP] = ((arg0[i][BCOMP] * arg2[i][BCOMP]) +
                              arg1[i][BCOMP]) * scaleRGB;
	 }
         break;
      case GL_MODULATE_SIGNED_ADD_ATI:
         for (i = 0; i < n; i++) {
            rgba[i][RCOMP] = ((arg0[i][RCOMP] * arg2[i][RCOMP]) +
                              arg1[i][RCOMP] - 0.5F) * scaleRGB;
            rgba[i][GCOMP] = ((arg0[i][GCOMP] * arg2[i][GCOMP]) +
                              arg1[i][GCOMP] - 0.5F) * scaleRGB;
            rgba[i][BCOMP] = ((arg0[i][BCOMP] * arg2[i][BCOMP]) +
                              arg1[i][BCOMP] - 0.5F) * scaleRGB;
	 }
         break;
      case GL_MODULATE_SUBTRACT_ATI:
         for (i = 0; i < n; i++) {
            rgba[i][RCOMP] = ((arg0[i][RCOMP] * arg2[i][RCOMP]) -
                              arg1[i][RCOMP]) * scaleRGB;
            rgba[i][GCOMP] = ((arg0[i][GCOMP] * arg2[i][GCOMP]) -
                              arg1[i][GCOMP]) * scaleRGB;
            rgba[i][BCOMP] = ((arg0[i][BCOMP] * arg2[i][BCOMP]) -
                              arg1[i][BCOMP]) * scaleRGB;
	 }
         break;
      case GL_BUMP_ENVMAP_ATI:
         /* this produces a fixed rgba color, and the coord calc is done elsewhere */
         for (i = 0; i < n; i++) {
            /* rgba result is 0,0,0,1 */
            rgba[i][RCOMP] = 0.0;
            rgba[i][GCOMP] = 0.0;
            rgba[i][BCOMP] = 0.0;
            rgba[i][ACOMP] = 1.0;
	 }
         goto end; /* no alpha processing */
      default:
         _mesa_problem(ctx, "invalid combine mode");
      }
   }

   /* Alpha channel combine */
   {
      float4_array arg0 = argA[0];
      float4_array arg1 = argA[1];
      float4_array arg2 = argA[2];
      float4_array arg3 = argA[3];

      switch (combine->ModeA) {
      case GL_REPLACE:
         for (i = 0; i < n; i++) {
            rgba[i][ACOMP] = arg0[i][ACOMP] * scaleA;
         }
         break;
      case GL_MODULATE:
         for (i = 0; i < n; i++) {
            rgba[i][ACOMP] = arg0[i][ACOMP] * arg1[i][ACOMP] * scaleA;
         }
         break;
      case GL_ADD:
         if (textureUnit->EnvMode == GL_COMBINE4_NV) {
            /* (a * b) + (c * d) */
            for (i = 0; i < n; i++) {
               rgba[i][ACOMP] = (arg0[i][ACOMP] * arg1[i][ACOMP] +
                                 arg2[i][ACOMP] * arg3[i][ACOMP]) * scaleA;
            }
         }
         else {
            /* two-term add */
            for (i = 0; i < n; i++) {
               rgba[i][ACOMP] = (arg0[i][ACOMP] + arg1[i][ACOMP]) * scaleA;
            }
         }
         break;
      case GL_ADD_SIGNED:
         if (textureUnit->EnvMode == GL_COMBINE4_NV) {
            /* (a * b) + (c * d) - 0.5 */
            for (i = 0; i < n; i++) {
               rgba[i][ACOMP] = (arg0[i][ACOMP] * arg1[i][ACOMP] +
                                 arg2[i][ACOMP] * arg3[i][ACOMP] -
                                 0.5F) * scaleA;
            }
         }
         else {
            /* a + b - 0.5 */
            for (i = 0; i < n; i++) {
               rgba[i][ACOMP] = (arg0[i][ACOMP] + arg1[i][ACOMP] - 0.5F) * scaleA;
            }
         }
         break;
      case GL_INTERPOLATE:
         for (i = 0; i < n; i++) {
            rgba[i][ACOMP] = (arg0[i][ACOMP] * arg2[i][ACOMP] +
                              arg1[i][ACOMP] * (1.0F - arg2[i][ACOMP]))
               * scaleA;
         }
         break;
      case GL_SUBTRACT:
         for (i = 0; i < n; i++) {
            rgba[i][ACOMP] = (arg0[i][ACOMP] - arg1[i][ACOMP]) * scaleA;
         }
         break;
      case GL_MODULATE_ADD_ATI:
         for (i = 0; i < n; i++) {
            rgba[i][ACOMP] = ((arg0[i][ACOMP] * arg2[i][ACOMP])
                              + arg1[i][ACOMP]) * scaleA;
         }
         break;
      case GL_MODULATE_SIGNED_ADD_ATI:
         for (i = 0; i < n; i++) {
            rgba[i][ACOMP] = ((arg0[i][ACOMP] * arg2[i][ACOMP]) +
                              arg1[i][ACOMP] - 0.5F) * scaleA;
         }
         break;
      case GL_MODULATE_SUBTRACT_ATI:
         for (i = 0; i < n; i++) {
            rgba[i][ACOMP] = ((arg0[i][ACOMP] * arg2[i][ACOMP])
                              - arg1[i][ACOMP]) * scaleA;
         }
         break;
      default:
         _mesa_problem(ctx, "invalid combine mode");
      }
   }

   /* Fix the alpha component for GL_DOT3_RGBA_EXT/ARB combining.
    * This is kind of a kludge.  It would have been better if the spec
    * were written such that the GL_COMBINE_ALPHA value could be set to
    * GL_DOT3.
    */
   if (combine->ModeRGB == GL_DOT3_RGBA_EXT ||
       combine->ModeRGB == GL_DOT3_RGBA) {
      for (i = 0; i < n; i++) {
	 rgba[i][ACOMP] = rgba[i][RCOMP];
      }
   }

   for (i = 0; i < n; i++) {
      UNCLAMPED_FLOAT_TO_CHAN(rgbaChan[i][RCOMP], rgba[i][RCOMP]);
      UNCLAMPED_FLOAT_TO_CHAN(rgbaChan[i][GCOMP], rgba[i][GCOMP]);
      UNCLAMPED_FLOAT_TO_CHAN(rgbaChan[i][BCOMP], rgba[i][BCOMP]);
      UNCLAMPED_FLOAT_TO_CHAN(rgbaChan[i][ACOMP], rgba[i][ACOMP]);
   }
   /* The span->array->rgba values are of CHAN type so set
    * span->array->ChanType field accordingly.
    */
   span->array->ChanType = CHAN_TYPE;

end:
   for (i = 0; i < numArgsRGB || i < numArgsA; i++) {
      free(ccolor[i]);
   }
   free(rgba);
}
示例#17
0
/**
 * Apply texture mapping to a span of fragments.
 */
void
_swrast_texture_span( struct gl_context *ctx, SWspan *span )
{
   SWcontext *swrast = SWRAST_CONTEXT(ctx);
   float4_array primary_rgba;
   GLuint unit;

   if (!swrast->TexelBuffer) {
#ifdef _OPENMP
      const GLint maxThreads = omp_get_max_threads();
#else
      const GLint maxThreads = 1;
#endif

      /* TexelBuffer is also global and normally shared by all SWspan
       * instances; when running with multiple threads, create one per
       * thread.
       */
      swrast->TexelBuffer =
	 malloc(ctx->Const.FragmentProgram.MaxTextureImageUnits * maxThreads *
			    SWRAST_MAX_WIDTH * 4 * sizeof(GLfloat));
      if (!swrast->TexelBuffer) {
	 _mesa_error(ctx, GL_OUT_OF_MEMORY, "texture_combine");
	 return;
      }
   }

   primary_rgba = malloc(span->end * 4 * sizeof(GLfloat));

   if (!primary_rgba) {
      _mesa_error(ctx, GL_OUT_OF_MEMORY, "texture_span");
      return;
   }

   ASSERT(span->end <= SWRAST_MAX_WIDTH);

   /*
    * Save copy of the incoming fragment colors (the GL_PRIMARY_COLOR)
    */
   if (swrast->_TextureCombinePrimary) {
      GLuint i;
      for (i = 0; i < span->end; i++) {
         primary_rgba[i][RCOMP] = CHAN_TO_FLOAT(span->array->rgba[i][RCOMP]);
         primary_rgba[i][GCOMP] = CHAN_TO_FLOAT(span->array->rgba[i][GCOMP]);
         primary_rgba[i][BCOMP] = CHAN_TO_FLOAT(span->array->rgba[i][BCOMP]);
         primary_rgba[i][ACOMP] = CHAN_TO_FLOAT(span->array->rgba[i][ACOMP]);
      }
   }

   /* First must sample all bump maps */
   for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) {
      const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];

      if (texUnit->_ReallyEnabled &&
         texUnit->_CurrentCombine->ModeRGB == GL_BUMP_ENVMAP_ATI) {
         const GLfloat (*texcoords)[4] = (const GLfloat (*)[4])
            span->array->attribs[VARYING_SLOT_TEX0 + unit];
         float4_array targetcoords =
            span->array->attribs[VARYING_SLOT_TEX0 +
               ctx->Texture.Unit[unit].BumpTarget - GL_TEXTURE0];

         const struct gl_sampler_object *samp = _mesa_get_samplerobj(ctx, unit);
         GLfloat *lambda = span->array->lambda[unit];
         float4_array texels = get_texel_array(swrast, unit);
         GLuint i;
         GLfloat rotMatrix00 = ctx->Texture.Unit[unit].RotMatrix[0];
         GLfloat rotMatrix01 = ctx->Texture.Unit[unit].RotMatrix[1];
         GLfloat rotMatrix10 = ctx->Texture.Unit[unit].RotMatrix[2];
         GLfloat rotMatrix11 = ctx->Texture.Unit[unit].RotMatrix[3];

         /* adjust texture lod (lambda) */
         if (span->arrayMask & SPAN_LAMBDA) {
            if (texUnit->LodBias + samp->LodBias != 0.0F) {
               /* apply LOD bias, but don't clamp yet */
               const GLfloat bias = CLAMP(texUnit->LodBias + samp->LodBias,
                                          -ctx->Const.MaxTextureLodBias,
                                          ctx->Const.MaxTextureLodBias);
               GLuint i;
               for (i = 0; i < span->end; i++) {
                  lambda[i] += bias;
               }
            }

            if (samp->MinLod != -1000.0 ||
                samp->MaxLod != 1000.0) {
               /* apply LOD clamping to lambda */
               const GLfloat min = samp->MinLod;
               const GLfloat max = samp->MaxLod;
               GLuint i;
               for (i = 0; i < span->end; i++) {
                  GLfloat l = lambda[i];
                  lambda[i] = CLAMP(l, min, max);
               }
            }
         }

         /* Sample the texture (span->end = number of fragments) */
         swrast->TextureSample[unit]( ctx, samp,
                                      ctx->Texture.Unit[unit]._Current,
                                      span->end, texcoords, lambda, texels );

         /* manipulate the span values of the bump target
            not sure this can work correctly even ignoring
            the problem that channel is unsigned */
         for (i = 0; i < span->end; i++) {
            targetcoords[i][0] += (texels[i][0] * rotMatrix00 + texels[i][1] *
                                  rotMatrix01) / targetcoords[i][3];
            targetcoords[i][1] += (texels[i][0] * rotMatrix10 + texels[i][1] *
                                  rotMatrix11) / targetcoords[i][3];
         }
      }
   }

   /*
    * Must do all texture sampling before combining in order to
    * accomodate GL_ARB_texture_env_crossbar.
    */
   for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) {
      const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
      if (texUnit->_ReallyEnabled &&
          texUnit->_CurrentCombine->ModeRGB != GL_BUMP_ENVMAP_ATI) {
         const GLfloat (*texcoords)[4] = (const GLfloat (*)[4])
            span->array->attribs[VARYING_SLOT_TEX0 + unit];
         const struct gl_texture_object *curObj = texUnit->_Current;
         const struct gl_sampler_object *samp = _mesa_get_samplerobj(ctx, unit);
         GLfloat *lambda = span->array->lambda[unit];
         float4_array texels = get_texel_array(swrast, unit);

         /* adjust texture lod (lambda) */
         if (span->arrayMask & SPAN_LAMBDA) {
            if (texUnit->LodBias + samp->LodBias != 0.0F) {
               /* apply LOD bias, but don't clamp yet */
               const GLfloat bias = CLAMP(texUnit->LodBias + samp->LodBias,
                                          -ctx->Const.MaxTextureLodBias,
                                          ctx->Const.MaxTextureLodBias);
               GLuint i;
               for (i = 0; i < span->end; i++) {
                  lambda[i] += bias;
               }
            }

            if (samp->MinLod != -1000.0 ||
                samp->MaxLod != 1000.0) {
               /* apply LOD clamping to lambda */
               const GLfloat min = samp->MinLod;
               const GLfloat max = samp->MaxLod;
               GLuint i;
               for (i = 0; i < span->end; i++) {
                  GLfloat l = lambda[i];
                  lambda[i] = CLAMP(l, min, max);
               }
            }
         }
         else if (samp->MaxAnisotropy > 1.0 &&
                  samp->MinFilter == GL_LINEAR_MIPMAP_LINEAR) {
            /* sample_lambda_2d_aniso is beeing used as texture_sample_func,
             * it requires the current SWspan *span as an additional parameter.
             * In order to keep the same function signature, the unused lambda
             * parameter will be modified to actually contain the SWspan pointer.
             * This is a Hack. To make it right, the texture_sample_func
             * signature and all implementing functions need to be modified.
             */
            /* "hide" SWspan struct; cast to (GLfloat *) to suppress warning */
            lambda = (GLfloat *)span;
         }

         /* Sample the texture (span->end = number of fragments) */
         swrast->TextureSample[unit]( ctx, samp,
                                      ctx->Texture.Unit[unit]._Current,
                                      span->end, texcoords, lambda, texels );

         /* GL_EXT_texture_swizzle */
         if (curObj->_Swizzle != SWIZZLE_NOOP) {
            swizzle_texels(curObj->_Swizzle, span->end, texels);
         }
      }
   }

   /*
    * OK, now apply the texture (aka texture combine/blend).
    * We modify the span->color.rgba values.
    */
   for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) {
      if (ctx->Texture.Unit[unit]._ReallyEnabled)
         texture_combine(ctx, unit, primary_rgba, swrast->TexelBuffer, span);
   }

   free(primary_rgba);
}
示例#18
0
static void
pop_texture_group(GLcontext *ctx, const struct gl_texture_attrib *texAttrib)
{
   GLuint u;

   for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
      const struct gl_texture_unit *unit = &texAttrib->Unit[u];
      GLuint i;

      _mesa_ActiveTextureARB(GL_TEXTURE0_ARB + u);
      _mesa_set_enable(ctx, GL_TEXTURE_1D,
              (GLboolean) (unit->Enabled & TEXTURE0_1D ? GL_TRUE : GL_FALSE));
      _mesa_set_enable(ctx, GL_TEXTURE_2D,
              (GLboolean) (unit->Enabled & TEXTURE0_2D ? GL_TRUE : GL_FALSE));
      _mesa_set_enable(ctx, GL_TEXTURE_3D,
              (GLboolean) (unit->Enabled & TEXTURE0_3D ? GL_TRUE : GL_FALSE));
      if (ctx->Extensions.ARB_texture_cube_map) {
         _mesa_set_enable(ctx, GL_TEXTURE_CUBE_MAP_ARB,
             (GLboolean) (unit->Enabled & TEXTURE0_CUBE ? GL_TRUE : GL_FALSE));
      }
      if (ctx->Extensions.NV_texture_rectangle) {
         _mesa_set_enable(ctx, GL_TEXTURE_RECTANGLE_NV,
             (GLboolean) (unit->Enabled & TEXTURE0_RECT ? GL_TRUE : GL_FALSE));
      }
      _mesa_TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, unit->EnvMode);
      _mesa_TexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, unit->EnvColor);
      _mesa_TexGeni(GL_S, GL_TEXTURE_GEN_MODE, unit->GenModeS);
      _mesa_TexGeni(GL_T, GL_TEXTURE_GEN_MODE, unit->GenModeT);
      _mesa_TexGeni(GL_R, GL_TEXTURE_GEN_MODE, unit->GenModeR);
      _mesa_TexGeni(GL_Q, GL_TEXTURE_GEN_MODE, unit->GenModeQ);
      _mesa_TexGenfv(GL_S, GL_OBJECT_PLANE, unit->ObjectPlaneS);
      _mesa_TexGenfv(GL_T, GL_OBJECT_PLANE, unit->ObjectPlaneT);
      _mesa_TexGenfv(GL_R, GL_OBJECT_PLANE, unit->ObjectPlaneR);
      _mesa_TexGenfv(GL_Q, GL_OBJECT_PLANE, unit->ObjectPlaneQ);
      _mesa_TexGenfv(GL_S, GL_EYE_PLANE, unit->EyePlaneS);
      _mesa_TexGenfv(GL_T, GL_EYE_PLANE, unit->EyePlaneT);
      _mesa_TexGenfv(GL_R, GL_EYE_PLANE, unit->EyePlaneR);
      _mesa_TexGenfv(GL_Q, GL_EYE_PLANE, unit->EyePlaneQ);
      if (ctx->Extensions.EXT_texture_lod_bias) {
         _mesa_TexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT,
                       GL_TEXTURE_LOD_BIAS_EXT, unit->LodBias);
      }
      if (ctx->Extensions.EXT_texture_env_combine ||
          ctx->Extensions.ARB_texture_env_combine) {
         _mesa_TexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT,
                       unit->CombineModeRGB);
         _mesa_TexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT,
                       unit->CombineModeA);
         _mesa_TexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT,
                       unit->CombineSourceRGB[0]);
         _mesa_TexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT,
                       unit->CombineSourceRGB[1]);
         _mesa_TexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_EXT,
                       unit->CombineSourceRGB[2]);
         _mesa_TexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT,
                       unit->CombineSourceA[0]);
         _mesa_TexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_EXT,
                       unit->CombineSourceA[1]);
         _mesa_TexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA_EXT,
                       unit->CombineSourceA[2]);
         _mesa_TexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT,
                       unit->CombineOperandRGB[0]);
         _mesa_TexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT,
                       unit->CombineOperandRGB[1]);
         _mesa_TexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_EXT,
                       unit->CombineOperandRGB[2]);
         _mesa_TexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_EXT,
                       unit->CombineOperandA[0]);
         _mesa_TexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_EXT,
                       unit->CombineOperandA[1]);
         _mesa_TexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA_EXT,
                       unit->CombineOperandA[2]);
         _mesa_TexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT,
                       1 << unit->CombineScaleShiftRGB);
         _mesa_TexEnvi(GL_TEXTURE_ENV, GL_ALPHA_SCALE,
                       1 << unit->CombineScaleShiftA);
      }

      /* Restore texture object state */
      for (i = 0; i < NUM_TEXTURE_TARGETS; i++) {
         GLenum target = 0;
         const struct gl_texture_object *obj = NULL;
         GLfloat bordColor[4];

         switch (i) {
         case 0:
            target = GL_TEXTURE_1D;
            obj = &unit->Saved1D;
            break;
         case 1:
            target = GL_TEXTURE_2D;
            obj = &unit->Saved2D;
            break;
         case 2:
            target = GL_TEXTURE_3D;
            obj = &unit->Saved3D;
            break;
         case 3:
            if (!ctx->Extensions.ARB_texture_cube_map)
               continue;
            target = GL_TEXTURE_CUBE_MAP_ARB;
            obj = &unit->SavedCubeMap;
            break;
         case 4:
            if (!ctx->Extensions.NV_texture_rectangle)
               continue;
            target = GL_TEXTURE_RECTANGLE_NV;
            obj = &unit->SavedRect;
            break;
         default:
            ; /* silence warnings */
         }

         _mesa_BindTexture(target, obj->Name);

         bordColor[0] = CHAN_TO_FLOAT(obj->BorderColor[0]);
         bordColor[1] = CHAN_TO_FLOAT(obj->BorderColor[1]);
         bordColor[2] = CHAN_TO_FLOAT(obj->BorderColor[2]);
         bordColor[3] = CHAN_TO_FLOAT(obj->BorderColor[3]);

         _mesa_TexParameterf(target, GL_TEXTURE_PRIORITY, obj->Priority);
         _mesa_TexParameterfv(target, GL_TEXTURE_BORDER_COLOR, bordColor);
         _mesa_TexParameteri(target, GL_TEXTURE_WRAP_S, obj->WrapS);
         _mesa_TexParameteri(target, GL_TEXTURE_WRAP_T, obj->WrapT);
         _mesa_TexParameteri(target, GL_TEXTURE_WRAP_R, obj->WrapR);
         _mesa_TexParameteri(target, GL_TEXTURE_MIN_FILTER, obj->MinFilter);
         _mesa_TexParameteri(target, GL_TEXTURE_MAG_FILTER, obj->MagFilter);
         _mesa_TexParameterf(target, GL_TEXTURE_MIN_LOD, obj->MinLod);
         _mesa_TexParameterf(target, GL_TEXTURE_MAX_LOD, obj->MaxLod);
         _mesa_TexParameteri(target, GL_TEXTURE_BASE_LEVEL, obj->BaseLevel);
         _mesa_TexParameteri(target, GL_TEXTURE_MAX_LEVEL, obj->MaxLevel);
         if (ctx->Extensions.EXT_texture_filter_anisotropic) {
            _mesa_TexParameterf(target, GL_TEXTURE_MAX_ANISOTROPY_EXT,
                                obj->MaxAnisotropy);
         }
         if (ctx->Extensions.SGIX_shadow) {
            _mesa_TexParameteri(target, GL_TEXTURE_COMPARE_SGIX,
                                obj->CompareFlag);
            _mesa_TexParameteri(target, GL_TEXTURE_COMPARE_OPERATOR_SGIX,
                                obj->CompareOperator);
         }
         if (ctx->Extensions.SGIX_shadow_ambient) {
            _mesa_TexParameterf(target, GL_SHADOW_AMBIENT_SGIX,
                                CHAN_TO_FLOAT(obj->ShadowAmbient));
         }

      }
   }
   _mesa_ActiveTextureARB(GL_TEXTURE0_ARB
                          + texAttrib->CurrentUnit);

   /* "un-bump" the texture object reference counts.  We did that so they
    * wouldn't inadvertantly get deleted while they were still referenced
    * inside the attribute state stack.
    */
   for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
      ctx->Texture.Unit[u].Current1D->RefCount--;
      ctx->Texture.Unit[u].Current2D->RefCount--;
      ctx->Texture.Unit[u].Current3D->RefCount--;
      ctx->Texture.Unit[u].CurrentCubeMap->RefCount--;
      ctx->Texture.Unit[u].CurrentRect->RefCount--;
   }
}
示例#19
0
/*
 * This function is kind of long just because we have to call a lot
 * of device driver functions to update device driver state.
 *
 * XXX As it is now, most of the pop-code calls immediate-mode Mesa functions
 * in order to restore GL state.  This isn't terribly efficient but it
 * ensures that dirty flags and any derived state gets updated correctly.
 * We could at least check if the value to restore equals the current value
 * and then skip the Mesa call.
 */
void
_mesa_PopAttrib(void)
{
   struct gl_attrib_node *attr, *next;
   GET_CURRENT_CONTEXT(ctx);
   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);

   if (ctx->AttribStackDepth == 0) {
      _mesa_error( ctx, GL_STACK_UNDERFLOW, "glPopAttrib" );
      return;
   }

   ctx->AttribStackDepth--;
   attr = ctx->AttribStack[ctx->AttribStackDepth];

   while (attr) {

      if (MESA_VERBOSE&VERBOSE_API) {
	 fprintf(stderr, "glPopAttrib %s\n",
                 _mesa_lookup_enum_by_nr(attr->kind));
      }

      switch (attr->kind) {
         case GL_ACCUM_BUFFER_BIT:
            {
               const struct gl_accum_attrib *accum;
               accum = (const struct gl_accum_attrib *) attr->data;
               _mesa_ClearAccum(accum->ClearColor[0],
                                accum->ClearColor[1],
                                accum->ClearColor[2],
                                accum->ClearColor[3]);
            }
            break;
         case GL_COLOR_BUFFER_BIT:
            {
               const struct gl_colorbuffer_attrib *color;
               color = (const struct gl_colorbuffer_attrib *) attr->data;
               _mesa_ClearIndex((GLfloat) color->ClearIndex);
               _mesa_ClearColor(CHAN_TO_FLOAT(color->ClearColor[0]),
                                CHAN_TO_FLOAT(color->ClearColor[1]),
                                CHAN_TO_FLOAT(color->ClearColor[2]),
                                CHAN_TO_FLOAT(color->ClearColor[3]));
               _mesa_IndexMask(color->IndexMask);
               _mesa_ColorMask((GLboolean) (color->ColorMask[0] != 0),
                               (GLboolean) (color->ColorMask[1] != 0),
                               (GLboolean) (color->ColorMask[2] != 0),
                               (GLboolean) (color->ColorMask[3] != 0));
               _mesa_DrawBuffer(color->DrawBuffer);
               _mesa_set_enable(ctx, GL_ALPHA_TEST, color->AlphaEnabled);
               _mesa_AlphaFunc(color->AlphaFunc,
                               CHAN_TO_FLOAT(color->AlphaRef));
               _mesa_set_enable(ctx, GL_BLEND, color->BlendEnabled);
               _mesa_BlendFuncSeparateEXT(color->BlendSrcRGB,
                                          color->BlendDstRGB,
                                          color->BlendSrcA,
                                          color->BlendDstA);
               _mesa_BlendEquation(color->BlendEquation);
               _mesa_BlendColor(color->BlendColor[0],
                                color->BlendColor[1],
                                color->BlendColor[2],
                                color->BlendColor[3]);
               _mesa_LogicOp(color->LogicOp);
               _mesa_set_enable(ctx, GL_COLOR_LOGIC_OP,
                                color->ColorLogicOpEnabled);
               _mesa_set_enable(ctx, GL_INDEX_LOGIC_OP,
                                color->IndexLogicOpEnabled);
               _mesa_set_enable(ctx, GL_DITHER, color->DitherFlag);
            }
            break;
         case GL_CURRENT_BIT:
	    FLUSH_CURRENT( ctx, 0 );
            MEMCPY( &ctx->Current, attr->data,
		    sizeof(struct gl_current_attrib) );
            break;
         case GL_DEPTH_BUFFER_BIT:
            {
               const struct gl_depthbuffer_attrib *depth;
               depth = (const struct gl_depthbuffer_attrib *) attr->data;
               _mesa_DepthFunc(depth->Func);
               _mesa_ClearDepth(depth->Clear);
               _mesa_set_enable(ctx, GL_DEPTH_TEST, depth->Test);
               _mesa_DepthMask(depth->Mask);
               if (ctx->Extensions.HP_occlusion_test)
                  _mesa_set_enable(ctx, GL_OCCLUSION_TEST_HP,
                                   depth->OcclusionTest);
            }
            break;
         case GL_ENABLE_BIT:
            {
               const struct gl_enable_attrib *enable;
               enable = (const struct gl_enable_attrib *) attr->data;
               pop_enable_group(ctx, enable);
	       ctx->NewState |= _NEW_ALL;
            }
            break;
         case GL_EVAL_BIT:
            MEMCPY( &ctx->Eval, attr->data, sizeof(struct gl_eval_attrib) );
	    ctx->NewState |= _NEW_EVAL;
            break;
         case GL_FOG_BIT:
            {
               const struct gl_fog_attrib *fog;
               fog = (const struct gl_fog_attrib *) attr->data;
               _mesa_set_enable(ctx, GL_FOG, fog->Enabled);
               _mesa_Fogfv(GL_FOG_COLOR, fog->Color);
               _mesa_Fogf(GL_FOG_DENSITY, fog->Density);
               _mesa_Fogf(GL_FOG_START, fog->Start);
               _mesa_Fogf(GL_FOG_END, fog->End);
               _mesa_Fogf(GL_FOG_INDEX, fog->Index);
               _mesa_Fogi(GL_FOG_MODE, fog->Mode);
            }
            break;
         case GL_HINT_BIT:
            {
               const struct gl_hint_attrib *hint;
               hint = (const struct gl_hint_attrib *) attr->data;
               _mesa_Hint(GL_PERSPECTIVE_CORRECTION_HINT,
                          hint->PerspectiveCorrection );
               _mesa_Hint(GL_POINT_SMOOTH_HINT, hint->PointSmooth);
               _mesa_Hint(GL_LINE_SMOOTH_HINT, hint->LineSmooth);
               _mesa_Hint(GL_POLYGON_SMOOTH_HINT, hint->PolygonSmooth);
               _mesa_Hint(GL_FOG_HINT, hint->Fog);
               _mesa_Hint(GL_CLIP_VOLUME_CLIPPING_HINT_EXT,
                          hint->ClipVolumeClipping);
               if (ctx->Extensions.ARB_texture_compression)
                  _mesa_Hint(GL_TEXTURE_COMPRESSION_HINT_ARB,
                             hint->TextureCompression);
            }
            break;
         case GL_LIGHTING_BIT:
            {
               GLuint i;
               const struct gl_light_attrib *light;
               light = (const struct gl_light_attrib *) attr->data;
               /* lighting enable */
               _mesa_set_enable(ctx, GL_LIGHTING, light->Enabled);
               /* per-light state */

	       if (ctx->ModelView.flags & MAT_DIRTY_INVERSE) 
		  _math_matrix_analyse( &ctx->ModelView );
	       
               for (i = 0; i < MAX_LIGHTS; i++) {
                  GLenum lgt = (GLenum) (GL_LIGHT0 + i);
		  const struct gl_light *l = &light->Light[i];
		  GLfloat tmp[4];
                  _mesa_set_enable(ctx, lgt, l->Enabled);
		  _mesa_Lightfv( lgt, GL_AMBIENT, l->Ambient );
		  _mesa_Lightfv( lgt, GL_DIFFUSE, l->Diffuse );
		  _mesa_Lightfv( lgt, GL_SPECULAR, l->Specular );
		  TRANSFORM_POINT( tmp, ctx->ModelView.inv, l->EyePosition );
		  _mesa_Lightfv( lgt, GL_POSITION, tmp );
		  TRANSFORM_POINT( tmp, ctx->ModelView.m, l->EyeDirection );
		  _mesa_Lightfv( lgt, GL_SPOT_DIRECTION, tmp );
		  _mesa_Lightfv( lgt, GL_SPOT_EXPONENT, &l->SpotExponent );
		  _mesa_Lightfv( lgt, GL_SPOT_CUTOFF, &l->SpotCutoff );
		  _mesa_Lightfv( lgt, GL_CONSTANT_ATTENUATION, 
				 &l->ConstantAttenuation );
		  _mesa_Lightfv( lgt, GL_LINEAR_ATTENUATION, 
				 &l->LinearAttenuation );
		  _mesa_Lightfv( lgt, GL_QUADRATIC_ATTENUATION, 
				 &l->QuadraticAttenuation );
               }
               /* light model */
               _mesa_LightModelfv(GL_LIGHT_MODEL_AMBIENT,
                                  light->Model.Ambient);
               _mesa_LightModelf(GL_LIGHT_MODEL_LOCAL_VIEWER,
                                 (GLfloat) light->Model.LocalViewer);
               _mesa_LightModelf(GL_LIGHT_MODEL_TWO_SIDE,
                                 (GLfloat) light->Model.TwoSide);
               _mesa_LightModelf(GL_LIGHT_MODEL_COLOR_CONTROL,
                                 (GLfloat) light->Model.ColorControl);
               /* materials */
               MEMCPY(ctx->Light.Material, light->Material,
                      2 * sizeof(struct gl_material));
               /* shade model */
               _mesa_ShadeModel(light->ShadeModel);
               /* color material */
               _mesa_ColorMaterial(light->ColorMaterialFace,
                                   light->ColorMaterialMode);
               _mesa_set_enable(ctx, GL_COLOR_MATERIAL,
                                light->ColorMaterialEnabled);
            }
            break;
         case GL_LINE_BIT:
            {
               const struct gl_line_attrib *line;
               line = (const struct gl_line_attrib *) attr->data;
               _mesa_set_enable(ctx, GL_LINE_SMOOTH, line->SmoothFlag);
               _mesa_set_enable(ctx, GL_LINE_STIPPLE, line->StippleFlag);
               _mesa_LineStipple(line->StippleFactor, line->StipplePattern);
               _mesa_LineWidth(line->Width);
            }
            break;
         case GL_LIST_BIT:
            MEMCPY( &ctx->List, attr->data, sizeof(struct gl_list_attrib) );
            break;
         case GL_PIXEL_MODE_BIT:
            MEMCPY( &ctx->Pixel, attr->data, sizeof(struct gl_pixel_attrib) );
	    ctx->NewState |= _NEW_PIXEL;
            break;
         case GL_POINT_BIT:
            {
               const struct gl_point_attrib *point;
               point = (const struct gl_point_attrib *) attr->data;
               _mesa_PointSize(point->Size);
               _mesa_set_enable(ctx, GL_POINT_SMOOTH, point->SmoothFlag);
               if (ctx->Extensions.EXT_point_parameters) {
                  _mesa_PointParameterfvEXT(GL_DISTANCE_ATTENUATION_EXT,
                                            point->Params);
                  _mesa_PointParameterfEXT(GL_POINT_SIZE_MIN_EXT,
                                           point->MinSize);
                  _mesa_PointParameterfEXT(GL_POINT_SIZE_MAX_EXT,
                                           point->MaxSize);
                  _mesa_PointParameterfEXT(GL_POINT_FADE_THRESHOLD_SIZE_EXT,
                                           point->Threshold);
               }
            }
            break;
         case GL_POLYGON_BIT:
            {
               const struct gl_polygon_attrib *polygon;
               polygon = (const struct gl_polygon_attrib *) attr->data;
               _mesa_CullFace(polygon->CullFaceMode);
               _mesa_FrontFace(polygon->FrontFace);
               _mesa_PolygonMode(GL_FRONT, polygon->FrontMode);
               _mesa_PolygonMode(GL_BACK, polygon->BackMode);
               _mesa_PolygonOffset(polygon->OffsetFactor,
                                   polygon->OffsetUnits);
               _mesa_set_enable(ctx, GL_POLYGON_SMOOTH, polygon->SmoothFlag);
               _mesa_set_enable(ctx, GL_POLYGON_STIPPLE, polygon->StippleFlag);
               _mesa_set_enable(ctx, GL_CULL_FACE, polygon->CullFlag);
               _mesa_set_enable(ctx, GL_POLYGON_OFFSET_POINT,
                                polygon->OffsetPoint);
               _mesa_set_enable(ctx, GL_POLYGON_OFFSET_LINE,
                                polygon->OffsetLine);
               _mesa_set_enable(ctx, GL_POLYGON_OFFSET_FILL,
                                polygon->OffsetFill);
            }
            break;
	 case GL_POLYGON_STIPPLE_BIT:
	    MEMCPY( ctx->PolygonStipple, attr->data, 32*sizeof(GLuint) );
	    ctx->NewState |= _NEW_POLYGONSTIPPLE;
	    if (ctx->Driver.PolygonStipple)
	       ctx->Driver.PolygonStipple( ctx, (const GLubyte *) attr->data );
	    break;
         case GL_SCISSOR_BIT:
            {
               const struct gl_scissor_attrib *scissor;
               scissor = (const struct gl_scissor_attrib *) attr->data;
               _mesa_Scissor(scissor->X, scissor->Y,
                             scissor->Width, scissor->Height);
               _mesa_set_enable(ctx, GL_SCISSOR_TEST, scissor->Enabled);
            }
            break;
         case GL_STENCIL_BUFFER_BIT:
            {
               const struct gl_stencil_attrib *stencil;
               stencil = (const struct gl_stencil_attrib *) attr->data;
               _mesa_set_enable(ctx, GL_STENCIL_TEST, stencil->Enabled);
               _mesa_ClearStencil(stencil->Clear);
               _mesa_StencilFunc(stencil->Function, stencil->Ref,
                                 stencil->ValueMask);
               _mesa_StencilMask(stencil->WriteMask);
               _mesa_StencilOp(stencil->FailFunc, stencil->ZFailFunc,
                               stencil->ZPassFunc);
            }
            break;
         case GL_TRANSFORM_BIT:
            {
               GLuint i;
               const struct gl_transform_attrib *xform;
               xform = (const struct gl_transform_attrib *) attr->data;
               _mesa_MatrixMode(xform->MatrixMode);

               if (ctx->ProjectionMatrix.flags & MAT_DIRTY)
                  _math_matrix_analyse( &ctx->ProjectionMatrix );

               /* restore clip planes */
               for (i = 0; i < MAX_CLIP_PLANES; i++) {
                  const GLfloat *eyePlane = xform->EyeUserPlane[i];
                  COPY_4V(ctx->Transform.EyeUserPlane[i], eyePlane);
                  if (xform->ClipEnabled[i]) {
                     _mesa_transform_vector( ctx->Transform._ClipUserPlane[i],
                                             eyePlane,
                                             ctx->ProjectionMatrix.inv );
                     _mesa_set_enable(ctx, GL_CLIP_PLANE0 + i, GL_TRUE );
                  }
                  else {
                     _mesa_set_enable(ctx, GL_CLIP_PLANE0 + i, GL_FALSE );
                  }
                  if (ctx->Driver.ClipPlane)
                     ctx->Driver.ClipPlane( ctx, GL_CLIP_PLANE0 + i, eyePlane );
               }

               /* normalize/rescale */
               _mesa_set_enable(ctx, GL_NORMALIZE, ctx->Transform.Normalize);
               _mesa_set_enable(ctx, GL_RESCALE_NORMAL_EXT,
                                ctx->Transform.RescaleNormals);
            }
            break;
         case GL_TEXTURE_BIT:
            /* Take care of texture object reference counters */
            {
               const struct gl_texture_attrib *texture;
               texture = (const struct gl_texture_attrib *) attr->data;
               pop_texture_group(ctx, texture);
	       ctx->NewState |= _NEW_TEXTURE;
            }
            break;
         case GL_VIEWPORT_BIT:
            {
               const struct gl_viewport_attrib *vp;
               vp = (const struct gl_viewport_attrib *) attr->data;
               _mesa_Viewport(vp->X, vp->Y, vp->Width, vp->Height);
               _mesa_DepthRange(vp->Near, vp->Far);
            }
            break;
         case GL_MULTISAMPLE_BIT_ARB:
            {
               const struct gl_multisample_attrib *ms;
               ms = (const struct gl_multisample_attrib *) attr->data;
               _mesa_SampleCoverageARB(ms->SampleCoverageValue,
                                       ms->SampleCoverageInvert);
            }
            break;

         default:
            _mesa_problem( ctx, "Bad attrib flag in PopAttrib");
            break;
      }

      next = attr->next;
      FREE( attr->data );
      FREE( attr );
      attr = next;
   }
}
示例#20
0
/**
 * Apply texture mapping to a span of fragments.
 */
void
_swrast_texture_span( struct gl_context *ctx, SWspan *span )
{
   SWcontext *swrast = SWRAST_CONTEXT(ctx);
   float4_array primary_rgba;

   if (!swrast->TexelBuffer) {
#ifdef _OPENMP
      const GLint maxThreads = omp_get_max_threads();
#else
      const GLint maxThreads = 1;
#endif

      /* TexelBuffer is also global and normally shared by all SWspan
       * instances; when running with multiple threads, create one per
       * thread.
       */
      swrast->TexelBuffer = (GLfloat *) MALLOC(maxThreads * MAX_WIDTH * 4 * sizeof(GLfloat));
      if (!swrast->TexelBuffer) {
         _mesa_error(ctx, GL_OUT_OF_MEMORY, "texture_combine");
         return;
      }
   }

   primary_rgba = (float4_array) malloc(span->end * 4 * sizeof(GLfloat));

   if (!primary_rgba) {
      _mesa_error(ctx, GL_OUT_OF_MEMORY, "texture_span");
      return;
   }

   ASSERT(span->end <= MAX_WIDTH);

   /*
    * Save copy of the incoming fragment colors (the GL_PRIMARY_COLOR)
    */
   if (swrast->_TextureCombinePrimary) {
      GLuint i;
      for (i = 0; i < span->end; i++) {
         primary_rgba[i][RCOMP] = CHAN_TO_FLOAT(span->array->rgba[i][RCOMP]);
         primary_rgba[i][GCOMP] = CHAN_TO_FLOAT(span->array->rgba[i][GCOMP]);
         primary_rgba[i][BCOMP] = CHAN_TO_FLOAT(span->array->rgba[i][BCOMP]);
         primary_rgba[i][ACOMP] = CHAN_TO_FLOAT(span->array->rgba[i][ACOMP]);
      }
   }

   /*
    * Must do all texture sampling before combining in order to
    * accomodate GL_ARB_texture_env_crossbar.
    */
   {
      const struct gl_texture_unit *texUnit = &ctx->Texture.Unit;
      if (texUnit->_ReallyEnabled) {
         const GLfloat (*texcoords)[4] = (const GLfloat (*)[4])
            span->array->attribs[FRAG_ATTRIB_TEX];
         const struct gl_texture_object *curObj = texUnit->_Current;
         GLfloat *lambda = span->array->lambda;
         float4_array texels = get_texel_array(swrast);

         if (curObj->Sampler.MaxAnisotropy > 1.0 &&
                  curObj->Sampler.MinFilter == GL_LINEAR_MIPMAP_LINEAR) {
            /* sample_lambda_2d_aniso is beeing used as texture_sample_func,
             * it requires the current SWspan *span as an additional parameter.
             * In order to keep the same function signature, the unused lambda
             * parameter will be modified to actually contain the SWspan pointer.
             * This is a Hack. To make it right, the texture_sample_func
             * signature and all implementing functions need to be modified.
             */
            /* "hide" SWspan struct; cast to (GLfloat *) to suppress warning */
            lambda = (GLfloat *)span;
         }

         /* Sample the texture (span->end = number of fragments) */
         swrast->TextureSample( ctx, texUnit->_Current, span->end,
                                texcoords, lambda, texels );
      }
   }

   /*
    * OK, now apply the texture (aka texture combine/blend).
    * We modify the span->color.rgba values.
    */
   if (ctx->Texture.Unit._ReallyEnabled)
      texture_combine(ctx, primary_rgba, swrast->TexelBuffer, span);

   free(primary_rgba);
}