-/* $Id: t_imm_api.c,v 1.10 2001/04/09 14:47:34 keithw Exp $ */
+/* $Id: t_imm_api.c,v 1.35 2002/10/29 20:29:01 brianp Exp $ */
/*
* Mesa 3-D graphics library
- * Version: 3.5
+ * Version: 4.1
*
* Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
*
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* Authors:
- * Keith Whitwell <keithw@valinux.com>
+ * Keith Whitwell <keith@tungstengraphics.com>
*/
#include "dlist.h"
#include "enums.h"
#include "light.h"
-#include "mem.h"
+#include "imports.h"
#include "state.h"
#include "colormac.h"
#include "macros.h"
+#include "vtxfmt.h"
#include "t_context.h"
#include "t_imm_api.h"
/* A cassette is full or flushed on a statechange.
*/
-void _tnl_flush_immediate( struct immediate *IM )
+void _tnl_flush_immediate( GLcontext *ctx, struct immediate *IM )
{
- GLcontext *ctx = IM->backref;
+ if (!ctx) {
+ /* We were called by glVertex, glEvalCoord, glArrayElement, etc.
+ * The current context is corresponds to the IM structure.
+ */
+ GET_CURRENT_CONTEXT(context);
+ ctx = context;
+ }
+
+ if (MESA_VERBOSE & VERBOSE_IMMEDIATE)
+ _mesa_debug(ctx, "_tnl_flush_immediate IM: %d compiling: %d\n",
+ IM->id, ctx->CompileFlag);
+
+ if (IM->FlushElt == FLUSH_ELT_EAGER) {
+ _tnl_translate_array_elts( ctx, IM, IM->LastPrimitive, IM->Count );
+ }
+
+ /* Mark the last primitive:
+ */
+ IM->PrimitiveLength[IM->LastPrimitive] = IM->Count - IM->LastPrimitive;
+ IM->Primitive[IM->LastPrimitive] |= PRIM_LAST;
if (ctx->CompileFlag)
_tnl_compile_cassette( ctx, IM );
}
+/* Hook for ctx->Driver.FlushVertices:
+ */
void _tnl_flush_vertices( GLcontext *ctx, GLuint flags )
{
struct immediate *IM = TNL_CURRENT_IM(ctx);
- if (IM->Flag[IM->Start])
- if ((flags & FLUSH_UPDATE_CURRENT) || IM->Count > IM->Start)
- _tnl_flush_immediate( IM );
+ if (MESA_VERBOSE & VERBOSE_IMMEDIATE)
+ _mesa_debug(ctx,
+ "_tnl_flush_vertices flags %x IM(%d) %d..%d Flag[%d]: %x\n",
+ flags, IM->id, IM->Start, IM->Count, IM->Start,
+ IM->Flag[IM->Start]);
+
+ if (IM->Flag[IM->Start]) {
+ if ((flags & FLUSH_UPDATE_CURRENT) ||
+ IM->Count > IM->Start ||
+ (IM->Flag[IM->Start] & (VERT_BIT_BEGIN | VERT_BIT_END))) {
+ _tnl_flush_immediate( ctx, IM );
+ }
+ }
}
-static void
-_tnl_begin( GLcontext *ctx, GLenum p )
+void
+_tnl_save_Begin( GLenum mode )
{
+ GET_CURRENT_CONTEXT(ctx);
struct immediate *IM = TNL_CURRENT_IM(ctx);
GLuint inflags, state;
- if (MESA_VERBOSE&VERBOSE_API)
- fprintf(stderr, "glBegin(IM %d) %s\n", IM->id,
- _mesa_lookup_enum_by_nr(p));
+/* _mesa_debug(ctx, "%s: before: %x\n", __FUNCTION__, IM->BeginState); */
+
+ if (mode > GL_POLYGON) {
+ _mesa_compile_error( ctx, GL_INVALID_ENUM, "_tnl_Begin" );
+ return;
+ }
if (ctx->NewState)
_mesa_update_state(ctx);
+#if 000
/* if only a very few slots left, might as well flush now
*/
if (IM->Count > IMM_MAXDATA-8) {
- _tnl_flush_immediate( IM );
+ _tnl_flush_immediate( ctx, IM );
IM = TNL_CURRENT_IM(ctx);
}
+#endif
/* Check for and flush buffered vertices from internal operations.
*/
if (IM->SavedBeginState) {
- _tnl_flush_immediate( IM );
+ _tnl_flush_immediate( ctx, IM );
IM = TNL_CURRENT_IM(ctx);
IM->BeginState = IM->SavedBeginState;
IM->SavedBeginState = 0;
GLuint count = IM->Count;
GLuint last = IM->LastPrimitive;
- ASSERT(IM->Primitive[IM->LastPrimitive] & PRIM_LAST);
-
state |= (VERT_BEGIN_0|VERT_BEGIN_1);
- IM->Flag[count] |= VERT_BEGIN;
- IM->Primitive[IM->LastPrimitive] &= ~PRIM_LAST;
- IM->Primitive[count] = p | PRIM_BEGIN | PRIM_LAST;
+ IM->Flag[count] |= VERT_BIT_BEGIN;
+ IM->Primitive[count] = mode | PRIM_BEGIN;
IM->PrimitiveLength[IM->LastPrimitive] = count - IM->LastPrimitive;
IM->LastPrimitive = count;
/* Not quite right. Need to use the fallback '_aa_ArrayElement'
- * when not known to be inside begin/end and arrays are unlocked.
+ * when not known to be inside begin/end and arrays are
+ * unlocked.
*/
- if (IM->FlushElt) {
+ if (IM->FlushElt == FLUSH_ELT_EAGER) {
_tnl_translate_array_elts( ctx, IM, last, count );
- IM->FlushElt = 0;
}
}
ctx->Driver.NeedFlush |= FLUSH_STORED_VERTICES;
IM->BeginState = state;
-}
+ /* Update save_primitive now. Don't touch ExecPrimitive as this is
+ * updated in the replay of this cassette if we are in
+ * COMPILE_AND_EXECUTE mode.
+ */
+ if (ctx->Driver.CurrentSavePrimitive == PRIM_UNKNOWN)
+ ctx->Driver.CurrentSavePrimitive = PRIM_INSIDE_UNKNOWN_PRIM;
+ else if (ctx->Driver.CurrentSavePrimitive == PRIM_OUTSIDE_BEGIN_END)
+ ctx->Driver.CurrentSavePrimitive = mode;
+}
-static void
+void
_tnl_Begin( GLenum mode )
{
GET_CURRENT_CONTEXT(ctx);
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+ ASSERT (!ctx->CompileFlag);
if (mode > GL_POLYGON) {
- _mesa_compile_error( ctx, GL_INVALID_ENUM, "glBegin" );
+ _mesa_error( ctx, GL_INVALID_ENUM, "_tnl_Begin(0x%x)", mode );
return;
}
- _tnl_begin(ctx, mode);
-
- /* If compiling update SavePrimitive now.
- *
- * In compile_and_exec mode, exec_primitive will be updated when
- * the cassette is finished.
- *
- * If not compiling, update exec_primitive now.
- */
- if (ctx->CompileFlag) {
- if (ctx->Driver.CurrentSavePrimitive == PRIM_UNKNOWN)
- ctx->Driver.CurrentSavePrimitive = PRIM_INSIDE_UNKNOWN_PRIM;
- else if (ctx->Driver.CurrentSavePrimitive == PRIM_OUTSIDE_BEGIN_END)
- ctx->Driver.CurrentSavePrimitive = mode;
- }
- else if (ctx->Driver.CurrentExecPrimitive == PRIM_OUTSIDE_BEGIN_END)
- ctx->Driver.CurrentExecPrimitive = mode;
-}
-
-
-GLboolean
-_tnl_hard_begin( GLcontext *ctx, GLenum p )
-{
- struct immediate *IM = TNL_CURRENT_IM(ctx);
- GLuint count, last;
+ if (ctx->Driver.CurrentExecPrimitive != PRIM_OUTSIDE_BEGIN_END) {
+ _mesa_error( ctx, GL_INVALID_OPERATION, "_tnl_Begin" );
+ return;
+ }
if (ctx->NewState)
_mesa_update_state(ctx);
- /* If not compiling, treat as a normal begin().
- */
- if (!ctx->CompileFlag) {
- _tnl_begin( ctx, p );
-
- /* Set this for the duration:
- */
- ctx->Driver.CurrentExecPrimitive = p;
- return GL_TRUE;
- }
-
- if (IM->Count > IMM_MAXDATA-8) {
- _tnl_flush_immediate( IM );
- IM = TNL_CURRENT_IM(ctx);
- }
-
- switch (IM->BeginState & (VERT_BEGIN_0|VERT_BEGIN_1)) {
- case VERT_BEGIN_0|VERT_BEGIN_1:
- /* This is an immediate known to be inside a begin/end object.
- */
- IM->BeginState |= (VERT_ERROR_1|VERT_ERROR_0);
- return GL_FALSE;
+ {
+ struct immediate *IM = TNL_CURRENT_IM(ctx);
+ GLuint count = IM->Count;
+ GLuint last = IM->LastPrimitive;
- case VERT_BEGIN_0:
- case VERT_BEGIN_1:
- /* This is a display-list immediate in an unknown begin/end
- * state. Assert it is empty and conviert it to a 'hard' one.
- */
- ASSERT (IM->SavedBeginState == 0);
+ if (IM->Start == IM->Count &&
+ tnl->Driver.NotifyBegin &&
+ tnl->Driver.NotifyBegin( ctx, mode )) {
+ return;
+ }
- /* Push current beginstate, to be restored later. Don't worry
- * about raising errors.
- */
- IM->SavedBeginState = IM->BeginState;
+ assert( IM->SavedBeginState == 0 );
+ assert( IM->BeginState == 0 );
- /* FALLTHROUGH */
- case 0:
- /* Unless we have fallen through, this is an immediate known to
- * be outside begin/end objects.
+ /* Not quite right. Need to use the fallback '_aa_ArrayElement'
+ * when not known to be inside begin/end and arrays are
+ * unlocked.
*/
+ if (IM->FlushElt == FLUSH_ELT_EAGER) {
+ _tnl_translate_array_elts( ctx, IM, last, count );
+ }
- IM->BeginState |= VERT_BEGIN_0|VERT_BEGIN_1;
-
-
- count = IM->Count;
- last = IM->LastPrimitive;
-
- ASSERT(IM->Primitive[IM->LastPrimitive] & PRIM_LAST);
-
- IM->Flag[count] |= VERT_BEGIN;
- IM->Primitive[last] &= ~PRIM_LAST;
- IM->Primitive[count] = p | PRIM_BEGIN | PRIM_LAST;
+ IM->Flag[count] |= VERT_BIT_BEGIN;
+ IM->Primitive[count] = mode | PRIM_BEGIN;
IM->PrimitiveLength[last] = count - last;
IM->LastPrimitive = count;
+ IM->BeginState = (VERT_BEGIN_0|VERT_BEGIN_1);
- ASSERT (!IM->FlushElt);
+/* _mesa_debug(ctx, "%s: %x\n", __FUNCTION__, IM->BeginState); */
- /* This is necessary as this immediate will not be flushed in
- * _tnl_end() -- we leave it active, hoping to pick up more
- * vertices before the next state change.
- */
ctx->Driver.NeedFlush |= FLUSH_STORED_VERTICES;
-
- return GL_TRUE;
-
- default:
- ASSERT (0);
- return GL_TRUE;
+ ctx->Driver.CurrentExecPrimitive = mode;
}
}
-
-/* Need to do this to get the correct begin/end error behaviour from
- * functions like ColorPointerEXT which are still active in
- * SAVE_AND_EXEC modes.
+/* Function which allows operations like 'glRectf' to decompose to a
+ * begin/end object and vertices without worrying about what happens
+ * with display lists.
*/
-void
-_tnl_save_Begin( GLenum mode )
+GLboolean
+_tnl_hard_begin( GLcontext *ctx, GLenum p )
{
- GET_CURRENT_CONTEXT(ctx);
+/* _mesa_debug(ctx, "%s\n", __FUNCTION__); */
- if (mode > GL_POLYGON) {
- _mesa_compile_error( ctx, GL_INVALID_ENUM, "glBegin" );
- return;
+ if (!ctx->CompileFlag) {
+ /* If not compiling, treat as a normal begin().
+ */
+/* _mesa_debug(ctx, "%s: treating as glBegin\n", __FUNCTION__); */
+ glBegin( p );
+ return GL_TRUE;
}
-
- if (ctx->ExecuteFlag) {
- /* Preserve vtxfmt invarient:
+ else {
+ /* Otherwise, need to do special processing to preserve the
+ * condition that these vertices will only be replayed outside
+ * future begin/end objects.
*/
+ struct immediate *IM = TNL_CURRENT_IM(ctx);
+
if (ctx->NewState)
- _mesa_update_state( ctx );
+ _mesa_update_state(ctx);
+
+ if (IM->Count > IMM_MAXDATA-8) {
+ _tnl_flush_immediate( ctx, IM );
+ IM = TNL_CURRENT_IM(ctx);
+ }
- /* Slot in geomexec: No need to call setdispatch as we know
- * CurrentDispatch is Save.
+ /* A lot depends on the degree to which the display list has
+ * constrained the possible begin/end states at this point:
*/
- ASSERT(ctx->CurrentDispatch == ctx->Save);
+ switch (IM->BeginState & (VERT_BEGIN_0|VERT_BEGIN_1)) {
+ case VERT_BEGIN_0|VERT_BEGIN_1:
+ /* This is an immediate known to be inside a begin/end object.
+ */
+ ASSERT(ctx->Driver.CurrentSavePrimitive <= GL_POLYGON);
+ IM->BeginState |= (VERT_ERROR_1|VERT_ERROR_0);
+ return GL_FALSE;
+
+ case VERT_BEGIN_0:
+ case VERT_BEGIN_1:
+ /* This is a display-list immediate in an unknown begin/end
+ * state. Assert it is empty and convert it to a 'hard' one.
+ */
+ ASSERT(IM->SavedBeginState == 0);
+ ASSERT(ctx->Driver.CurrentSavePrimitive == PRIM_UNKNOWN);
+
+ /* Push current beginstate, to be restored later. Don't worry
+ * about raising errors.
+ */
+ IM->SavedBeginState = IM->BeginState;
+
+ /* FALLTHROUGH */
+
+ case 0:
+ /* Unless we have fallen through, this is an immediate known to
+ * be outside begin/end objects.
+ */
+ ASSERT(ctx->Driver.CurrentSavePrimitive == PRIM_UNKNOWN ||
+ ctx->Driver.CurrentSavePrimitive == PRIM_OUTSIDE_BEGIN_END);
+ ASSERT (IM->FlushElt != FLUSH_ELT_EAGER);
+
+ IM->BeginState |= VERT_BEGIN_0|VERT_BEGIN_1;
+ IM->Flag[IM->Count] |= VERT_BIT_BEGIN;
+ IM->Primitive[IM->Count] = p | PRIM_BEGIN;
+ IM->PrimitiveLength[IM->LastPrimitive] = IM->Count - IM->LastPrimitive;
+ IM->LastPrimitive = IM->Count;
+
+ /* This is necessary as this immediate will not be flushed in
+ * _tnl_end() -- we leave it active, hoping to pick up more
+ * vertices before the next state change.
+ */
+ ctx->Driver.NeedFlush |= FLUSH_STORED_VERTICES;
+ return GL_TRUE;
+
+ default:
+ assert (0);
+ return GL_TRUE;
+ }
}
-
- _tnl_begin( ctx, mode );
}
+
+
/* Both streams now outside begin/end.
*
* Leave SavedBeginState untouched -- attempt to gather several
GLuint state = IM->BeginState;
GLuint inflags = (~state) & (VERT_BEGIN_0|VERT_BEGIN_1);
+ assert( ctx->Driver.NeedFlush & FLUSH_STORED_VERTICES );
+
state |= inflags << 2; /* errors */
if (inflags != (VERT_BEGIN_0|VERT_BEGIN_1))
GLuint count = IM->Count;
GLuint last = IM->LastPrimitive;
- ASSERT(IM->Primitive[IM->LastPrimitive] & PRIM_LAST);
-
state &= ~(VERT_BEGIN_0|VERT_BEGIN_1); /* update state */
- IM->Flag[count] |= VERT_END;
+ IM->Flag[count] |= VERT_BIT_END;
IM->Primitive[last] |= PRIM_END;
- IM->Primitive[last] &= ~PRIM_LAST;
IM->PrimitiveLength[last] = count - last;
- IM->Primitive[count] = (GL_POLYGON+1) | PRIM_LAST;
+ IM->Primitive[count] = PRIM_OUTSIDE_BEGIN_END; /* removes PRIM_BEGIN
+ * flag if length == 0
+ */
IM->LastPrimitive = count;
- if (IM->FlushElt) {
+ if (IM->FlushElt == FLUSH_ELT_EAGER) {
_tnl_translate_array_elts( ctx, IM, last, count );
- IM->FlushElt = 0;
}
}
IM->BeginState = state;
- if (!ctx->CompileFlag)
- ctx->Driver.CurrentExecPrimitive = PRIM_OUTSIDE_BEGIN_END;
-
+ if (!ctx->CompileFlag) {
+ if (ctx->Driver.CurrentExecPrimitive == PRIM_OUTSIDE_BEGIN_END)
+ _mesa_error( ctx, GL_INVALID_OPERATION, "_tnl_End" );
+ else
+ ctx->Driver.CurrentExecPrimitive = PRIM_OUTSIDE_BEGIN_END;
+ }
/* You can set this flag to get the old 'flush_vb on glEnd()'
* behaviour.
*/
- if ((MESA_DEBUG_FLAGS&DEBUG_ALWAYS_FLUSH))
- _tnl_flush_immediate( IM );
+ if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH)
+ _tnl_flush_immediate( ctx, IM );
}
-static void
+void
_tnl_End(void)
{
GET_CURRENT_CONTEXT(ctx);
+
_tnl_end( ctx );
/* Need to keep save primitive uptodate in COMPILE and
}
-#define COLOR( IM, r, g, b, a ) \
-{ \
- GLuint count = IM->Count; \
- IM->Flag[count] |= VERT_RGBA; \
- IM->Color[count][0] = r; \
- IM->Color[count][1] = g; \
- IM->Color[count][2] = b; \
- IM->Color[count][3] = a; \
-}
-
-#define COLORV( IM, v ) \
-{ \
- GLuint count = IM->Count; \
- IM->Flag[count] |= VERT_RGBA; \
- COPY_CHAN4(IM->Color[count], v); \
+#define COLOR( r, g, b, a ) \
+{ \
+ GET_IMMEDIATE; \
+ GLuint count = IM->Count; \
+ GLfloat *color = IM->Attrib[VERT_ATTRIB_COLOR0][count]; \
+ IM->Flag[count] |= VERT_BIT_COLOR0; \
+ color[0] = r; \
+ color[1] = g; \
+ color[2] = b; \
+ color[3] = a; \
}
-
static void
_tnl_Color3f( GLfloat red, GLfloat green, GLfloat blue )
{
- GLchan col[4];
- GET_IMMEDIATE;
- UNCLAMPED_FLOAT_TO_CHAN(col[0], red);
- UNCLAMPED_FLOAT_TO_CHAN(col[1], green);
- UNCLAMPED_FLOAT_TO_CHAN(col[2], blue);
- col[3] = CHAN_MAX;
- COLORV( IM, col );
+ COLOR( red, green, blue, 1.0 );
}
-
static void
_tnl_Color3ub( GLubyte red, GLubyte green, GLubyte blue )
{
-#if CHAN_BITS == 8
- GET_IMMEDIATE;
- COLOR( IM, red, green, blue, CHAN_MAX );
-#else
- GET_IMMEDIATE;
- COLOR(IM,
- UBYTE_TO_CHAN(red),
- UBYTE_TO_CHAN(green),
- UBYTE_TO_CHAN(blue),
- CHAN_MAX);
-#endif
+ COLOR(UBYTE_TO_FLOAT(red),
+ UBYTE_TO_FLOAT(green),
+ UBYTE_TO_FLOAT(blue),
+ 1.0);
}
-
-
-
static void
_tnl_Color4f( GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha )
{
- GLchan col[4];
- GET_IMMEDIATE;
- UNCLAMPED_FLOAT_TO_CHAN(col[0], red);
- UNCLAMPED_FLOAT_TO_CHAN(col[1], green);
- UNCLAMPED_FLOAT_TO_CHAN(col[2], blue);
- UNCLAMPED_FLOAT_TO_CHAN(col[3], alpha);
- COLORV( IM, col );
+ COLOR( red, green, blue, alpha );
}
static void
_tnl_Color4ub( GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha )
{
- GET_IMMEDIATE;
- COLOR(IM,
- UBYTE_TO_CHAN(red),
- UBYTE_TO_CHAN(green),
- UBYTE_TO_CHAN(blue),
- UBYTE_TO_CHAN(alpha));
+ COLOR(UBYTE_TO_FLOAT(red),
+ UBYTE_TO_FLOAT(green),
+ UBYTE_TO_FLOAT(blue),
+ UBYTE_TO_FLOAT(alpha));
}
-
static void
_tnl_Color3fv( const GLfloat *v )
{
- GLchan col[4];
- GET_IMMEDIATE;
- UNCLAMPED_FLOAT_TO_CHAN(col[0], v[0]);
- UNCLAMPED_FLOAT_TO_CHAN(col[1], v[1]);
- UNCLAMPED_FLOAT_TO_CHAN(col[2], v[2]);
- col[3] = CHAN_MAX;
- COLORV( IM, col );
+ COLOR( v[0], v[1], v[2], 1.0 );
}
-
-
static void
_tnl_Color3ubv( const GLubyte *v )
{
- GET_IMMEDIATE;
- COLOR(IM,
- UBYTE_TO_CHAN(v[0]),
- UBYTE_TO_CHAN(v[1]),
- UBYTE_TO_CHAN(v[2]),
- CHAN_MAX );
+ COLOR(UBYTE_TO_FLOAT(v[0]),
+ UBYTE_TO_FLOAT(v[1]),
+ UBYTE_TO_FLOAT(v[2]),
+ 1.0 );
}
static void
_tnl_Color4fv( const GLfloat *v )
{
- GLchan col[4];
- GET_IMMEDIATE;
- UNCLAMPED_FLOAT_TO_CHAN(col[0], v[0]);
- UNCLAMPED_FLOAT_TO_CHAN(col[1], v[1]);
- UNCLAMPED_FLOAT_TO_CHAN(col[2], v[2]);
- UNCLAMPED_FLOAT_TO_CHAN(col[3], v[3]);
- COLORV( IM, col );
+ COLOR( v[0], v[1], v[2], v[3] );
}
-
-
static void
_tnl_Color4ubv( const GLubyte *v)
{
- GET_IMMEDIATE;
- COLOR(IM,
- UBYTE_TO_CHAN(v[0]),
- UBYTE_TO_CHAN(v[1]),
- UBYTE_TO_CHAN(v[2]),
- UBYTE_TO_CHAN(v[3]));
+ COLOR(UBYTE_TO_FLOAT(v[0]),
+ UBYTE_TO_FLOAT(v[1]),
+ UBYTE_TO_FLOAT(v[2]),
+ UBYTE_TO_FLOAT(v[3]));
}
-#define SECONDARY_COLOR( IM, r, g, b ) \
-{ \
- GLuint count = IM->Count; \
- IM->Flag[count] |= VERT_SPEC_RGB; \
- IM->SecondaryColor[count][0] = r; \
- IM->SecondaryColor[count][1] = g; \
- IM->SecondaryColor[count][2] = b; \
-}
-
-#define SECONDARY_COLORV( IM, v ) \
-{ \
- GLuint count = IM->Count; \
- IM->Flag[count] |= VERT_SPEC_RGB; \
- IM->SecondaryColor[count][0] = v[0]; \
- IM->SecondaryColor[count][1] = v[1]; \
- IM->SecondaryColor[count][2] = v[2]; \
+#define SECONDARY_COLOR( r, g, b ) \
+{ \
+ GLuint count; \
+ GET_IMMEDIATE; \
+ count = IM->Count; \
+ IM->Flag[count] |= VERT_BIT_COLOR1; \
+ IM->Attrib[VERT_ATTRIB_COLOR1][count][0] = r; \
+ IM->Attrib[VERT_ATTRIB_COLOR1][count][1] = g; \
+ IM->Attrib[VERT_ATTRIB_COLOR1][count][2] = b; \
}
-
-
-
static void
_tnl_SecondaryColor3fEXT( GLfloat red, GLfloat green, GLfloat blue )
{
- GLchan col[3];
- GET_IMMEDIATE;
- UNCLAMPED_FLOAT_TO_CHAN(col[0], red);
- UNCLAMPED_FLOAT_TO_CHAN(col[1], green);
- UNCLAMPED_FLOAT_TO_CHAN(col[2], blue);
- SECONDARY_COLORV( IM, col );
+ SECONDARY_COLOR( red, green, blue );
}
-
-
static void
_tnl_SecondaryColor3ubEXT( GLubyte red, GLubyte green, GLubyte blue )
{
- GET_IMMEDIATE;
- SECONDARY_COLOR(IM,
- UBYTE_TO_CHAN(red),
- UBYTE_TO_CHAN(green),
- UBYTE_TO_CHAN(blue));
+ SECONDARY_COLOR(UBYTE_TO_FLOAT(red),
+ UBYTE_TO_FLOAT(green),
+ UBYTE_TO_FLOAT(blue));
}
-
-
-
static void
_tnl_SecondaryColor3fvEXT( const GLfloat *v )
{
- GLchan col[3];
- GET_IMMEDIATE;
- UNCLAMPED_FLOAT_TO_CHAN(col[0], v[0]);
- UNCLAMPED_FLOAT_TO_CHAN(col[1], v[1]);
- UNCLAMPED_FLOAT_TO_CHAN(col[2], v[2]);
- SECONDARY_COLORV( IM, col );
+ SECONDARY_COLOR( v[0], v[1], v[2] );
}
-
-
static void
_tnl_SecondaryColor3ubvEXT( const GLubyte *v )
{
- GET_IMMEDIATE;
- SECONDARY_COLOR(IM,
- UBYTE_TO_CHAN(v[0]),
- UBYTE_TO_CHAN(v[1]),
- UBYTE_TO_CHAN(v[2]));
+ SECONDARY_COLOR(UBYTE_TO_FLOAT(v[0]),
+ UBYTE_TO_FLOAT(v[1]),
+ UBYTE_TO_FLOAT(v[2]));
}
-
-
static void
_tnl_EdgeFlag( GLboolean flag )
{
GET_IMMEDIATE;
count = IM->Count;
IM->EdgeFlag[count] = flag;
- IM->Flag[count] |= VERT_EDGE;
+ IM->Flag[count] |= VERT_BIT_EDGEFLAG;
}
GET_IMMEDIATE;
count = IM->Count;
IM->EdgeFlag[count] = *flag;
- IM->Flag[count] |= VERT_EDGE;
+ IM->Flag[count] |= VERT_BIT_EDGEFLAG;
}
GLuint count;
GET_IMMEDIATE;
count = IM->Count;
- IM->FogCoord[count] = f;
- IM->Flag[count] |= VERT_FOG_COORD;
+ IM->Attrib[VERT_ATTRIB_FOG][count][0] = f; /*FogCoord[count] = f;*/
+ IM->Flag[count] |= VERT_BIT_FOG;
}
static void
GLuint count;
GET_IMMEDIATE;
count = IM->Count;
- IM->FogCoord[count] = v[0];
- IM->Flag[count] |= VERT_FOG_COORD;
+ IM->Attrib[VERT_ATTRIB_FOG][count][0] = v[0]; /*FogCoord[count] = v[0];*/
+ IM->Flag[count] |= VERT_BIT_FOG;
}
GET_IMMEDIATE;
count = IM->Count;
IM->Index[count] = c;
- IM->Flag[count] |= VERT_INDEX;
+ IM->Flag[count] |= VERT_BIT_INDEX;
}
GET_IMMEDIATE;
count = IM->Count;
IM->Index[count] = *c;
- IM->Flag[count] |= VERT_INDEX;
+ IM->Flag[count] |= VERT_BIT_INDEX;
}
-#define NORMAL( x, y, z ) \
-{ \
- GLuint count; \
- GLfloat *normal; \
- GET_IMMEDIATE; \
- count = IM->Count; \
- IM->Flag[count] |= VERT_NORM; \
- normal = IM->Normal[count]; \
- ASSIGN_3V(normal, x,y,z); \
+#define NORMAL( x, y, z ) \
+{ \
+ GLuint count; \
+ GLfloat *normal; \
+ GET_IMMEDIATE; \
+ count = IM->Count; \
+ IM->Flag[count] |= VERT_BIT_NORMAL; \
+ normal = IM->Attrib[VERT_ATTRIB_NORMAL][count]; \
+ ASSIGN_3V(normal, x,y,z); \
}
#if defined(USE_IEEE)
#define NORMALF( x, y, z ) \
{ \
GLuint count; \
- GLint *normal; \
+ fi_type *normal; \
GET_IMMEDIATE; \
count = IM->Count; \
- IM->Flag[count] |= VERT_NORM; \
- normal = (GLint *)IM->Normal[count]; \
- ASSIGN_3V(normal, *(int*)&(x), *(int*)&(y), *(int*)&(z)); \
+ IM->Flag[count] |= VERT_BIT_NORMAL; \
+ normal = (fi_type *)IM->Attrib[VERT_ATTRIB_NORMAL][count]; \
+ normal[0].i = ((fi_type *)&(x))->i; \
+ normal[1].i = ((fi_type *)&(y))->i; \
+ normal[2].i = ((fi_type *)&(z))->i; \
}
#else
#define NORMALF NORMAL
_tnl_Normal3fv( const GLfloat *v )
{
NORMALF( v[0], v[1], v[2] );
+/* struct immediate *IM = (struct immediate *)(((GLcontext *) _glapi_Context)->swtnl_im); */
+/* IM->Flag[IM->Count] = VERT_NORM; */
}
GLfloat *tc; \
GET_IMMEDIATE; \
count = IM->Count; \
- IM->Flag[count] |= VERT_TEX0; \
- tc = IM->TexCoord0[count]; \
+ IM->Flag[count] |= VERT_BIT_TEX0; \
+ tc = IM->Attrib[VERT_ATTRIB_TEX0][count]; \
ASSIGN_4V(tc,s,0,0,1); \
}
-#define TEXCOORD2(s,t) \
+#define TEXCOORD2(s, t) \
{ \
GLuint count; \
GLfloat *tc; \
GET_IMMEDIATE; \
count = IM->Count; \
- IM->Flag[count] |= VERT_TEX0; \
- tc = IM->TexCoord0[count]; \
- ASSIGN_4V(tc, s,t,0,1); \
+ IM->Flag[count] |= VERT_BIT_TEX0; \
+ tc = IM->Attrib[VERT_ATTRIB_TEX0][count]; \
+ ASSIGN_4V(tc, s, t, 0, 1); \
}
-#define TEXCOORD3(s,t,u) \
+#define TEXCOORD3(s, t, u) \
{ \
GLuint count; \
GLfloat *tc; \
GET_IMMEDIATE; \
count = IM->Count; \
- IM->Flag[count] |= VERT_TEX0; \
- IM->TexSize |= TEX_0_SIZE_3; \
- tc = IM->TexCoord0[count]; \
- ASSIGN_4V(tc, s,t,u,1); \
+ IM->Flag[count] |= VERT_BIT_TEX0; \
+ IM->TexSize |= TEX_0_SIZE_3; \
+ tc = IM->Attrib[VERT_ATTRIB_TEX0][count]; \
+ ASSIGN_4V(tc, s, t, u, 1); \
}
-#define TEXCOORD4(s,t,u,v) \
+#define TEXCOORD4(s, t, u, v) \
{ \
GLuint count; \
GLfloat *tc; \
GET_IMMEDIATE; \
count = IM->Count; \
- IM->Flag[count] |= VERT_TEX0; \
- IM->TexSize |= TEX_0_SIZE_4; \
- tc = IM->TexCoord0[count]; \
- ASSIGN_4V(tc, s,t,u,v); \
+ IM->Flag[count] |= VERT_BIT_TEX0; \
+ IM->TexSize |= TEX_0_SIZE_4; \
+ tc = IM->Attrib[VERT_ATTRIB_TEX0][count]; \
+ ASSIGN_4V(tc, s, t, u, v); \
}
#if defined(USE_IEEE)
-#define TEXCOORD2F(s,t) \
-{ \
- GLuint count; \
- GLint *tc; \
- GET_IMMEDIATE; \
- count = IM->Count; \
- IM->Flag[count] |= VERT_TEX0; \
- tc = (GLint *)IM->TexCoord0[count]; \
- tc[0] = *(GLint *)&(s); \
- tc[1] = *(GLint *)&(t); \
- tc[2] = 0; \
- tc[3] = IEEE_ONE; \
+#define TEXCOORD2F(s, t) \
+{ \
+ GLuint count; \
+ fi_type *tc; \
+ GET_IMMEDIATE; \
+ count = IM->Count; \
+ IM->Flag[count] |= VERT_BIT_TEX0; \
+ tc = (fi_type *)IM->Attrib[VERT_ATTRIB_TEX0][count]; \
+ tc[0].i = ((fi_type *)&(s))->i; \
+ tc[1].i = ((fi_type *)&(t))->i; \
+ tc[2].i = 0; \
+ tc[3].i = IEEE_ONE; \
}
#else
#define TEXCOORD2F TEXCOORD2
static void
_tnl_TexCoord2f( GLfloat s, GLfloat t )
{
- TEXCOORD2F(s,t);
+ TEXCOORD2F(s, t);
}
static void
_tnl_TexCoord3f( GLfloat s, GLfloat t, GLfloat r )
{
- TEXCOORD3(s,t,r);
+ TEXCOORD3(s, t, r);
}
static void
_tnl_TexCoord4f( GLfloat s, GLfloat t, GLfloat r, GLfloat q )
{
- TEXCOORD4(s,t,r,q)
+ TEXCOORD4(s, t, r, q)
}
static void
static void
_tnl_TexCoord2fv( const GLfloat *v )
{
- TEXCOORD2F(v[0],v[1]);
+ TEXCOORD2F(v[0], v[1]);
}
static void
_tnl_TexCoord3fv( const GLfloat *v )
{
- TEXCOORD3(v[0],v[1],v[2]);
+ TEXCOORD3(v[0], v[1], v[2]);
}
static void
_tnl_TexCoord4fv( const GLfloat *v )
{
- TEXCOORD4(v[0],v[1],v[2],v[3]);
+ TEXCOORD4(v[0], v[1], v[2], v[3]);
}
/* KW: Run into bad problems in vertex copying if we don't fully pad
* the incoming vertices.
*/
-#define VERTEX2(IM, x,y) \
-{ \
- GLuint count = IM->Count++; \
- GLfloat *dest = IM->Obj[count]; \
- IM->Flag[count] |= VERT_OBJ; \
- ASSIGN_4V(dest, x, y, 0, 1); \
-/* ASSERT(IM->Flag[IM->Count]==0); */\
- if (count == IMM_MAXDATA - 1) \
- _tnl_flush_immediate( IM ); \
+#define VERTEX2(IM, x,y) \
+{ \
+ GLuint count = IM->Count++; \
+ GLfloat *dest = IM->Attrib[VERT_ATTRIB_POS][count]; \
+ IM->Flag[count] |= VERT_BIT_POS; \
+ ASSIGN_4V(dest, x, y, 0, 1); \
+/* ASSERT(IM->Flag[IM->Count]==0); */ \
+ if (count == IMM_MAXDATA - 1) \
+ _tnl_flush_immediate( NULL, IM ); \
}
-#define VERTEX3(IM,x,y,z) \
-{ \
- GLuint count = IM->Count++; \
- GLfloat *dest = IM->Obj[count]; \
- IM->Flag[count] |= VERT_OBJ_23; \
- ASSIGN_4V(dest, x, y, z, 1); \
+#define VERTEX3(IM,x,y,z) \
+{ \
+ GLuint count = IM->Count++; \
+ GLfloat *dest = IM->Attrib[VERT_ATTRIB_POS][count]; \
+ IM->Flag[count] |= VERT_BITS_OBJ_23; \
+ ASSIGN_4V(dest, x, y, z, 1); \
/* ASSERT(IM->Flag[IM->Count]==0); */ \
- if (count == IMM_MAXDATA - 1) \
- _tnl_flush_immediate( IM ); \
+ if (count == IMM_MAXDATA - 1) \
+ _tnl_flush_immediate( NULL, IM ); \
}
-#define VERTEX4(IM, x,y,z,w) \
-{ \
- GLuint count = IM->Count++; \
- GLfloat *dest = IM->Obj[count]; \
- IM->Flag[count] |= VERT_OBJ_234; \
- ASSIGN_4V(dest, x, y, z, w); \
+#define VERTEX4(IM, x,y,z,w) \
+{ \
+ GLuint count = IM->Count++; \
+ GLfloat *dest = IM->Attrib[VERT_ATTRIB_POS][count]; \
+ IM->Flag[count] |= VERT_BITS_OBJ_234; \
+ ASSIGN_4V(dest, x, y, z, w); \
if (count == IMM_MAXDATA - 1) \
- _tnl_flush_immediate( IM ); \
+ _tnl_flush_immediate( NULL, IM ); \
}
#if defined(USE_IEEE)
-#define VERTEX2F(IM, x, y) \
-{ \
- GLuint count = IM->Count++; \
- GLint *dest = (GLint *)IM->Obj[count]; \
- IM->Flag[count] |= VERT_OBJ; \
- dest[0] = *(GLint *)&(x); \
- dest[1] = *(GLint *)&(y); \
- dest[2] = 0; \
- dest[3] = IEEE_ONE; \
-/* ASSERT(IM->Flag[IM->Count]==0); */ \
- if (count == IMM_MAXDATA - 1) \
- _tnl_flush_immediate( IM ); \
+#define VERTEX2F(IM, x, y) \
+{ \
+ GLuint count = IM->Count++; \
+ fi_type *dest = (fi_type *)IM->Attrib[VERT_ATTRIB_POS][count]; \
+ IM->Flag[count] |= VERT_BIT_POS; \
+ dest[0].i = ((fi_type *)&(x))->i; \
+ dest[1].i = ((fi_type *)&(y))->i; \
+ dest[2].i = 0; \
+ dest[3].i = IEEE_ONE; \
+/* ASSERT(IM->Flag[IM->Count]==0); */ \
+ if (count == IMM_MAXDATA - 1) \
+ _tnl_flush_immediate( NULL, IM ); \
}
#else
#define VERTEX2F VERTEX2
#endif
#if defined(USE_IEEE)
-#define VERTEX3F(IM, x, y, z) \
-{ \
- GLuint count = IM->Count++; \
- GLint *dest = (GLint *)IM->Obj[count]; \
- IM->Flag[count] |= VERT_OBJ_23; \
- dest[0] = *(GLint *)&(x); \
- dest[1] = *(GLint *)&(y); \
- dest[2] = *(GLint *)&(z); \
- dest[3] = IEEE_ONE; \
-/* ASSERT(IM->Flag[IM->Count]==0); */ \
- if (count == IMM_MAXDATA - 1) \
- _tnl_flush_immediate( IM ); \
+#define VERTEX3F(IM, x, y, z) \
+{ \
+ GLuint count = IM->Count++; \
+ fi_type *dest = (fi_type *)IM->Attrib[VERT_ATTRIB_POS][count]; \
+ IM->Flag[count] |= VERT_BITS_OBJ_23; \
+ dest[0].i = ((fi_type *)&(x))->i; \
+ dest[1].i = ((fi_type *)&(y))->i; \
+ dest[2].i = ((fi_type *)&(z))->i; \
+ dest[3].i = IEEE_ONE; \
+/* ASSERT(IM->Flag[IM->Count]==0); */ \
+ if (count == IMM_MAXDATA - 1) \
+ _tnl_flush_immediate( NULL, IM ); \
}
#else
#define VERTEX3F VERTEX3
#endif
#if defined(USE_IEEE)
-#define VERTEX4F(IM, x, y, z, w) \
-{ \
- GLuint count = IM->Count++; \
- GLint *dest = (GLint *)IM->Obj[count]; \
- IM->Flag[count] |= VERT_OBJ_234; \
- dest[0] = *(GLint *)&(x); \
- dest[1] = *(GLint *)&(y); \
- dest[2] = *(GLint *)&(z); \
- dest[3] = *(GLint *)&(w); \
- if (count == IMM_MAXDATA - 1) \
- _tnl_flush_immediate( IM ); \
+#define VERTEX4F(IM, x, y, z, w) \
+{ \
+ GLuint count = IM->Count++; \
+ fi_type *dest = (fi_type *)IM->Attrib[VERT_ATTRIB_POS][count]; \
+ IM->Flag[count] |= VERT_BITS_OBJ_234; \
+ dest[0].i = ((fi_type *)&(x))->i; \
+ dest[1].i = ((fi_type *)&(y))->i; \
+ dest[2].i = ((fi_type *)&(z))->i; \
+ dest[3].i = ((fi_type *)&(w))->i; \
+ if (count == IMM_MAXDATA - 1) \
+ _tnl_flush_immediate( NULL, IM ); \
}
#else
#define VERTEX4F VERTEX4
GLuint texunit = target - GL_TEXTURE0_ARB; \
if (texunit < IM->MaxTextureUnits) { \
GLuint count = IM->Count; \
- GLfloat *tc = IM->TexCoord[texunit][count]; \
+ GLfloat *tc = IM->Attrib[VERT_ATTRIB_TEX0 + texunit][count]; \
ASSIGN_4V(tc, s, 0.0F, 0.0F, 1.0F); \
- IM->Flag[count] |= VERT_TEX(texunit); \
+ IM->Flag[count] |= VERT_BIT_TEX(texunit); \
} \
}
GLuint texunit = target - GL_TEXTURE0_ARB; \
if (texunit < IM->MaxTextureUnits) { \
GLuint count = IM->Count; \
- GLfloat *tc = IM->TexCoord[texunit][count]; \
+ GLfloat *tc = IM->Attrib[VERT_ATTRIB_TEX0 + texunit][count]; \
ASSIGN_4V(tc, s, t, 0.0F, 1.0F); \
- IM->Flag[count] |= VERT_TEX(texunit); \
+ IM->Flag[count] |= VERT_BIT_TEX(texunit); \
} \
}
GLuint texunit = target - GL_TEXTURE0_ARB; \
if (texunit < IM->MaxTextureUnits) { \
GLuint count = IM->Count; \
- GLfloat *tc = IM->TexCoord[texunit][count]; \
+ GLfloat *tc = IM->Attrib[VERT_ATTRIB_TEX0 + texunit][count]; \
ASSIGN_4V(tc, s, t, u, 1.0F); \
- IM->Flag[count] |= VERT_TEX(texunit); \
+ IM->Flag[count] |= VERT_BIT_TEX(texunit); \
IM->TexSize |= TEX_SIZE_3(texunit); \
} \
}
GLuint texunit = target - GL_TEXTURE0_ARB; \
if (texunit < IM->MaxTextureUnits) { \
GLuint count = IM->Count; \
- GLfloat *tc = IM->TexCoord[texunit][count]; \
+ GLfloat *tc = IM->Attrib[VERT_ATTRIB_TEX0 + texunit][count]; \
ASSIGN_4V(tc, s, t, u, v); \
- IM->Flag[count] |= VERT_TEX(texunit); \
+ IM->Flag[count] |= VERT_BIT_TEX(texunit); \
IM->TexSize |= TEX_SIZE_4(texunit); \
} \
}
GLuint texunit = target - GL_TEXTURE0_ARB; \
if (texunit < IM->MaxTextureUnits) { \
GLuint count = IM->Count; \
- GLint *tc = (GLint *)IM->TexCoord[texunit][count]; \
- IM->Flag[count] |= VERT_TEX(texunit); \
- tc[0] = *(int *)&(s); \
- tc[1] = *(int *)&(t); \
- tc[2] = 0; \
- tc[3] = IEEE_ONE; \
+ fi_type *tc = (fi_type *)IM->Attrib[VERT_ATTRIB_TEX0 + texunit][count];\
+ IM->Flag[count] |= VERT_BIT_TEX(texunit); \
+ tc[0].i = ((fi_type *)&(s))->i; \
+ tc[1].i = ((fi_type *)&(t))->i; \
+ tc[2].i = 0; \
+ tc[3].i = IEEE_ONE; \
} \
}
#else
#define EVALCOORD1(IM, x) \
{ \
GLuint count = IM->Count++; \
- IM->Flag[count] |= VERT_EVAL_C1; \
- ASSIGN_4V(IM->Obj[count], x, 0, 0, 1); \
+ GLfloat *dest = IM->Attrib[VERT_ATTRIB_POS][count]; \
+ IM->Flag[count] |= VERT_BIT_EVAL_C1; \
+ ASSIGN_4V(dest, x, 0, 0, 1); \
if (count == IMM_MAXDATA-1) \
- _tnl_flush_immediate( IM ); \
+ _tnl_flush_immediate( NULL, IM ); \
}
#define EVALCOORD2(IM, x, y) \
{ \
GLuint count = IM->Count++; \
- IM->Flag[count] |= VERT_EVAL_C2; \
- ASSIGN_4V(IM->Obj[count], x, y, 0, 1); \
+ GLfloat *dest = IM->Attrib[VERT_ATTRIB_POS][count]; \
+ IM->Flag[count] |= VERT_BIT_EVAL_C2; \
+ ASSIGN_4V(dest, x, y, 0, 1); \
if (count == IMM_MAXDATA-1) \
- _tnl_flush_immediate( IM ); \
+ _tnl_flush_immediate( NULL, IM ); \
}
#define EVALPOINT1(IM, x) \
{ \
GLuint count = IM->Count++; \
- IM->Flag[count] |= VERT_EVAL_P1; \
- ASSIGN_4V(IM->Obj[count], x, 0, 0, 1); \
+ GLfloat *dest = IM->Attrib[VERT_ATTRIB_POS][count]; \
+ IM->Flag[count] |= VERT_BIT_EVAL_P1; \
+ ASSIGN_4V(dest, x, 0, 0, 1); \
if (count == IMM_MAXDATA-1) \
- _tnl_flush_immediate( IM ); \
+ _tnl_flush_immediate( NULL, IM ); \
}
#define EVALPOINT2(IM, x, y) \
{ \
GLuint count = IM->Count++; \
- IM->Flag[count] |= VERT_EVAL_P2; \
- ASSIGN_4V(IM->Obj[count], x, y, 0, 1); \
+ GLfloat *dest = IM->Attrib[VERT_ATTRIB_POS][count]; \
+ IM->Flag[count] |= VERT_BIT_EVAL_P2; \
+ ASSIGN_4V(dest, x, y, 0, 1); \
if (count == IMM_MAXDATA-1) \
- _tnl_flush_immediate( IM ); \
+ _tnl_flush_immediate( NULL, IM ); \
}
static void
_tnl_EvalPoint1( GLint i )
{
GET_IMMEDIATE;
- EVALPOINT1( IM, i );
+ EVALPOINT1( IM, (GLfloat) i );
}
_tnl_EvalPoint2( GLint i, GLint j )
{
GET_IMMEDIATE;
- EVALPOINT2( IM, i, j );
+ EVALPOINT2( IM, (GLfloat) i, (GLfloat) j );
}
GLuint count = IM->Count; \
IM->Elt[count] = i; \
IM->Flag[count] &= IM->ArrayEltFlags; \
- IM->Flag[count] |= VERT_ELT; \
- IM->FlushElt |= IM->ArrayEltFlush; \
+ IM->Flag[count] |= VERT_BIT_ELT; \
+ IM->FlushElt = IM->ArrayEltFlush; \
IM->Count += IM->ArrayEltIncr; \
- if (IM->Count == IMM_MAXDATA) \
- _tnl_flush_immediate( IM ); \
+ if (IM->Count == IMM_MAXDATA) \
+ _tnl_flush_immediate( NULL, IM ); \
}
EVALCOORD2( i, u, v );
}
-void
-_tnl_array_element( GLcontext *CC, GLint i )
-{
- struct immediate *im = TNL_CURRENT_IM(CC);
- ARRAY_ELT( im, i );
-}
-void
-_tnl_vertex2f( GLcontext *ctx, GLfloat x, GLfloat y )
-{
- struct immediate *im = TNL_CURRENT_IM(ctx);
- VERTEX2( im, x, y );
-}
+/*
+ * NV_vertex_program
+ */
+static void
+_tnl_VertexAttrib4fNV( GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w )
+{
+ if (index < 16) {
+ GET_IMMEDIATE;
+ const GLuint count = IM->Count;
+ GLfloat *attrib = IM->Attrib[index][count];
+ ASSIGN_4V(attrib, x, y, z, w);
+ IM->Flag[count] |= (1 << index);
+ if (index == 0) {
+ IM->Count++;
+ if (count == IMM_MAXDATA - 1)
+ _tnl_flush_immediate( NULL, IM );
+ }
+ }
+ else {
+ GET_CURRENT_CONTEXT(ctx);
+ _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribNV(index > 15)");
+ }
+}
+
+static void
+_tnl_VertexAttrib4fvNV( GLuint index, const GLfloat *v )
+{
+ if (index < 16) {
+ GET_IMMEDIATE;
+ const GLuint count = IM->Count;
+ GLfloat *attrib = IM->Attrib[index][count];
+ COPY_4V(attrib, v);
+ IM->Flag[count] |= (1 << index);
+ if (index == 0) {
+ IM->Count++;
+ if (count == IMM_MAXDATA - 1)
+ _tnl_flush_immediate( NULL, IM );
+ }
+ }
+ else {
+ GET_CURRENT_CONTEXT(ctx);
+ _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribNV(index > 15)");
+ }
+}
/* Execute a glRectf() function. _tnl_hard_begin() ensures the check
* on outside_begin_end is executed even in compiled lists. These
- * vertices can now participate in the same VB as regular ones, even
- * in most display lists.
+ * vertices can now participate in the same immediate as regular ones,
+ * even in most display lists.
*/
static void
_tnl_Rectf( GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2 )
GET_CURRENT_CONTEXT(ctx);
if (_tnl_hard_begin( ctx, GL_QUADS )) {
- _tnl_vertex2f( ctx, x1, y1 );
- _tnl_vertex2f( ctx, x2, y1 );
- _tnl_vertex2f( ctx, x2, y2 );
- _tnl_vertex2f( ctx, x1, y2 );
- _tnl_end( ctx );
+ glVertex2f( x1, y1 );
+ glVertex2f( x2, y1 );
+ glVertex2f( x2, y2 );
+ glVertex2f( x1, y2 );
+ glEnd();
}
}
_tnl_Materialfv( GLenum face, GLenum pname, const GLfloat *params )
{
GET_CURRENT_CONTEXT(ctx);
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
struct immediate *IM = TNL_CURRENT_IM(ctx);
GLuint count = IM->Count;
struct gl_material *mat;
if (bitmask == 0)
return;
+
+ if (MESA_VERBOSE & VERBOSE_API)
+ _mesa_debug(ctx, "_tnl_Materialfv\n");
+
+ if (tnl->IsolateMaterials &&
+ !(IM->BeginState & VERT_BEGIN_1)) /* heuristic */
+ {
+ _tnl_flush_immediate( ctx, IM );
+ IM = TNL_CURRENT_IM(ctx);
+ count = IM->Count;
+ }
- if (!(IM->Flag[count] & VERT_MATERIAL)) {
+ if (!(IM->Flag[count] & VERT_BIT_MATERIAL)) {
if (!IM->Material) {
- IM->Material = (GLmaterial (*)[2]) MALLOC( sizeof(GLmaterial) *
- IMM_SIZE * 2 );
+ IM->Material = (struct gl_material (*)[2])
+ MALLOC( sizeof(struct gl_material) * IMM_SIZE * 2 );
IM->MaterialMask = (GLuint *) MALLOC( sizeof(GLuint) * IMM_SIZE );
IM->MaterialMask[IM->LastMaterial] = 0;
}
IM->MaterialOrMask & ~bitmask );
}
- IM->Flag[count] |= VERT_MATERIAL;
+ IM->Flag[count] |= VERT_BIT_MATERIAL;
IM->MaterialMask[count] = 0;
IM->MaterialAndMask &= IM->MaterialMask[IM->LastMaterial];
IM->LastMaterial = count;
mat[1].DiffuseIndex = params[1];
mat[1].SpecularIndex = params[2];
}
+
+ if (tnl->IsolateMaterials &&
+ !(IM->BeginState & VERT_BEGIN_1)) /* heuristic */
+ {
+ _tnl_flush_immediate( ctx, IM );
+ }
}
void _tnl_imm_vtxfmt_init( GLcontext *ctx )
vfmt->Vertex3fv = _tnl_Vertex3fv;
vfmt->Vertex4f = _tnl_Vertex4f;
vfmt->Vertex4fv = _tnl_Vertex4fv;
+ vfmt->VertexAttrib4fNV = _tnl_VertexAttrib4fNV;
+ vfmt->VertexAttrib4fvNV = _tnl_VertexAttrib4fvNV;
/* Outside begin/end functions (from t_varray.c, t_eval.c, ...):
*/