Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1.  
  2. /*
  3.  * Mesa 3-D graphics library
  4.  * Version:  3.5
  5.  *
  6.  * Copyright (C) 1999-2001  Brian Paul   All Rights Reserved.
  7.  *
  8.  * Permission is hereby granted, free of charge, to any person obtaining a
  9.  * copy of this software and associated documentation files (the "Software"),
  10.  * to deal in the Software without restriction, including without limitation
  11.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  12.  * and/or sell copies of the Software, and to permit persons to whom the
  13.  * Software is furnished to do so, subject to the following conditions:
  14.  *
  15.  * The above copyright notice and this permission notice shall be included
  16.  * in all copies or substantial portions of the Software.
  17.  *
  18.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  19.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  20.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  21.  * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
  22.  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  23.  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  24.  *
  25.  * Authors:
  26.  *    Keith Whitwell <keith_whitwell@yahoo.com>
  27.  */
  28.  
  29. /* Template to build clipping routines to support t_dd_imm_primtmp.h.
  30.  *
  31.  * The TAG(draw_line) and TAG(draw_triangle) routines are called in
  32.  * clipping and fallback scenarios, and when the native hardware
  33.  * primitive (eg polygons) is unavailable.
  34.  */
  35.  
  36.  
  37. #define CLIP_DOTPROD(K, A, B, C, D)             \
  38.    (CLIP_X(K)*A + CLIP_Y(K)*B +         \
  39.     CLIP_Z(K)*C + CLIP_W(K)*D)
  40.  
  41. #define POLY_CLIP( PLANE, A, B, C, D )                                  \
  42. do {                                                                    \
  43.    if (mask & PLANE) {                                                  \
  44.       TNL_VERTEX **indata = inlist[in];                                 \
  45.       TNL_VERTEX **outdata = inlist[in ^= 1];                           \
  46.       TNL_VERTEX *J = indata[0];                                        \
  47.       GLfloat dpJ = CLIP_DOTPROD(J, A, B, C, D );                       \
  48.       GLuint outcount = 0;                                              \
  49.       GLuint i;                                                         \
  50.                                                                         \
  51.       indata[n] = indata[0]; /* prevent rotation of vertices */         \
  52.       for (i = 1; i <= n; i++) {                                        \
  53.          TNL_VERTEX *I = indata[i];                                     \
  54.          GLfloat dpI = CLIP_DOTPROD(idx, A, B, C, D );                  \
  55.                                                                         \
  56.          if (!NEGATIVE(dpPrev)) {                                       \
  57.             outdata[outcount++] = J;                                    \
  58.          }                                                              \
  59.                                                                         \
  60.          if (DIFFERENT_SIGNS(dpI, dpJ)) {                               \
  61.             TNL_VERTEX *O = verts++;                                    \
  62.             outdata[outcount++] = O;                                    \
  63.             if (NEGATIVE(dpI)) {                                        \
  64.                /* Going out of bounds.  Avoid division by zero as we    \
  65.                 * know dp != dpPrev from DIFFERENT_SIGNS, above.        \
  66.                 */                                                      \
  67.                GLfloat t = dpI / (dpI - dpJ);                           \
  68.                INTERP( ctx, t, O, I, J );                               \
  69.             } else {                                                    \
  70.                /* Coming back in.                                       \
  71.                 */                                                      \
  72.                GLfloat t = dpJ / (dpJ - dpI);                           \
  73.                INTERP( ctx, t, O, J, I );                               \
  74.             }                                                           \
  75.          }                                                              \
  76.                                                                         \
  77.          J = I;                                                         \
  78.          dpJ = dpI;                                                     \
  79.       }                                                                 \
  80.                                                                         \
  81.       if (outcount < 3)                                                 \
  82.          return;                                                        \
  83.                                                                         \
  84.       nr = outcount;                                                    \
  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( I, A, B, C, D );      \
  93.       GLfloat dpJ = CLIP_DOTPROD( J, A, B, C, D );      \
  94.                                                         \
  95.       if (DIFFERENT_SIGNS(dpI, dpJ)) {                  \
  96.          TNL_VERTEX *O = verts++;                       \
  97.          if (NEGATIVE(dpJ)) {                           \
  98.             GLfloat t = dpI / (dpI - dpJ);              \
  99.             INTERP( ctx, t, O, I, J );  \
  100.             J = O;                                      \
  101.          } else {                                       \
  102.             GLfloat t = dpJ / (dpJ - dpI);              \
  103.             INTERP( ctx, t, O, J, I );  \
  104.             I = O;                                      \
  105.          }                                              \
  106.       }                                                 \
  107.       else if (NEGATIVE(dpI))                           \
  108.          return;                                        \
  109.   }                                                     \
  110. } while (0)
  111.  
  112.  
  113.  
  114. /* Clip a line against the viewport and user clip planes.
  115.  */
  116. static void TAG(clip_draw_line)( struct gl_context *ctx,
  117.                                  TNL_VERTEX *I,
  118.                                  TNL_VERTEX *J,
  119.                                  GLuint mask )
  120. {
  121.    LOCAL_VARS;
  122.    GET_INTERP_FUNC;
  123.    TNL_VERTEX tmp[MAX_CLIPPED_VERTICES];
  124.    TNL_VERTEX *verts = tmp;
  125.    TNL_VERTEX *pv = J;
  126.  
  127.    LINE_CLIP( CLIP_RIGHT_BIT,  -1,  0,  0, 1 );
  128.    LINE_CLIP( CLIP_LEFT_BIT,    1,  0,  0, 1 );
  129.    LINE_CLIP( CLIP_TOP_BIT,     0, -1,  0, 1 );
  130.    LINE_CLIP( CLIP_BOTTOM_BIT,  0,  1,  0, 1 );
  131.    LINE_CLIP( CLIP_FAR_BIT,     0,  0, -1, 1 );
  132.    LINE_CLIP( CLIP_NEAR_BIT,    0,  0,  1, 1 );
  133.  
  134.    if ((ctx->_TriangleCaps & DD_FLATSHADE) && J != pv)
  135.       COPY_PV( ctx, J, pv );
  136.  
  137.    DRAW_LINE( I, J );
  138. }
  139.  
  140.  
  141. /* Clip a triangle against the viewport and user clip planes.
  142.  */
  143. static void TAG(clip_draw_triangle)( struct gl_context *ctx,
  144.                                      TNL_VERTEX *v0,
  145.                                      TNL_VERTEX *v1,
  146.                                      TNL_VERTEX *v2,
  147.                                      GLuint mask )
  148. {
  149.    LOCAL_VARS;
  150.    GET_INTERP_FUNC;
  151.    TNL_VERTEX tmp[MAX_CLIPPED_VERTICES];
  152.    TNL_VERTEX *verts = tmp;
  153.    TNL_VERTEX *(inlist[2][MAX_CLIPPED_VERTICES]);
  154.    TNL_VERTEX **out;
  155.    GLuint in = 0;
  156.    GLuint n = 3;
  157.    GLuint i;
  158.  
  159.    ASSIGN_3V(inlist, v2, v0, v1 ); /* pv rotated to slot zero */
  160.  
  161.    POLY_CLIP( CLIP_RIGHT_BIT,  -1,  0,  0, 1 );
  162.    POLY_CLIP( CLIP_LEFT_BIT,    1,  0,  0, 1 );
  163.    POLY_CLIP( CLIP_TOP_BIT,     0, -1,  0, 1 );
  164.    POLY_CLIP( CLIP_BOTTOM_BIT,  0,  1,  0, 1 );
  165.    POLY_CLIP( CLIP_FAR_BIT,     0,  0, -1, 1 );
  166.    POLY_CLIP( CLIP_NEAR_BIT,    0,  0,  1, 1 );
  167.  
  168.    if ((ctx->_TriangleCaps & DD_FLATSHADE) && v2 != inlist[0])
  169.       COPY_PV( ctx, inlist[0], v2 );
  170.  
  171.    out = inlist[in];
  172.    DRAW_POLYGON( out, n );
  173. }
  174.  
  175.  
  176. static __inline void TAG(draw_triangle)( struct gl_context *ctx,
  177.                                          TNL_VERTEX *v0,
  178.                                          TNL_VERTEX *v1,
  179.                                          TNL_VERTEX *v2 )
  180. {
  181.    LOCAL_VARS;
  182.    GLubyte ormask = (v0->mask | v1->mask | v2->mask);
  183.  
  184.    if ( !ormask ) {
  185.       DRAW_TRI( v0, v1, v2 );
  186.    } else if ( !(v0->mask & v1->mask & v2->mask) ) {
  187.       TAG(clip_draw_triangle)( ctx, v0, v1, v2, ormask );
  188.    }
  189. }
  190.  
  191. static __inline void TAG(draw_line)( struct gl_context *ctx,
  192.                                      TNL_VERTEX *v0,
  193.                                      TNL_VERTEX *v1 )
  194. {
  195.    LOCAL_VARS;
  196.    GLubyte ormask = (v0->mask | v1->mask);
  197.  
  198.    if ( !ormask ) {
  199.       DRAW_LINE( v0, v1 );
  200.    } else if ( !(v0->mask & v1->mask) ) {
  201.       TAG(clip_draw_line)( ctx, v0, v1, ormask );
  202.    }
  203. }
  204.  
  205.