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

  1. /* $Id: t_vb_rendertmp.h,v 1.10 2002/10/29 20:29:04 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. #ifndef POSTFIX
  32. #define POSTFIX
  33. #endif
  34.  
  35. #ifndef INIT
  36. #define INIT(x)
  37. #endif
  38.  
  39. #ifndef NEED_EDGEFLAG_SETUP
  40. #define NEED_EDGEFLAG_SETUP 0
  41. #define EDGEFLAG_GET(a) 0
  42. #define EDGEFLAG_SET(a,b) (void)b
  43. #endif
  44.  
  45. #ifndef RESET_STIPPLE
  46. #define RESET_STIPPLE
  47. #endif
  48.  
  49. #ifndef RESET_OCCLUSION
  50. #define RESET_OCCLUSION
  51. #endif
  52.  
  53. #ifndef TEST_PRIM_END
  54. #define TEST_PRIM_END(flags) (flags & PRIM_END)
  55. #define TEST_PRIM_BEGIN(flags) (flags & PRIM_BEGIN)
  56. #define TEST_PRIM_PARITY(flags) (flags & PRIM_PARITY)
  57. #endif
  58.  
  59. #ifndef ELT
  60. #define ELT(x) x
  61. #endif
  62.  
  63. #ifndef RENDER_TAB_QUALIFIER
  64. #define RENDER_TAB_QUALIFIER static
  65. #endif
  66.  
  67. static void TAG(render_points)( GLcontext *ctx,
  68.                 GLuint start,
  69.                 GLuint count,
  70.                 GLuint flags )
  71. {
  72.    LOCAL_VARS;
  73.    (void) flags;
  74.  
  75.    RESET_OCCLUSION;
  76.    INIT(GL_POINTS);
  77.    RENDER_POINTS( start, count );
  78.    POSTFIX;
  79. }
  80.  
  81. static void TAG(render_lines)( GLcontext *ctx,
  82.                    GLuint start,
  83.                    GLuint count,
  84.                    GLuint flags )
  85. {
  86.    GLuint j;
  87.    LOCAL_VARS;
  88.    (void) flags;
  89.  
  90.    RESET_OCCLUSION;
  91.    INIT(GL_LINES);
  92.    for (j=start+1; j<count; j+=2 ) {
  93.       RESET_STIPPLE;
  94.       RENDER_LINE( ELT(j-1), ELT(j) );
  95.    }
  96.    POSTFIX;
  97. }
  98.  
  99.  
  100. static void TAG(render_line_strip)( GLcontext *ctx,
  101.                     GLuint start,
  102.                     GLuint count,
  103.                     GLuint flags )
  104. {
  105.    GLuint j;
  106.    LOCAL_VARS;
  107.    (void) flags;
  108.  
  109.    RESET_OCCLUSION;
  110.    INIT(GL_LINE_STRIP);
  111.  
  112.    if (TEST_PRIM_BEGIN(flags)) {
  113.       RESET_STIPPLE;
  114.    }
  115.  
  116.    for (j=start+1; j<count; j++ )
  117.       RENDER_LINE( ELT(j-1), ELT(j) );
  118.  
  119.    POSTFIX;
  120. }
  121.  
  122.  
  123. static void TAG(render_line_loop)( GLcontext *ctx,
  124.                    GLuint start,
  125.                    GLuint count,
  126.                    GLuint flags )
  127. {
  128.    GLuint i;
  129.    LOCAL_VARS;
  130.  
  131.    (void) flags;
  132.  
  133.    RESET_OCCLUSION;
  134.    INIT(GL_LINE_LOOP);
  135.  
  136.    if (start+1 < count) {
  137.       if (TEST_PRIM_BEGIN(flags)) {
  138.      RESET_STIPPLE;
  139.      RENDER_LINE( ELT(start), ELT(start+1) );
  140.       }
  141.  
  142.       for ( i = start+2 ; i < count ; i++) {
  143.      RENDER_LINE( ELT(i-1), ELT(i) );
  144.       }
  145.  
  146.       if ( TEST_PRIM_END(flags)) {
  147.      RENDER_LINE( ELT(count-1), ELT(start) );
  148.       }
  149.    }
  150.  
  151.    POSTFIX;
  152. }
  153.  
  154.  
  155. static void TAG(render_triangles)( GLcontext *ctx,
  156.                    GLuint start,
  157.                    GLuint count,
  158.                    GLuint flags )
  159. {
  160.    GLuint j;
  161.    LOCAL_VARS;
  162.    (void) flags;
  163.  
  164.    INIT(GL_TRIANGLES);
  165.    if (NEED_EDGEFLAG_SETUP) {
  166.       for (j=start+2; j<count; j+=3) {
  167.      /* Leave the edgeflags as supplied by the user.
  168.       */
  169.      RESET_STIPPLE;
  170.      RENDER_TRI( ELT(j-2), ELT(j-1), ELT(j) );
  171.       }
  172.    } else {
  173.       for (j=start+2; j<count; j+=3) {
  174.      RENDER_TRI( ELT(j-2), ELT(j-1), ELT(j) );
  175.       }
  176.    }
  177.    POSTFIX;
  178. }
  179.  
  180.  
  181.  
  182. static void TAG(render_tri_strip)( GLcontext *ctx,
  183.                    GLuint start,
  184.                    GLuint count,
  185.                    GLuint flags )
  186. {
  187.    GLuint j;
  188.    GLuint parity = 0;
  189.    LOCAL_VARS;
  190.  
  191.    if (TEST_PRIM_PARITY(flags))
  192.       parity = 1;
  193.  
  194.    INIT(GL_TRIANGLE_STRIP);
  195.    if (NEED_EDGEFLAG_SETUP) {
  196.       for (j=start+2;j<count;j++,parity^=1) {
  197.      GLuint ej2 = ELT(j-2+parity);
  198.      GLuint ej1 = ELT(j-1-parity);
  199.      GLuint ej = ELT(j);
  200.      GLboolean ef2 = EDGEFLAG_GET( ej2 );
  201.      GLboolean ef1 = EDGEFLAG_GET( ej1 );
  202.      GLboolean ef = EDGEFLAG_GET( ej );
  203.      if (TEST_PRIM_BEGIN(flags)) {
  204.         RESET_STIPPLE;
  205.      }
  206.      EDGEFLAG_SET( ej2, GL_TRUE );
  207.      EDGEFLAG_SET( ej1, GL_TRUE );
  208.      EDGEFLAG_SET( ej, GL_TRUE );
  209.      RENDER_TRI( ej2, ej1, ej );
  210.      EDGEFLAG_SET( ej2, ef2 );
  211.      EDGEFLAG_SET( ej1, ef1 );
  212.      EDGEFLAG_SET( ej, ef );
  213.       }
  214.    } else {
  215.       for (j=start+2; j<count ; j++, parity^=1) {
  216.      RENDER_TRI( ELT(j-2+parity), ELT(j-1-parity), ELT(j) );
  217.       }
  218.    }
  219.    POSTFIX;
  220. }
  221.  
  222.  
  223. static void TAG(render_tri_fan)( GLcontext *ctx,
  224.                  GLuint start,
  225.                  GLuint count,
  226.                  GLuint flags )
  227. {
  228.    GLuint j;
  229.    LOCAL_VARS;
  230.    (void) flags;
  231.  
  232.    INIT(GL_TRIANGLE_FAN);
  233.    if (NEED_EDGEFLAG_SETUP) {
  234.       for (j=start+2;j<count;j++) {
  235.      /* For trifans, all edges are boundary.
  236.       */
  237.      GLuint ejs = ELT(start);
  238.      GLuint ej1 = ELT(j-1);
  239.      GLuint ej = ELT(j);
  240.      GLboolean efs = EDGEFLAG_GET( ejs );
  241.      GLboolean ef1 = EDGEFLAG_GET( ej1 );
  242.      GLboolean ef = EDGEFLAG_GET( ej );
  243.      if (TEST_PRIM_BEGIN(flags)) {
  244.         RESET_STIPPLE;
  245.      }
  246.      EDGEFLAG_SET( ejs, GL_TRUE );
  247.      EDGEFLAG_SET( ej1, GL_TRUE );
  248.      EDGEFLAG_SET( ej, GL_TRUE );
  249.      RENDER_TRI( ejs, ej1, ej);
  250.      EDGEFLAG_SET( ejs, efs );
  251.      EDGEFLAG_SET( ej1, ef1 );
  252.      EDGEFLAG_SET( ej, ef );
  253.       }
  254.    } else {
  255.       for (j=start+2;j<count;j++) {
  256.      RENDER_TRI( ELT(start), ELT(j-1), ELT(j) );
  257.       }
  258.    }
  259.  
  260.    POSTFIX;
  261. }
  262.  
  263.  
  264. static void TAG(render_poly)( GLcontext *ctx,
  265.                   GLuint start,
  266.                   GLuint count,
  267.                   GLuint flags )
  268. {
  269.    GLuint j = start+2;
  270.    LOCAL_VARS;
  271.    (void) flags;
  272.  
  273.    INIT(GL_POLYGON);
  274.    if (NEED_EDGEFLAG_SETUP) {
  275.       GLboolean efstart = EDGEFLAG_GET( ELT(start) );
  276.       GLboolean efcount = EDGEFLAG_GET( ELT(count-1) );
  277.  
  278.       /* If the primitive does not begin here, the first edge
  279.        * is non-boundary.
  280.        */
  281.       if (!TEST_PRIM_BEGIN(flags))
  282.      EDGEFLAG_SET( ELT(start), GL_FALSE );
  283.       else {
  284.      RESET_STIPPLE;
  285.       }
  286.  
  287.       /* If the primitive does not end here, the final edge is
  288.        * non-boundary.
  289.        */
  290.       if (!TEST_PRIM_END(flags))
  291.      EDGEFLAG_SET( ELT(count-1), GL_FALSE );
  292.  
  293.       /* Draw the first triangles (possibly zero)
  294.        */
  295.       if (j+1<count) {
  296.      GLboolean ef = EDGEFLAG_GET( ELT(j) );
  297.      EDGEFLAG_SET( ELT(j), GL_FALSE );
  298.      RENDER_TRI( ELT(j-1), ELT(j), ELT(start) );
  299.      EDGEFLAG_SET( ELT(j), ef );
  300.      j++;
  301.  
  302.      /* Don't render the first edge again:
  303.       */
  304.      EDGEFLAG_SET( ELT(start), GL_FALSE );
  305.  
  306.      for (;j+1<count;j++) {
  307.         GLboolean efj = EDGEFLAG_GET( ELT(j) );
  308.         EDGEFLAG_SET( ELT(j), GL_FALSE );
  309.         RENDER_TRI( ELT(j-1), ELT(j), ELT(start) );
  310.         EDGEFLAG_SET( ELT(j), efj );
  311.      }
  312.       }
  313.  
  314.       /* Draw the last or only triangle
  315.        */
  316.       if (j < count)
  317.      RENDER_TRI( ELT(j-1), ELT(j), ELT(start) );
  318.  
  319.       /* Restore the first and last edgeflags:
  320.        */
  321.       EDGEFLAG_SET( ELT(count-1), efcount );
  322.       EDGEFLAG_SET( ELT(start), efstart );
  323.  
  324.    }
  325.    else {
  326.       for (j=start+2;j<count;j++) {
  327.      RENDER_TRI( ELT(j-1), ELT(j), ELT(start) );
  328.       }
  329.    }
  330.    POSTFIX;
  331. }
  332.  
  333. static void TAG(render_quads)( GLcontext *ctx,
  334.                    GLuint start,
  335.                    GLuint count,
  336.                    GLuint flags )
  337. {
  338.    GLuint j;
  339.    LOCAL_VARS;
  340.    (void) flags;
  341.  
  342.    INIT(GL_QUADS);
  343.    if (NEED_EDGEFLAG_SETUP) {
  344.       for (j=start+3; j<count; j+=4) {
  345.      /* Use user-specified edgeflags for quads.
  346.       */
  347.      RESET_STIPPLE;
  348.      RENDER_QUAD( ELT(j-3), ELT(j-2), ELT(j-1), ELT(j) );
  349.       }
  350.    } else {
  351.       for (j=start+3; j<count; j+=4) {
  352.      RENDER_QUAD( ELT(j-3), ELT(j-2), ELT(j-1), ELT(j) );
  353.       }
  354.    }
  355.    POSTFIX;
  356. }
  357.  
  358. static void TAG(render_quad_strip)( GLcontext *ctx,
  359.                     GLuint start,
  360.                     GLuint count,
  361.                     GLuint flags )
  362. {
  363.    GLuint j;
  364.    LOCAL_VARS;
  365.    (void) flags;
  366.  
  367.    INIT(GL_QUAD_STRIP);
  368.    if (NEED_EDGEFLAG_SETUP) {
  369.       for (j=start+3;j<count;j+=2) {
  370.      /* All edges are boundary.  Set edgeflags to 1, draw the
  371.       * quad, and restore them to the original values.
  372.       */
  373.      GLboolean ef3 = EDGEFLAG_GET( ELT(j-3) );
  374.      GLboolean ef2 = EDGEFLAG_GET( ELT(j-2) );
  375.      GLboolean ef1 = EDGEFLAG_GET( ELT(j-1) );
  376.      GLboolean ef = EDGEFLAG_GET( ELT(j) );
  377.      if (TEST_PRIM_BEGIN(flags)) {
  378.         RESET_STIPPLE;
  379.      }
  380.      EDGEFLAG_SET( ELT(j-3), GL_TRUE );
  381.      EDGEFLAG_SET( ELT(j-2), GL_TRUE );
  382.      EDGEFLAG_SET( ELT(j-1), GL_TRUE );
  383.      EDGEFLAG_SET( ELT(j), GL_TRUE );
  384.      RENDER_QUAD( ELT(j-1), ELT(j-3), ELT(j-2), ELT(j) );
  385.      EDGEFLAG_SET( ELT(j-3), ef3 );
  386.      EDGEFLAG_SET( ELT(j-2), ef2 );
  387.      EDGEFLAG_SET( ELT(j-1), ef1 );
  388.      EDGEFLAG_SET( ELT(j), ef );
  389.       }
  390.    } else {
  391.       for (j=start+3;j<count;j+=2) {
  392.      RENDER_QUAD( ELT(j-1), ELT(j-3), ELT(j-2), ELT(j) );
  393.       }
  394.    }
  395.    POSTFIX;
  396. }
  397.  
  398. static void TAG(render_noop)( GLcontext *ctx,
  399.                   GLuint start,
  400.                   GLuint count,
  401.                   GLuint flags )
  402. {
  403.    (void)(ctx && start && count && flags);
  404. }
  405.  
  406. RENDER_TAB_QUALIFIER void (*TAG(render_tab)[GL_POLYGON+2])(GLcontext *,
  407.                                GLuint,
  408.                                GLuint,
  409.                                GLuint) =
  410. {
  411.    TAG(render_points),
  412.    TAG(render_lines),
  413.    TAG(render_line_loop),
  414.    TAG(render_line_strip),
  415.    TAG(render_triangles),
  416.    TAG(render_tri_strip),
  417.    TAG(render_tri_fan),
  418.    TAG(render_quads),
  419.    TAG(render_quad_strip),
  420.    TAG(render_poly),
  421.    TAG(render_noop),
  422. };
  423.  
  424.  
  425.  
  426. #ifndef PRESERVE_VB_DEFS
  427. #undef RENDER_TRI
  428. #undef RENDER_QUAD
  429. #undef RENDER_LINE
  430. #undef RENDER_POINTS
  431. #undef LOCAL_VARS
  432. #undef INIT
  433. #undef POSTFIX
  434. #undef RESET_STIPPLE
  435. #undef DBG
  436. #undef ELT
  437. #undef RENDER_TAB_QUALIFIER
  438. #endif
  439.  
  440. #ifndef PRESERVE_TAG
  441. #undef TAG
  442. #endif
  443.  
  444. #undef PRESERVE_VB_DEFS
  445. #undef PRESERVE_TAG
  446.