示例#1
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]);
}
示例#2
0
/**
 * Fetch a texel with the given partial derivatives to compute a level
 * of detail in the mipmap.
 * Called via machine->FetchTexelDeriv()
 * \param lodBias  the lod bias which may be specified by a TXB instruction,
 *                 otherwise zero.
 */
static void
fetch_texel_deriv( struct gl_context *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_unit *texUnit = &ctx->Texture.Unit[unit];
   const struct gl_texture_object *texObj = texUnit->_Current;

   if (texObj) {
      const struct gl_texture_image *texImg =
         texObj->Image[0][texObj->BaseLevel];
      const struct swrast_texture_image *swImg =
         swrast_texture_image_const(texImg);
      const struct gl_sampler_object *samp = _mesa_get_samplerobj(ctx, unit);
      const GLfloat texW = (GLfloat) swImg->WidthScale;
      const GLfloat texH = (GLfloat) swImg->HeightScale;
      GLfloat lambda;
      GLfloat rgba[4];

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

      lambda += lodBias + texUnit->LodBias + samp->LodBias;

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

      swrast->TextureSample[unit](ctx, samp, ctx->Texture.Unit[unit]._Current,
                                  1, (const GLfloat (*)[4]) texcoord,
                                  &lambda, &rgba);
      swizzle_texel(rgba, color, texObj->_Swizzle);
   }
   else {
      ASSIGN_4V(color, 0.0F, 0.0F, 0.0F, 1.0F);
   }
}
示例#3
0
/**
 * Fill in the span.array->attrib[FRAG_ATTRIB_TEXn] arrays from the
 * using the attrStart/Step values.
 *
 * This function only used during fixed-function fragment processing.
 *
 * Note: in the places where we divide by Q (or mult by invQ) we're
 * really doing two things: perspective correction and texcoord
 * projection.  Remember, for texcoord (s,t,r,q) we need to index
 * texels with (s/q, t/q, r/q).
 */
static void
interpolate_texcoords(struct gl_context *ctx, SWspan *span)
{
   if (ctx->Texture._EnabledCoord) {
      const GLuint attr = FRAG_ATTRIB_TEX;
      const struct gl_texture_object *obj = ctx->Texture.Unit._Current;
      GLfloat texW, texH;
      GLboolean needLambda;
      GLfloat (*texcoord)[4] = span->array->attribs[attr];
      GLfloat *lambda = span->array->lambda;
      const GLfloat dsdx = span->attrStepX[attr][0];
      const GLfloat dsdy = span->attrStepY[attr][0];
      const GLfloat dtdx = span->attrStepX[attr][1];
      const GLfloat dtdy = span->attrStepY[attr][1];
      const GLfloat drdx = span->attrStepX[attr][2];
      const GLfloat dqdx = span->attrStepX[attr][3];
      const GLfloat dqdy = span->attrStepY[attr][3];
      GLfloat s = span->attrStart[attr][0] + span->leftClip * dsdx;
      GLfloat t = span->attrStart[attr][1] + span->leftClip * dtdx;
      GLfloat r = span->attrStart[attr][2] + span->leftClip * drdx;
      GLfloat q = span->attrStart[attr][3] + span->leftClip * dqdx;

      if (obj) {
         const struct gl_texture_image *img = obj->Image[0][obj->BaseLevel];
         const struct swrast_texture_image *swImg =
            swrast_texture_image_const(img);

         needLambda = (obj->Sampler.MinFilter != obj->Sampler.MagFilter);
         /* LOD is calculated directly in the ansiotropic filter, we can
          * skip the normal lambda function as the result is ignored.
          */
         if (obj->Sampler.MaxAnisotropy > 1.0 &&
             obj->Sampler.MinFilter == GL_LINEAR_MIPMAP_LINEAR) {
            needLambda = GL_FALSE;
         }
         texW = swImg->WidthScale;
         texH = swImg->HeightScale;
      }
      else {
         /* using a fragment program */
         texW = 1.0;
         texH = 1.0;
         needLambda = GL_FALSE;
      }

      if (needLambda) {
         GLuint i;
         for (i = 0; i < span->end; i++) {
            const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q);
            texcoord[i][0] = s * invQ;
            texcoord[i][1] = t * invQ;
            texcoord[i][2] = r * invQ;
            texcoord[i][3] = q;
            lambda[i] = _swrast_compute_lambda(dsdx, dsdy, dtdx, dtdy,
                                               dqdx, dqdy, texW, texH,
                                               s, t, q, invQ);
            s += dsdx;
            t += dtdx;
            r += drdx;
            q += dqdx;
         }
         span->arrayMask |= SPAN_LAMBDA;
      }
      else {
         GLuint i;
         if (dqdx == 0.0F) {
            /* Ortho projection or polygon's parallel to window X axis */
            const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q);
            for (i = 0; i < span->end; i++) {
               texcoord[i][0] = s * invQ;
               texcoord[i][1] = t * invQ;
               texcoord[i][2] = r * invQ;
               texcoord[i][3] = q;
               lambda[i] = 0.0;
               s += dsdx;
               t += dtdx;
               r += drdx;
            }
         }
         else {
            for (i = 0; i < span->end; i++) {
               const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q);
               texcoord[i][0] = s * invQ;
               texcoord[i][1] = t * invQ;
               texcoord[i][2] = r * invQ;
               texcoord[i][3] = q;
               lambda[i] = 0.0;
               s += dsdx;
               t += dtdx;
               r += drdx;
               q += dqdx;
            }
         }
      } /* lambda */
   } /* if */
}