summaryrefslogtreecommitdiffstats
path: root/src/mesa/main
diff options
context:
space:
mode:
authorBrian Paul <[email protected]>2000-04-11 20:42:22 +0000
committerBrian Paul <[email protected]>2000-04-11 20:42:22 +0000
commitd0130a989a3b331eb8114f1ee4addb95ce31e0e2 (patch)
tree5e04dc0ace3827b6ac5367da1b6d1b06c60a5249 /src/mesa/main
parent4fe34b27f641459acae8150cde927eb4952277ad (diff)
clip depth/stencil spans to window bounds
Diffstat (limited to 'src/mesa/main')
-rw-r--r--src/mesa/main/depth.c102
-rw-r--r--src/mesa/main/depth.h9
-rw-r--r--src/mesa/main/drawpix.c4
-rw-r--r--src/mesa/main/stencil.c107
-rw-r--r--src/mesa/main/stencil.h12
5 files changed, 178 insertions, 56 deletions
diff --git a/src/mesa/main/depth.c b/src/mesa/main/depth.c
index 88a0a1a69db..8a09206a6a9 100644
--- a/src/mesa/main/depth.c
+++ b/src/mesa/main/depth.c
@@ -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
@@ -1418,6 +1418,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.
* Input: n - how many pixels
@@ -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) {
diff --git a/src/mesa/main/depth.h b/src/mesa/main/depth.h
index ec16ecf37d4..ef176005d4e 100644
--- a/src/mesa/main/depth.h
+++ b/src/mesa/main/depth.h
@@ -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[] );
diff --git a/src/mesa/main/drawpix.c b/src/mesa/main/drawpix.c
index ad9ce929f10..184248c2706 100644
--- a/src/mesa/main/drawpix.c
+++ b/src/mesa/main/drawpix.c
@@ -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 );
}
}
}
diff --git a/src/mesa/main/stencil.c b/src/mesa/main/stencil.c
index 79c66d3fb2f..ecd610df2e9 100644
--- a/src/mesa/main/stencil.c
+++ b/src/mesa/main/stencil.c
@@ -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
- }
}
}
diff --git a/src/mesa/main/stencil.h b/src/mesa/main/stencil.h
index 860a4774e9e..b27be16e274 100644
--- a/src/mesa/main/stencil.h
+++ b/src/mesa/main/stencil.h
@@ -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 );