tnl: implement GL_EXT_provoking_vertex
[mesa.git] / src / mesa / tnl / t_vb_rendertmp.h
index 2b5f4e93b2202a6d058902ccef6233aea4ebecab..f0da0cdf0deac90875e99382f0a2ffc248fa56e2 100644 (file)
@@ -82,7 +82,10 @@ static void TAG(render_lines)( GLcontext *ctx,
    INIT(GL_LINES);
    for (j=start+1; j<count; j+=2 ) {
       RESET_STIPPLE;
-      RENDER_LINE( ELT(j-1), ELT(j) );
+      if (ctx->Light.ProvokingVertex == GL_LAST_VERTEX_CONVENTION_EXT)
+         RENDER_LINE( ELT(j-1), ELT(j) );
+      else
+         RENDER_LINE( ELT(j), ELT(j-1) );
    }
    POSTFIX;
 }
@@ -103,9 +106,12 @@ static void TAG(render_line_strip)( GLcontext *ctx,
       RESET_STIPPLE;
    }
 
-   for (j=start+1; j<count; j++ )
-      RENDER_LINE( ELT(j-1), ELT(j) );
-
+   for (j=start+1; j<count; j++ ) {
+      if (ctx->Light.ProvokingVertex == GL_LAST_VERTEX_CONVENTION_EXT)
+         RENDER_LINE( ELT(j-1), ELT(j) );
+      else
+         RENDER_LINE( ELT(j), ELT(j-1) );
+   }
    POSTFIX;
 }
 
@@ -125,15 +131,24 @@ static void TAG(render_line_loop)( GLcontext *ctx,
    if (start+1 < count) {
       if (TEST_PRIM_BEGIN(flags)) {
         RESET_STIPPLE;
-        RENDER_LINE( ELT(start), ELT(start+1) );
+         if (ctx->Light.ProvokingVertex == GL_LAST_VERTEX_CONVENTION_EXT)
+            RENDER_LINE( ELT(start), ELT(start+1) );
+         else
+            RENDER_LINE( ELT(start+1), ELT(start) );
       }
 
       for ( i = start+2 ; i < count ; i++) {
-        RENDER_LINE( ELT(i-1), ELT(i) );
+         if (ctx->Light.ProvokingVertex == GL_LAST_VERTEX_CONVENTION_EXT)
+            RENDER_LINE( ELT(i-1), ELT(i) );
+         else
+            RENDER_LINE( ELT(i), ELT(i-1) );
       }
 
       if ( TEST_PRIM_END(flags)) {
-        RENDER_LINE( ELT(count-1), ELT(start) );
+         if (ctx->Light.ProvokingVertex == GL_LAST_VERTEX_CONVENTION_EXT)
+            RENDER_LINE( ELT(count-1), ELT(start) );
+         else
+            RENDER_LINE( ELT(count), ELT(start-1) ); /* XXX check this one */
       }
    }
 
@@ -156,11 +171,17 @@ static void TAG(render_triangles)( GLcontext *ctx,
         /* Leave the edgeflags as supplied by the user.
          */
         RESET_STIPPLE;
-        RENDER_TRI( ELT(j-2), ELT(j-1), ELT(j) );
+         if (ctx->Light.ProvokingVertex == GL_LAST_VERTEX_CONVENTION_EXT)
+            RENDER_TRI( ELT(j-2), ELT(j-1), ELT(j) );
+         else
+            RENDER_TRI( ELT(j), ELT(j-2), ELT(j-1) );
       }
    } else {
       for (j=start+2; j<count; j+=3) {
-        RENDER_TRI( ELT(j-2), ELT(j-1), ELT(j) );
+         if (ctx->Light.ProvokingVertex == GL_LAST_VERTEX_CONVENTION_EXT)
+            RENDER_TRI( ELT(j-2), ELT(j-1), ELT(j) );
+         else
+            RENDER_TRI( ELT(j-1), ELT(j), ELT(j-2) );
       }
    }
    POSTFIX;
@@ -192,14 +213,20 @@ static void TAG(render_tri_strip)( GLcontext *ctx,
         EDGEFLAG_SET( ej2, GL_TRUE );
         EDGEFLAG_SET( ej1, GL_TRUE );
         EDGEFLAG_SET( ej, GL_TRUE );
-        RENDER_TRI( ej2, ej1, ej );
+         if (ctx->Light.ProvokingVertex == GL_LAST_VERTEX_CONVENTION_EXT)
+            RENDER_TRI( ej2, ej1, ej );
+         else
+            RENDER_TRI( ej, ej2, ej1 );
         EDGEFLAG_SET( ej2, ef2 );
         EDGEFLAG_SET( ej1, ef1 );
         EDGEFLAG_SET( ej, ef );
       }
    } else {
       for (j=start+2; j<count ; j++, parity^=1) {
-        RENDER_TRI( ELT(j-2+parity), ELT(j-1-parity), ELT(j) );
+         if (ctx->Light.ProvokingVertex == GL_LAST_VERTEX_CONVENTION_EXT)
+            RENDER_TRI( ELT(j-2+parity), ELT(j-1-parity), ELT(j) );
+         else
+            RENDER_TRI( ELT(j), ELT(j-2+parity), ELT(j-1-parity) );
       }
    }
    POSTFIX;
