Ejemplo n.º 1
0
/*
 * TODO: Optimize!!!!
 */
static void
copy_depth_pixels( GLcontext *ctx, GLint srcx, GLint srcy,
                   GLint width, GLint height,
                   GLint destx, GLint desty )
{
   SWcontext *swrast = SWRAST_CONTEXT(ctx);
   struct gl_framebuffer *fb = ctx->ReadBuffer;
   struct gl_renderbuffer *readRb = fb->_DepthBuffer;
   const GLfloat depthMax = fb->_DepthMaxF;
   GLfloat *p, *tmpImage;
   GLint sy, dy, stepy;
   GLint i, j;
   const GLboolean zoom = ctx->Pixel.ZoomX != 1.0F || ctx->Pixel.ZoomY != 1.0F;
   GLint overlapping;
   struct sw_span span;

   if (!readRb) {
      /* no readbuffer - OK */
      return;
   }

   INIT_SPAN(span, GL_BITMAP, 0, 0, SPAN_Z);

   /* Determine if copy should be bottom-to-top or top-to-bottom */
   if (srcy<desty) {
      /* top-down  max-to-min */
      sy = srcy + height - 1;
      dy = desty + height - 1;
      stepy = -1;
   }
   else {
      /* bottom-up  min-to-max */
      sy = srcy;
      dy = desty;
      stepy = 1;
   }

   if (ctx->DrawBuffer == ctx->ReadBuffer) {
      overlapping = regions_overlap(srcx, srcy, destx, desty, width, height,
                                    ctx->Pixel.ZoomX, ctx->Pixel.ZoomY);
   }
   else {
      overlapping = GL_FALSE;
   }

   _swrast_span_default_color(ctx, &span);
   if (swrast->_FogEnabled)
      _swrast_span_default_fog(ctx, &span);

   if (overlapping) {
      GLint ssy = sy;
      tmpImage = (GLfloat *) _mesa_malloc(width * height * sizeof(GLfloat));
      if (!tmpImage) {
         _mesa_error( ctx, GL_OUT_OF_MEMORY, "glCopyPixels" );
         return;
      }
      p = tmpImage;
      for (j = 0; j < height; j++, ssy += stepy) {
         _swrast_read_depth_span_float(ctx, readRb, width, srcx, ssy, p);
         p += width;
      }
      p = tmpImage;
   }
   else {
      tmpImage = NULL;  /* silence compiler warning */
      p = NULL;
   }

   for (j = 0; j < height; j++, sy += stepy, dy += stepy) {
      GLfloat depth[MAX_WIDTH];
      /* get depth values */
      if (overlapping) {
         _mesa_memcpy(depth, p, width * sizeof(GLfloat));
         p += width;
      }
      else {
         _swrast_read_depth_span_float(ctx, readRb, width, srcx, sy, depth);
      }

      /* apply scale and bias */
      for (i = 0; i < width; i++) {
         GLfloat d = depth[i] * ctx->Pixel.DepthScale + ctx->Pixel.DepthBias;
         span.array->z[i] = (GLuint) (CLAMP(d, 0.0F, 1.0F) * depthMax);
      }

      /* write depth values */
      span.x = destx;
      span.y = dy;
      span.end = width;
      if (fb->Visual.rgbMode) {
         if (zoom)
            _swrast_write_zoomed_rgba_span(ctx, destx, desty, &span, 
                                       (const GLchan (*)[4]) span.array->rgba);
         else
            _swrast_write_rgba_span(ctx, &span);
      }
      else {
         if (zoom)
            _swrast_write_zoomed_index_span(ctx, destx, desty, &span);
         else
            _swrast_write_index_span(ctx, &span);
      }
   }

   if (overlapping)
      _mesa_free(tmpImage);
}
Ejemplo n.º 2
0
/*
 * Draw depth image.
 */
static void
draw_depth_pixels( GLcontext *ctx, GLint x, GLint y,
                   GLsizei width, GLsizei height,
                   GLenum type,
                   const struct gl_pixelstore_attrib *unpack,
                   const GLvoid *pixels )
{
   const GLboolean bias_or_scale = ctx->Pixel.DepthBias!=0.0 || ctx->Pixel.DepthScale!=1.0;
   const GLboolean zoom = ctx->Pixel.ZoomX != 1.0 || ctx->Pixel.ZoomY != 1.0;
   const GLint desty = y;
   struct sw_span span;

   INIT_SPAN(span, GL_BITMAP, 0, 0, SPAN_Z);

   if (type != GL_BYTE
       && type != GL_UNSIGNED_BYTE
       && type != GL_SHORT
       && type != GL_UNSIGNED_SHORT
       && type != GL_INT
       && type != GL_UNSIGNED_INT
       && type != GL_FLOAT) {
      _mesa_error(ctx, GL_INVALID_ENUM, "glDrawPixels(type)");
      return;
   }

   _swrast_span_default_color(ctx, &span);

   if (ctx->Fog.Enabled)
      _swrast_span_default_fog(ctx, &span);
   if (ctx->Texture._EnabledCoordUnits)
      _swrast_span_default_texcoords(ctx, &span);

   if (type == GL_UNSIGNED_SHORT
       && ctx->Visual.depthBits == 16
       && !bias_or_scale
       && !zoom
       && ctx->Visual.rgbMode
       && width <= MAX_WIDTH) {
      /* Special case: directly write 16-bit depth values */
      GLint row, spanY = y;
      for (row = 0; row < height; row++, spanY++) {
         const GLushort *zSrc = (const GLushort *)
            _mesa_image_address2d(unpack, pixels, width, height,
                                  GL_DEPTH_COMPONENT, type, row, 0);
         GLint i;
         for (i = 0; i < width; i++)
            span.array->z[i] = zSrc[i];
         span.x = x;
         span.y = spanY;
         span.end = width;
         _swrast_write_rgba_span(ctx, &span);
      }
   }
   else if (type == GL_UNSIGNED_INT
            && sizeof(GLdepth) == 4
            && !bias_or_scale
            && !zoom
            && ctx->Visual.rgbMode
            && width <= MAX_WIDTH) {
      /* Special case: shift 32-bit values down to ctx->Visual.depthBits */
      const GLint shift = 32 - ctx->Visual.depthBits;
      GLint row, spanY = y;
      for (row = 0; row < height; row++, spanY++) {
         const GLuint *zSrc = (const GLuint *)
            _mesa_image_address2d(unpack, pixels, width, height,
                                  GL_DEPTH_COMPONENT, type, row, 0);
         if (shift == 0) {
            MEMCPY(span.array->z, zSrc, width * sizeof(GLdepth));
         }
         else {
            GLint col;
            for (col = 0; col < width; col++)
               span.array->z[col] = zSrc[col] >> shift;
         }
         span.x = x;
         span.y = spanY;
         span.end = width;
         _swrast_write_rgba_span(ctx, &span);
      }
   }
   else {