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

📄 s_span.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 4 页
字号:
         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, struct sw_span *span)
{
   const SWcontext *swrast = SWRAST_CONTEXT(ctx);
   const struct gl_framebuffer *fb = ctx->DrawBuffer;
   const GLuint output = 0;
   const GLuint origInterpMask = span->interpMask;
   const GLuint origArrayMask = span->arrayMask;
   GLuint buf;

   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 && ctx->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] >= ctx->DrawBuffer->_Xmin);
            assert(span->array->x[i] < ctx->DrawBuffer->_Xmax);
            assert(span->array->y[i] >= ctx->DrawBuffer->_Ymin);
            assert(span->array->y[i] < ctx->DrawBuffer->_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->interpMask & 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 we get here, something passed the depth test */
   if (ctx->Depth.OcclusionTest) {
      ctx->OcclusionResult = GL_TRUE;
   }

#if FEATURE_ARB_occlusion_query
   if (ctx->Occlusion.Active) {
      /* update count of 'passed' fragments */
      GLuint i;
      for (i = 0; i < span->end; i++)
         ctx->Occlusion.PassedCounter += span->array->mask[i];
   }
#endif

   /* we have to wait until after occlusion to do this test */
   if (ctx->Color.DrawBuffer == GL_NONE || ctx->Color.IndexMask == 0) {
      /* write no pixels */
      span->arrayMask = origArrayMask;
      return;
   }

   /* Interpolate the color indexes if needed */
   if (ctx->Fog.Enabled ||
       ctx->Color.IndexLogicOpEnabled ||
       ctx->Color.IndexMask != 0xffffffff ||
       (span->arrayMask & SPAN_COVERAGE)) {
      if (span->interpMask & SPAN_INDEX) {
         interpolate_indexes(ctx, span);
      }
   }

   /* Fog */
   if (ctx->Fog.Enabled) {
      _swrast_fog_ci_span(ctx, span);
   }

   /* Antialias coverage application */
   if (span->arrayMask & SPAN_COVERAGE) {
      const GLfloat *coverage = span->array->coverage;
      GLuint *index = span->array->index;
      GLuint i;
      for (i = 0; i < span->end; i++) {
         ASSERT(coverage[i] < 16);
         index[i] = (index[i] & ~0xf) | ((GLuint) coverage[i]);
      }
   }

   /* Loop over drawing buffers */
   for (buf = 0; buf < fb->_NumColorDrawBuffers[output]; buf++) {
      struct gl_renderbuffer *rb = fb->_ColorDrawBuffers[output][buf];
      GLuint indexTemp[MAX_WIDTH], *index32;

      ASSERT(rb->_BaseFormat == GL_COLOR_INDEX);

      if (ctx->Color.IndexLogicOpEnabled ||
          ctx->Color.IndexMask != 0xffffffff) {
         /* make copy of incoming indexes */
         MEMCPY(indexTemp, span->array->index, span->end * sizeof(GLuint));

         if (ctx->Color.IndexLogicOpEnabled) {
            _swrast_logicop_ci_span(ctx, rb, span, indexTemp);
         }

         if (ctx->Color.IndexMask != 0xffffffff) {
            _swrast_mask_ci_span(ctx, rb, span, indexTemp);
         }
         index32 = indexTemp;
      }
      else {
         index32 = span->array->index;
      }

      if ((span->interpMask & SPAN_INDEX) && span->indexStep == 0) {
         /* all fragments have same color index */
         GLubyte index8;
         GLushort index16;
         GLuint index32;
         void *value;

         if (rb->DataType == GL_UNSIGNED_BYTE) {
            index8 = FixedToInt(span->index);
            value = &index8;
         }
         else if (rb->DataType == GL_UNSIGNED_SHORT) {
            index16 = FixedToInt(span->index);
            value = &index16;
         }
         else {
            ASSERT(rb->DataType == GL_UNSIGNED_INT);
            index32 = FixedToInt(span->index);
            value = &index32;
         }

         if (span->arrayMask & SPAN_XY) {
            rb->PutMonoValues(ctx, rb, span->end, span->array->x, 
                              span->array->y, value, span->array->mask);
         }
         else {
            rb->PutMonoRow(ctx, rb, span->end, span->x, span->y,
                           value, span->array->mask);
         }
      }
      else {
         /* each fragment is a different color */
         GLubyte index8[MAX_WIDTH];
         GLushort index16[MAX_WIDTH];
         void *values;

         if (rb->DataType == GL_UNSIGNED_BYTE) {
            GLuint k;
            for (k = 0; k < span->end; k++) {
               index8[k] = (GLubyte) index32[k];
            }
            values = index8;
         }
         else if (rb->DataType == GL_UNSIGNED_SHORT) {
            GLuint k;
            for (k = 0; k < span->end; k++) {
               index16[k] = (GLushort) index32[k];
            }
            values = index16;
         }
         else {
            ASSERT(rb->DataType == GL_UNSIGNED_INT);
            values = index32;
         }

         if (span->arrayMask & SPAN_XY) {
            rb->PutValues(ctx, rb, span->end, span->array->x, span->array->y,
                          values, span->array->mask);
         }
         else {
            rb->PutRow(ctx, rb, span->end, span->x, span->y,
                       values, span->array->mask);
         }
      }
   }

#if OLD_RENDERBUFFER
   /* restore default dest buffer */
   _swrast_use_draw_buffer(ctx);
#endif

   span->interpMask = origInterpMask;
   span->arrayMask = origArrayMask;
}


