-
/*
* Mesa 3-D graphics library
- * Version: 3.5
*
- * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
+ * Copyright (C) 1999-2005 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
*
* Authors:
- * Keith Whitwell <keith@tungstengraphics.com>
+ * Keith Whitwell <keithw@vmware.com>
*/
#define RESET_STIPPLE
#endif
-#ifndef RESET_OCCLUSION
-#define RESET_OCCLUSION
-#endif
-
#ifndef TEST_PRIM_END
-#define TEST_PRIM_END(flags) (flags & PRIM_END)
-#define TEST_PRIM_BEGIN(flags) (flags & PRIM_BEGIN)
-#define TEST_PRIM_PARITY(flags) (flags & PRIM_PARITY)
+#define TEST_PRIM_END(prim) (flags & PRIM_END)
+#define TEST_PRIM_BEGIN(prim) (flags & PRIM_BEGIN)
#endif
#ifndef ELT
#define RENDER_TAB_QUALIFIER static
#endif
-static void TAG(render_points)( GLcontext *ctx,
+static void TAG(render_points)( struct gl_context *ctx,
GLuint start,
GLuint count,
GLuint flags )
LOCAL_VARS;
(void) flags;
- RESET_OCCLUSION;
INIT(GL_POINTS);
RENDER_POINTS( start, count );
POSTFIX;
}
-static void TAG(render_lines)( GLcontext *ctx,
+static void TAG(render_lines)( struct gl_context *ctx,
GLuint start,
GLuint count,
GLuint flags )
LOCAL_VARS;
(void) flags;
- RESET_OCCLUSION;
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;
}
-static void TAG(render_line_strip)( GLcontext *ctx,
+static void TAG(render_line_strip)( struct gl_context *ctx,
GLuint start,
GLuint count,
GLuint flags )
LOCAL_VARS;
(void) flags;
- RESET_OCCLUSION;
INIT(GL_LINE_STRIP);
if (TEST_PRIM_BEGIN(flags)) {
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;
}
-static void TAG(render_line_loop)( GLcontext *ctx,
+static void TAG(render_line_loop)( struct gl_context *ctx,
GLuint start,
GLuint count,
GLuint flags )
GLuint i;
LOCAL_VARS;
- (void) flags;
-
- RESET_OCCLUSION;
INIT(GL_LINE_LOOP);
if (start+1 < count) {
if (TEST_PRIM_BEGIN(flags)) {
RESET_STIPPLE;
- RENDER_LINE( ELT(start), ELT(start+1) );
+ /* draw the first line from v[0] to v[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) );
}
+ /* draw lines from v[1] to v[n-1] */
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) );
+ /* draw final line from v[n-1] to v[0] (the very first vertex) */
+ if (ctx->Light.ProvokingVertex == GL_LAST_VERTEX_CONVENTION_EXT)
+ RENDER_LINE( ELT(count-1), ELT(start) );
+ else
+ RENDER_LINE( ELT(start), ELT(count-1) );
}
}
}
-static void TAG(render_triangles)( GLcontext *ctx,
+static void TAG(render_triangles)( struct gl_context *ctx,
GLuint start,
GLuint count,
GLuint flags )
/* 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-1), ELT(j), ELT(j-2) );
}
} 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;
-static void TAG(render_tri_strip)( GLcontext *ctx,
+static void TAG(render_tri_strip)( struct gl_context *ctx,
GLuint start,
GLuint count,
GLuint flags )
GLuint parity = 0;
LOCAL_VARS;
- if (TEST_PRIM_PARITY(flags))
- parity = 1;
-
INIT(GL_TRIANGLE_STRIP);
if (NEED_EDGEFLAG_SETUP) {
for (j=start+2;j<count;j++,parity^=1) {
- GLuint ej2 = ELT(j-2+parity);
- GLuint ej1 = ELT(j-1-parity);
- GLuint ej = ELT(j);
- GLboolean ef2 = EDGEFLAG_GET( ej2 );
- GLboolean ef1 = EDGEFLAG_GET( ej1 );
- GLboolean ef = EDGEFLAG_GET( ej );
+ GLuint ej2, ej1, ej;
+ GLboolean ef2, ef1, ef;
+ if (ctx->Light.ProvokingVertex == GL_LAST_VERTEX_CONVENTION_EXT) {
+ ej2 = ELT(j-2+parity);
+ ej1 = ELT(j-1-parity);
+ ej = ELT(j);
+ }
+ else {
+ ej2 = ELT(j-1+parity);
+ ej1 = ELT(j-parity);
+ ej = ELT(j-2);
+ }
+ ef2 = EDGEFLAG_GET( ej2 );
+ ef1 = EDGEFLAG_GET( ej1 );
+ ef = EDGEFLAG_GET( ej );
if (TEST_PRIM_BEGIN(flags)) {
RESET_STIPPLE;
}
EDGEFLAG_SET( ej2, GL_TRUE );
EDGEFLAG_SET( ej1, GL_TRUE );
EDGEFLAG_SET( ej, GL_TRUE );
- RENDER_TRI( ej2, ej1, ej );
+ RENDER_TRI( ej2, ej1, ej );
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-1+parity), ELT(j-parity), ELT(j-2) );
}
}
POSTFIX;
}
-static void TAG(render_tri_fan)( GLcontext *ctx,
+static void TAG(render_tri_fan)( struct gl_context *ctx,
GLuint start,
GLuint count,
GLuint flags )
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) );
}
}
}
-static void TAG(render_poly)( GLcontext *ctx,
+static void TAG(render_poly)( struct gl_context *ctx,
GLuint start,
GLuint count,
GLuint flags )
POSTFIX;
}
-static void TAG(render_quads)( GLcontext *ctx,
+static void TAG(render_quads)( struct gl_context *ctx,
GLuint start,
GLuint count,
GLuint flags )
/* 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;
}
-static void TAG(render_quad_strip)( GLcontext *ctx,
+static void TAG(render_quad_strip)( struct gl_context *ctx,
GLuint start,
GLuint count,
GLuint flags )
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 );
}
} 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;
}
-static void TAG(render_noop)( GLcontext *ctx,
+static void TAG(render_noop)( struct gl_context *ctx,
GLuint start,
GLuint count,
GLuint flags )
(void)(ctx && start && count && flags);
}
-RENDER_TAB_QUALIFIER void (*TAG(render_tab)[GL_POLYGON+2])(GLcontext *,
+RENDER_TAB_QUALIFIER void (*TAG(render_tab)[GL_POLYGON+2])(struct gl_context *,
GLuint,
GLuint,
GLuint) =