diff options
-rw-r--r-- | src/mesa/tnl/t_context.h | 5 | ||||
-rw-r--r-- | src/mesa/tnl/t_vb_cliptmp.h | 82 |
2 files changed, 46 insertions, 41 deletions
diff --git a/src/mesa/tnl/t_context.h b/src/mesa/tnl/t_context.h index f36dec23a5..da225b518e 100644 --- a/src/mesa/tnl/t_context.h +++ b/src/mesa/tnl/t_context.h @@ -450,11 +450,6 @@ struct vertex_buffer /* Inputs to the vertex program stage */ GLvector4f *AttribPtr[_TNL_ATTRIB_MAX]; /* GL_NV_vertex_program */ - - GLuint LastClipped; - /* Private data from _tnl_render_stage that has no business being - * in this struct. - */ }; diff --git a/src/mesa/tnl/t_vb_cliptmp.h b/src/mesa/tnl/t_vb_cliptmp.h index 1e3a6b02ee..ef034032f4 100644 --- a/src/mesa/tnl/t_vb_cliptmp.h +++ b/src/mesa/tnl/t_vb_cliptmp.h @@ -42,16 +42,11 @@ do { \ GLuint idx = inlist[i]; \ GLfloat dp = CLIP_DOTPROD(idx, A, B, C, D ); \ \ - clipmask[idxPrev] |= PLANE; \ if (!IS_NEGATIVE(dpPrev)) { \ outlist[outcount++] = idxPrev; \ - clipmask[idxPrev] &= ~PLANE; \ } \ \ if (DIFFERENT_SIGNS(dp, dpPrev)) { \ - GLuint newvert = VB->LastClipped++; \ - VB->ClipMask[newvert] = 0; \ - outlist[outcount++] = newvert; \ if (IS_NEGATIVE(dp)) { \ /* Going out of bounds. Avoid division by zero as we \ * know dp != dpPrev from DIFFERENT_SIGNS, above. \ @@ -66,6 +61,7 @@ do { \ INTERP_4F( t, coord[newvert], coord[idxPrev], coord[idx]); \ interp( ctx, t, newvert, idxPrev, idx, GL_FALSE ); \ } \ + outlist[outcount++] = newvert++; \ } \ \ idxPrev = idx; \ @@ -88,27 +84,24 @@ do { \ #define LINE_CLIP(PLANE, A, B, C, D ) \ do { \ if (mask & PLANE) { \ - GLfloat dpI = CLIP_DOTPROD( ii, A, B, C, D ); \ - GLfloat dpJ = CLIP_DOTPROD( jj, A, B, C, D ); \ + GLfloat dp0 = CLIP_DOTPROD( v0, A, B, C, D ); \ + GLfloat dp1 = CLIP_DOTPROD( v1, A, B, C, D ); \ \ - if (DIFFERENT_SIGNS(dpI, dpJ)) { \ - GLuint newvert = VB->LastClipped++; \ - VB->ClipMask[newvert] = 0; \ - if (IS_NEGATIVE(dpJ)) { \ - GLfloat t = dpI / (dpI - dpJ); \ - VB->ClipMask[jj] |= PLANE; \ - INTERP_4F( t, coord[newvert], coord[ii], coord[jj] ); \ - interp( ctx, t, newvert, ii, jj, GL_FALSE ); \ - jj = newvert; \ - } else { \ - GLfloat t = dpJ / (dpJ - dpI); \ - VB->ClipMask[ii] |= PLANE; \ - INTERP_4F( t, coord[newvert], coord[jj], coord[ii] ); \ - interp( ctx, t, newvert, jj, ii, GL_FALSE ); \ - ii = newvert; \ - } \ + /* For regular clipping, we know from the clipmask that one of \ + * these must be negative (otherwise we wouldn't be here). For \ + * userclip, there is only a single bit for all active planes, \ + * so we can end up here when there is nothing to do, hence the \ + * second IS_NEGATIVE() test: \ + */ \ + if (IS_NEGATIVE(dp1)) { \ + GLfloat t = dp1 / (dp1 - dp0); \ + if (t > t1) t1 = t; \ + } else if (IS_NEGATIVE(dp0)) { \ + GLfloat t = dp0 / (dp0 - dp1); \ + if (t > t0) t0 = t; \ } \ - else if (IS_NEGATIVE(dpI)) \ + \ + if (t0 + t1 >= 1.0) \ return; \ } \ } while (0) @@ -118,15 +111,17 @@ do { \ /* Clip a line against the viewport and user clip planes. */ static INLINE void -TAG(clip_line)( GLcontext *ctx, GLuint i, GLuint j, GLubyte mask ) +TAG(clip_line)( GLcontext *ctx, GLuint v0, GLuint v1, GLubyte mask ) { TNLcontext *tnl = TNL_CONTEXT(ctx); struct vertex_buffer *VB = &tnl->vb; tnl_interp_func interp = tnl->Driver.Render.Interp; GLfloat (*coord)[4] = VB->ClipPtr->data; - GLuint ii = i, jj = j, p; + GLuint newvert = VB->Count; + GLfloat t0 = 0; + GLfloat t1 = 0; + GLuint p; - VB->LastClipped = VB->Count; if (mask & 0x3f) { LINE_CLIP( CLIP_RIGHT_BIT, -1, 0, 0, 1 ); @@ -149,10 +144,29 @@ TAG(clip_line)( GLcontext *ctx, GLuint i, GLuint j, GLubyte mask ) } } - if ((ctx->_TriangleCaps & DD_FLATSHADE) && j != jj) - tnl->Driver.Render.CopyPV( ctx, jj, j ); + if (VB->ClipMask[v0]) { + INTERP_4F( t0, coord[newvert], coord[v0], coord[v1] ); + interp( ctx, t0, newvert, v0, v1, GL_FALSE ); + v0 = newvert; + newvert++; + } + else + ASSERT(t0 == 0.0); + + if (VB->ClipMask[v1]) { + INTERP_4F( t1, coord[newvert], coord[v1], coord[v0] ); + interp( ctx, t1, newvert, v1, v0, GL_FALSE ); - tnl->Driver.Render.ClippedLine( ctx, ii, jj ); + if (ctx->_TriangleCaps & DD_FLATSHADE) + tnl->Driver.Render.CopyPV( ctx, newvert, v1 ); + + v1 = newvert; + newvert++; + } + else + ASSERT(t1 == 0.0); + + tnl->Driver.Render.ClippedLine( ctx, v0, v1 ); } @@ -164,18 +178,16 @@ TAG(clip_tri)( GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2, GLubyte mask ) TNLcontext *tnl = TNL_CONTEXT(ctx); struct vertex_buffer *VB = &tnl->vb; tnl_interp_func interp = tnl->Driver.Render.Interp; + GLuint newvert = VB->Count; GLfloat (*coord)[4] = VB->ClipPtr->data; GLuint pv = v2; GLuint vlist[2][MAX_CLIPPED_VERTICES]; GLuint *inlist = vlist[0], *outlist = vlist[1]; GLuint p; - GLubyte *clipmask = VB->ClipMask; GLuint n = 3; ASSIGN_3V(inlist, v2, v0, v1 ); /* pv rotated to slot zero */ - VB->LastClipped = VB->Count; - if (mask & 0x3f) { POLY_CLIP( CLIP_RIGHT_BIT, -1, 0, 0, 1 ); POLY_CLIP( CLIP_LEFT_BIT, 1, 0, 0, 1 ); @@ -217,18 +229,16 @@ TAG(clip_quad)( GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2, GLuint v3, TNLcontext *tnl = TNL_CONTEXT(ctx); struct vertex_buffer *VB = &tnl->vb; tnl_interp_func interp = tnl->Driver.Render.Interp; + GLuint newvert = VB->Count; GLfloat (*coord)[4] = VB->ClipPtr->data; GLuint pv = v3; GLuint vlist[2][MAX_CLIPPED_VERTICES]; GLuint *inlist = vlist[0], *outlist = vlist[1]; GLuint p; - GLubyte *clipmask = VB->ClipMask; GLuint n = 4; ASSIGN_4V(inlist, v3, v0, v1, v2 ); /* pv rotated to slot zero */ - VB->LastClipped = VB->Count; - if (mask & 0x3f) { POLY_CLIP( CLIP_RIGHT_BIT, -1, 0, 0, 1 ); POLY_CLIP( CLIP_LEFT_BIT, 1, 0, 0, 1 ); |