/**
 * Add specular color to base color.  This is used only when
 * GL_LIGHT_MODEL_COLOR_CONTROL = GL_SEPARATE_SPECULAR_COLOR.
 */
static void
add_colors(GLuint n, GLchan rgba[][4], GLchan specular[][4] )
{
   GLuint i;
   for (i = 0; i < n; i++) {
#if CHAN_TYPE == GL_FLOAT
      /* no clamping */
      rgba[i][RCOMP] += specular[i][RCOMP];
      rgba[i][GCOMP] += specular[i][GCOMP];
      rgba[i][BCOMP] += specular[i][BCOMP];
#else
      GLint r = rgba[i][RCOMP] + specular[i][RCOMP];
      GLint g = rgba[i][GCOMP] + specular[i][GCOMP];
      GLint b = rgba[i][BCOMP] + specular[i][BCOMP];
      rgba[i][RCOMP] = (GLchan) MIN2(r, CHAN_MAX);
      rgba[i][GCOMP] = (GLchan) MIN2(g, CHAN_MAX);
      rgba[i][BCOMP] = (GLchan) MIN2(b, CHAN_MAX);
#endif
   }
}


/**
 * XXX merge this code into the _swrast_write_rgba_span() routine!
 *
 * Draw to more than one RGBA color buffer (or none).
 * All fragment operations, up to (but not) blending/logicop should
 * have been done first.
 */
static void
multi_write_rgba_span( GLcontext *ctx, struct sw_span *span )
{
#if OLD_RENDERBUFFER
   SWcontext *swrast = SWRAST_CONTEXT(ctx);
#endif
   const GLuint colorMask = *((GLuint *) ctx->Color.ColorMask);
   struct gl_framebuffer *fb = ctx->DrawBuffer;
   const GLuint output = 0;
   GLuint i;

   ASSERT(span->end < MAX_WIDTH);
   ASSERT(colorMask != 0x0);

   for (i = 0; i < fb->_NumColorDrawBuffers[output]; i++) {
      struct gl_renderbuffer *rb = fb->_ColorDrawBuffers[output][i];
      GLchan rgbaTmp[MAX_WIDTH][4];

#if OLD_RENDERBUFFER
      /* obsolete code */
      GLuint bufferBit = fb->_ColorDrawBit[output][i];
      /* Set the current read/draw buffer */
      swrast->CurrentBufferBit = bufferBit;
      if (swrast->Driver.SetBuffer)
         (*swrast->Driver.SetBuffer)(ctx, ctx->DrawBuffer, bufferBit);
#endif

      /* make copy of incoming colors */
      MEMCPY( rgbaTmp, span->array->rgba, 4 * span->end * sizeof(GLchan) );

      if (ctx->Color._LogicOpEnabled) {
         _swrast_logicop_rgba_span(ctx, rb, span, rgbaTmp);
      }
      else if (ctx->Color.BlendEnabled) {
         _swrast_blend_span(ctx, rb, span, rgbaTmp);
      }

      if (colorMask != 0xffffffff) {
         _swrast_mask_rgba_span(ctx, rb, span, rgbaTmp);
      }

      if (span->arrayMask & SPAN_XY) {
         /* array of pixel coords */
         ASSERT(rb->PutValues);
         rb->PutValues(ctx, rb, span->end, span->array->x,
                       span->array->y, rgbaTmp, span->array->mask);
      }
      else {
         /* horizontal run of pixels */
         ASSERT(rb->PutRow);
         rb->PutRow(ctx, rb, span->end, span->x, span->y, rgbaTmp,
                    span->array->mask);
      }
   }

#if OLD_RENDERBUFFER
   /* restore default dest buffer */
   _swrast_use_draw_buffer(ctx);
#endif
}


/**
 * Apply all the per-fragment operations to a span.
 * This now includes texturing (_swrast_write_texture_span() is history).
 * This function may modify any of the array values in the span.
 * span->interpMask and span->arrayMask may be changed but will be restored
 * to their original values before returning.
 */
void
_swrast_write_rgba_span( GLcontext *ctx, struct sw_span *span)
{
   const GLuint colorMask = *((GLuint *) ctx->Color.ColorMask);
   SWcontext *swrast = SWRAST_CONTEXT(ctx);
   const GLuint origInterpMask = span->interpMask;
   const GLuint origArrayMask = span->arrayMask;
   const GLboolean deferredTexture = !(ctx->Color.AlphaEnabled ||
                                       ctx->FragmentProgram._Active ||
                                       ctx->ATIFragmentShader._Enabled);

   ASSERT(span->primitive == GL_POINT  ||  span->primitive == GL_LINE ||
	  span->primitive == GL_POLYGON  ||  span->primitive == GL_BITMAP);
   ASSERT(span->end <= MAX_WIDTH);
   ASSERT((span->interpMask & span->arrayMask) == 0);

   /*
   printf("%s()  interp 0x%x  array 0x%x\n", __FUNCTION__,
          span->interpMask, span->arrayMask);
   */

   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;
   }

   /* Clip to window/scissor box */
   if ((swrast->_RasterMask & CLIP_BIT) || (span->primitive != GL_POLYGON)) {

⌨️ 快捷键说明

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