clip depth/stencil spans to window bounds

This commit is contained in:
Brian Paul 2000-04-11 20:42:22 +00:00
parent 4fe34b27f6
commit d0130a989a
5 changed files with 178 additions and 56 deletions

View file

@ -1,4 +1,4 @@
/* $Id: depth.c,v 1.16 2000/04/04 00:54:23 brianp Exp $ */
/* $Id: depth.c,v 1.17 2000/04/11 20:42:22 brianp Exp $ */
/*
* Mesa 3-D graphics library
@ -1417,6 +1417,74 @@ _mesa_depth_test_pixels( GLcontext *ctx,
/**********************************************************************/
/*
* Read a span of depth values from the depth buffer.
* This function does clipping before calling the device driver function.
*/
void
_mesa_read_depth_span( GLcontext *ctx,
GLint n, GLint x, GLint y, GLdepth depth[] )
{
if (y < 0 || y >= ctx->DrawBuffer->Height ||
x + (GLint) n <= 0 || x >= ctx->DrawBuffer->Width) {
/* span is completely outside framebuffer */
GLint i;
for (i = 0; i < n; i++)
depth[i] = 0;
return;
}
if (x < 0) {
GLint dx = -x;
GLint i;
for (i = 0; i < dx; i++)
depth[i] = 0;
x = 0;
n -= dx;
depth += dx;
}
if (x + n > ctx->DrawBuffer->Width) {
GLint dx = x + n - ctx->DrawBuffer->Width;
GLint i;
for (i = 0; i < dx; i++)
depth[n - i - 1] = 0;
n -= dx;
}
if (n <= 0) {
return;
}
if (ctx->DrawBuffer->DepthBuffer) {
/* read from software depth buffer */
if (ctx->Visual->DepthBits <= 16) {
const GLushort *zptr = Z_ADDRESS16( ctx, x, y );
GLuint i;
for (i = 0; i < n; i++) {
depth[i] = zptr[i];
}
}
else {
const GLuint *zptr = Z_ADDRESS32( ctx, x, y );
GLuint i;
for (i = 0; i < n; i++) {
depth[i] = zptr[i];
}
}
}
else if (ctx->Driver.ReadDepthSpan) {
/* read from hardware depth buffer */
(*ctx->Driver.ReadDepthSpan)( ctx, n, x, y, depth );
}
else {
/* no depth buffer */
BZERO(depth, n * sizeof(GLfloat));
}
}
/*
* Return a span of depth values from the depth buffer as floats in [0,1].
* This is used for both hardware and software depth buffers.
@ -1425,11 +1493,39 @@ _mesa_depth_test_pixels( GLcontext *ctx,
* Output: depth - the array of depth values
*/
void
_mesa_read_depth_span_float( GLcontext* ctx,
GLuint n, GLint x, GLint y, GLfloat depth[] )
_mesa_read_depth_span_float( GLcontext *ctx,
GLint n, GLint x, GLint y, GLfloat depth[] )
{
const GLfloat scale = 1.0F / ctx->Visual->DepthMaxF;
if (y < 0 || y >= ctx->DrawBuffer->Height ||
x + (GLint) n <= 0 || x >= ctx->DrawBuffer->Width) {
/* span is completely outside framebuffer */
GLint i;
for (i = 0; i < n; i++)
depth[i] = 0.0F;
return;
}
if (x < 0) {
GLint dx = -x;
GLint i;
for (i = 0; i < dx; i++)
depth[i] = 0.0F;
n -= dx;
x = 0;
}
if (x + n > ctx->DrawBuffer->Width) {
GLint dx = x + n - ctx->DrawBuffer->Width;
GLint i;
for (i = 0; i < dx; i++)
depth[n - i - 1] = 0.0F;
n -= dx;
}
if (n <= 0) {
return;
}
if (ctx->DrawBuffer->DepthBuffer) {
/* read from software depth buffer */
if (ctx->Visual->DepthBits <= 16) {

View file

@ -1,4 +1,4 @@
/* $Id: depth.h,v 1.7 2000/03/03 17:47:39 brianp Exp $ */
/* $Id: depth.h,v 1.8 2000/04/11 20:42:22 brianp Exp $ */
/*
* Mesa 3-D graphics library
@ -68,7 +68,12 @@ _mesa_depth_test_pixels( GLcontext *ctx,
extern void
_mesa_read_depth_span_float( GLcontext *ctx, GLuint n, GLint x, GLint y,
_mesa_read_depth_span( GLcontext *ctx,
GLint n, GLint x, GLint y, GLdepth depth[] );
extern void
_mesa_read_depth_span_float( GLcontext *ctx, GLint n, GLint x, GLint y,
GLfloat depth[] );

View file

@ -1,4 +1,4 @@
/* $Id: drawpix.c,v 1.18 2000/04/08 18:57:45 brianp Exp $ */
/* $Id: drawpix.c,v 1.19 2000/04/11 20:42:22 brianp Exp $ */
/*
* Mesa 3-D graphics library
@ -479,7 +479,7 @@ draw_stencil_pixels( GLcontext *ctx, GLint x, GLint y,
values, desty );
}
else {
gl_write_stencil_span( ctx, (GLuint) drawWidth, x, y, values );
_mesa_write_stencil_span( ctx, (GLuint) drawWidth, x, y, values );
}
}
}

View file

@ -1,4 +1,4 @@
/* $Id: stencil.c,v 1.14 2000/02/02 22:16:04 brianp Exp $ */
/* $Id: stencil.c,v 1.15 2000/04/11 20:42:22 brianp Exp $ */
/*
* Mesa 3-D graphics library
@ -1130,24 +1130,44 @@ gl_stencil_and_depth_test_pixels( GLcontext *ctx,
* x,y - location of first pixel
* Output: stencil - the array of stencil values
*/
void gl_read_stencil_span( GLcontext *ctx,
GLint n, GLint x, GLint y, GLstencil stencil[] )
void
_mesa_read_stencil_span( GLcontext *ctx,
GLint n, GLint x, GLint y, GLstencil stencil[] )
{
if (y < 0 || y >= ctx->DrawBuffer->Height ||
x + n <= 0 || x >= ctx->DrawBuffer->Width) {
/* span is completely outside framebuffer */
return; /* undefined values OK */
}
if (x < 0) {
GLint dx = -x;
x = 0;
n -= dx;
stencil += dx;
}
if (x + n > ctx->DrawBuffer->Width) {
GLint dx = x + n - ctx->DrawBuffer->Width;
n -= dx;
}
if (n <= 0) {
return;
}
ASSERT(n >= 0);
if (ctx->DrawBuffer->Stencil) {
if (ctx->Driver.ReadStencilSpan) {
(*ctx->Driver.ReadStencilSpan)( ctx, (GLuint) n, x, y, stencil );
}
else {
const GLstencil *s = STENCIL_ADDRESS( x, y );
if (ctx->Driver.ReadStencilSpan) {
(*ctx->Driver.ReadStencilSpan)( ctx, (GLuint) n, x, y, stencil );
}
else if (ctx->DrawBuffer->Stencil) {
const GLstencil *s = STENCIL_ADDRESS( x, y );
#if STENCIL_BITS == 8
MEMCPY( stencil, s, n * sizeof(GLstencil) );
MEMCPY( stencil, s, n * sizeof(GLstencil) );
#else
GLuint i;
for (i=0;i<n;i++)
stencil[i] = s[i];
GLuint i;
for (i=0;i<n;i++)
stencil[i] = s[i];
#endif
}
}
}
@ -1160,41 +1180,42 @@ void gl_read_stencil_span( GLcontext *ctx,
* x, y - location of first pixel
* stencil - the array of stencil values
*/
void gl_write_stencil_span( GLcontext *ctx,
GLint n, GLint x, GLint y,
const GLstencil stencil[] )
void
_mesa_write_stencil_span( GLcontext *ctx, GLint n, GLint x, GLint y,
const GLstencil stencil[] )
{
ASSERT(n >= 0);
if (ctx->DrawBuffer->Stencil) {
/* do clipping */
if (y < ctx->DrawBuffer->Ymin || y > ctx->DrawBuffer->Ymax)
return;
if (x < ctx->DrawBuffer->Xmin) {
GLint diff = ctx->DrawBuffer->Xmin - x;
n -= diff;
stencil += diff;
x = ctx->DrawBuffer->Xmin;
}
if (x + n > ctx->DrawBuffer->Xmax) {
GLint diff = x + n - ctx->DrawBuffer->Xmax;
n -= diff;
}
if (y < 0 || y >= ctx->DrawBuffer->Height ||
x + n <= 0 || x >= ctx->DrawBuffer->Width) {
/* span is completely outside framebuffer */
return; /* undefined values OK */
}
ASSERT( n >= 0);
if (x < 0) {
GLint dx = -x;
x = 0;
n -= dx;
stencil += dx;
}
if (x + n > ctx->DrawBuffer->Width) {
GLint dx = x + n - ctx->DrawBuffer->Width;
n -= dx;
}
if (n <= 0) {
return;
}
if (ctx->Driver.WriteStencilSpan) {
(*ctx->Driver.WriteStencilSpan)( ctx, n, x, y, stencil, NULL );
}
else {
GLstencil *s = STENCIL_ADDRESS( x, y );
if (ctx->Driver.WriteStencilSpan) {
(*ctx->Driver.WriteStencilSpan)( ctx, n, x, y, stencil, NULL );
}
else if (ctx->DrawBuffer->Stencil) {
GLstencil *s = STENCIL_ADDRESS( x, y );
#if STENCIL_BITS == 8
MEMCPY( s, stencil, n * sizeof(GLstencil) );
MEMCPY( s, stencil, n * sizeof(GLstencil) );
#else
GLuint i;
for (i=0;i<n;i++)
s[i] = stencil[i];
GLuint i;
for (i=0;i<n;i++)
s[i] = stencil[i];
#endif
}
}
}

View file

@ -1,10 +1,10 @@
/* $Id: stencil.h,v 1.4 1999/12/13 04:08:27 joukj Exp $ */
/* $Id: stencil.h,v 1.5 2000/04/11 20:42:22 brianp Exp $ */
/*
* Mesa 3-D graphics library
* Version: 3.3
*
* Copyright (C) 1999 Brian Paul All Rights Reserved.
* Copyright (C) 1999-2000 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@ -64,13 +64,13 @@ gl_stencil_and_depth_test_pixels( GLcontext *ctx, GLuint n,
extern void
gl_read_stencil_span( GLcontext *ctx, GLint n, GLint x, GLint y,
GLstencil stencil[] );
_mesa_read_stencil_span( GLcontext *ctx, GLint n, GLint x, GLint y,
GLstencil stencil[] );
extern void
gl_write_stencil_span( GLcontext *ctx, GLint n, GLint x, GLint y,
const GLstencil stencil[] );
_mesa_write_stencil_span( GLcontext *ctx, GLint n, GLint x, GLint y,
const GLstencil stencil[] );
extern void gl_alloc_stencil_buffer( GLcontext *ctx );