home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / mesa5.zip / mesa5src.zip / tnl / t_vb_vertex.cpp < prev    next >
C/C++ Source or Header  |  2002-10-31  |  10KB  |  324 lines

  1. /* $Id: t_vb_vertex.c,v 1.17 2002/10/31 17:14:37 brianp Exp $ */
  2.  
  3. /*
  4.  * Mesa 3-D graphics library
  5.  * Version:  5.0
  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. #include "glheader.h"
  32. #include "colormac.h"
  33. #include "context.h"
  34. #include "macros.h"
  35. #include "imports.h"
  36. #include "mmath.h"
  37. #include "mtypes.h"
  38.  
  39. #include "math/m_xform.h"
  40.  
  41. #include "t_context.h"
  42. #include "t_pipeline.h"
  43.  
  44.  
  45.  
  46. struct vertex_stage_data {
  47.    GLvector4f eye;
  48.    GLvector4f clip;
  49.    GLvector4f proj;
  50.    GLubyte *clipmask;
  51.    GLubyte ormask;
  52.    GLubyte andmask;
  53.  
  54.  
  55.    /* Need these because it's difficult to replay the sideeffects
  56.     * analytically.
  57.     */
  58.    GLvector4f *save_eyeptr;
  59.    GLvector4f *save_clipptr;
  60.    GLvector4f *save_ndcptr;
  61. };
  62.  
  63. #define VERTEX_STAGE_DATA(stage) ((struct vertex_stage_data *)stage->privatePtr)
  64.  
  65.  
  66.  
  67.  
  68. /* This function implements cliptesting for user-defined clip planes.
  69.  * The clipping of primitives to these planes is implemented in
  70.  * t_render_clip.h.
  71.  */
  72. #define USER_CLIPTEST(NAME, SZ)                    \
  73. static void NAME( GLcontext *ctx,                \
  74.           GLvector4f *clip,                \
  75.           GLubyte *clipmask,                \
  76.           GLubyte *clipormask,                \
  77.           GLubyte *clipandmask )            \
  78. {                                \
  79.    GLuint p;                            \
  80.                                 \
  81.    for (p = 0; p < ctx->Const.MaxClipPlanes; p++)        \
  82.       if (ctx->Transform.ClipPlanesEnabled & (1 << p)) {    \
  83.      GLuint nr, i;                        \
  84.      const GLfloat a = ctx->Transform._ClipUserPlane[p][0];    \
  85.      const GLfloat b = ctx->Transform._ClipUserPlane[p][1];    \
  86.      const GLfloat c = ctx->Transform._ClipUserPlane[p][2];    \
  87.      const GLfloat d = ctx->Transform._ClipUserPlane[p][3];    \
  88.          GLfloat *coord = (GLfloat *)clip->data;        \
  89.          GLuint stride = clip->stride;                \
  90.          GLuint count = clip->count;                \
  91.                                 \
  92.      for (nr = 0, i = 0 ; i < count ; i++) {        \
  93.         GLfloat dp = coord[0] * a + coord[1] * b;        \
  94.         if (SZ > 2) dp += coord[2] * c;            \
  95.         if (SZ > 3) dp += coord[3] * d; else dp += d;    \
  96.                                 \
  97.         if (dp < 0) {                    \
  98.            nr++;                        \
  99.            clipmask[i] |= CLIP_USER_BIT;            \
  100.         }                            \
  101.                                 \
  102.         STRIDE_F(coord, stride);                \
  103.      }                            \
  104.                                 \
  105.      if (nr > 0) {                        \
  106.         *clipormask |= CLIP_USER_BIT;            \
  107.         if (nr == count) {                    \
  108.            *clipandmask |= CLIP_USER_BIT;            \
  109.            return;                        \
  110.         }                            \
  111.      }                            \
  112.       }                                \
  113. }
  114.  
  115.  
  116. USER_CLIPTEST(userclip2, 2)
  117. USER_CLIPTEST(userclip3, 3)
  118. USER_CLIPTEST(userclip4, 4)
  119.  
  120. static void (*(usercliptab[5]))( GLcontext *,
  121.                  GLvector4f *, GLubyte *,
  122.                  GLubyte *, GLubyte * ) =
  123. {
  124.    0,
  125.    0,
  126.    userclip2,
  127.    userclip3,
  128.    userclip4
  129. };
  130.  
  131.  
  132.  
  133. static GLboolean run_vertex_stage( GLcontext *ctx,
  134.                    struct gl_pipeline_stage *stage )
  135. {
  136.    struct vertex_stage_data *store = (struct vertex_stage_data *)stage->privatePtr;
  137.    TNLcontext *tnl = TNL_CONTEXT(ctx);
  138.    struct vertex_buffer *VB = &tnl->vb;
  139.  
  140.    ASSERT(!ctx->VertexProgram.Enabled);
  141.  
  142.    if (stage->changed_inputs) {
  143.  
  144.       if (ctx->_NeedEyeCoords) {
  145.      /* Separate modelview transformation:
  146.       * Use combined ModelProject to avoid some depth artifacts
  147.       */
  148.      if (ctx->ModelviewMatrixStack.Top->type == MATRIX_IDENTITY)
  149.         VB->EyePtr = VB->ObjPtr;
  150.      else
  151.         VB->EyePtr = TransformRaw( &store->eye,
  152.                                        ctx->ModelviewMatrixStack.Top,
  153.                        VB->ObjPtr);
  154.  
  155.      if (ctx->ProjectionMatrixStack.Top->type == MATRIX_IDENTITY)
  156.         VB->ClipPtr = VB->EyePtr;
  157.      else
  158.         VB->ClipPtr = TransformRaw( &store->clip,
  159.                                         &ctx->_ModelProjectMatrix,
  160.                     VB->ObjPtr );
  161.       }
  162.       else {
  163.      /* Combined modelviewproject transform:
  164.       */
  165.      if (ctx->_ModelProjectMatrix.type == MATRIX_IDENTITY)
  166.         VB->ClipPtr = VB->ObjPtr;
  167.      else
  168.         VB->ClipPtr = TransformRaw( &store->clip,
  169.                                         &ctx->_ModelProjectMatrix,
  170.                     VB->ObjPtr );
  171.       }
  172.  
  173.       /* Drivers expect this to be clean to element 4...
  174.        */
  175.       if (VB->ClipPtr->size < 4) {
  176.      if (VB->ClipPtr->flags & VEC_NOT_WRITEABLE) {
  177.         ASSERT(VB->ClipPtr == VB->ObjPtr);
  178.         VB->import_data( ctx, VERT_BIT_POS, VEC_NOT_WRITEABLE );
  179.         VB->ClipPtr = VB->ObjPtr;
  180.      }
  181.      if (VB->ClipPtr->size == 2)
  182.         _mesa_vector4f_clean_elem( VB->ClipPtr, VB->Count, 2 );
  183.      _mesa_vector4f_clean_elem( VB->ClipPtr, VB->Count, 3 );
  184.       }
  185.  
  186.       /* Cliptest and perspective divide.  Clip functions must clear
  187.        * the clipmask.
  188.        */
  189.       store->ormask = 0;
  190.       store->andmask = CLIP_ALL_BITS;
  191.  
  192.       if (tnl->NeedNdcCoords) {
  193.      VB->NdcPtr =
  194.         _mesa_clip_tab[VB->ClipPtr->size]( VB->ClipPtr,
  195.                                                &store->proj,
  196.                                                store->clipmask,
  197.                                                &store->ormask,
  198.                                                &store->andmask );
  199.       }
  200.       else {
  201.      VB->NdcPtr = 0;
  202.      _mesa_clip_np_tab[VB->ClipPtr->size]( VB->ClipPtr,
  203.                                                0,
  204.                                                store->clipmask,
  205.                                                &store->ormask,
  206.                                                &store->andmask );
  207.       }
  208.  
  209.       if (store->andmask)
  210.      return GL_FALSE;
  211.  
  212.  
  213.       /* Test userclip planes.  This contributes to VB->ClipMask, so
  214.        * is essentially required to be in this stage.
  215.        */
  216.       if (ctx->Transform.ClipPlanesEnabled) {
  217.      usercliptab[VB->ClipPtr->size]( ctx,
  218.                      VB->ClipPtr,
  219.                      store->clipmask,
  220.                      &store->ormask,
  221.                      &store->andmask );
  222.  
  223.      if (store->andmask)
  224.         return GL_FALSE;
  225.       }
  226.  
  227.       VB->ClipOrMask = store->ormask;
  228.       VB->ClipMask = store->clipmask;
  229.  
  230.       if (VB->ClipPtr == VB->ObjPtr && (VB->importable_data & VERT_BIT_POS))
  231.      VB->importable_data |= VERT_BIT_CLIP;
  232.  
  233.       store->save_eyeptr = VB->EyePtr;
  234.       store->save_clipptr = VB->ClipPtr;
  235.       store->save_ndcptr = VB->NdcPtr;
  236.    }
  237.    else {
  238.       /* Replay the sideeffects.
  239.        */
  240.       VB->EyePtr = store->save_eyeptr;
  241.       VB->ClipPtr = store->save_clipptr;
  242.       VB->NdcPtr = store->save_ndcptr;
  243.       VB->ClipMask = store->clipmask;
  244.       VB->ClipOrMask = store->ormask;
  245.       if (VB->ClipPtr == VB->ObjPtr && (VB->importable_data & VERT_BIT_POS))
  246.      VB->importable_data |= VERT_BIT_CLIP;
  247.       if (store->andmask)
  248.      return GL_FALSE;
  249.    }
  250.  
  251.    return GL_TRUE;
  252. }
  253.  
  254.  
  255. static void check_vertex( GLcontext *ctx, struct gl_pipeline_stage *stage )
  256. {
  257.    stage->active = !ctx->VertexProgram.Enabled;
  258. }
  259.  
  260. static GLboolean init_vertex_stage( GLcontext *ctx,
  261.                     struct gl_pipeline_stage *stage )
  262. {
  263.    struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
  264.    struct vertex_stage_data *store;
  265.    GLuint size = VB->Size;
  266.  
  267.    stage->privatePtr = CALLOC(sizeof(*store));
  268.    store = VERTEX_STAGE_DATA(stage);
  269.    if (!store)
  270.       return GL_FALSE;
  271.  
  272.    _mesa_vector4f_alloc( &store->eye, 0, size, 32 );
  273.    _mesa_vector4f_alloc( &store->clip, 0, size, 32 );
  274.    _mesa_vector4f_alloc( &store->proj, 0, size, 32 );
  275.  
  276.    store->clipmask = (GLubyte *) ALIGN_MALLOC(sizeof(GLubyte)*size, 32 );
  277.  
  278.    if (!store->clipmask ||
  279.        !store->eye.data ||
  280.        !store->clip.data ||
  281.        !store->proj.data)
  282.       return GL_FALSE;
  283.  
  284.    /* Now run the stage.
  285.     */
  286.    stage->run = run_vertex_stage;
  287.    return stage->run( ctx, stage );
  288. }
  289.  
  290. static void dtr( struct gl_pipeline_stage *stage )
  291. {
  292.    struct vertex_stage_data *store = VERTEX_STAGE_DATA(stage);
  293.  
  294.    if (store) {
  295.       _mesa_vector4f_free( &store->eye );
  296.       _mesa_vector4f_free( &store->clip );
  297.       _mesa_vector4f_free( &store->proj );
  298.       ALIGN_FREE( store->clipmask );
  299.       FREE(store);
  300.       stage->privatePtr = NULL;
  301.       stage->run = init_vertex_stage;
  302.    }
  303. }
  304.  
  305.  
  306. const struct gl_pipeline_stage _tnl_vertex_transform_stage =
  307. {
  308.    "modelview/project/cliptest/divide",
  309.    _NEW_PROGRAM,                /* check_state: only care about vertex prog */
  310.    _MESA_NEW_NEED_EYE_COORDS |  /* run_state: when to invalidate / re-run */
  311.    _NEW_MODELVIEW|
  312.    _NEW_PROJECTION|
  313.    _NEW_PROGRAM|
  314.    _NEW_TRANSFORM,
  315.    GL_TRUE,            /* active */
  316.    VERT_BIT_POS,        /* inputs */
  317.    VERT_BIT_EYE|VERT_BIT_CLIP,        /* outputs */
  318.    0,                /* changed_inputs */
  319.    NULL,            /* private data */
  320.    dtr,                /* destructor */
  321.    check_vertex,        /* check */
  322.    init_vertex_stage        /* run -- initially set to init */
  323. };
  324.