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

📄 s_span.c

📁 这是一个开放源代码的与WINNT/WIN2K/WIN2003兼容的操作系统
💻 C
📖 第 1 页 / 共 4 页
字号:
      if (!clip_span(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);
   }

   /* Interpolate texcoords? */
   if (ctx->Texture._EnabledCoordUnits
       && (span->interpMask & SPAN_TEXTURE)
       && (span->arrayMask & SPAN_TEXTURE) == 0) {
      interpolate_texcoords(ctx, span);
   }

   /* This is the normal place to compute the resulting fragment color/Z.
    * As an optimization, we try to defer this until after Z/stencil
    * testing in order to try to avoid computing colors that we won't
    * actually need.
    */
   if (!deferredTexture) {
      /* Now we need the rgba array, fill it in if needed */
      if ((span->interpMask & SPAN_RGBA) && (span->arrayMask & SPAN_RGBA) == 0)
         interpolate_colors(ctx, span);

      if (span->interpMask & SPAN_SPEC)
         interpolate_specular(ctx, span);

      if (span->interpMask & SPAN_FOG)
         interpolate_fog(ctx, span);

      /* Compute fragment colors with fragment program or texture lookups */
      if (ctx->FragmentProgram._Active) {
         /* frag prog may need Z values */
         if (span->interpMask & SPAN_Z)
            _swrast_span_interpolate_z(ctx, span);
         _swrast_exec_fragment_program( ctx, span );
      }
      else if (ctx->ATIFragmentShader._Enabled)
         _swrast_exec_fragment_shader( ctx, span );
      else if (ctx->Texture._EnabledUnits && (span->arrayMask & SPAN_TEXTURE))
         _swrast_texture_span( ctx, span );

      /* Do the alpha test */
      if (!_swrast_alpha_test(ctx, span)) {
         span->arrayMask = origArrayMask;
	 return;
      }
   }

   /* Stencil and Z testing */
   if (ctx->Stencil.Enabled || ctx->Depth.Test) {
      if (span->interpMask & SPAN_Z)
         _swrast_span_interpolate_z(ctx, span);

      if (ctx->Stencil.Enabled && ctx->DrawBuffer->Visual.stencilBits > 0) {
         /* Combined Z/stencil tests */
         if (!_swrast_stencil_and_ztest_span(ctx, span)) {
            span->interpMask = origInterpMask;
            span->arrayMask = origArrayMask;
            return;
         }
      }
      else if (ctx->DrawBuffer->Visual.depthBits > 0) {
         /* Just regular depth testing */
         ASSERT(ctx->Depth.Test);
         ASSERT(span->arrayMask & SPAN_Z);
         if (!_swrast_depth_test_span(ctx, span)) {
            span->interpMask = origInterpMask;
            span->arrayMask = origArrayMask;
            return;
         }
      }
   }

   /* if we get here, some fragments 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 had to wait until now to check for glColorMask(0,0,0,0) because of
    * the occlusion test.
    */
   if (colorMask == 0x0) {
      span->interpMask = origInterpMask;
      span->arrayMask = origArrayMask;
      return;
   }

   /* If we were able to defer fragment color computation to now, there's
    * a good chance that many fragments will have already been killed by
    * Z/stencil testing.
    */
   if (deferredTexture) {
      /* Now we need the rgba array, fill it in if needed */
      if ((span->interpMask & SPAN_RGBA) && (span->arrayMask & SPAN_RGBA) == 0)
         interpolate_colors(ctx, span);

      if (span->interpMask & SPAN_SPEC)
         interpolate_specular(ctx, span);

      if (span->interpMask & SPAN_FOG)
         interpolate_fog(ctx, span);

      if (ctx->FragmentProgram._Active)
         _swrast_exec_fragment_program( ctx, span );
      else if (ctx->ATIFragmentShader._Enabled)
         _swrast_exec_fragment_shader( ctx, span );
      else if (ctx->Texture._EnabledUnits && (span->arrayMask & SPAN_TEXTURE))
         _swrast_texture_span( ctx, span );
   }

   ASSERT(span->arrayMask & SPAN_RGBA);

   if (!ctx->FragmentProgram._Enabled) {
      /* Add base and specular colors */
      if (ctx->Fog.ColorSumEnabled ||
          (ctx->Light.Enabled &&
           ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)) {
         if (span->interpMask & SPAN_SPEC) {
            interpolate_specular(ctx, span);
         }
         if (span->arrayMask & SPAN_SPEC) {
            add_colors( span->end, span->array->rgba, span->array->spec );
         }
         else {
            /* We probably added the base/specular colors during the
             * vertex stage!
             */
         }
      }
   }

   /* Fog */
   if (swrast->_FogEnabled) {
      _swrast_fog_rgba_span(ctx, span);
   }

   /* Antialias coverage application */
   if (span->arrayMask & SPAN_COVERAGE) {
      GLchan (*rgba)[4] = span->array->rgba;
      GLfloat *coverage = span->array->coverage;
      GLuint i;
      for (i = 0; i < span->end; i++) {
         rgba[i][ACOMP] = (GLchan) (rgba[i][ACOMP] * coverage[i]);
      }
   }

   if (swrast->_RasterMask & MULTI_DRAW_BIT) {
      /* need to do blend/logicop separately for each color buffer */
      multi_write_rgba_span(ctx, span);
   }
   else {
      /* normal: write to exactly one buffer */
      struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0][0];

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

      /* Color component masking */
      if (colorMask != 0xffffffff) {
         _swrast_mask_rgba_span(ctx, rb, span, span->array->rgba);
      }

      /* Finally, write the pixels to a color buffer */
      if (span->arrayMask & SPAN_XY) {
         /* array of pixel coords */
         ASSERT(rb->PutValues);
         ASSERT(rb->_BaseFormat == GL_RGB || rb->_BaseFormat == GL_RGBA);
         /* XXX check datatype */
         rb->PutValues(ctx, rb, span->end, span->array->x, span->array->y,
                       span->array->rgba, span->array->mask);
      }
      else {
         /* horizontal run of pixels */
         ASSERT(rb->PutRow);
         ASSERT(rb->_BaseFormat == GL_RGB || rb->_BaseFormat == GL_RGBA);
         /* XXX check datatype */
         rb->PutRow(ctx, rb, span->end, span->x, span->y, span->array->rgba,
                    span->writeAll ? NULL : span->array->mask);
      }
   }

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



