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

📄 s_span.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 4 页
字号:
   return lambda;
}


/**
 * Fill in the span.texcoords array from the interpolation values.
 * 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).
 * If we're using a fragment program, we never do the division
 * for texcoord projection.  That's done by the TXP instruction
 * or user-written code.
 */
static void
interpolate_texcoords(GLcontext *ctx, struct sw_span *span)
{
   ASSERT(span->interpMask & SPAN_TEXTURE);
   ASSERT(!(span->arrayMask & SPAN_TEXTURE));

   if (ctx->Texture._EnabledCoordUnits > 1) {
      /* multitexture */
      GLuint u;
      span->arrayMask |= SPAN_TEXTURE;
      for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
         if (ctx->Texture._EnabledCoordUnits & (1 << u)) {
            const struct gl_texture_object *obj =ctx->Texture.Unit[u]._Current;
            GLfloat texW, texH;
            GLboolean needLambda;
            if (obj) {
               const struct gl_texture_image *img = obj->Image[0][obj->BaseLevel];
               needLambda = (obj->MinFilter != obj->MagFilter)
                  || ctx->FragmentProgram._Active;
               texW = img->WidthScale;
               texH = img->HeightScale;
            }
            else {
               /* using a fragment program */
               texW = 1.0;
               texH = 1.0;
               needLambda = GL_FALSE;
            }
            if (needLambda) {
               GLfloat (*texcoord)[4] = span->array->texcoords[u];
               GLfloat *lambda = span->array->lambda[u];
               const GLfloat dsdx = span->texStepX[u][0];
               const GLfloat dsdy = span->texStepY[u][0];
               const GLfloat dtdx = span->texStepX[u][1];
               const GLfloat dtdy = span->texStepY[u][1];
               const GLfloat drdx = span->texStepX[u][2];
               const GLfloat dqdx = span->texStepX[u][3];
               const GLfloat dqdy = span->texStepY[u][3];
               GLfloat s = span->tex[u][0];
               GLfloat t = span->tex[u][1];
               GLfloat r = span->tex[u][2];
               GLfloat q = span->tex[u][3];
               GLuint i;
               if (ctx->FragmentProgram._Active) {
                  /* do perspective correction but don't divide s, t, r by q */
                  const GLfloat dwdx = span->dwdx;
                  GLfloat w = span->w;
                  for (i = 0; i < span->end; i++) {
                     const GLfloat invW = 1.0F / w;
                     texcoord[i][0] = s * invW;
                     texcoord[i][1] = t * invW;
                     texcoord[i][2] = r * invW;
                     texcoord[i][3] = q * invW;
                     lambda[i] = _swrast_compute_lambda(dsdx, dsdy, dtdx, dtdy,
                                                        dqdx, dqdy, texW, texH,
                                                        s, t, q, invW);
                     s += dsdx;
                     t += dtdx;
                     r += drdx;
                     q += dqdx;
                     w += dwdx;
                  }

               }
               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] = _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 {
               GLfloat (*texcoord)[4] = span->array->texcoords[u];
               GLfloat *lambda = span->array->lambda[u];
               const GLfloat dsdx = span->texStepX[u][0];
               const GLfloat dtdx = span->texStepX[u][1];
               const GLfloat drdx = span->texStepX[u][2];
               const GLfloat dqdx = span->texStepX[u][3];
               GLfloat s = span->tex[u][0];
               GLfloat t = span->tex[u][1];
               GLfloat r = span->tex[u][2];
               GLfloat q = span->tex[u][3];
               GLuint i;
               if (ctx->FragmentProgram._Active) {
                  /* do perspective correction but don't divide s, t, r by q */
                  const GLfloat dwdx = span->dwdx;
                  GLfloat w = span->w;
                  for (i = 0; i < span->end; i++) {
                     const GLfloat invW = 1.0F / w;
                     texcoord[i][0] = s * invW;
                     texcoord[i][1] = t * invW;
                     texcoord[i][2] = r * invW;
                     texcoord[i][3] = q * invW;
                     lambda[i] = 0.0;
                     s += dsdx;
                     t += dtdx;
                     r += drdx;
                     q += dqdx;
                     w += dwdx;
                  }
               }
               else 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 */
      } /* for */
   }
   else {
      /* single texture */
      const struct gl_texture_object *obj = ctx->Texture.Unit[0]._Current;
      GLfloat texW, texH;
      GLboolean needLambda;
      if (obj) {
         const struct gl_texture_image *img = obj->Image[0][obj->BaseLevel];
         needLambda = (obj->MinFilter != obj->MagFilter)
            || ctx->FragmentProgram._Active;
         texW = (GLfloat) img->WidthScale;
         texH = (GLfloat) img->HeightScale;
      }
      else {
         needLambda = GL_FALSE;
         texW = texH = 1.0;
      }
      span->arrayMask |= SPAN_TEXTURE;
      if (needLambda) {
         /* just texture unit 0, with lambda */
         GLfloat (*texcoord)[4] = span->array->texcoords[0];
         GLfloat *lambda = span->array->lambda[0];
         const GLfloat dsdx = span->texStepX[0][0];
         const GLfloat dsdy = span->texStepY[0][0];
         const GLfloat dtdx = span->texStepX[0][1];
         const GLfloat dtdy = span->texStepY[0][1];
         const GLfloat drdx = span->texStepX[0][2];
         const GLfloat dqdx = span->texStepX[0][3];
         const GLfloat dqdy = span->texStepY[0][3];
         GLfloat s = span->tex[0][0];
         GLfloat t = span->tex[0][1];
         GLfloat r = span->tex[0][2];
         GLfloat q = span->tex[0][3];
         GLuint i;
         if (ctx->FragmentProgram._Active) {
            /* do perspective correction but don't divide s, t, r by q */
            const GLfloat dwdx = span->dwdx;
            GLfloat w = span->w;
            for (i = 0; i < span->end; i++) {
               const GLfloat invW = 1.0F / w;
               texcoord[i][0] = s * invW;
               texcoord[i][1] = t * invW;
               texcoord[i][2] = r * invW;
               texcoord[i][3] = q * invW;
               lambda[i] = _swrast_compute_lambda(dsdx, dsdy, dtdx, dtdy,
                                                  dqdx, dqdy, texW, texH,
                                                  s, t, q, invW);
               s += dsdx;
               t += dtdx;
               r += drdx;
               q += dqdx;
               w += dwdx;
            }
         }
         else {
            /* tex.c */
            for (i = 0; i < span->end; i++) {
               const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q);
               lambda[i] = _swrast_compute_lambda(dsdx, dsdy, dtdx, dtdy,
                                                dqdx, dqdy, texW, texH,
                                                s, t, q, invQ);
               texcoord[i][0] = s * invQ;
               texcoord[i][1] = t * invQ;
               texcoord[i][2] = r * invQ;
               texcoord[i][3] = q;
               s += dsdx;
               t += dtdx;
               r += drdx;
               q += dqdx;
            }
         }
         span->arrayMask |= SPAN_LAMBDA;
      }
      else {
         /* just texture 0, without lambda */
         GLfloat (*texcoord)[4] = span->array->texcoords[0];
         const GLfloat dsdx = span->texStepX[0][0];
         const GLfloat dtdx = span->texStepX[0][1];
         const GLfloat drdx = span->texStepX[0][2];
         const GLfloat dqdx = span->texStepX[0][3];
         GLfloat s = span->tex[0][0];
         GLfloat t = span->tex[0][1];
         GLfloat r = span->tex[0][2];
         GLfloat q = span->tex[0][3];
         GLuint i;
         if (ctx->FragmentProgram._Active) {
            /* do perspective correction but don't divide s, t, r by q */
            const GLfloat dwdx = span->dwdx;
            GLfloat w = span->w;
            for (i = 0; i < span->end; i++) {
               const GLfloat invW = 1.0F / w;
               texcoord[i][0] = s * invW;
               texcoord[i][1] = t * invW;
               texcoord[i][2] = r * invW;
               texcoord[i][3] = q * invW;
               s += dsdx;
               t += dtdx;
               r += drdx;
               q += dqdx;
               w += dwdx;
            }
         }
         else 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;
               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;
               s += dsdx;
               t += dtdx;
               r += drdx;
               q += dqdx;
            }
         }
      }
   }
}


