From c26d81842a9e074d059a802033d3311ac628aa8e Mon Sep 17 00:00:00 2001 From: Randy Frank Date: Sat, 15 Jan 2000 06:13:26 +0000 Subject: [PATCH] Added occlusion test code. Follows the HP proposed occlusion test extension. --- src/mesa/drivers/osmesa/osmesa.c | 221 ++++++++++++++++++++++++++++++- 1 file changed, 219 insertions(+), 2 deletions(-) diff --git a/src/mesa/drivers/osmesa/osmesa.c b/src/mesa/drivers/osmesa/osmesa.c index 27203be4ebc..a5a71bfc2dc 100644 --- a/src/mesa/drivers/osmesa/osmesa.c +++ b/src/mesa/drivers/osmesa/osmesa.c @@ -1,4 +1,4 @@ -/* $Id: osmesa.c,v 1.8 2000/01/14 04:55:44 brianp Exp $ */ +/* $Id: osmesa.c,v 1.9 2000/01/15 06:13:26 rjfrank Exp $ */ /* * Mesa 3-D graphics library @@ -74,6 +74,7 @@ struct osmesa_context { void *rowaddr[MAX_HEIGHT]; /* address of first pixel in each image row */ GLboolean yup; /* TRUE -> Y increases upward */ /* FALSE -> Y increases downward */ + GLboolean bVisible; /* TRUE if geometry is visible */ }; @@ -253,6 +254,7 @@ OSMesaCreateContext( GLenum format, OSMesaContext sharelist ) osmesa->rind = rind; osmesa->gind = gind; osmesa->bind = bind; + osmesa->bVisible = GL_FALSE; } return osmesa; } @@ -465,7 +467,20 @@ void GLAPIENTRY OSMesaGetIntegerv( GLint pname, GLint *value ) } } +void GLAPIENTRY OSMesaGetBooleanv( GLint pname, GLboolean *value ) +{ + OSMesaContext ctx = OSMesaGetCurrentContext(); + switch (pname) { + case OSMESA_OCCLUSION_TEST_RESULT_HP: + *value = ctx->bVisible; + ctx->bVisible = GL_FALSE; + return; + default: + gl_error(&ctx->gl_ctx, GL_INVALID_ENUM, "OSMesaGetBooleanv(pname)" ); + return; + } +} /* * Return the depth buffer associated with an OSMesa context. @@ -697,6 +712,7 @@ static void write_rgba_span( const GLcontext *ctx, GLint gshift = osmesa->gshift; GLint bshift = osmesa->bshift; GLint ashift = osmesa->ashift; + osmesa->bVisible = GL_TRUE; /* if here, the occlusion test is misused */ if (mask) { for (i=0;ibVisible = GL_TRUE; /* if here, the occlusion test is misused */ if (mask) { for (i=0;igshift; GLint bshift = osmesa->bshift; GLint ashift = osmesa->ashift; + osmesa->bVisible = GL_TRUE; /* if here, the occlusion test is misused */ if (mask) { for (i=0;ibVisible = GL_TRUE; /* if here, the occlusion test is misused */ for (i=0;ipixel; @@ -789,6 +808,7 @@ static void write_rgba_pixels( const GLcontext *ctx, GLint gshift = osmesa->gshift; GLint bshift = osmesa->bshift; GLint ashift = osmesa->ashift; + osmesa->bVisible = GL_TRUE; /* if here, the occlusion test is misused */ for (i=0;ibVisible = GL_TRUE; /* if here, the occlusion test is misused */ for (i=0;irind; GLint gind = osmesa->gind; GLint bind = osmesa->bind; + osmesa->bVisible = GL_TRUE; /* if here, the occlusion test is misused */ if (mask) { for (i=0;irind; GLint gind = osmesa->gind; GLint bind = osmesa->bind; + osmesa->bVisible = GL_TRUE; /* if here, the occlusion test is misused */ if (mask) { for (i=0;ibVisible = GL_TRUE; /* if here, the occlusion test is misused */ for (i=0;irind; GLint gind = osmesa->gind; GLint bind = osmesa->bind; - + osmesa->bVisible = GL_TRUE; /* if here, the occlusion test is misused */ for (i=0;ipixel); GLubyte gval = UNPACK_GREEN(osmesa->pixel); GLubyte bval = UNPACK_BLUE(osmesa->pixel); + osmesa->bVisible = GL_TRUE; /* if here, the occlusion test is misused */ for (i=0;ibVisible = GL_TRUE; /* if here, the occlusion test is misused */ if (mask) { for (i=0;ibVisible = GL_TRUE; /* if here, the occlusion test is misused */ if (mask) { for (i=0;ibVisible = GL_TRUE; /* if here, the occlusion test is misused */ for (i=0;ipixel; @@ -1097,6 +1125,7 @@ static void write_index_pixels( const GLcontext *ctx, { OSMesaContext osmesa = (OSMesaContext) ctx; GLuint i; + osmesa->bVisible = GL_TRUE; /* if here, the occlusion test is misused */ for (i=0;ibVisible = GL_TRUE; /* if here, the occlusion test is misused */ for (i=0;iVB->ColorPtr->data[pvert]; unsigned long pixel = PACK_RGBA( color[0], color[1], color[2], color[3] ); + osmesa->bVisible = GL_TRUE; /* if here, the occlusion test is misused */ #define INTERP_XY 1 #define CLIP_HACK 1 @@ -1185,6 +1216,7 @@ static void flat_rgba_z_line( GLcontext *ctx, OSMesaContext osmesa = (OSMesaContext) ctx; GLubyte *color = ctx->VB->ColorPtr->data[pvert]; unsigned long pixel = PACK_RGBA( color[0], color[1], color[2], color[3] ); + osmesa->bVisible = GL_TRUE; /* if here, the occlusion test is misused */ #define INTERP_XY 1 #define INTERP_Z 1 @@ -1220,6 +1252,7 @@ static void flat_blend_rgba_line( GLcontext *ctx, GLint rvalue = VB->ColorPtr->data[pvert][0]*avalue; GLint gvalue = VB->ColorPtr->data[pvert][1]*avalue; GLint bvalue = VB->ColorPtr->data[pvert][2]*avalue; + osmesa->bVisible = GL_TRUE; /* if here, the occlusion test is misused */ #define INTERP_XY 1 #define CLIP_HACK 1 @@ -1255,6 +1288,7 @@ static void flat_blend_rgba_z_line( GLcontext *ctx, GLint rvalue = VB->ColorPtr->data[pvert][0]*avalue; GLint gvalue = VB->ColorPtr->data[pvert][1]*avalue; GLint bvalue = VB->ColorPtr->data[pvert][2]*avalue; + osmesa->bVisible = GL_TRUE; /* if here, the occlusion test is misused */ #define INTERP_XY 1 #define INTERP_Z 1 @@ -1293,6 +1327,7 @@ static void flat_blend_rgba_z_line_write( GLcontext *ctx, GLint rvalue = VB->ColorPtr->data[pvert][0]*avalue; GLint gvalue = VB->ColorPtr->data[pvert][1]*avalue; GLint bvalue = VB->ColorPtr->data[pvert][2]*avalue; + osmesa->bVisible = GL_TRUE; /* if here, the occlusion test is misused */ #define INTERP_XY 1 #define INTERP_Z 1 @@ -1430,6 +1465,7 @@ static void smooth_rgba_z_triangle( GLcontext *ctx, GLuint v0, GLuint v1, GLint bshift = osmesa->bshift; GLint ashift = osmesa->ashift; (void) pv; + osmesa->bVisible = GL_TRUE; /* if here, the occlusion test is misused */ #define INTERP_Z 1 #define INTERP_RGB 1 #define INTERP_ALPHA 1 @@ -1522,7 +1558,150 @@ static triangle_func choose_triangle_function( GLcontext *ctx ) return NULL; } +/**********************************************************************/ +/***** Occlusion rendering routines *****/ +/**********************************************************************/ + +#define OCC_STD_MASK_TEST \ + OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx; \ + if (osmesa->bVisible) return; \ + if (mask) { \ + GLuint i; \ + for (i=0;ibVisible = GL_TRUE; \ + return; \ + } \ + } else { \ + osmesa->bVisible = GL_TRUE; \ + } \ + return; +/***** Color Index *****/ +static void write_index32_span_occ( const GLcontext *ctx, + GLuint n, GLint x, GLint y, + const GLuint index[], const GLubyte mask[] ) +{ + OCC_STD_MASK_TEST +} +static void write_index8_span_occ( const GLcontext *ctx, + GLuint n, GLint x, GLint y, + const GLubyte index[], const GLubyte mask[] ) +{ + OCC_STD_MASK_TEST +} +static void write_monoindex_span_occ( const GLcontext *ctx, + GLuint n, GLint x, GLint y, + const GLubyte mask[] ) +{ + OCC_STD_MASK_TEST +} +static void write_index_pixels_occ( const GLcontext *ctx, + GLuint n, const GLint x[], const GLint y[], + const GLuint index[], const GLubyte mask[] ) +{ + OCC_STD_MASK_TEST +} +static void write_monoindex_pixels_occ( const GLcontext *ctx, + GLuint n, const GLint x[], const GLint y[], + const GLubyte mask[] ) +{ + OCC_STD_MASK_TEST +} + +/***** RGB/RGBA *****/ +static void write_rgba_span_occ( const GLcontext *ctx, + GLuint n, GLint x, GLint y, + CONST GLubyte rgba[][4], const GLubyte mask[] ) +{ + OCC_STD_MASK_TEST +} +static void write_rgb_span_occ( const GLcontext *ctx, + GLuint n, GLint x, GLint y, + CONST GLubyte rgb[][3], + const GLubyte mask[] ) +{ + OCC_STD_MASK_TEST +} +static void write_rgba_pixels_occ( const GLcontext *ctx, + GLuint n, const GLint x[], const GLint y[], + CONST GLubyte rgba[][4], const GLubyte mask[] ) +{ + OCC_STD_MASK_TEST +} +static void write_monocolor_span_occ( const GLcontext *ctx, + GLuint n, GLint x, GLint y, + const GLubyte mask[] ) +{ + OCC_STD_MASK_TEST +} +static void write_monocolor_pixels_occ( const GLcontext *ctx, + GLuint n, const GLint x[], const GLint y[], + const GLubyte mask[] ) +{ + OCC_STD_MASK_TEST +} + +/***** Line Drawing *****/ +static void line_occ( GLcontext *ctx, + GLuint vert0, GLuint vert1, GLuint pvert ) +{ + OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx; + osmesa->bVisible = GL_TRUE; +} + +static void line_z_occ( GLcontext *ctx, + GLuint vert0, GLuint vert1, GLuint pvert ) +{ + OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx; + if (osmesa->bVisible) return; + +#define INTERP_XY 1 +#define INTERP_Z 1 +#define CLIP_HACK 1 +#define PLOT(X,Y) \ + if (Z < *zPtr) { \ + osmesa->bVisible = GL_TRUE; \ + return; \ + } + +#ifdef WIN32 +#include "..\linetemp.h" +#else +#include "linetemp.h" +#endif +} + +/***** Triangle Drawing *****/ +static void triangle_occ( GLcontext *ctx, GLuint v0, GLuint v1, + GLuint v2, GLuint pv ) +{ + OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx; + osmesa->bVisible = GL_TRUE; +} +static void triangle_z_occ( GLcontext *ctx, GLuint v0, GLuint v1, + GLuint v2, GLuint pv ) +{ + OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx; + if (osmesa->bVisible) return; +#define INTERP_Z 1 +#define INNER_LOOP( LEFT, RIGHT, Y ) \ +{ \ + GLint i, len = RIGHT-LEFT; \ + for (i=0;ibVisible = GL_TRUE; \ + return; \ + } \ + ffz += fdzdx; \ + } \ +} +#ifdef WIN32 +#include "..\tritemp.h" +#else +#include "tritemp.h" +#endif +} static const GLubyte *get_string( GLcontext *ctx, GLenum name ) { @@ -1598,4 +1777,42 @@ static void osmesa_update_state( GLcontext *ctx ) ctx->Driver.WriteMonoCIPixels = write_monoindex_pixels; ctx->Driver.ReadCI32Span = read_index_span; ctx->Driver.ReadCI32Pixels = read_index_pixels; + + /* Occlusion test cases: + * If no buffers have been selected for writing, + * we swap in occlusion routines that: + * (1) check the current flag and return if set + * (2) set the flag if any pixel would be updated + * Note: all the other buffer writing routines will + * always set the visible flag so in cases of "improper" + * extension use will just cause unnecessary rasterization + * to occur. The image will be correct in any case. + */ + if ((ctx->Color.IndexMask == 0) && + (ctx->Color.ColorMask[0] == 0) && + (ctx->Color.ColorMask[1] == 0) && + (ctx->Color.ColorMask[2] == 0) && + (ctx->Color.ColorMask[3] == 0) && + (ctx->Stencil.Enabled == GL_FALSE)) { + + ctx->Driver.WriteCI32Span = write_index32_span_occ; + ctx->Driver.WriteCI8Span = write_index8_span_occ; + ctx->Driver.WriteMonoCISpan = write_monoindex_span_occ; + ctx->Driver.WriteCI32Pixels = write_index_pixels_occ; + ctx->Driver.WriteMonoCIPixels = write_monoindex_pixels_occ; + + ctx->Driver.WriteRGBASpan = write_rgba_span_occ; + ctx->Driver.WriteRGBSpan = write_rgb_span_occ; + ctx->Driver.WriteRGBAPixels = write_rgba_pixels_occ; + ctx->Driver.WriteMonoRGBASpan = write_monocolor_span_occ; + ctx->Driver.WriteMonoRGBAPixels = write_monocolor_pixels_occ; + + if (ctx->RasterMask & DEPTH_BIT) { + ctx->Driver.LineFunc = line_z_occ; + ctx->Driver.TriangleFunc = triangle_z_occ; + } else { + ctx->Driver.LineFunc = line_occ; + ctx->Driver.TriangleFunc = triangle_occ; + } + } } -- 2.30.2