| @@ -117,3 +117,45 @@ _mesa_GetClipPlane( GLenum plane, GLdouble *equation ) | |||
| equation[3] = (GLdouble) ctx->Transform.EyeUserPlane[p][3]; | |||
| } | |||
| void GLAPIENTRY | |||
| _mesa_CullParameterfvEXT (GLenum cap, GLfloat *v) | |||
| { | |||
| GET_CURRENT_CONTEXT(ctx); | |||
| ASSERT_OUTSIDE_BEGIN_END(ctx); | |||
| switch (cap) { | |||
| case GL_CULL_VERTEX_EYE_POSITION_EXT: | |||
| FLUSH_VERTICES(ctx, _NEW_TRANSFORM); | |||
| COPY_4FV(ctx->Transform.CullEyePos, v); | |||
| _mesa_transform_vector( ctx->Transform.CullObjPos, | |||
| ctx->Transform.CullEyePos, | |||
| ctx->ModelviewMatrixStack.Top->inv ); | |||
| break; | |||
| case GL_CULL_VERTEX_OBJECT_POSITION_EXT: | |||
| FLUSH_VERTICES(ctx, _NEW_TRANSFORM); | |||
| COPY_4FV(ctx->Transform.CullObjPos, v); | |||
| _mesa_transform_vector( ctx->Transform.CullEyePos, | |||
| ctx->Transform.CullObjPos, | |||
| ctx->ModelviewMatrixStack.Top->m ); | |||
| break; | |||
| default: | |||
| _mesa_error( ctx, GL_INVALID_ENUM, "glCullParameterfvEXT" ); | |||
| } | |||
| } | |||
| void GLAPIENTRY | |||
| _mesa_CullParameterdvEXT (GLenum cap, GLdouble *v) | |||
| { | |||
| GLfloat f[4]; | |||
| f[0] = (GLfloat)v[0]; | |||
| f[1] = (GLfloat)v[1]; | |||
| f[2] = (GLfloat)v[2]; | |||
| f[3] = (GLfloat)v[3]; | |||
| _mesa_CullParameterfvEXT(cap, f); | |||
| } | |||
| @@ -39,4 +39,11 @@ _mesa_ClipPlane( GLenum plane, const GLdouble *equation ); | |||
| extern void GLAPIENTRY | |||
| _mesa_GetClipPlane( GLenum plane, GLdouble *equation ); | |||
| extern void GLAPIENTRY | |||
| _mesa_CullParameterfvEXT (GLenum cap, GLfloat *v); | |||
| extern void GLAPIENTRY | |||
| _mesa_CullParameterdvEXT (GLenum cap, GLdouble *v); | |||
| #endif | |||
| @@ -290,6 +290,15 @@ void _mesa_set_enable( GLcontext *ctx, GLenum cap, GLboolean state ) | |||
| FLUSH_VERTICES(ctx, _NEW_POLYGON); | |||
| ctx->Polygon.CullFlag = state; | |||
| break; | |||
| case GL_CULL_VERTEX_EXT: | |||
| CHECK_EXTENSION(EXT_cull_vertex, cap); | |||
| if (ctx->Transform.CullVertexFlag == state) | |||
| return; | |||
| FLUSH_VERTICES(ctx, _NEW_TRANSFORM); | |||
| ctx->Transform.CullVertexFlag = state; | |||
| break; | |||
| case GL_DEPTH_TEST: | |||
| if (state && ctx->Visual.depthBits==0) { | |||
| _mesa_warning(ctx,"glEnable(GL_DEPTH_TEST) but no depth buffer"); | |||
| @@ -75,6 +75,7 @@ static const struct { | |||
| { OFF, "GL_EXT_blend_minmax", F(EXT_blend_minmax) }, | |||
| { OFF, "GL_EXT_blend_subtract", F(EXT_blend_subtract) }, | |||
| { ON, "GL_EXT_clip_volume_hint", F(EXT_clip_volume_hint) }, | |||
| { OFF, "GL_EXT_cull_vertex", F(EXT_cull_vertex) }, | |||
| { ON, "GL_EXT_compiled_vertex_array", F(EXT_compiled_vertex_array) }, | |||
| { OFF, "GL_EXT_convolution", F(EXT_convolution) }, | |||
| { ON, "GL_EXT_copy_texture", F(EXT_copy_texture) }, | |||
| @@ -745,8 +745,16 @@ calculate_model_project_matrix( GLcontext *ctx ) | |||
| */ | |||
| void _mesa_update_modelview_project( GLcontext *ctx, GLuint new_state ) | |||
| { | |||
| if (new_state & _NEW_MODELVIEW) | |||
| if (new_state & _NEW_MODELVIEW) { | |||
| _math_matrix_analyse( ctx->ModelviewMatrixStack.Top ); | |||
| /* Bring cull position uptodate. | |||
| */ | |||
| TRANSFORM_POINT3( ctx->Transform.CullObjPos, | |||
| ctx->ModelviewMatrixStack.Top->inv, | |||
| ctx->Transform.CullEyePos ); | |||
| } | |||
| if (new_state & _NEW_PROJECTION) | |||
| update_projection( ctx ); | |||
| @@ -898,6 +906,9 @@ void _mesa_init_transform( GLcontext *ctx ) | |||
| ASSIGN_4V( ctx->Transform.EyeUserPlane[i], 0.0, 0.0, 0.0, 0.0 ); | |||
| } | |||
| ctx->Transform.ClipPlanesEnabled = 0; | |||
| ASSIGN_4V( ctx->Transform.CullObjPos, 0.0, 0.0, 1.0, 0.0 ); | |||
| ASSIGN_4V( ctx->Transform.CullEyePos, 0.0, 0.0, 1.0, 0.0 ); | |||
| } | |||
| @@ -1323,6 +1323,10 @@ struct gl_transform_attrib { | |||
| GLboolean Normalize; /**< Normalize all normals? */ | |||
| GLboolean RescaleNormals; /**< GL_EXT_rescale_normal */ | |||
| GLboolean RasterPositionUnclipped; /**< GL_IBM_rasterpos_clip */ | |||
| GLboolean CullVertexFlag; /**< True if GL_CULL_VERTEX_EXT is enabled */ | |||
| GLfloat CullEyePos[4]; | |||
| GLfloat CullObjPos[4]; | |||
| }; | |||
| @@ -1885,6 +1889,7 @@ struct gl_extensions | |||
| GLboolean EXT_blend_minmax; | |||
| GLboolean EXT_blend_subtract; | |||
| GLboolean EXT_clip_volume_hint; | |||
| GLboolean EXT_cull_vertex; | |||
| GLboolean EXT_convolution; | |||
| GLboolean EXT_compiled_vertex_array; | |||
| GLboolean EXT_copy_texture; | |||
| @@ -211,6 +211,8 @@ _mesa_init_exec_table(struct _glapi_table *exec, GLuint tableSize) | |||
| exec->ClipPlane = _mesa_ClipPlane; | |||
| exec->ColorMaterial = _mesa_ColorMaterial; | |||
| exec->CopyPixels = _mesa_CopyPixels; | |||
| exec->CullParameterfvEXT = _mesa_CullParameterfvEXT; | |||
| exec->CullParameterdvEXT = _mesa_CullParameterdvEXT; | |||
| exec->DeleteLists = _mesa_DeleteLists; | |||
| exec->DepthFunc = _mesa_DepthFunc; | |||
| exec->DepthMask = _mesa_DepthMask; | |||
| @@ -98,6 +98,7 @@ _math_init_transformation(void); | |||
| #define CLIP_NEAR_BIT 0x10 | |||
| #define CLIP_FAR_BIT 0x20 | |||
| #define CLIP_USER_BIT 0x40 | |||
| #define CLIP_CULL_BIT 0x80 | |||
| #define CLIP_ALL_BITS 0x3f | |||
| @@ -432,6 +432,7 @@ struct vertex_buffer | |||
| GLvector4f *ClipPtr; /* _TNL_BIT_POS */ | |||
| GLvector4f *NdcPtr; /* _TNL_BIT_POS */ | |||
| GLubyte ClipOrMask; /* _TNL_BIT_POS */ | |||
| GLubyte ClipAndMask; /* _TNL_BIT_POS */ | |||
| GLubyte *ClipMask; /* _TNL_BIT_POS */ | |||
| GLvector4f *NormalPtr; /* _TNL_BIT_NORMAL */ | |||
| GLfloat *NormalLengthPtr; /* _TNL_BIT_NORMAL */ | |||
| @@ -47,6 +47,7 @@ extern void _tnl_install_pipeline( GLcontext *ctx, | |||
| /* These are implemented in the t_vb_*.c files: | |||
| */ | |||
| extern const struct tnl_pipeline_stage _tnl_vertex_transform_stage; | |||
| extern const struct tnl_pipeline_stage _tnl_vertex_cull_stage; | |||
| extern const struct tnl_pipeline_stage _tnl_normal_transform_stage; | |||
| extern const struct tnl_pipeline_stage _tnl_lighting_stage; | |||
| extern const struct tnl_pipeline_stage _tnl_fog_coordinate_stage; | |||
| @@ -0,0 +1,111 @@ | |||
| /* | |||
| * Mesa 3-D graphics library | |||
| * Version: 6.1 | |||
| * | |||
| * Copyright (C) 1999-2004 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"), | |||
| * to deal in the Software without restriction, including without limitation | |||
| * the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
| * and/or sell copies of the Software, and to permit persons to whom the | |||
| * Software is furnished to do so, subject to the following conditions: | |||
| * | |||
| * The above copyright notice and this permission notice shall be included | |||
| * in all copies or substantial portions of the Software. | |||
| * | |||
| * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | |||
| * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
| * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |||
| * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN | |||
| * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | |||
| * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |||
| * | |||
| * Authors: | |||
| * Keith Whitwell <keith@tungstengraphics.com> | |||
| */ | |||
| #include "glheader.h" | |||
| #include "colormac.h" | |||
| #include "context.h" | |||
| #include "macros.h" | |||
| #include "imports.h" | |||
| #include "mtypes.h" | |||
| #include "math/m_xform.h" | |||
| #include "t_context.h" | |||
| #include "t_pipeline.h" | |||
| /* EXT_vertex_cull. Not really a big win, but probably depends on | |||
| * your application. This stage not included in the default pipeline. | |||
| */ | |||
| static GLboolean run_cull_stage( GLcontext *ctx, | |||
| struct tnl_pipeline_stage *stage ) | |||
| { | |||
| TNLcontext *tnl = TNL_CONTEXT(ctx); | |||
| struct vertex_buffer *VB = &tnl->vb; | |||
| const GLfloat a = ctx->Transform.CullObjPos[0]; | |||
| const GLfloat b = ctx->Transform.CullObjPos[1]; | |||
| const GLfloat c = ctx->Transform.CullObjPos[2]; | |||
| GLfloat *norm = (GLfloat *)VB->NormalPtr->data; | |||
| GLuint stride = VB->NormalPtr->stride; | |||
| GLuint count = VB->Count; | |||
| GLuint i; | |||
| VB->ClipOrMask &= ~CLIP_CULL_BIT; | |||
| VB->ClipAndMask |= CLIP_CULL_BIT; | |||
| for (i = 0 ; i < count ; i++) { | |||
| GLfloat dp = (norm[0] * a + | |||
| norm[1] * b + | |||
| norm[2] * c); | |||
| if (dp < 0) { | |||
| VB->ClipMask[i] |= CLIP_CULL_BIT; | |||
| VB->ClipOrMask |= CLIP_CULL_BIT; | |||
| } | |||
| else { | |||
| VB->ClipMask[i] &= ~CLIP_CULL_BIT; | |||
| VB->ClipAndMask &= ~CLIP_CULL_BIT; | |||
| } | |||
| STRIDE_F(norm, stride); | |||
| } | |||
| return !(VB->ClipAndMask & CLIP_CULL_BIT); | |||
| } | |||
| static void check_cull( GLcontext *ctx, struct tnl_pipeline_stage *stage ) | |||
| { | |||
| stage->active = (!ctx->VertexProgram._Enabled && | |||
| ctx->Transform.CullVertexFlag); | |||
| } | |||
| static void dtr( struct tnl_pipeline_stage *stage ) | |||
| { | |||
| } | |||
| const struct tnl_pipeline_stage _tnl_vertex_cull_stage = | |||
| { | |||
| "EXT_cull_vertex", | |||
| _NEW_PROGRAM | | |||
| _NEW_TRANSFORM, | |||
| _NEW_TRANSFORM, | |||
| GL_TRUE, /* active */ | |||
| _TNL_BIT_NORMAL | | |||
| _TNL_BIT_POS, /* inputs */ | |||
| _TNL_BIT_POS, /* outputs */ | |||
| 0, /* changed_inputs */ | |||
| NULL, /* private data */ | |||
| dtr, /* destructor */ | |||
| check_cull, /* check */ | |||
| run_cull_stage /* run -- initially set to init */ | |||
| }; | |||
| @@ -77,6 +77,9 @@ | |||
| #define EDGEFLAG_SET(idx, val) VB->EdgeFlag[idx] = val | |||
| #define CLIPMASK (CLIP_ALL_BITS|CLIP_CULL_BIT) | |||
| /* Vertices, with the possibility of clipping. | |||
| */ | |||
| #define RENDER_POINTS( start, count ) \ | |||
| @@ -88,7 +91,7 @@ do { \ | |||
| GLubyte ormask = c1|c2; \ | |||
| if (!ormask) \ | |||
| LineFunc( ctx, v1, v2 ); \ | |||
| else if (!(c1 & c2 & 0x3f)) \ | |||
| else if (!(c1 & c2 & CLIPMASK)) \ | |||
| clip_line_4( ctx, v1, v2, ormask ); \ | |||
| } while (0) | |||
| @@ -98,7 +101,7 @@ do { \ | |||
| GLubyte ormask = c1|c2|c3; \ | |||
| if (!ormask) \ | |||
| TriangleFunc( ctx, v1, v2, v3 ); \ | |||
| else if (!(c1 & c2 & c3 & 0x3f)) \ | |||
| else if (!(c1 & c2 & c3 & CLIPMASK)) \ | |||
| clip_tri_4( ctx, v1, v2, v3, ormask ); \ | |||
| } while (0) | |||
| @@ -109,7 +112,7 @@ do { \ | |||
| GLubyte ormask = c1|c2|c3|c4; \ | |||
| if (!ormask) \ | |||
| QuadFunc( ctx, v1, v2, v3, v4 ); \ | |||
| else if (!(c1 & c2 & c3 & c4 & 0x3f)) \ | |||
| else if (!(c1 & c2 & c3 & c4 & CLIPMASK)) \ | |||
| clip_quad_4( ctx, v1, v2, v3, v4, ormask ); \ | |||
| } while (0) | |||
| @@ -170,7 +173,7 @@ static void clip_elt_triangles( GLcontext *ctx, | |||
| if (ormask) { | |||
| if (start < j) | |||
| render_tris( ctx, start, j, 0 ); | |||
| if (!(c1&c2&c3&0x3f)) | |||
| if (!(c1&c2&c3&CLIPMASK)) | |||
| clip_tri_4( ctx, elt[j], elt[j+1], elt[j+2], ormask ); | |||
| start = j+3; | |||
| } | |||
| @@ -208,6 +208,7 @@ static GLboolean run_vertex_stage( GLcontext *ctx, | |||
| return GL_FALSE; | |||
| } | |||
| VB->ClipAndMask = store->andmask; | |||
| VB->ClipOrMask = store->ormask; | |||
| VB->ClipMask = store->clipmask; | |||
| @@ -222,6 +223,7 @@ static GLboolean run_vertex_stage( GLcontext *ctx, | |||
| VB->ClipPtr = store->save_clipptr; | |||
| VB->NdcPtr = store->save_ndcptr; | |||
| VB->ClipMask = store->clipmask; | |||
| VB->ClipAndMask = store->andmask; | |||
| VB->ClipOrMask = store->ormask; | |||
| if (store->andmask) | |||
| return GL_FALSE; | |||
| @@ -1152,7 +1152,7 @@ static GLboolean TAG(validate_render)( GLcontext *ctx, | |||
| { | |||
| GLint i; | |||
| if (VB->ClipOrMask) | |||
| if (VB->ClipOrMask & ~CLIP_CULL_BIT) | |||
| return GL_FALSE; | |||
| if (VB->Elts && !HAVE_ELTS) | |||