/* * 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); }
/* * 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 {