/**
 * Apply the current polygon stipple pattern to a span of pixels.
 */
static void
stipple_polygon_span( GLcontext *ctx, struct sw_span *span )
{
   const GLuint highbit = 0x80000000;
   const GLuint stipple = ctx->PolygonStipple[span->y % 32];
   GLubyte *mask = span->array->mask;
   GLuint i, m;

   ASSERT(ctx->Polygon.StippleFlag);
   ASSERT((span->arrayMask & SPAN_XY) == 0);

   m = highbit >> (GLuint) (span->x % 32);

   for (i = 0; i < span->end; i++) {
      if ((m & stipple) == 0) {
	 mask[i] = 0;
      }
      m = m >> 1;
      if (m == 0) {
         m = highbit;
      }
   }
   span->writeAll = GL_FALSE;
}


/**
 * Clip a pixel span to the current buffer/window boundaries:
 * DrawBuffer->_Xmin, _Xmax, _Ymin, _Ymax.  This will accomplish
 * window clipping and scissoring.
 * Return:   GL_TRUE   some pixels still visible
 *           GL_FALSE  nothing visible
 */
static GLuint
clip_span( GLcontext *ctx, struct sw_span *span )
{
   const GLint xmin = ctx->DrawBuffer->_Xmin;
   const GLint xmax = ctx->DrawBuffer->_Xmax;
   const GLint ymin = ctx->DrawBuffer->_Ymin;
   const GLint ymax = ctx->DrawBuffer->_Ymax;

   if (span->arrayMask & SPAN_XY) {
      /* arrays of x/y pixel coords */
      const GLint *x = span->array->x;
      const GLint *y = span->array->y;
      const GLint n = span->end;
      GLubyte *mask = span->array->mask;
      GLint i;
      if (span->arrayMask & SPAN_MASK) {
         /* note: using & intead of && to reduce branches */
         for (i = 0; i < n; i++) {
            mask[i] &= (x[i] >= xmin) & (x[i] < xmax)
                     & (y[i] >= ymin) & (y[i] < ymax);
         }
      }
      else {
         /* note: using & intead of && to reduce branches */
         for (i = 0; i < n; i++) {
            mask[i] = (x[i] >= xmin) & (x[i] < xmax)
                    & (y[i] >= ymin) & (y[i] < ymax);
         }
      }
      return GL_TRUE;  /* some pixels visible */
   }
   else {
      /* horizontal span of pixels */
      const GLint x = span->x;
      const GLint y = span->y;
      const GLint n = span->end;

      /* Trivial rejection tests */
      if (y < ymin || y >= ymax || x + n <= xmin || x >= xmax) {
         span->end = 0;
         return GL_FALSE;  /* all pixels clipped */
      }

      /* Clip to the left */
      if (x < xmin) {
         ASSERT(x + n > xmin);
         span->writeAll = GL_FALSE;
         _mesa_bzero(span->array->mask, (xmin - x) * sizeof(GLubyte));
      }

      /* Clip to right */
      if (x + n > xmax) {

⌨️ 快捷键说明

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