@@ -232,14 +259,20 @@ static void TAG(render_tri_fan)( GLcontext *ctx,
         EDGEFLAG_SET( ejs, GL_TRUE );
         EDGEFLAG_SET( ej1, GL_TRUE );
         EDGEFLAG_SET( ej, GL_TRUE );
-        RENDER_TRI( ejs, ej1, ej);
+         if (ctx->Light.ProvokingVertex == GL_LAST_VERTEX_CONVENTION_EXT)
+            RENDER_TRI( ejs, ej1, ej);
+         else
+            RENDER_TRI( ej, ejs, ej1);
         EDGEFLAG_SET( ejs, efs );
         EDGEFLAG_SET( ej1, ef1 );
         EDGEFLAG_SET( ej, ef );
       }
    } else {
       for (j=start+2;j<count;j++) {
-        RENDER_TRI( ELT(start), ELT(j-1), ELT(j) );
+         if (ctx->Light.ProvokingVertex == GL_LAST_VERTEX_CONVENTION_EXT)
+            RENDER_TRI( ELT(start), ELT(j-1), ELT(j) );
+         else
+            RENDER_TRI( ELT(j), ELT(start), ELT(j-1) );
       }
    }
 
@@ -331,11 +364,19 @@ static void TAG(render_quads)( GLcontext *ctx,
         /* Use user-specified edgeflags for quads.
          */
         RESET_STIPPLE;
-        RENDER_QUAD( ELT(j-3), ELT(j-2), ELT(j-1), ELT(j) );
+         if (ctx->Light.ProvokingVertex == GL_LAST_VERTEX_CONVENTION_EXT ||
+             !ctx->Const.QuadsFollowProvokingVertexConvention)
+            RENDER_QUAD( ELT(j-3), ELT(j-2), ELT(j-1), ELT(j) );
+         else
+            RENDER_QUAD( ELT(j-2), ELT(j-1), ELT(j), ELT(j-3) );
       }
    } else {
       for (j=start+3; j<count; j+=4) {
-        RENDER_QUAD( ELT(j-3), ELT(j-2), ELT(j-1), ELT(j) );
+         if (ctx->Light.ProvokingVertex == GL_LAST_VERTEX_CONVENTION_EXT ||
+             !ctx->Const.QuadsFollowProvokingVertexConvention)
+            RENDER_QUAD( ELT(j-3), ELT(j-2), ELT(j-1), ELT(j) );
+         else
+            RENDER_QUAD( ELT(j-2), ELT(j-1), ELT(j), ELT(j-3) );
       }
    }
    POSTFIX;
@@ -367,7 +408,11 @@ static void TAG(render_quad_strip)( GLcontext *ctx,
         EDGEFLAG_SET( ELT(j-2), GL_TRUE );
         EDGEFLAG_SET( ELT(j-1), GL_TRUE );
         EDGEFLAG_SET( ELT(j), GL_TRUE );
-        RENDER_QUAD( ELT(j-1), ELT(j-3), ELT(j-2), ELT(j) );
+         if (ctx->Light.ProvokingVertex == GL_LAST_VERTEX_CONVENTION_EXT ||
+             !ctx->Const.QuadsFollowProvokingVertexConvention)
+            RENDER_QUAD( ELT(j-1), ELT(j-3), ELT(j-2), ELT(j) );
+         else
+            RENDER_QUAD( ELT(j-2), ELT(j), ELT(j-1), ELT(j-3) );
         EDGEFLAG_SET( ELT(j-3), ef3 );
         EDGEFLAG_SET( ELT(j-2), ef2 );
         EDGEFLAG_SET( ELT(j-1), ef1 );
@@ -375,7 +420,11 @@ static void TAG(render_quad_strip)( GLcontext *ctx,
       }
    } else {
       for (j=start+3;j<count;j+=2) {
-        RENDER_QUAD( ELT(j-1), ELT(j-3), ELT(j-2), ELT(j) );
+         if (ctx->Light.ProvokingVertex == GL_LAST_VERTEX_CONVENTION_EXT ||
+             !ctx->Const.QuadsFollowProvokingVertexConvention)
+            RENDER_QUAD( ELT(j-1), ELT(j-3), ELT(j-2), ELT(j) );
+         else
+            RENDER_QUAD( ELT(j-2), ELT(j), ELT(j-1), ELT(j-3) );
       }
    }
    POSTFIX;