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

📄 s_span.c

📁 Mesa is an open-source implementation of the OpenGL specification - a system for rendering interacti
💻 C
📖 第 1 页 / 共 4 页
字号:
/** * Compute mipmap LOD from partial derivatives. * This the ideal solution, as given in the OpenGL spec. */#if 0static GLfloatcompute_lambda(GLfloat dsdx, GLfloat dsdy, GLfloat dtdx, GLfloat dtdy,               GLfloat dqdx, GLfloat dqdy, GLfloat texW, GLfloat texH,               GLfloat s, GLfloat t, GLfloat q, GLfloat invQ){   GLfloat dudx = texW * ((s + dsdx) / (q + dqdx) - s * invQ);   GLfloat dvdx = texH * ((t + dtdx) / (q + dqdx) - t * invQ);   GLfloat dudy = texW * ((s + dsdy) / (q + dqdy) - s * invQ);   GLfloat dvdy = texH * ((t + dtdy) / (q + dqdy) - t * invQ);   GLfloat x = SQRTF(dudx * dudx + dvdx * dvdx);   GLfloat y = SQRTF(dudy * dudy + dvdy * dvdy);   GLfloat rho = MAX2(x, y);   GLfloat lambda = LOG2(rho);   return lambda;}#endif/** * Compute mipmap LOD from partial derivatives. * This is a faster approximation than above function. */GLfloat_swrast_compute_lambda(GLfloat dsdx, GLfloat dsdy, GLfloat dtdx, GLfloat dtdy,                     GLfloat dqdx, GLfloat dqdy, GLfloat texW, GLfloat texH,                     GLfloat s, GLfloat t, GLfloat q, GLfloat invQ){   GLfloat dsdx2 = (s + dsdx) / (q + dqdx) - s * invQ;   GLfloat dtdx2 = (t + dtdx) / (q + dqdx) - t * invQ;   GLfloat dsdy2 = (s + dsdy) / (q + dqdy) - s * invQ;   GLfloat dtdy2 = (t + dtdy) / (q + dqdy) - t * invQ;   GLfloat maxU, maxV, rho, lambda;   dsdx2 = FABSF(dsdx2);   dsdy2 = FABSF(dsdy2);   dtdx2 = FABSF(dtdx2);   dtdy2 = FABSF(dtdy2);   maxU = MAX2(dsdx2, dsdy2) * texW;   maxV = MAX2(dtdx2, dtdy2) * texH;   rho = MAX2(maxU, maxV);   lambda = LOG2(rho);   return lambda;}/** * 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 voidinterpolate_texcoords(GLcontext *ctx, SWspan *span){   const GLuint maxUnit      = (ctx->Texture._EnabledCoordUnits > 1) ? ctx->Const.MaxTextureUnits : 1;   GLuint u;   /* XXX CoordUnits vs. ImageUnits */   for (u = 0; u < maxUnit; u++) {      if (ctx->Texture._EnabledCoordUnits & (1 << u)) {         const GLuint attr = FRAG_ATTRIB_TEX0 + u;         const struct gl_texture_object *obj = ctx->Texture.Unit[u]._Current;         GLfloat texW, texH;         GLboolean needLambda;         GLfloat (*texcoord)[4] = span->array->attribs[attr];         GLfloat *lambda = span->array->lambda[u];         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];         GLfloat t = span->attrStart[attr][1];         GLfloat r = span->attrStart[attr][2];         GLfloat q = span->attrStart[attr][3];         if (obj) {            const struct gl_texture_image *img = obj->Image[0][obj->BaseLevel];            needLambda = (obj->MinFilter != obj->MagFilter)               || ctx->FragmentProgram._Current;            texW = img->WidthScale;            texH = img->HeightScale;         }         else {            /* using a fragment program */            texW = 1.0;            texH = 1.0;            needLambda = GL_FALSE;         }         if (needLambda) {            GLuint i;            if (ctx->FragmentProgram._Current                || ctx->ATIFragmentShader._Enabled) {               /* do perspective correction but don't divide s, t, r by q */               const GLfloat dwdx = span->attrStepX[FRAG_ATTRIB_WPOS][3];               GLfloat w = span->attrStart[FRAG_ATTRIB_WPOS][3];               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 {            GLuint i;            if (ctx->FragmentProgram._Current ||                ctx->ATIFragmentShader._Enabled) {               /* do perspective correction but don't divide s, t, r by q */               const GLfloat dwdx = span->attrStepX[FRAG_ATTRIB_WPOS][3];               GLfloat w = span->attrStart[FRAG_ATTRIB_WPOS][3];               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 */}/** * Fill in the arrays->attribs[FRAG_ATTRIB_WPOS] array. */static INLINE voidinterpolate_wpos(GLcontext *ctx, SWspan *span){   GLfloat (*wpos)[4] = span->array->attribs[FRAG_ATTRIB_WPOS];   GLuint i;   const GLfloat zScale = 1.0 / ctx->DrawBuffer->_DepthMaxF;   GLfloat w, dw;   if (span->arrayMask & SPAN_XY) {      for (i = 0; i < span->end; i++) {         wpos[i][0] = (GLfloat) span->array->x[i];         wpos[i][1] = (GLfloat) span->array->y[i];      }   }   else {      for (i = 0; i < span->end; i++) {         wpos[i][0] = (GLfloat) span->x + i;         wpos[i][1] = (GLfloat) span->y;      }   }   w = span->attrStart[FRAG_ATTRIB_WPOS][3];   dw = span->attrStepX[FRAG_ATTRIB_WPOS][3];   for (i = 0; i < span->end; i++) {      wpos[i][2] = (GLfloat) span->array->z[i] * zScale;      wpos[i][3] = w;      w += dw;   }}/** * Apply the current polygon stipple pattern to a span of pixels. */static INLINE voidstipple_polygon_span(GLcontext *ctx, SWspan *span){   GLubyte *mask = span->array->mask;   ASSERT(ctx->Polygon.StippleFlag);   if (span->arrayMask & SPAN_XY) {      /* arrays of x/y pixel coords */      GLuint i;      for (i = 0; i < span->end; i++) {         const GLint col = span->array->x[i] % 32;         const GLint row = span->array->y[i] % 32;         const GLuint stipple = ctx->PolygonStipple[row];         if (((1 << col) & stipple) == 0) {            mask[i] = 0;         }      }   }   else {      /* horizontal span of pixels */      const GLuint highBit = 1 << 31;      const GLuint stipple = ctx->PolygonStipple[span->y % 32];      GLuint i, 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 INLINE GLuintclip_span( GLcontext *ctx, SWspan *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) {         ASSERT(x < xmax);         span->end = xmax - x;      }      return GL_TRUE;  /* some pixels visible */   }}/** * Apply all the per-fragment opertions to a span of color index fragments * and write them to the enabled color drawbuffers. * The 'span' parameter can be considered to be const.  Note that * span->interpMask and span->arrayMask may be changed but will be restored * to their original values before returning. */void_swrast_write_index_span( GLcontext *ctx, SWspan *span){   const SWcontext *swrast = SWRAST_CONTEXT(ctx);   const GLbitfield origInterpMask = span->interpMask;   const GLbitfield origArrayMask = span->arrayMask;   struct gl_framebuffer *fb = ctx->DrawBuffer;   ASSERT(span->end <= MAX_WIDTH);   ASSERT(span->primitive == GL_POINT  ||  span->primitive == GL_LINE ||	  span->primitive == GL_POLYGON  ||  span->primitive == GL_BITMAP);   ASSERT((span->interpMask | span->arrayMask) & SPAN_INDEX);   /*   ASSERT((span->interpMask & span->arrayMask) == 0);   */   if (span->arrayMask & SPAN_MASK) {      /* mask was initialized by caller, probably glBitmap */      span->writeAll = GL_FALSE;   }   else {      _mesa_memset(span->array->mask, 1, span->end);      span->writeAll = GL_TRUE;   }   /* Clipping */   if ((swrast->_RasterMask & CLIP_BIT) || (span->primitive != GL_POLYGON)) {      if (!clip_span(ctx, span)) {         return;      }   }   /* Depth bounds test */   if (ctx->Depth.BoundsTest && fb->Visual.depthBits > 0) {      if (!_swrast_depth_bounds_test(ctx, span)) {         return;      }   }#ifdef DEBUG   /* Make sure all fragments are within window bounds */   if (span->arrayMask & SPAN_XY) {      GLuint i;      for (i = 0; i < span->end; i++) {         if (span->array->mask[i]) {            assert(span->array->x[i] >= fb->_Xmin);            assert(span->array->x[i] < fb->_Xmax);            assert(span->array->y[i] >= fb->_Ymin);            assert(span->array->y[i] < fb->_Ymax);         }      }   }#endif   /* Polygon Stippling */   if (ctx->Polygon.StippleFlag && span->primitive == GL_POLYGON) {      stipple_polygon_span(ctx, span);   }   /* Stencil and Z testing */   if (ctx->Depth.Test || ctx->Stencil.Enabled) {      if (!(span->arrayMask & SPAN_Z))         _swrast_span_interpolate_z(ctx, span);      if (ctx->Stencil.Enabled) {         if (!_swrast_stencil_and_ztest_span(ctx, span)) {            span->arrayMask = origArrayMask;            return;         }      }      else {         ASSERT(ctx->Depth.Test);         if (!_swrast_depth_test_span(ctx, span)) {            span->interpMask = origInterpMask;            span->arrayMask = origArrayMask;            return;         }      }   }#if FEATURE_ARB_occlusion_query   if (ctx->Query.CurrentOcclusionObject) {      /* update count of 'passed' fragments */      struct gl_query_object *q = ctx->Query.CurrentOcclusionObject;      GLuint i;      for (i = 0; i < span->end; i++)         q->Result += span->array->mask[i];   }

⌨️ 快捷键说明

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