X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Ftnl%2Ft_vb_cliptmp.h;h=61b0a89554c9feffdd1514374c6b1c7bf58f0d50;hb=e7cb125b2d9e9c7b1ad89b988fa3bf53ead9eb0c;hp=1aeb014e1598a8c0b5dd84df1a37e65c86a2338b;hpb=88f3b89a2cb77766d2009b9868c44e03abe2dbb2;p=mesa.git diff --git a/src/mesa/tnl/t_vb_cliptmp.h b/src/mesa/tnl/t_vb_cliptmp.h index 1aeb014e159..61b0a89554c 100644 --- a/src/mesa/tnl/t_vb_cliptmp.h +++ b/src/mesa/tnl/t_vb_cliptmp.h @@ -1,21 +1,19 @@ -/* $Id: t_vb_cliptmp.h,v 1.4 2000/12/28 22:11:05 keithw Exp $ */ - /* * Mesa 3-D graphics library - * Version: 3.5 - * - * Copyright (C) 1999 Brian Paul All Rights Reserved. - * + * Version: 6.5.2 + * + * Copyright (C) 1999-2006 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 @@ -23,345 +21,46 @@ * 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. * - * Author: - * Keith Whitwell - */ - - -#define INSIDE( J ) !NEGATIVE(J) -#define OUTSIDE( J ) NEGATIVE(J) - - - - -static GLuint TAG(userclip_line)( GLcontext *ctx, - GLuint *i, GLuint *j, - interp_func interp ) -{ - struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; - GLfloat (*coord)[4] = VB->ClipPtr->data; - GLuint ii = *i; - GLuint jj = *j; - GLuint p; - - for (p=0;pTransform.ClipEnabled[p]) { - GLfloat a = ctx->Transform._ClipUserPlane[p][0]; - GLfloat b = ctx->Transform._ClipUserPlane[p][1]; - GLfloat c = ctx->Transform._ClipUserPlane[p][2]; - GLfloat d = ctx->Transform._ClipUserPlane[p][3]; - - GLfloat dpI = d*W(ii) + c*Z(ii) + b*Y(ii) + a*X(ii); - GLfloat dpJ = d*W(jj) + c*Z(jj) + b*Y(jj) + a*X(jj); - - GLuint flagI = OUTSIDE( dpI ); - GLuint flagJ = OUTSIDE( dpJ ); - - if (flagI ^ flagJ) { - if (flagJ) { - GLfloat t = dpI / (dpI - dpJ); - VB->ClipMask[jj] |= CLIP_USER_BIT; - jj = interp( ctx, t, ii, jj, GL_FALSE ); - VB->ClipMask[jj] = 0; - } else { - GLfloat t = dpJ / (dpJ - dpI); - VB->ClipMask[ii] |= CLIP_USER_BIT; - ii = interp( ctx, t, jj, ii, GL_FALSE ); - VB->ClipMask[ii] = 0; - } - } - else if (flagI) - return 0; - } - } - - *i = ii; - *j = jj; - return 1; -} - - -static GLuint TAG(userclip_polygon)( GLcontext *ctx, - GLuint n, - GLuint vlist[], - interp_func interp ) -{ - struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; - GLfloat (*coord)[4] = VB->ClipPtr->data; - GLuint vlist2[MAX_CLIPPED_VERTICES]; - GLuint *inlist = vlist, *outlist = vlist2; - GLubyte *clipmask = VB->ClipMask; - GLuint p; - -#define CLIP_DOTPROD(xx) d*W(xx) + c*Z(xx) + b*Y(xx) + a*X(xx) - - /* Can be speeded up to if vertex_stage actually saves the - * UserClipMask, and if it is used in this loop (after computing a - * UserClipOrMask). - */ - for (p=0;pTransform.ClipEnabled[p]) { - register float a = ctx->Transform._ClipUserPlane[p][0]; - register float b = ctx->Transform._ClipUserPlane[p][1]; - register float c = ctx->Transform._ClipUserPlane[p][2]; - register float d = ctx->Transform._ClipUserPlane[p][3]; - - /* initialize prev to be last in the input list */ - GLuint idxPrev = inlist[n-1]; - GLfloat dpPrev = CLIP_DOTPROD(idxPrev); - GLuint outcount = 0; - GLuint i; - - for (i = 0 ; i < n ; i++) { - GLuint idx = inlist[i]; - GLfloat dp = CLIP_DOTPROD(idx); - - if (!NEGATIVE(dpPrev)) { - outlist[outcount++] = idxPrev; - clipmask[idxPrev] &= ~CLIP_USER_BIT; - } else { - clipmask[idxPrev] |= CLIP_USER_BIT; - } - - - if (DIFFERENT_SIGNS(dp, dpPrev)) { - GLuint newvert; - if (NEGATIVE(dp)) { - /* Going out of bounds. Avoid division by zero as we - * know dp != dpPrev from DIFFERENT_SIGNS, above. - */ - GLfloat t = dp / (dp - dpPrev); - newvert = interp( ctx, t, idx, idxPrev, GL_TRUE ); - } else { - /* Coming back in. - */ - GLfloat t = dpPrev / (dpPrev - dp); - newvert = interp( ctx, t, idxPrev, idx, GL_FALSE ); - } - clipmask[newvert] = 0; - outlist[outcount++] = newvert; - } - - idxPrev = idx; - dpPrev = dp; - } - - if (outcount < 3) - return 0; - - { - GLuint *tmp; - tmp = inlist; - inlist = outlist; - outlist = tmp; - n = outcount; - } - } /* if */ - } /* for p */ - - if (inlist!=vlist) { - GLuint i; - for (i = 0 ; i < n ; i++) - vlist[i] = inlist[i]; - } - - return n; -} - - -/* This now calls the user clip functions if required. - */ -static void TAG(viewclip_line)( GLcontext *ctx, - GLuint i, GLuint j, - GLubyte mask ) -{ - struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; - interp_func interp = (interp_func) VB->interpfunc; - GLfloat (*coord)[4] = VB->ClipPtr->data; - GLuint ii = i, jj = j; - GLuint vlist[2]; - GLuint n; - - VB->LastClipped = VB->FirstClipped; - -/* - * We use 6 instances of this code to clip against the 6 planes. - */ -#define GENERAL_CLIP \ - if (mask & PLANE) { \ - GLfloat dpI = CLIP_DOTPROD( ii ); \ - GLfloat dpJ = CLIP_DOTPROD( jj ); \ - \ - if (DIFFERENT_SIGNS(dpI, dpJ)) { \ - if (NEGATIVE(dpJ)) { \ - GLfloat t = dpI / (dpI - dpJ); \ - VB->ClipMask[jj] |= PLANE; \ - jj = interp( ctx, t, ii, jj, GL_FALSE ); \ - VB->ClipMask[jj] = 0; \ - } else { \ - GLfloat t = dpJ / (dpJ - dpI); \ - VB->ClipMask[ii] |= PLANE; \ - ii = interp( ctx, t, jj, ii, GL_FALSE ); \ - VB->ClipMask[ii] = 0; \ - } \ - } \ - else if (NEGATIVE(dpI)) \ - return; \ - } - -#undef CLIP_DOTPROD -#define PLANE CLIP_RIGHT_BIT -#define CLIP_DOTPROD(K) (- X(K) + W(K)) - - GENERAL_CLIP - -#undef CLIP_DOTPROD -#undef PLANE -#define PLANE CLIP_LEFT_BIT -#define CLIP_DOTPROD(K) (X(K) + W(K)) - - GENERAL_CLIP - -#undef CLIP_DOTPROD -#undef PLANE -#define PLANE CLIP_TOP_BIT -#define CLIP_DOTPROD(K) (- Y(K) + W(K)) - - GENERAL_CLIP - -#undef CLIP_DOTPROD -#undef PLANE -#define PLANE CLIP_BOTTOM_BIT -#define CLIP_DOTPROD(K) (Y(K) + W(K)) - - GENERAL_CLIP - -#undef CLIP_DOTPROD -#undef PLANE -#define PLANE CLIP_FAR_BIT -#define CLIP_DOTPROD(K) (- Z(K) + W(K)) - - if (SIZE >= 3) { - GENERAL_CLIP - } - -#undef CLIP_DOTPROD -#undef PLANE -#define PLANE CLIP_NEAR_BIT -#define CLIP_DOTPROD(K) (Z(K) + W(K)) - - if (SIZE >=3 ) { - GENERAL_CLIP - } - -#undef CLIP_DOTPROD -#undef PLANE -#undef GENERAL_CLIP - - - if (mask & CLIP_USER_BIT) { - if ( TAG(userclip_line)( ctx, &ii, &jj, interp ) == 0 ) - return; - } - - vlist[0] = ii; - vlist[1] = jj; - n = 2; - - /* If necessary, project new vertices. - */ - { - GLuint i, j; - GLfloat (*proj)[4] = VB->ProjectedClipPtr->data; - GLuint start = VB->FirstClipped; - - for (i = 0; i < n; i++) { - j = vlist[i]; - if (j >= start) { - if (SIZE == 4 && W(j) != 0.0F) { - GLfloat wInv = 1.0F / W(j); - proj[j][0] = X(j) * wInv; - proj[j][1] = Y(j) * wInv; - proj[j][2] = Z(j) * wInv; - proj[j][3] = wInv; - } else { - proj[j][0] = X(j); - proj[j][1] = Y(j); - proj[j][2] = Z(j); - proj[j][3] = W(j); - } - } - } - } - - if (ctx->Driver.BuildProjectedVertices) - ctx->Driver.BuildProjectedVertices(ctx, - VB->FirstClipped, - VB->LastClipped, - ~0); - - - /* Render the new line. - */ - ctx->Driver.LineFunc( ctx, ii, jj, j ); -} - -/* We now clip polygon triangles individually. This is necessary to - * avoid artifacts dependent on where the boundary of the VB falls - * within the polygon. As a result, there is an upper bound on the - * number of vertices which may be created, and the test against VB_SIZE - * is redundant. + * Authors: + * Keith Whitwell */ -static void TAG(viewclip_polygon)( GLcontext *ctx, - GLuint n, GLuint vlist[], GLuint pv, - GLubyte mask ) -{ - struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; - interp_func interp = (interp_func) VB->interpfunc; - GLfloat (*coord)[4] = VB->ClipPtr->data; - GLuint vlist2[MAX_CLIPPED_VERTICES]; - GLuint *inlist = vlist, *outlist = vlist2; - GLuint i; - GLubyte *clipmask = VB->ClipMask; - VB->LastClipped = VB->FirstClipped; - if (mask & CLIP_ALL_BITS) { +#define CLIP_DOTPROD(K, A, B, C, D) X(K)*A + Y(K)*B + Z(K)*C + W(K)*D -#define GENERAL_CLIP \ - if (mask & PLANE) { \ - GLuint idxPrev = inlist[n-1]; \ - GLfloat dpPrev = CLIP_DOTPROD(idxPrev); \ +#define POLY_CLIP( PLANE_BIT, A, B, C, D ) \ +do { \ + if (mask & PLANE_BIT) { \ + GLuint idxPrev = inlist[0]; \ + GLfloat dpPrev = CLIP_DOTPROD(idxPrev, A, B, C, D ); \ GLuint outcount = 0; \ GLuint i; \ \ - mask &= ~PLANE; \ - \ - for (i = 0; i < n; i++) { \ + inlist[n] = inlist[0]; /* prevent rotation of vertices */ \ + for (i = 1; i <= n; i++) { \ GLuint idx = inlist[i]; \ - GLfloat dp = CLIP_DOTPROD(idx); \ + GLfloat dp = CLIP_DOTPROD(idx, A, B, C, D ); \ \ - if (!NEGATIVE(dpPrev)) { \ + if (!IS_NEGATIVE(dpPrev)) { \ outlist[outcount++] = idxPrev; \ - clipmask[idxPrev] &= ~PLANE; \ } \ \ if (DIFFERENT_SIGNS(dp, dpPrev)) { \ - GLuint newvert; \ - if (NEGATIVE(dp)) { \ + if (IS_NEGATIVE(dp)) { \ /* Going out of bounds. Avoid division by zero as we \ * know dp != dpPrev from DIFFERENT_SIGNS, above. \ */ \ GLfloat t = dp / (dp - dpPrev); \ - newvert = interp( ctx, t, idx, idxPrev, GL_TRUE ); \ + INTERP_4F( t, coord[newvert], coord[idx], coord[idxPrev]); \ + interp( ctx, t, newvert, idx, idxPrev, GL_TRUE ); \ } else { \ /* Coming back in. \ */ \ GLfloat t = dpPrev / (dpPrev - dp); \ - newvert = interp( ctx, t, idxPrev, idx, GL_FALSE ); \ + INTERP_4F( t, coord[newvert], coord[idxPrev], coord[idx]); \ + interp( ctx, t, newvert, idxPrev, idx, GL_FALSE ); \ } \ - clipmask[newvert] = mask; \ - outlist[outcount++] = newvert; \ + outlist[outcount++] = newvert++; \ } \ \ idxPrev = idx; \ @@ -377,119 +76,229 @@ static void TAG(viewclip_polygon)( GLcontext *ctx, outlist = tmp; \ n = outcount; \ } \ - } + } \ +} while (0) + + +#define LINE_CLIP(PLANE_BIT, A, B, C, D ) \ +do { \ + if (mask & PLANE_BIT) { \ + const GLfloat dp0 = CLIP_DOTPROD( v0, A, B, C, D ); \ + const GLfloat dp1 = CLIP_DOTPROD( v1, A, B, C, D ); \ + const GLboolean neg_dp0 = IS_NEGATIVE(dp0); \ + const GLboolean neg_dp1 = IS_NEGATIVE(dp1); \ + \ + /* For regular clipping, we know from the clipmask that one \ + * (or both) 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 (neg_dp0 && neg_dp1) \ + return; /* both vertices outside clip plane: discard */ \ + \ + if (neg_dp1) { \ + GLfloat t = dp1 / (dp1 - dp0); \ + if (t > t1) t1 = t; \ + } else if (neg_dp0) { \ + GLfloat t = dp0 / (dp0 - dp1); \ + if (t > t0) t0 = t; \ + } \ + if (t0 + t1 >= 1.0) \ + return; /* discard */ \ + } \ +} while (0) -#define PLANE CLIP_RIGHT_BIT -#define CLIP_DOTPROD(K) (- X(K) + W(K)) - GENERAL_CLIP +/* Clip a line against the viewport and user clip planes. + */ +static INLINE void +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 newvert = VB->Count; + GLfloat t0 = 0; + GLfloat t1 = 0; + GLuint p; + const GLuint v0_orig = v0; + + if (mask & CLIP_FRUSTUM_BITS) { + LINE_CLIP( CLIP_RIGHT_BIT, -1, 0, 0, 1 ); + LINE_CLIP( CLIP_LEFT_BIT, 1, 0, 0, 1 ); + LINE_CLIP( CLIP_TOP_BIT, 0, -1, 0, 1 ); + LINE_CLIP( CLIP_BOTTOM_BIT, 0, 1, 0, 1 ); + LINE_CLIP( CLIP_FAR_BIT, 0, 0, -1, 1 ); + LINE_CLIP( CLIP_NEAR_BIT, 0, 0, 1, 1 ); + } -#undef CLIP_DOTPROD -#undef PLANE + if (mask & CLIP_USER_BIT) { + for (p = 0; p < ctx->Const.MaxClipPlanes; p++) { + if (ctx->Transform.ClipPlanesEnabled & (1 << p)) { + const GLfloat a = ctx->Transform._ClipUserPlane[p][0]; + const GLfloat b = ctx->Transform._ClipUserPlane[p][1]; + const GLfloat c = ctx->Transform._ClipUserPlane[p][2]; + const GLfloat d = ctx->Transform._ClipUserPlane[p][3]; + LINE_CLIP( CLIP_USER_BIT, a, b, c, d ); + } + } + } + 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); + } -#define PLANE CLIP_LEFT_BIT -#define CLIP_DOTPROD(K) (X(K) + W(K)) + /* Note: we need to use vertex v0_orig when computing the new + * interpolated/clipped vertex position, not the current v0 which + * may have got set when we clipped the other end of the line! + */ + if (VB->ClipMask[v1]) { + INTERP_4F( t1, coord[newvert], coord[v1], coord[v0_orig] ); + interp( ctx, t1, newvert, v1, v0_orig, GL_FALSE ); - GENERAL_CLIP + if (ctx->Light.ShadeModel == GL_FLAT) + tnl->Driver.Render.CopyPV( ctx, newvert, v1 ); -#undef CLIP_DOTPROD -#undef PLANE + v1 = newvert; -#define PLANE CLIP_TOP_BIT -#define CLIP_DOTPROD(K) (- Y(K) + W(K)) + newvert++; + } + else { + ASSERT(t1 == 0.0); + } - GENERAL_CLIP + tnl->Driver.Render.ClippedLine( ctx, v0, v1 ); +} -#undef CLIP_DOTPROD -#undef PLANE -#define PLANE CLIP_BOTTOM_BIT -#define CLIP_DOTPROD(K) (Y(K) + W(K)) +/* Clip a triangle against the viewport and user clip planes. + */ +static INLINE void +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; + GLuint n = 3; - GENERAL_CLIP + ASSIGN_3V(inlist, v2, v0, v1 ); /* pv rotated to slot zero */ -#undef CLIP_DOTPROD -#undef PLANE + if (mask & CLIP_FRUSTUM_BITS) { + POLY_CLIP( CLIP_RIGHT_BIT, -1, 0, 0, 1 ); + POLY_CLIP( CLIP_LEFT_BIT, 1, 0, 0, 1 ); + POLY_CLIP( CLIP_TOP_BIT, 0, -1, 0, 1 ); + POLY_CLIP( CLIP_BOTTOM_BIT, 0, 1, 0, 1 ); + POLY_CLIP( CLIP_FAR_BIT, 0, 0, -1, 1 ); + POLY_CLIP( CLIP_NEAR_BIT, 0, 0, 1, 1 ); + } -#define PLANE CLIP_FAR_BIT -#define CLIP_DOTPROD(K) (- Z(K) + W(K)) + if (mask & CLIP_USER_BIT) { + for (p = 0; p < ctx->Const.MaxClipPlanes; p++) { + if (ctx->Transform.ClipPlanesEnabled & (1 << p)) { + const GLfloat a = ctx->Transform._ClipUserPlane[p][0]; + const GLfloat b = ctx->Transform._ClipUserPlane[p][1]; + const GLfloat c = ctx->Transform._ClipUserPlane[p][2]; + const GLfloat d = ctx->Transform._ClipUserPlane[p][3]; + POLY_CLIP( CLIP_USER_BIT, a, b, c, d ); + } + } + } - if (SIZE >= 3) { - GENERAL_CLIP + if (ctx->Light.ShadeModel == GL_FLAT) { + if (pv != inlist[0]) { + ASSERT( inlist[0] >= VB->Count ); + tnl->Driver.Render.CopyPV( ctx, inlist[0], pv ); + } } -#undef CLIP_DOTPROD -#undef PLANE + if (0) { + /* print pre/post-clip vertex coords */ + GLuint i, j; + _mesa_printf("pre clip\n"); + for (i = 0; i < 3; i++) { + j = outlist[i]; + _mesa_printf(" %u: %u: %f, %f, %f, %f\n", + i, j, + coord[j][0], coord[j][1], coord[j][2], coord[j][3]); + } + _mesa_printf("post clip\n"); + for (i = 0; i < n; i++) { + j = inlist[i]; + _mesa_printf(" %u: %u: %f, %f, %f, %f\n", + i, j, + coord[j][0], coord[j][1], coord[j][2], coord[j][3]); + } + } -#define PLANE CLIP_NEAR_BIT -#define CLIP_DOTPROD(K) (Z(K) + W(K)) + tnl->Driver.Render.ClippedPolygon( ctx, inlist, n ); +} - if (SIZE >=3 ) { - GENERAL_CLIP - } -#undef CLIP_DOTPROD -#undef PLANE -#undef GENERAL_CLIP +/* Clip a quad against the viewport and user clip planes. + */ +static INLINE void +TAG(clip_quad)( GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2, GLuint v3, + 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 = v3; + GLuint vlist[2][MAX_CLIPPED_VERTICES]; + GLuint *inlist = vlist[0], *outlist = vlist[1]; + GLuint p; + GLuint n = 4; + + ASSIGN_4V(inlist, v3, v0, v1, v2 ); /* pv rotated to slot zero */ - if (inlist != vlist) - for (i = 0 ; i < n ; i++) - vlist[i] = inlist[i]; + if (mask & CLIP_FRUSTUM_BITS) { + POLY_CLIP( CLIP_RIGHT_BIT, -1, 0, 0, 1 ); + POLY_CLIP( CLIP_LEFT_BIT, 1, 0, 0, 1 ); + POLY_CLIP( CLIP_TOP_BIT, 0, -1, 0, 1 ); + POLY_CLIP( CLIP_BOTTOM_BIT, 0, 1, 0, 1 ); + POLY_CLIP( CLIP_FAR_BIT, 0, 0, -1, 1 ); + POLY_CLIP( CLIP_NEAR_BIT, 0, 0, 1, 1 ); } - /* Clip against user clipping planes in clip space. - */ if (mask & CLIP_USER_BIT) { - n = TAG(userclip_polygon)( ctx, n, vlist, interp ); - if (n < 3) return; - } - - /* Project if necessary. - */ - { - GLuint i; - GLfloat (*proj)[4] = VB->ProjectedClipPtr->data; - GLuint first = VB->FirstClipped; - - for (i = 0; i < n; i++) { - GLuint j = vlist[i]; - if (j >= first) { - if (SIZE == 4 && W(j) != 0.0F) { - GLfloat wInv = 1.0F / W(j); - proj[j][0] = X(j) * wInv; - proj[j][1] = Y(j) * wInv; - proj[j][2] = Z(j) * wInv; - proj[j][3] = wInv; - } else { - proj[j][0] = X(j); - proj[j][1] = Y(j); - proj[j][2] = Z(j); - proj[j][3] = W(j); - } + for (p = 0; p < ctx->Const.MaxClipPlanes; p++) { + if (ctx->Transform.ClipPlanesEnabled & (1 << p)) { + const GLfloat a = ctx->Transform._ClipUserPlane[p][0]; + const GLfloat b = ctx->Transform._ClipUserPlane[p][1]; + const GLfloat c = ctx->Transform._ClipUserPlane[p][2]; + const GLfloat d = ctx->Transform._ClipUserPlane[p][3]; + POLY_CLIP( CLIP_USER_BIT, a, b, c, d ); } } } - if (ctx->Driver.BuildProjectedVertices) - ctx->Driver.BuildProjectedVertices(ctx, - VB->FirstClipped, - VB->LastClipped, - ~0); - - /* Render the new vertices as an unclipped polygon. - * Argh - need to pass in pv... - */ - { - GLuint *tmp = VB->Elts; - VB->Elts = vlist; - render_poly_pv_raw_elts( ctx, 0, n, PRIM_BEGIN|PRIM_END, pv ); - VB->Elts = tmp; + if (ctx->Light.ShadeModel == GL_FLAT) { + if (pv != inlist[0]) { + ASSERT( inlist[0] >= VB->Count ); + tnl->Driver.Render.CopyPV( ctx, inlist[0], pv ); + } } -} - + tnl->Driver.Render.ClippedPolygon( ctx, inlist, n ); +} #undef W #undef Z @@ -497,5 +306,5 @@ static void TAG(viewclip_polygon)( GLcontext *ctx, #undef X #undef SIZE #undef TAG -#undef INSIDE -#undef OUTSIDE +#undef POLY_CLIP +#undef LINE_CLIP