|
|
|
@@ -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 ); |