home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / mesa5.zip / mesa5src.zip / tnl / t_vb_cliptmp.h < prev    next >
Text File  |  2002-10-29  |  9KB  |  272 lines

  1. /* $Id: t_vb_cliptmp.h,v 1.16 2002/10/29 20:29:03 brianp Exp $ */
  2.  
  3. /*
  4.  * Mesa 3-D graphics library
  5.  * Version:  3.5
  6.  *
  7.  * Copyright (C) 1999-2001  Brian Paul   All Rights Reserved.
  8.  *
  9.  * Permission is hereby granted, free of charge, to any person obtaining a
  10.  * copy of this software and associated documentation files (the "Software"),
  11.  * to deal in the Software without restriction, including without limitation
  12.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  13.  * and/or sell copies of the Software, and to permit persons to whom the
  14.  * Software is furnished to do so, subject to the following conditions:
  15.  *
  16.  * The above copyright notice and this permission notice shall be included
  17.  * in all copies or substantial portions of the Software.
  18.  *
  19.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  20.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  21.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  22.  * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
  23.  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  24.  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  25.  *
  26.  * Authors:
  27.  *    Keith Whitwell <keith@tungstengraphics.com>
  28.  */
  29.  
  30.  
  31. #define CLIP_DOTPROD(K, A, B, C, D) X(K)*A + Y(K)*B + Z(K)*C + W(K)*D
  32.  
  33. #define POLY_CLIP( PLANE, A, B, C, D )                    \
  34. do {                                    \
  35.    if (mask & PLANE) {                            \
  36.       GLuint idxPrev = inlist[0];                    \
  37.       GLfloat dpPrev = CLIP_DOTPROD(idxPrev, A, B, C, D );        \
  38.       GLuint outcount = 0;                        \
  39.       GLuint i;                                \
  40.                                     \
  41.       inlist[n] = inlist[0]; /* prevent rotation of vertices */        \
  42.       for (i = 1; i <= n; i++) {                    \
  43.      GLuint idx = inlist[i];                    \
  44.      GLfloat dp = CLIP_DOTPROD(idx, A, B, C, D );            \
  45.                                     \
  46.          clipmask[idxPrev] |= PLANE;                    \
  47.      if (!NEGATIVE(dpPrev)) {                    \
  48.         outlist[outcount++] = idxPrev;                \
  49.          clipmask[idxPrev] &= ~PLANE;                \
  50.      }                                \
  51.                                     \
  52.      if (DIFFERENT_SIGNS(dp, dpPrev)) {                \
  53.             GLuint newvert = VB->LastClipped++;                \
  54.             VB->ClipMask[newvert] = 0;                    \
  55.             outlist[outcount++] = newvert;                \
  56.         if (NEGATIVE(dp)) {                        \
  57.            /* Going out of bounds.  Avoid division by zero as we    \
  58.         * know dp != dpPrev from DIFFERENT_SIGNS, above.    \
  59.         */                            \
  60.            GLfloat t = dp / (dp - dpPrev);                \
  61.                INTERP_4F( t, coord[newvert], coord[idx], coord[idxPrev]); \
  62.                  interp( ctx, t, newvert, idx, idxPrev, GL_TRUE );    \
  63.         } else {                            \
  64.            /* Coming back in.                    \
  65.         */                            \
  66.            GLfloat t = dpPrev / (dpPrev - dp);            \
  67.                INTERP_4F( t, coord[newvert], coord[idxPrev], coord[idx]); \
  68.            interp( ctx, t, newvert, idxPrev, idx, GL_FALSE );    \
  69.         }                                \
  70.      }                                \
  71.                                     \
  72.      idxPrev = idx;                            \
  73.      dpPrev = dp;                            \
  74.       }                                    \
  75.                                     \
  76.       if (outcount < 3)                            \
  77.      return;                            \
  78.                                     \
  79.       {                                    \
  80.      GLuint *tmp = inlist;                        \
  81.      inlist = outlist;                        \
  82.      outlist = tmp;                            \
  83.      n = outcount;                            \
  84.       }                                    \
  85.    }                                    \
  86. } while (0)
  87.  
  88.  
  89. #define LINE_CLIP(PLANE, A, B, C, D )                    \
  90. do {                                    \
  91.    if (mask & PLANE) {                            \
  92.       GLfloat dpI = CLIP_DOTPROD( ii, A, B, C, D );            \
  93.       GLfloat dpJ = CLIP_DOTPROD( jj, A, B, C, D );            \
  94.                                     \
  95.       if (DIFFERENT_SIGNS(dpI, dpJ)) {                    \
  96.          GLuint newvert = VB->LastClipped++;                \
  97.          VB->ClipMask[newvert] = 0;                    \
  98.      if (NEGATIVE(dpJ)) {                        \
  99.         GLfloat t = dpI / (dpI - dpJ);                \
  100.             VB->ClipMask[jj] |= PLANE;                    \
  101.             INTERP_4F( t, coord[newvert], coord[ii], coord[jj] );    \
  102.         interp( ctx, t, newvert, ii, jj, GL_FALSE );        \
  103.             jj = newvert;                        \
  104.      } else {                            \
  105.           GLfloat t = dpJ / (dpJ - dpI);                \
  106.             VB->ClipMask[ii] |= PLANE;                    \
  107.             INTERP_4F( t, coord[newvert], coord[jj], coord[ii] );    \
  108.         interp( ctx, t, newvert, jj, ii, GL_FALSE );        \
  109.             ii = newvert;                        \
  110.      }                                \
  111.       }                                    \
  112.       else if (NEGATIVE(dpI))                        \
  113.      return;                            \
  114.   }                                    \
  115. } while (0)
  116.  
  117.  
  118.  
  119. /* Clip a line against the viewport and user clip planes.
  120.  */
  121. static INLINE void
  122. TAG(clip_line)( GLcontext *ctx, GLuint i, GLuint j, GLubyte mask )
  123. {
  124.    TNLcontext *tnl = TNL_CONTEXT(ctx);
  125.    struct vertex_buffer *VB = &tnl->vb;
  126.    interp_func interp = tnl->Driver.Render.Interp;
  127.    GLfloat (*coord)[4] = VB->ClipPtr->data;
  128.    GLuint ii = i, jj = j, p;
  129.  
  130.    VB->LastClipped = VB->FirstClipped;
  131.  
  132.    if (mask & 0x3f) {
  133.       LINE_CLIP( CLIP_RIGHT_BIT,  -1,  0,  0, 1 );
  134.       LINE_CLIP( CLIP_LEFT_BIT,    1,  0,  0, 1 );
  135.       LINE_CLIP( CLIP_TOP_BIT,     0, -1,  0, 1 );
  136.       LINE_CLIP( CLIP_BOTTOM_BIT,  0,  1,  0, 1 );
  137.       LINE_CLIP( CLIP_FAR_BIT,     0,  0, -1, 1 );
  138.       LINE_CLIP( CLIP_NEAR_BIT,    0,  0,  1, 1 );
  139.    }
  140.  
  141.    if (mask & CLIP_USER_BIT) {
  142.       for (p=0;p<MAX_CLIP_PLANES;p++) {
  143.      if (ctx->Transform.ClipPlanesEnabled & (1 << p)) {
  144.             const GLfloat a = ctx->Transform._ClipUserPlane[p][0];
  145.             const GLfloat b = ctx->Transform._ClipUserPlane[p][1];
  146.             const GLfloat c = ctx->Transform._ClipUserPlane[p][2];
  147.             const GLfloat d = ctx->Transform._ClipUserPlane[p][3];
  148.         LINE_CLIP( CLIP_USER_BIT, a, b, c, d );
  149.      }
  150.       }
  151.    }
  152.  
  153.    if ((ctx->_TriangleCaps & DD_FLATSHADE) && j != jj)
  154.       tnl->Driver.Render.CopyPV( ctx, jj, j );
  155.  
  156.    tnl->Driver.Render.ClippedLine( ctx, ii, jj );
  157. }
  158.  
  159.  
  160. /* Clip a triangle against the viewport and user clip planes.
  161.  */
  162. static INLINE void
  163. TAG(clip_tri)( GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2, GLubyte mask )
  164. {
  165.    TNLcontext *tnl = TNL_CONTEXT(ctx);
  166.    struct vertex_buffer *VB = &tnl->vb;
  167.    interp_func interp = tnl->Driver.Render.Interp;
  168.    GLfloat (*coord)[4] = VB->ClipPtr->data;
  169.    GLuint pv = v2;
  170.    GLuint vlist[2][MAX_CLIPPED_VERTICES];
  171.    GLuint *inlist = vlist[0], *outlist = vlist[1];
  172.    GLuint p;
  173.    GLubyte *clipmask = VB->ClipMask;
  174.    GLuint n = 3;
  175.  
  176.    ASSIGN_3V(inlist, v2, v0, v1 ); /* pv rotated to slot zero */
  177.  
  178.    VB->LastClipped = VB->FirstClipped;
  179.  
  180.    if (mask & 0x3f) {
  181.       POLY_CLIP( CLIP_RIGHT_BIT,  -1,  0,  0, 1 );
  182.       POLY_CLIP( CLIP_LEFT_BIT,    1,  0,  0, 1 );
  183.       POLY_CLIP( CLIP_TOP_BIT,     0, -1,  0, 1 );
  184.       POLY_CLIP( CLIP_BOTTOM_BIT,  0,  1,  0, 1 );
  185.       POLY_CLIP( CLIP_FAR_BIT,     0,  0, -1, 1 );
  186.       POLY_CLIP( CLIP_NEAR_BIT,    0,  0,  1, 1 );
  187.    }
  188.  
  189.    if (mask & CLIP_USER_BIT) {
  190.       for (p=0;p<MAX_CLIP_PLANES;p++) {
  191.          if (ctx->Transform.ClipPlanesEnabled & (1 << p)) {
  192.             const GLfloat a = ctx->Transform._ClipUserPlane[p][0];
  193.             const GLfloat b = ctx->Transform._ClipUserPlane[p][1];
  194.             const GLfloat c = ctx->Transform._ClipUserPlane[p][2];
  195.             const GLfloat d = ctx->Transform._ClipUserPlane[p][3];
  196.             POLY_CLIP( CLIP_USER_BIT, a, b, c, d );
  197.          }
  198.       }
  199.    }
  200.  
  201.    if (ctx->_TriangleCaps & DD_FLATSHADE) {
  202.       if (pv != inlist[0]) {
  203.      ASSERT( inlist[0] >= VB->FirstClipped );
  204.      tnl->Driver.Render.CopyPV( ctx, inlist[0], pv );
  205.       }
  206.    }
  207.  
  208.    tnl->Driver.Render.ClippedPolygon( ctx, inlist, n );
  209. }
  210.  
  211.  
  212. /* Clip a quad against the viewport and user clip planes.
  213.  */
  214. static INLINE void
  215. TAG(clip_quad)( GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2, GLuint v3,
  216.                 GLubyte mask )
  217. {
  218.    TNLcontext *tnl = TNL_CONTEXT(ctx);
  219.    struct vertex_buffer *VB = &tnl->vb;
  220.    interp_func interp = tnl->Driver.Render.Interp;
  221.    GLfloat (*coord)[4] = VB->ClipPtr->data;
  222.    GLuint pv = v3;
  223.    GLuint vlist[2][MAX_CLIPPED_VERTICES];
  224.    GLuint *inlist = vlist[0], *outlist = vlist[1];
  225.    GLuint p;
  226.    GLubyte *clipmask = VB->ClipMask;
  227.    GLuint n = 4;
  228.  
  229.    ASSIGN_4V(inlist, v3, v0, v1, v2 ); /* pv rotated to slot zero */
  230.  
  231.    VB->LastClipped = VB->FirstClipped;
  232.  
  233.    if (mask & 0x3f) {
  234.       POLY_CLIP( CLIP_RIGHT_BIT,  -1,  0,  0, 1 );
  235.       POLY_CLIP( CLIP_LEFT_BIT,    1,  0,  0, 1 );
  236.       POLY_CLIP( CLIP_TOP_BIT,     0, -1,  0, 1 );
  237.       POLY_CLIP( CLIP_BOTTOM_BIT,  0,  1,  0, 1 );
  238.       POLY_CLIP( CLIP_FAR_BIT,     0,  0, -1, 1 );
  239.       POLY_CLIP( CLIP_NEAR_BIT,    0,  0,  1, 1 );
  240.    }
  241.  
  242.    if (mask & CLIP_USER_BIT) {
  243.       for (p=0;p<MAX_CLIP_PLANES;p++) {
  244.      if (ctx->Transform.ClipPlanesEnabled & (1 << p)) {
  245.             const GLfloat a = ctx->Transform._ClipUserPlane[p][0];
  246.             const GLfloat b = ctx->Transform._ClipUserPlane[p][1];
  247.             const GLfloat c = ctx->Transform._ClipUserPlane[p][2];
  248.             const GLfloat d = ctx->Transform._ClipUserPlane[p][3];
  249.         POLY_CLIP( CLIP_USER_BIT, a, b, c, d );
  250.      }
  251.       }
  252.    }
  253.  
  254.    if (ctx->_TriangleCaps & DD_FLATSHADE) {
  255.       if (pv != inlist[0]) {
  256.      ASSERT( inlist[0] >= VB->FirstClipped );
  257.      tnl->Driver.Render.CopyPV( ctx, inlist[0], pv );
  258.       }
  259.    }
  260.  
  261.    tnl->Driver.Render.ClippedPolygon( ctx, inlist, n );
  262. }
  263.  
  264. #undef W
  265. #undef Z
  266. #undef Y
  267. #undef X
  268. #undef SIZE
  269. #undef TAG
  270. #undef POLY_CLIP
  271. #undef LINE_CLIP
  272.