Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygent_vb_cliptmp.h
Go to the documentation of this file.
00001 /* 00002 * Mesa 3-D graphics library 00003 * Version: 6.5.2 00004 * 00005 * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. 00006 * 00007 * Permission is hereby granted, free of charge, to any person obtaining a 00008 * copy of this software and associated documentation files (the "Software"), 00009 * to deal in the Software without restriction, including without limitation 00010 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 00011 * and/or sell copies of the Software, and to permit persons to whom the 00012 * Software is furnished to do so, subject to the following conditions: 00013 * 00014 * The above copyright notice and this permission notice shall be included 00015 * in all copies or substantial portions of the Software. 00016 * 00017 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 00018 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00019 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 00020 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 00021 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 00022 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00023 * 00024 * Authors: 00025 * Keith Whitwell <keith@tungstengraphics.com> 00026 */ 00027 00028 00029 #define CLIP_DOTPROD(K, A, B, C, D) X(K)*A + Y(K)*B + Z(K)*C + W(K)*D 00030 00031 #define POLY_CLIP( PLANE_BIT, A, B, C, D ) \ 00032 do { \ 00033 if (mask & PLANE_BIT) { \ 00034 GLuint idxPrev = inlist[0]; \ 00035 GLfloat dpPrev = CLIP_DOTPROD(idxPrev, A, B, C, D ); \ 00036 GLuint outcount = 0; \ 00037 GLuint i; \ 00038 \ 00039 inlist[n] = inlist[0]; /* prevent rotation of vertices */ \ 00040 for (i = 1; i <= n; i++) { \ 00041 GLuint idx = inlist[i]; \ 00042 GLfloat dp = CLIP_DOTPROD(idx, A, B, C, D ); \ 00043 \ 00044 if (!IS_NEGATIVE(dpPrev)) { \ 00045 outlist[outcount++] = idxPrev; \ 00046 } \ 00047 \ 00048 if (DIFFERENT_SIGNS(dp, dpPrev)) { \ 00049 if (IS_NEGATIVE(dp)) { \ 00050 /* Going out of bounds. Avoid division by zero as we \ 00051 * know dp != dpPrev from DIFFERENT_SIGNS, above. \ 00052 */ \ 00053 GLfloat t = dp / (dp - dpPrev); \ 00054 INTERP_4F( t, coord[newvert], coord[idx], coord[idxPrev]); \ 00055 interp( ctx, t, newvert, idx, idxPrev, GL_TRUE ); \ 00056 } else { \ 00057 /* Coming back in. \ 00058 */ \ 00059 GLfloat t = dpPrev / (dpPrev - dp); \ 00060 INTERP_4F( t, coord[newvert], coord[idxPrev], coord[idx]); \ 00061 interp( ctx, t, newvert, idxPrev, idx, GL_FALSE ); \ 00062 } \ 00063 outlist[outcount++] = newvert++; \ 00064 } \ 00065 \ 00066 idxPrev = idx; \ 00067 dpPrev = dp; \ 00068 } \ 00069 \ 00070 if (outcount < 3) \ 00071 return; \ 00072 \ 00073 { \ 00074 GLuint *tmp = inlist; \ 00075 inlist = outlist; \ 00076 outlist = tmp; \ 00077 n = outcount; \ 00078 } \ 00079 } \ 00080 } while (0) 00081 00082 00083 #define LINE_CLIP(PLANE_BIT, A, B, C, D ) \ 00084 do { \ 00085 if (mask & PLANE_BIT) { \ 00086 const GLfloat dp0 = CLIP_DOTPROD( v0, A, B, C, D ); \ 00087 const GLfloat dp1 = CLIP_DOTPROD( v1, A, B, C, D ); \ 00088 const GLboolean neg_dp0 = IS_NEGATIVE(dp0); \ 00089 const GLboolean neg_dp1 = IS_NEGATIVE(dp1); \ 00090 \ 00091 /* For regular clipping, we know from the clipmask that one \ 00092 * (or both) of these must be negative (otherwise we wouldn't \ 00093 * be here). \ 00094 * For userclip, there is only a single bit for all active \ 00095 * planes, so we can end up here when there is nothing to do, \ 00096 * hence the second IS_NEGATIVE() test: \ 00097 */ \ 00098 if (neg_dp0 && neg_dp1) \ 00099 return; /* both vertices outside clip plane: discard */ \ 00100 \ 00101 if (neg_dp1) { \ 00102 GLfloat t = dp1 / (dp1 - dp0); \ 00103 if (t > t1) t1 = t; \ 00104 } else if (neg_dp0) { \ 00105 GLfloat t = dp0 / (dp0 - dp1); \ 00106 if (t > t0) t0 = t; \ 00107 } \ 00108 if (t0 + t1 >= 1.0) \ 00109 return; /* discard */ \ 00110 } \ 00111 } while (0) 00112 00113 00114 00115 /* Clip a line against the viewport and user clip planes. 00116 */ 00117 static INLINE void 00118 TAG(clip_line)( GLcontext *ctx, GLuint v0, GLuint v1, GLubyte mask ) 00119 { 00120 TNLcontext *tnl = TNL_CONTEXT(ctx); 00121 struct vertex_buffer *VB = &tnl->vb; 00122 tnl_interp_func interp = tnl->Driver.Render.Interp; 00123 GLfloat (*coord)[4] = VB->ClipPtr->data; 00124 GLuint newvert = VB->Count; 00125 GLfloat t0 = 0; 00126 GLfloat t1 = 0; 00127 GLuint p; 00128 const GLuint v0_orig = v0; 00129 00130 if (mask & 0x3f) { 00131 LINE_CLIP( CLIP_RIGHT_BIT, -1, 0, 0, 1 ); 00132 LINE_CLIP( CLIP_LEFT_BIT, 1, 0, 0, 1 ); 00133 LINE_CLIP( CLIP_TOP_BIT, 0, -1, 0, 1 ); 00134 LINE_CLIP( CLIP_BOTTOM_BIT, 0, 1, 0, 1 ); 00135 LINE_CLIP( CLIP_FAR_BIT, 0, 0, -1, 1 ); 00136 LINE_CLIP( CLIP_NEAR_BIT, 0, 0, 1, 1 ); 00137 } 00138 00139 if (mask & CLIP_USER_BIT) { 00140 for (p = 0; p < ctx->Const.MaxClipPlanes; p++) { 00141 if (ctx->Transform.ClipPlanesEnabled & (1 << p)) { 00142 const GLfloat a = ctx->Transform._ClipUserPlane[p][0]; 00143 const GLfloat b = ctx->Transform._ClipUserPlane[p][1]; 00144 const GLfloat c = ctx->Transform._ClipUserPlane[p][2]; 00145 const GLfloat d = ctx->Transform._ClipUserPlane[p][3]; 00146 LINE_CLIP( CLIP_USER_BIT, a, b, c, d ); 00147 } 00148 } 00149 } 00150 00151 if (VB->ClipMask[v0]) { 00152 INTERP_4F( t0, coord[newvert], coord[v0], coord[v1] ); 00153 interp( ctx, t0, newvert, v0, v1, GL_FALSE ); 00154 v0 = newvert; 00155 newvert++; 00156 } 00157 else { 00158 ASSERT(t0 == 0.0); 00159 } 00160 00161 /* Note: we need to use vertex v0_orig when computing the new 00162 * interpolated/clipped vertex position, not the current v0 which 00163 * may have got set when we clipped the other end of the line! 00164 */ 00165 if (VB->ClipMask[v1]) { 00166 INTERP_4F( t1, coord[newvert], coord[v1], coord[v0_orig] ); 00167 interp( ctx, t1, newvert, v1, v0_orig, GL_FALSE ); 00168 00169 if (ctx->Light.ShadeModel == GL_FLAT) 00170 tnl->Driver.Render.CopyPV( ctx, newvert, v1 ); 00171 00172 v1 = newvert; 00173 00174 newvert++; 00175 } 00176 else { 00177 ASSERT(t1 == 0.0); 00178 } 00179 00180 tnl->Driver.Render.ClippedLine( ctx, v0, v1 ); 00181 } 00182 00183 00184 /* Clip a triangle against the viewport and user clip planes. 00185 */ 00186 static INLINE void 00187 TAG(clip_tri)( GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2, GLubyte mask ) 00188 { 00189 TNLcontext *tnl = TNL_CONTEXT(ctx); 00190 struct vertex_buffer *VB = &tnl->vb; 00191 tnl_interp_func interp = tnl->Driver.Render.Interp; 00192 GLuint newvert = VB->Count; 00193 GLfloat (*coord)[4] = VB->ClipPtr->data; 00194 GLuint pv = v2; 00195 GLuint vlist[2][MAX_CLIPPED_VERTICES]; 00196 GLuint *inlist = vlist[0], *outlist = vlist[1]; 00197 GLuint p; 00198 GLuint n = 3; 00199 00200 ASSIGN_3V(inlist, v2, v0, v1 ); /* pv rotated to slot zero */ 00201 00202 if (mask & 0x3f) { 00203 POLY_CLIP( CLIP_RIGHT_BIT, -1, 0, 0, 1 ); 00204 POLY_CLIP( CLIP_LEFT_BIT, 1, 0, 0, 1 ); 00205 POLY_CLIP( CLIP_TOP_BIT, 0, -1, 0, 1 ); 00206 POLY_CLIP( CLIP_BOTTOM_BIT, 0, 1, 0, 1 ); 00207 POLY_CLIP( CLIP_FAR_BIT, 0, 0, -1, 1 ); 00208 POLY_CLIP( CLIP_NEAR_BIT, 0, 0, 1, 1 ); 00209 } 00210 00211 if (mask & CLIP_USER_BIT) { 00212 for (p = 0; p < ctx->Const.MaxClipPlanes; p++) { 00213 if (ctx->Transform.ClipPlanesEnabled & (1 << p)) { 00214 const GLfloat a = ctx->Transform._ClipUserPlane[p][0]; 00215 const GLfloat b = ctx->Transform._ClipUserPlane[p][1]; 00216 const GLfloat c = ctx->Transform._ClipUserPlane[p][2]; 00217 const GLfloat d = ctx->Transform._ClipUserPlane[p][3]; 00218 POLY_CLIP( CLIP_USER_BIT, a, b, c, d ); 00219 } 00220 } 00221 } 00222 00223 if (ctx->Light.ShadeModel == GL_FLAT) { 00224 if (pv != inlist[0]) { 00225 ASSERT( inlist[0] >= VB->Count ); 00226 tnl->Driver.Render.CopyPV( ctx, inlist[0], pv ); 00227 } 00228 } 00229 00230 tnl->Driver.Render.ClippedPolygon( ctx, inlist, n ); 00231 } 00232 00233 00234 /* Clip a quad against the viewport and user clip planes. 00235 */ 00236 static INLINE void 00237 TAG(clip_quad)( GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2, GLuint v3, 00238 GLubyte mask ) 00239 { 00240 TNLcontext *tnl = TNL_CONTEXT(ctx); 00241 struct vertex_buffer *VB = &tnl->vb; 00242 tnl_interp_func interp = tnl->Driver.Render.Interp; 00243 GLuint newvert = VB->Count; 00244 GLfloat (*coord)[4] = VB->ClipPtr->data; 00245 GLuint pv = v3; 00246 GLuint vlist[2][MAX_CLIPPED_VERTICES]; 00247 GLuint *inlist = vlist[0], *outlist = vlist[1]; 00248 GLuint p; 00249 GLuint n = 4; 00250 00251 ASSIGN_4V(inlist, v3, v0, v1, v2 ); /* pv rotated to slot zero */ 00252 00253 if (mask & 0x3f) { 00254 POLY_CLIP( CLIP_RIGHT_BIT, -1, 0, 0, 1 ); 00255 POLY_CLIP( CLIP_LEFT_BIT, 1, 0, 0, 1 ); 00256 POLY_CLIP( CLIP_TOP_BIT, 0, -1, 0, 1 ); 00257 POLY_CLIP( CLIP_BOTTOM_BIT, 0, 1, 0, 1 ); 00258 POLY_CLIP( CLIP_FAR_BIT, 0, 0, -1, 1 ); 00259 POLY_CLIP( CLIP_NEAR_BIT, 0, 0, 1, 1 ); 00260 } 00261 00262 if (mask & CLIP_USER_BIT) { 00263 for (p = 0; p < ctx->Const.MaxClipPlanes; p++) { 00264 if (ctx->Transform.ClipPlanesEnabled & (1 << p)) { 00265 const GLfloat a = ctx->Transform._ClipUserPlane[p][0]; 00266 const GLfloat b = ctx->Transform._ClipUserPlane[p][1]; 00267 const GLfloat c = ctx->Transform._ClipUserPlane[p][2]; 00268 const GLfloat d = ctx->Transform._ClipUserPlane[p][3]; 00269 POLY_CLIP( CLIP_USER_BIT, a, b, c, d ); 00270 } 00271 } 00272 } 00273 00274 if (ctx->Light.ShadeModel == GL_FLAT) { 00275 if (pv != inlist[0]) { 00276 ASSERT( inlist[0] >= VB->Count ); 00277 tnl->Driver.Render.CopyPV( ctx, inlist[0], pv ); 00278 } 00279 } 00280 00281 tnl->Driver.Render.ClippedPolygon( ctx, inlist, n ); 00282 } 00283 00284 #undef W 00285 #undef Z 00286 #undef Y 00287 #undef X 00288 #undef SIZE 00289 #undef TAG 00290 #undef POLY_CLIP 00291 #undef LINE_CLIP Generated on Thu May 24 2012 04:20:58 for ReactOS by
1.7.6.1
|