/**
 * Read RGBA pixels from frame buffer.  Clipping will be done to prevent
 * reading ouside the buffer's boundaries.
 */
void
_swrast_read_rgba_span( GLcontext *ctx, struct gl_renderbuffer *rb,
                        GLuint n, GLint x, GLint y, GLchan rgba[][4] )
{
   const GLint bufWidth = (GLint) rb->Width;
   const GLint bufHeight = (GLint) rb->Height;

   if (y < 0 || y >= bufHeight || x + (GLint) n < 0 || x >= bufWidth) {
      /* completely above, below, or right */
      /* XXX maybe leave rgba values undefined? */
      _mesa_bzero(rgba, 4 * n * sizeof(GLchan));
   }
   else {
      GLint skip, length;
      if (x < 0) {
         /* left edge clipping */
         skip = -x;
         length = (GLint) n - skip;
         if (length < 0) {
            /* completely left of window */
            return;
         }
         if (length > bufWidth) {
            length = bufWidth;
         }
      }
      else if ((GLint) (x + n) > bufWidth) {
         /* right edge clipping */
         skip = 0;
         length = bufWidth - x;
         if (length < 0) {
            /* completely to right of window */
            return;
         }
      }
      else {
         /* no clipping */
         skip = 0;
         length = (GLint) n;
      }

      ASSERT(rb);
      ASSERT(rb->GetRow);
      ASSERT(rb->_BaseFormat == GL_RGB || rb->_BaseFormat == GL_RGBA);
      ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
      rb->GetRow(ctx, rb, length, x + skip, y, rgba + skip);
   }
}


/**
 * Read CI pixels from frame buffer.  Clipping will be done to prevent
 * reading ouside the buffer's boundaries.
 */
void
_swrast_read_index_span( GLcontext *ctx, struct gl_renderbuffer *rb,
                         GLuint n, GLint x, GLint y, GLuint index[] )
{
   const GLint bufWidth = (GLint) rb->Width;
   const GLint bufHeight = (GLint) rb->Height;

   if (y < 0 || y >= bufHeight || x + (GLint) n < 0 || x >= bufWidth) {
      /* completely above, below, or right */
      _mesa_bzero(index, n * sizeof(GLuint));
   }
   else {
      GLint skip, length;
      if (x < 0) {
         /* left edge clipping */
         skip = -x;
         length = (GLint) n - skip;
         if (length < 0) {
            /* completely left of window */
            return;
         }
         if (length > bufWidth) {
            length = bufWidth;
         }
      }
      else if ((GLint) (x + n) > bufWidth) {
         /* right edge clipping */
         skip = 0;
         length = bufWidth - x;
         if (length < 0) {
            /* completely to right of window */
            return;
         }
      }
      else {
         /* no clipping */
         skip = 0;
         length = (GLint) n;
      }

      ASSERT(rb->GetRow);
      ASSERT(rb->_BaseFormat == GL_COLOR_INDEX);

      if (rb->DataType == GL_UNSIGNED_BYTE) {
         GLubyte index8[MAX_WIDTH];
         GLint i;
         rb->GetRow(ctx, rb, length, x + skip, y, index8);
         for (i = 0; i < length; i++)
            index[skip + i] = index8[i];
      }
      else if (rb->DataType == GL_UNSIGNED_SHORT) {
         GLushort index16[MAX_WIDTH];
         GLint i;
         rb->GetRow(ctx, rb, length, x + skip, y, index16);
         for (i = 0; i < length; i++)
            index[skip + i] = index16[i];
      }
      else if (rb->DataType == GL_UNSIGNED_INT) {
         rb->GetRow(ctx, rb, length, x + skip, y, index + skip);
      }
   }
}


/**
 * Wrapper for gl_renderbuffer::GetValues() which does clipping to avoid
 * reading values outside the buffer bounds.
 * We can use this for reading any format/type of renderbuffer.
 * \param valueSize is the size in bytes of each value put into the
 *                  values array.
 */
void
_swrast_get_values(GLcontext *ctx, struct gl_renderbuffer *rb,
                   GLuint count, const GLint x[], const GLint y[],
                   void *values, GLuint valueSize)
{
   GLuint i, inCount = 0, inStart = 0;

   for (i = 0; i < count; i++) {
      if (x[i] >= 0 && y[i] >= 0 && x[i] < rb->Width && y[i] < rb->Height) {
         /* inside */
         if (inCount == 0)
            inStart = i;
         inCount++;
      }
      else {
         if (inCount > 0) {
            /* read [inStart, inStart + inCount) */
            rb->GetValues(ctx, rb, inCount, x + inStart, y + inStart,
                          (GLubyte *) values + inStart * valueSize);
            inCount = 0;
         }
      }
   }
   if (inCount > 0) {
      /* read last values */
      rb->GetValues(ctx, rb, inCount, x + inStart, y + inStart,
                    (GLubyte *) values + inStart * valueSize);
   }
}

⌨️ 快捷键说明

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