Subversion Repositories Kolibri OS

Rev

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

  1. /*
  2.  * Mesa 3-D graphics library
  3.  * Version:  6.5
  4.  *
  5.  * Copyright (C) 1999-2005  Brian Paul   All Rights Reserved.
  6.  *
  7.  * Permission is hereby granted, free of charge, to any person obtaining a
  8.  * copy of this software and associated documentation files (the "Software"),
  9.  * to deal in the Software without restriction, including without limitation
  10.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  11.  * and/or sell copies of the Software, and to permit persons to whom the
  12.  * Software is furnished to do so, subject to the following conditions:
  13.  *
  14.  * The above copyright notice and this permission notice shall be included
  15.  * in all copies or substantial portions of the Software.
  16.  *
  17.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  18.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  20.  * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
  21.  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  22.  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  23.  *
  24.  * Authors:
  25.  *    Keith Whitwell <keith@tungstengraphics.com>
  26.  */
  27.  
  28.  
  29. #ifndef POSTFIX
  30. #define POSTFIX
  31. #endif
  32.  
  33. #ifndef INIT
  34. #define INIT(x)
  35. #endif
  36.  
  37. #ifndef NEED_EDGEFLAG_SETUP
  38. #define NEED_EDGEFLAG_SETUP 0
  39. #define EDGEFLAG_GET(a) 0
  40. #define EDGEFLAG_SET(a,b) (void)b
  41. #endif
  42.  
  43. #ifndef RESET_STIPPLE
  44. #define RESET_STIPPLE
  45. #endif
  46.  
  47. #ifndef TEST_PRIM_END
  48. #define TEST_PRIM_END(prim) (flags & PRIM_END)
  49. #define TEST_PRIM_BEGIN(prim) (flags & PRIM_BEGIN)
  50. #endif
  51.  
  52. #ifndef ELT
  53. #define ELT(x) x
  54. #endif
  55.  
  56. #ifndef RENDER_TAB_QUALIFIER
  57. #define RENDER_TAB_QUALIFIER static
  58. #endif
  59.  
  60. static void TAG(render_points)( struct gl_context *ctx,
  61.                                 GLuint start,
  62.                                 GLuint count,
  63.                                 GLuint flags )
  64. {
  65.    LOCAL_VARS;
  66.    (void) flags;
  67.  
  68.    INIT(GL_POINTS);
  69.    RENDER_POINTS( start, count );
  70.    POSTFIX;
  71. }
  72.  
  73. static void TAG(render_lines)( struct gl_context *ctx,
  74.                                GLuint start,
  75.                                GLuint count,
  76.                                GLuint flags )
  77. {
  78.    GLuint j;
  79.    LOCAL_VARS;
  80.    (void) flags;
  81.  
  82.    INIT(GL_LINES);
  83.    for (j=start+1; j<count; j+=2 ) {
  84.       RESET_STIPPLE;
  85.       if (ctx->Light.ProvokingVertex == GL_LAST_VERTEX_CONVENTION_EXT)
  86.          RENDER_LINE( ELT(j-1), ELT(j) );
  87.       else
  88.          RENDER_LINE( ELT(j), ELT(j-1) );
  89.    }
  90.    POSTFIX;
  91. }
  92.  
  93.  
  94. static void TAG(render_line_strip)( struct gl_context *ctx,
  95.                                     GLuint start,
  96.                                     GLuint count,
  97.                                     GLuint flags )
  98. {
  99.    GLuint j;
  100.    LOCAL_VARS;
  101.    (void) flags;
  102.  
  103.    INIT(GL_LINE_STRIP);
  104.  
  105.    if (TEST_PRIM_BEGIN(flags)) {
  106.       RESET_STIPPLE;
  107.    }
  108.  
  109.    for (j=start+1; j<count; j++ ) {
  110.       if (ctx->Light.ProvokingVertex == GL_LAST_VERTEX_CONVENTION_EXT)
  111.          RENDER_LINE( ELT(j-1), ELT(j) );
  112.       else
  113.          RENDER_LINE( ELT(j), ELT(j-1) );
  114.    }
  115.    POSTFIX;
  116. }
  117.  
  118.  
  119. static void TAG(render_line_loop)( struct gl_context *ctx,
  120.                                    GLuint start,
  121.                                    GLuint count,
  122.                                    GLuint flags )
  123. {
  124.    GLuint i;
  125.    LOCAL_VARS;
  126.  
  127.    (void) flags;
  128.  
  129.    INIT(GL_LINE_LOOP);
  130.  
  131.    if (start+1 < count) {
  132.       if (TEST_PRIM_BEGIN(flags)) {
  133.          RESET_STIPPLE;
  134.          if (ctx->Light.ProvokingVertex == GL_LAST_VERTEX_CONVENTION_EXT)
  135.             RENDER_LINE( ELT(start), ELT(start+1) );
  136.          else
  137.             RENDER_LINE( ELT(start+1), ELT(start) );
  138.       }
  139.  
  140.       for ( i = start+2 ; i < count ; i++) {
  141.          if (ctx->Light.ProvokingVertex == GL_LAST_VERTEX_CONVENTION_EXT)
  142.             RENDER_LINE( ELT(i-1), ELT(i) );
  143.          else
  144.             RENDER_LINE( ELT(i), ELT(i-1) );
  145.       }
  146.  
  147.       if ( TEST_PRIM_END(flags)) {
  148.          if (ctx->Light.ProvokingVertex == GL_LAST_VERTEX_CONVENTION_EXT)
  149.             RENDER_LINE( ELT(count-1), ELT(start) );
  150.          else
  151.             RENDER_LINE( ELT(start), ELT(count-1) );
  152.       }
  153.    }
  154.  
  155.    POSTFIX;
  156. }
  157.  
  158.  
  159. static void TAG(render_triangles)( struct gl_context *ctx,
  160.                                    GLuint start,
  161.                                    GLuint count,
  162.                                    GLuint flags )
  163. {
  164.    GLuint j;
  165.    LOCAL_VARS;
  166.    (void) flags;
  167.  
  168.    INIT(GL_TRIANGLES);
  169.    if (NEED_EDGEFLAG_SETUP) {
  170.       for (j=start+2; j<count; j+=3) {
  171.          /* Leave the edgeflags as supplied by the user.
  172.           */
  173.          RESET_STIPPLE;
  174.          if (ctx->Light.ProvokingVertex == GL_LAST_VERTEX_CONVENTION_EXT)
  175.             RENDER_TRI( ELT(j-2), ELT(j-1), ELT(j) );
  176.          else
  177.             RENDER_TRI( ELT(j-1), ELT(j), ELT(j-2) );
  178.       }
  179.    } else {
  180.       for (j=start+2; j<count; j+=3) {
  181.          if (ctx->Light.ProvokingVertex == GL_LAST_VERTEX_CONVENTION_EXT)
  182.             RENDER_TRI( ELT(j-2), ELT(j-1), ELT(j) );
  183.          else
  184.             RENDER_TRI( ELT(j-1), ELT(j), ELT(j-2) );
  185.       }
  186.    }
  187.    POSTFIX;
  188. }
  189.  
  190.  
  191.  
  192. static void TAG(render_tri_strip)( struct gl_context *ctx,
  193.                                    GLuint start,
  194.                                    GLuint count,
  195.                                    GLuint flags )
  196. {
  197.    GLuint j;
  198.    GLuint parity = 0;
  199.    LOCAL_VARS;
  200.  
  201.    INIT(GL_TRIANGLE_STRIP);
  202.    if (NEED_EDGEFLAG_SETUP) {
  203.       for (j=start+2;j<count;j++,parity^=1) {
  204.          GLuint ej2, ej1, ej;
  205.          GLboolean ef2, ef1, ef;
  206.          if (ctx->Light.ProvokingVertex == GL_LAST_VERTEX_CONVENTION_EXT) {
  207.             ej2 = ELT(j-2+parity);
  208.             ej1 = ELT(j-1-parity);
  209.             ej = ELT(j);
  210.          }
  211.          else {
  212.             ej2 = ELT(j-1+parity);
  213.             ej1 = ELT(j-parity);
  214.             ej = ELT(j-2);
  215.          }
  216.          ef2 = EDGEFLAG_GET( ej2 );
  217.          ef1 = EDGEFLAG_GET( ej1 );
  218.          ef = EDGEFLAG_GET( ej );
  219.          if (TEST_PRIM_BEGIN(flags)) {
  220.             RESET_STIPPLE;
  221.          }
  222.          EDGEFLAG_SET( ej2, GL_TRUE );
  223.          EDGEFLAG_SET( ej1, GL_TRUE );
  224.          EDGEFLAG_SET( ej, GL_TRUE );
  225.          RENDER_TRI( ej2, ej1, ej );
  226.          EDGEFLAG_SET( ej2, ef2 );
  227.          EDGEFLAG_SET( ej1, ef1 );
  228.          EDGEFLAG_SET( ej, ef );
  229.       }
  230.    } else {
  231.       for (j=start+2; j<count ; j++, parity^=1) {
  232.          if (ctx->Light.ProvokingVertex == GL_LAST_VERTEX_CONVENTION_EXT)
  233.             RENDER_TRI( ELT(j-2+parity), ELT(j-1-parity), ELT(j) );
  234.          else
  235.             RENDER_TRI( ELT(j-1+parity), ELT(j-parity), ELT(j-2) );
  236.       }
  237.    }
  238.    POSTFIX;
  239. }
  240.  
  241.  
  242. static void TAG(render_tri_fan)( struct gl_context *ctx,
  243.                                  GLuint start,
  244.                                  GLuint count,
  245.                                  GLuint flags )
  246. {
  247.    GLuint j;
  248.    LOCAL_VARS;
  249.    (void) flags;
  250.  
  251.    INIT(GL_TRIANGLE_FAN);
  252.    if (NEED_EDGEFLAG_SETUP) {
  253.       for (j=start+2;j<count;j++) {
  254.          /* For trifans, all edges are boundary.
  255.           */
  256.          GLuint ejs = ELT(start);
  257.          GLuint ej1 = ELT(j-1);
  258.          GLuint ej = ELT(j);
  259.          GLboolean efs = EDGEFLAG_GET( ejs );
  260.          GLboolean ef1 = EDGEFLAG_GET( ej1 );
  261.          GLboolean ef = EDGEFLAG_GET( ej );
  262.          if (TEST_PRIM_BEGIN(flags)) {
  263.             RESET_STIPPLE;
  264.          }
  265.          EDGEFLAG_SET( ejs, GL_TRUE );
  266.          EDGEFLAG_SET( ej1, GL_TRUE );
  267.          EDGEFLAG_SET( ej, GL_TRUE );
  268.          if (ctx->Light.ProvokingVertex == GL_LAST_VERTEX_CONVENTION_EXT)
  269.             RENDER_TRI( ejs, ej1, ej);
  270.          else
  271.             RENDER_TRI( ej, ejs, ej1);
  272.          EDGEFLAG_SET( ejs, efs );
  273.          EDGEFLAG_SET( ej1, ef1 );
  274.          EDGEFLAG_SET( ej, ef );
  275.       }
  276.    } else {
  277.       for (j=start+2;j<count;j++) {
  278.          if (ctx->Light.ProvokingVertex == GL_LAST_VERTEX_CONVENTION_EXT)
  279.             RENDER_TRI( ELT(start), ELT(j-1), ELT(j) );
  280.          else
  281.             RENDER_TRI( ELT(j), ELT(start), ELT(j-1) );
  282.       }
  283.    }
  284.  
  285.    POSTFIX;
  286. }
  287.  
  288.  
  289. static void TAG(render_poly)( struct gl_context *ctx,
  290.                               GLuint start,
  291.                               GLuint count,
  292.                               GLuint flags )
  293. {
  294.    GLuint j = start+2;
  295.    LOCAL_VARS;
  296.    (void) flags;
  297.  
  298.    INIT(GL_POLYGON);
  299.    if (NEED_EDGEFLAG_SETUP) {
  300.       GLboolean efstart = EDGEFLAG_GET( ELT(start) );
  301.       GLboolean efcount = EDGEFLAG_GET( ELT(count-1) );
  302.  
  303.       /* If the primitive does not begin here, the first edge
  304.        * is non-boundary.
  305.        */
  306.       if (!TEST_PRIM_BEGIN(flags))
  307.          EDGEFLAG_SET( ELT(start), GL_FALSE );
  308.       else {
  309.          RESET_STIPPLE;
  310.       }
  311.  
  312.       /* If the primitive does not end here, the final edge is
  313.        * non-boundary.
  314.        */
  315.       if (!TEST_PRIM_END(flags))
  316.          EDGEFLAG_SET( ELT(count-1), GL_FALSE );
  317.  
  318.       /* Draw the first triangles (possibly zero)
  319.        */
  320.       if (j+1<count) {
  321.          GLboolean ef = EDGEFLAG_GET( ELT(j) );
  322.          EDGEFLAG_SET( ELT(j), GL_FALSE );
  323.          RENDER_TRI( ELT(j-1), ELT(j), ELT(start) );
  324.          EDGEFLAG_SET( ELT(j), ef );
  325.          j++;
  326.  
  327.          /* Don't render the first edge again:
  328.           */
  329.          EDGEFLAG_SET( ELT(start), GL_FALSE );
  330.  
  331.          for (;j+1<count;j++) {
  332.             GLboolean efj = EDGEFLAG_GET( ELT(j) );
  333.             EDGEFLAG_SET( ELT(j), GL_FALSE );
  334.             RENDER_TRI( ELT(j-1), ELT(j), ELT(start) );
  335.             EDGEFLAG_SET( ELT(j), efj );
  336.          }
  337.       }
  338.  
  339.       /* Draw the last or only triangle
  340.        */
  341.       if (j < count)
  342.          RENDER_TRI( ELT(j-1), ELT(j), ELT(start) );
  343.  
  344.       /* Restore the first and last edgeflags:
  345.        */
  346.       EDGEFLAG_SET( ELT(count-1), efcount );
  347.       EDGEFLAG_SET( ELT(start), efstart );
  348.  
  349.    }
  350.    else {
  351.       for (j=start+2;j<count;j++) {
  352.          RENDER_TRI( ELT(j-1), ELT(j), ELT(start) );
  353.       }
  354.    }
  355.    POSTFIX;
  356. }
  357.  
  358. static void TAG(render_quads)( struct gl_context *ctx,
  359.                                GLuint start,
  360.                                GLuint count,
  361.                                GLuint flags )
  362. {
  363.    GLuint j;
  364.    LOCAL_VARS;
  365.    (void) flags;
  366.  
  367.    INIT(GL_QUADS);
  368.    if (NEED_EDGEFLAG_SETUP) {
  369.       for (j=start+3; j<count; j+=4) {
  370.          /* Use user-specified edgeflags for quads.
  371.           */
  372.          RESET_STIPPLE;
  373.          if (ctx->Light.ProvokingVertex == GL_LAST_VERTEX_CONVENTION_EXT ||
  374.              !ctx->Const.QuadsFollowProvokingVertexConvention)
  375.             RENDER_QUAD( ELT(j-3), ELT(j-2), ELT(j-1), ELT(j) );
  376.          else
  377.             RENDER_QUAD( ELT(j-2), ELT(j-1), ELT(j), ELT(j-3) );
  378.       }
  379.    } else {
  380.       for (j=start+3; j<count; j+=4) {
  381.          if (ctx->Light.ProvokingVertex == GL_LAST_VERTEX_CONVENTION_EXT ||
  382.              !ctx->Const.QuadsFollowProvokingVertexConvention)
  383.             RENDER_QUAD( ELT(j-3), ELT(j-2), ELT(j-1), ELT(j) );
  384.          else
  385.             RENDER_QUAD( ELT(j-2), ELT(j-1), ELT(j), ELT(j-3) );
  386.       }
  387.    }
  388.    POSTFIX;
  389. }
  390.  
  391. static void TAG(render_quad_strip)( struct gl_context *ctx,
  392.                                     GLuint start,
  393.                                     GLuint count,
  394.                                     GLuint flags )
  395. {
  396.    GLuint j;
  397.    LOCAL_VARS;
  398.    (void) flags;
  399.  
  400.    INIT(GL_QUAD_STRIP);
  401.    if (NEED_EDGEFLAG_SETUP) {
  402.       for (j=start+3;j<count;j+=2) {
  403.          /* All edges are boundary.  Set edgeflags to 1, draw the
  404.           * quad, and restore them to the original values.
  405.           */
  406.          GLboolean ef3 = EDGEFLAG_GET( ELT(j-3) );
  407.          GLboolean ef2 = EDGEFLAG_GET( ELT(j-2) );
  408.          GLboolean ef1 = EDGEFLAG_GET( ELT(j-1) );
  409.          GLboolean ef = EDGEFLAG_GET( ELT(j) );
  410.          if (TEST_PRIM_BEGIN(flags)) {
  411.             RESET_STIPPLE;
  412.          }
  413.          EDGEFLAG_SET( ELT(j-3), GL_TRUE );
  414.          EDGEFLAG_SET( ELT(j-2), GL_TRUE );
  415.          EDGEFLAG_SET( ELT(j-1), GL_TRUE );
  416.          EDGEFLAG_SET( ELT(j), GL_TRUE );
  417.          if (ctx->Light.ProvokingVertex == GL_LAST_VERTEX_CONVENTION_EXT ||
  418.              !ctx->Const.QuadsFollowProvokingVertexConvention)
  419.             RENDER_QUAD( ELT(j-1), ELT(j-3), ELT(j-2), ELT(j) );
  420.          else
  421.             RENDER_QUAD( ELT(j-2), ELT(j), ELT(j-1), ELT(j-3) );
  422.          EDGEFLAG_SET( ELT(j-3), ef3 );
  423.          EDGEFLAG_SET( ELT(j-2), ef2 );
  424.          EDGEFLAG_SET( ELT(j-1), ef1 );
  425.          EDGEFLAG_SET( ELT(j), ef );
  426.       }
  427.    } else {
  428.       for (j=start+3;j<count;j+=2) {
  429.          if (ctx->Light.ProvokingVertex == GL_LAST_VERTEX_CONVENTION_EXT ||
  430.              !ctx->Const.QuadsFollowProvokingVertexConvention)
  431.             RENDER_QUAD( ELT(j-1), ELT(j-3), ELT(j-2), ELT(j) );
  432.          else
  433.             RENDER_QUAD( ELT(j-2), ELT(j), ELT(j-1), ELT(j-3) );
  434.       }
  435.    }
  436.    POSTFIX;
  437. }
  438.  
  439. static void TAG(render_noop)( struct gl_context *ctx,
  440.                               GLuint start,
  441.                               GLuint count,
  442.                               GLuint flags )
  443. {
  444.    (void)(ctx && start && count && flags);
  445. }
  446.  
  447. RENDER_TAB_QUALIFIER void (*TAG(render_tab)[GL_POLYGON+2])(struct gl_context *,
  448.                                                            GLuint,
  449.                                                            GLuint,
  450.                                                            GLuint) =
  451. {
  452.    TAG(render_points),
  453.    TAG(render_lines),
  454.    TAG(render_line_loop),
  455.    TAG(render_line_strip),
  456.    TAG(render_triangles),
  457.    TAG(render_tri_strip),
  458.    TAG(render_tri_fan),
  459.    TAG(render_quads),
  460.    TAG(render_quad_strip),
  461.    TAG(render_poly),
  462.    TAG(render_noop),
  463. };
  464.  
  465.  
  466.  
  467. #ifndef PRESERVE_VB_DEFS
  468. #undef RENDER_TRI
  469. #undef RENDER_QUAD
  470. #undef RENDER_LINE
  471. #undef RENDER_POINTS
  472. #undef LOCAL_VARS
  473. #undef INIT
  474. #undef POSTFIX
  475. #undef RESET_STIPPLE
  476. #undef DBG
  477. #undef ELT
  478. #undef RENDER_TAB_QUALIFIER
  479. #endif
  480.  
  481. #ifndef PRESERVE_TAG
  482. #undef TAG
  483. #endif
  484.  
  485. #undef PRESERVE_VB_DEFS
  486. #undef PRESERVE_TAG
  487.