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. \
INTERP_4F( t, coord[newvert], coord[idxPrev], coord[idx]); \
interp( ctx, t, newvert, idxPrev, idx, GL_FALSE ); \
} \
+ outlist[outcount++] = newvert++; \
} \
\
idxPrev = idx; \
#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)
/* 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 );
}
}
- 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 );
}
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 );
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 );