-/* $Id: t_vb_rendertmp.h,v 1.3 2000/12/28 22:11:06 keithw Exp $ */
-
/*
* Mesa 3-D graphics library
- * Version: 3.5
- *
- * Copyright (C) 1999 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"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of 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.
*
- * Author:
- * Keith Whitwell <keithw@valinux.com>
+ * Authors:
+ * Keith Whitwell <keithw@vmware.com>
*/
#endif
#ifndef INIT
-#define INIT(x)
+#define INIT(x)
#endif
#ifndef NEED_EDGEFLAG_SETUP
#define NEED_EDGEFLAG_SETUP 0
#define EDGEFLAG_GET(a) 0
-#define EDGEFLAG_SET(a,b) (void)b
+#define EDGEFLAG_SET(a,b) (void)b
#endif
#ifndef RESET_STIPPLE
#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 ELT(x) x
#endif
-static void TAG(render_points)( GLcontext *ctx,
+#ifndef RENDER_TAB_QUALIFIER
+#define RENDER_TAB_QUALIFIER static
+#endif
+
+static void TAG(render_points)( struct gl_context *ctx,
GLuint start,
GLuint count,
GLuint flags )
LOCAL_VARS;
(void) flags;
-/* fprintf(stderr, "%s %d..%d\n", __FUNCTION__, start, count); */
- 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;
-/* fprintf(stderr, "%s %d..%d\n", __FUNCTION__, start, count); */
- RESET_OCCLUSION;
INIT(GL_LINES);
for (j=start+1; j<count; j+=2 ) {
- RENDER_LINE( ELT(j-1), ELT(j) );
RESET_STIPPLE;
+ 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;
-/* fprintf(stderr, "%s %d..%d\n", __FUNCTION__, start, count); */
- RESET_OCCLUSION;
- INIT(GL_LINES);
-
- for (j=start+1; j<count; j++ )
- RENDER_LINE( ELT(j-1), ELT(j) );
+ INIT(GL_LINE_STRIP);
- if (TEST_PRIM_END(flags))
+ if (TEST_PRIM_BEGIN(flags)) {
RESET_STIPPLE;
+ }
+ 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;
+ GLuint i;
LOCAL_VARS;
- (void) flags;
-
-/* fprintf(stderr, "%s %d..%d\n", __FUNCTION__, start, count); */
- RESET_OCCLUSION;
- INIT(GL_LINES);
+ INIT(GL_LINE_LOOP);
if (start+1 < count) {
if (TEST_PRIM_BEGIN(flags)) {
- RENDER_LINE( ELT(start), ELT(start+1) );
+ RESET_STIPPLE;
+ /* 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) );
- RESET_STIPPLE;
+ /* 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 )
LOCAL_VARS;
(void) flags;
-/* fprintf(stderr, "%s %d..%d\n", __FUNCTION__, start, count); */
- INIT(GL_POLYGON);
+ INIT(GL_TRIANGLES);
if (NEED_EDGEFLAG_SETUP) {
for (j=start+2; j<count; j+=3) {
/* Leave the edgeflags as supplied by the user.
*/
- RENDER_TRI( ELT(j-2), ELT(j-1), ELT(j), ELT(j), 0 );
RESET_STIPPLE;
+ 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), ELT(j), 0 );
+ 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 j;
GLuint parity = 0;
LOCAL_VARS;
-
- if (TEST_PRIM_PARITY(flags))
- parity = 1;
-
-/* fprintf(stderr, "%s %d..%d\n", __FUNCTION__, start, count); */
- INIT(GL_POLYGON);
+
+ INIT(GL_TRIANGLE_STRIP);
if (NEED_EDGEFLAG_SETUP) {
for (j=start+2;j<count;j++,parity^=1) {
- /* All edges are boundary. Set edgeflags to 1, draw the
- * triangle, and restore them to the original values.
- */
- GLuint ej2 = ELT(j-2);
- GLuint ej1 = ELT(j-1);
- 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, ej, parity );
+ RENDER_TRI( ej2, ej1, ej );
EDGEFLAG_SET( ej2, ef2 );
EDGEFLAG_SET( ej1, ef1 );
EDGEFLAG_SET( ej, ef );
- RESET_STIPPLE;
}
} else {
- for (j=start+2;j<count;j++,parity^=1) {
- RENDER_TRI( ELT(j-2), ELT(j-1), ELT(j), ELT(j), parity );
+ for (j=start+2; j<count ; j++, parity^=1) {
+ 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 )
LOCAL_VARS;
(void) flags;
-/* fprintf(stderr, "%s %d..%d\n", __FUNCTION__, start, count); */
- INIT(GL_POLYGON);
+ INIT(GL_TRIANGLE_FAN);
if (NEED_EDGEFLAG_SETUP) {
for (j=start+2;j<count;j++) {
/* For trifans, all edges are boundary.
GLboolean efs = EDGEFLAG_GET( ejs );
GLboolean ef1 = EDGEFLAG_GET( ej1 );
GLboolean ef = EDGEFLAG_GET( ej );
+ if (TEST_PRIM_BEGIN(flags)) {
+ RESET_STIPPLE;
+ }
EDGEFLAG_SET( ejs, GL_TRUE );
EDGEFLAG_SET( ej1, GL_TRUE );
EDGEFLAG_SET( ej, GL_TRUE );
- RENDER_TRI( ejs, ej1, ej, ej, 0);
+ 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 );
- RESET_STIPPLE;
}
} else {
for (j=start+2;j<count;j++) {
- RENDER_TRI( ELT(start), ELT(j-1), ELT(j), ELT(j), 0 );
+ 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) );
}
}
}
-/* This is a bit of a hack. Clipping produces polygons and really
- * wants to use this function to render them (in particular to get the
- * edgeflags right). However, the rule that pv==start for polys
- * doens't hold there, hence the extra arg and the wrapper below.
- */
-static void TAG(render_poly_pv)( GLcontext *ctx,
- GLuint start,
- GLuint count,
- GLuint flags,
- GLuint pv )
+static void TAG(render_poly)( struct gl_context *ctx,
+ GLuint start,
+ GLuint count,
+ GLuint flags )
{
GLuint j = start+2;
LOCAL_VARS;
(void) flags;
-/* fprintf(stderr, "%s %d..%d\n", __FUNCTION__, start, count); */
INIT(GL_POLYGON);
if (NEED_EDGEFLAG_SETUP) {
GLboolean efstart = EDGEFLAG_GET( ELT(start) );
/* If the primitive does not begin here, the first edge
* is non-boundary.
*/
- if (!TEST_PRIM_BEGIN(flags))
+ if (!TEST_PRIM_BEGIN(flags))
EDGEFLAG_SET( ELT(start), GL_FALSE );
+ else {
+ RESET_STIPPLE;
+ }
/* If the primitive does not end here, the final edge is
* non-boundary.
*/
- if (!TEST_PRIM_END(flags))
+ if (!TEST_PRIM_END(flags))
EDGEFLAG_SET( ELT(count-1), GL_FALSE );
/* Draw the first triangles (possibly zero)
*/
- if (j<count-1) {
+ if (j+1<count) {
GLboolean ef = EDGEFLAG_GET( ELT(j) );
EDGEFLAG_SET( ELT(j), GL_FALSE );
- RENDER_TRI( ELT(start), ELT(j-1), ELT(j), ELT(pv), 0 );
+ RENDER_TRI( ELT(j-1), ELT(j), ELT(start) );
EDGEFLAG_SET( ELT(j), ef );
j++;
-
+
/* Don't render the first edge again:
*/
EDGEFLAG_SET( ELT(start), GL_FALSE );
- for (;j<count-1;j++) {
+ for (;j+1<count;j++) {
GLboolean efj = EDGEFLAG_GET( ELT(j) );
EDGEFLAG_SET( ELT(j), GL_FALSE );
- RENDER_TRI( ELT(start), ELT(j-1), ELT(j), ELT(pv), 0 );
+ RENDER_TRI( ELT(j-1), ELT(j), ELT(start) );
EDGEFLAG_SET( ELT(j), efj );
}
}
/* Draw the last or only triangle
*/
if (j < count)
- RENDER_TRI( ELT(start), ELT(j-1), ELT(j), ELT(pv), 0 );
+ RENDER_TRI( ELT(j-1), ELT(j), ELT(start) );
/* Restore the first and last edgeflags:
*/
EDGEFLAG_SET( ELT(count-1), efcount );
EDGEFLAG_SET( ELT(start), efstart );
-
- if (TEST_PRIM_END(flags)) {
- RESET_STIPPLE;
- }
+
}
else {
for (j=start+2;j<count;j++) {
- RENDER_TRI( ELT(start), ELT(j-1), ELT(j), ELT(start), 0 );
+ RENDER_TRI( ELT(j-1), ELT(j), ELT(start) );
}
}
POSTFIX;
}
-static void TAG(render_poly)( GLcontext *ctx,
- GLuint start,
- GLuint count,
- GLuint flags )
-{
-/* fprintf(stderr, "%s %d..%d\n", __FUNCTION__, start, count); */
- TAG(render_poly_pv)( ctx, start, count, flags, start );
-}
-
-static void TAG(render_quads)( GLcontext *ctx,
+static void TAG(render_quads)( struct gl_context *ctx,
GLuint start,
GLuint count,
GLuint flags )
LOCAL_VARS;
(void) flags;
-/* fprintf(stderr, "%s %d..%d\n", __FUNCTION__, start, count); */
- INIT(GL_POLYGON);
+ INIT(GL_QUADS);
if (NEED_EDGEFLAG_SETUP) {
for (j=start+3; j<count; j+=4) {
/* Use user-specified edgeflags for quads.
*/
- RENDER_QUAD( ELT(j-3), ELT(j-2), ELT(j-1), ELT(j), ELT(j) );
RESET_STIPPLE;
+ 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), 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 )
LOCAL_VARS;
(void) flags;
-/* fprintf(stderr, "%s %d..%d\n", __FUNCTION__, start, count); */
- INIT(GL_POLYGON);
+ INIT(GL_QUAD_STRIP);
if (NEED_EDGEFLAG_SETUP) {
for (j=start+3;j<count;j+=2) {
/* All edges are boundary. Set edgeflags to 1, draw the
GLboolean ef2 = EDGEFLAG_GET( ELT(j-2) );
GLboolean ef1 = EDGEFLAG_GET( ELT(j-1) );
GLboolean ef = EDGEFLAG_GET( ELT(j) );
+ if (TEST_PRIM_BEGIN(flags)) {
+ RESET_STIPPLE;
+ }
EDGEFLAG_SET( ELT(j-3), GL_TRUE );
EDGEFLAG_SET( ELT(j-2), GL_TRUE );
EDGEFLAG_SET( ELT(j-1), GL_TRUE );
EDGEFLAG_SET( ELT(j), GL_TRUE );
- RENDER_QUAD( ELT(j-3), ELT(j-2), ELT(j), ELT(j-1), 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 );
EDGEFLAG_SET( ELT(j), ef );
- RESET_STIPPLE;
}
} else {
for (j=start+3;j<count;j+=2) {
- RENDER_QUAD( ELT(j-3), ELT(j-2), ELT(j), ELT(j-1), 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 )
{
-/* fprintf(stderr, "%s %d..%d\n", __FUNCTION__, start, count); */
(void)(ctx && start && count && flags);
}
-static void (*TAG(render_tab)[GL_POLYGON+2])(GLcontext *,
- GLuint,
- GLuint,
- GLuint) =
+RENDER_TAB_QUALIFIER void (*TAG(render_tab)[GL_POLYGON+2])(struct gl_context *,
+ GLuint,
+ GLuint,
+ GLuint) =
{
TAG(render_points),
TAG(render_lines),
#undef RESET_STIPPLE
#undef DBG
#undef ELT
+#undef RENDER_TAB_QUALIFIER
#endif
#ifndef PRESERVE_TAG
#undef PRESERVE_VB_DEFS
#undef PRESERVE_TAG
-