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