summaryrefslogtreecommitdiff
path: root/src/mesa/tnl/t_imm_dlist.c
diff options
context:
space:
mode:
authorKeith Whitwell <keith@tungstengraphics.com>2003-11-24 15:23:18 +0000
committerKeith Whitwell <keith@tungstengraphics.com>2003-11-24 15:23:18 +0000
commitae0eaf93e092ac8e8b1c98f3e986de96940663fa (patch)
tree56aae7c4b985f657384df5e088227c4dd08130fb /src/mesa/tnl/t_imm_dlist.c
parent57c9814b9e87924696df4c741861c29d4236d1eb (diff)
Merge vtx-0-2-branch
Diffstat (limited to 'src/mesa/tnl/t_imm_dlist.c')
-rw-r--r--src/mesa/tnl/t_imm_dlist.c667
1 files changed, 0 insertions, 667 deletions
diff --git a/src/mesa/tnl/t_imm_dlist.c b/src/mesa/tnl/t_imm_dlist.c
deleted file mode 100644
index 8fcc9b25f0..0000000000
--- a/src/mesa/tnl/t_imm_dlist.c
+++ /dev/null
@@ -1,667 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version: 5.1
- *
- * Copyright (C) 1999-2003 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.
- *
- * Authors:
- * Keith Whitwell <keith@tungstengraphics.com>
- */
-
-
-#include "glheader.h"
-#include "context.h"
-#include "dlist.h"
-#include "debug.h"
-#include "macros.h"
-#include "imports.h"
-#include "state.h"
-
-#include "t_context.h"
-#include "t_imm_api.h"
-#include "t_imm_elt.h"
-#include "t_imm_alloc.h"
-#include "t_imm_dlist.h"
-#include "t_imm_debug.h"
-#include "t_imm_exec.h"
-#include "t_imm_fixup.h"
-#include "t_pipeline.h"
-
-typedef struct {
- struct immediate *IM;
- GLuint Start;
- GLuint Count;
- GLuint BeginState;
- GLuint SavedBeginState;
- GLuint OrFlag;
- GLuint AndFlag;
- GLuint TexSize;
- GLuint LastData;
- GLuint LastPrimitive;
- GLuint LastMaterial;
- GLuint MaterialOrMask;
- GLuint MaterialAndMask;
-} TNLvertexcassette;
-
-static void execute_compiled_cassette( GLcontext *ctx, void *data );
-static void loopback_compiled_cassette( GLcontext *ctx, struct immediate *IM );
-
-
-static void
-build_normal_lengths( struct immediate *IM )
-{
- GLuint i;
- GLfloat len;
- GLfloat (*data)[4] = IM->Attrib[VERT_ATTRIB_NORMAL] + IM->Start;
- GLfloat *dest = IM->NormalLengthPtr;
- const GLuint *flags = IM->Flag + IM->Start;
- const GLuint count = IM->Count - IM->Start;
-
- if (!dest) {
- dest = IM->NormalLengthPtr = (GLfloat *) ALIGN_MALLOC( IMM_SIZE*sizeof(GLfloat), 32 );
- if (!dest) return;
- }
- dest += IM->Start;
-
- len = (GLfloat) LEN_3FV( data[0] );
- if (len > 0.0F) len = 1.0F / len;
-
- for (i = 0 ; i < count ; ) {
- dest[i] = len;
- if (flags[++i] & VERT_BIT_NORMAL) {
- len = (GLfloat) LEN_3FV( data[i] );
- if (len > 0.0F) len = 1.0F / len;
- }
- }
-}
-
-
-static void
-fixup_normal_lengths( struct immediate *IM )
-{
- GLuint i;
- GLfloat len = 1.0F; /* just to silence warnings */
- GLfloat (*data)[4] = IM->Attrib[VERT_ATTRIB_NORMAL];
- GLfloat *dest = IM->NormalLengthPtr;
- const GLuint *flags = IM->Flag;
-
- for (i = IM->CopyStart ; i <= IM->Start ; i++) {
- len = (GLfloat) LEN_3FV( data[i] );
- if (len > 0.0F)
- len = 1.0F / len;
- dest[i] = len;
- }
-
- if (i < IM->Count) {
- while (!(flags[i] & (VERT_BIT_NORMAL|VERT_BIT_END_VB))) {
- dest[i] = len;
- i++;
- }
- }
-}
-
-
-
-/* Insert the active immediate struct onto the display list currently
- * being built.
- */
-void
-_tnl_compile_cassette( GLcontext *ctx, struct immediate *IM )
-{
- struct immediate *im = TNL_CURRENT_IM(ctx);
- TNLcontext *tnl = TNL_CONTEXT(ctx);
- TNLvertexcassette *node;
- GLuint new_beginstate;
-
- if (MESA_VERBOSE & VERBOSE_DISPLAY_LIST)
- _mesa_debug(ctx, "_tnl_compiled_cassette IM: %d\n", IM->id);
-
- if (IM->FlushElt) {
- ASSERT (IM->FlushElt == FLUSH_ELT_LAZY);
- _tnl_translate_array_elts( ctx, IM, IM->Start, IM->Count );
- }
-
- _tnl_compute_orflag( IM, IM->Start );
-
- /* Need to clear this flag, or fixup gets confused. (The
- * array-elements have been translated away by now, so it's ok to
- * remove it.)
- */
- IM->OrFlag &= ~VERT_BIT_ELT;
- IM->AndFlag &= ~VERT_BIT_ELT;
-
- _tnl_fixup_input( ctx, IM );
-
- /* Allocate space for this structure in the display list currently
- * being compiled.
- */
- node = (TNLvertexcassette *)
- _mesa_alloc_instruction(ctx,
- tnl->opcode_vertex_cassette,
- sizeof(TNLvertexcassette));
- if (!node)
- return;
-
- node->IM = im; im->ref_count++;
- node->Start = im->Start;
- node->Count = im->Count;
- node->BeginState = im->BeginState;
- node->SavedBeginState = im->SavedBeginState;
- node->OrFlag = im->OrFlag;
- node->TexSize = im->TexSize;
- node->AndFlag = im->AndFlag;
- node->LastData = im->LastData;
- node->LastPrimitive = im->LastPrimitive;
- node->LastMaterial = im->LastMaterial;
- node->MaterialOrMask = im->MaterialOrMask;
- node->MaterialAndMask = im->MaterialAndMask;
-
- /*
- * XXX always allocate VERT_ATTRIB_NORMAL array now???
- */
- if (tnl->CalcDListNormalLengths && IM->Attrib[VERT_ATTRIB_NORMAL]) {
- build_normal_lengths( im );
- }
-
- if (ctx->ExecuteFlag) {
- execute_compiled_cassette( ctx, (void *)node );
- }
-
- /* Discard any errors raised in the last cassette.
- */
- new_beginstate = node->BeginState & (VERT_BEGIN_0|VERT_BEGIN_1);
-
- /* Decide whether this immediate struct is full, or can be used for
- * the next batch of vertices as well.
- */
- if (im->Count > IMM_MAXDATA - 16) {
- /* Call it full...
- */
- struct immediate *new_im = _tnl_alloc_immediate(ctx);
- new_im->ref_count++;
- im->ref_count--; /* remove CURRENT_IM reference */
- ASSERT(im->ref_count > 0); /* it is compiled into a display list */
- SET_IMMEDIATE( ctx, new_im );
- _tnl_reset_compile_input( ctx, IMM_MAX_COPIED_VERTS,
- new_beginstate, node->SavedBeginState );
- } else {
- /* Still some room in the current immediate.
- */
- _tnl_reset_compile_input( ctx, im->Count+1+IMM_MAX_COPIED_VERTS,
- new_beginstate, node->SavedBeginState);
- }
-}
-
-
-static void
-fixup_compiled_primitives( GLcontext *ctx, struct immediate *IM )
-{
- TNLcontext *tnl = TNL_CONTEXT(ctx);
-
- /* Can potentially overwrite primitive details - need to save the
- * first slot:
- */
- tnl->DlistPrimitive = IM->Primitive[IM->Start];
- tnl->DlistPrimitiveLength = IM->PrimitiveLength[IM->Start];
- tnl->DlistLastPrimitive = IM->LastPrimitive;
-
- /* The first primitive may be different from what was recorded in
- * the immediate struct. Consider an immediate that starts with a
- * glBegin, compiled in a display list, which is called from within
- * an existing Begin/End object.
- */
- if (ctx->Driver.CurrentExecPrimitive == GL_POLYGON+1) {
- GLuint i;
-
- if (IM->BeginState & VERT_ERROR_1)
- _mesa_error( ctx, GL_INVALID_OPERATION, "glBegin/glEnd");
-
- for (i = IM->Start ; i <= IM->Count ; i += IM->PrimitiveLength[i])
- if (IM->Flag[i] & (VERT_BIT_BEGIN|VERT_BIT_END_VB))
- break;
-
- /* Would like to just ignore vertices upto this point. Can't
- * set copystart because it might skip materials?
- */
- ASSERT(IM->Start == IM->CopyStart);
- if (i > IM->CopyStart || !(IM->Flag[IM->Start] & VERT_BIT_BEGIN)) {
- IM->Primitive[IM->CopyStart] = GL_POLYGON+1;
- IM->PrimitiveLength[IM->CopyStart] = i - IM->CopyStart;
- if (IM->Flag[i] & VERT_BIT_END_VB) {
- IM->Primitive[IM->CopyStart] |= PRIM_LAST;
- IM->LastPrimitive = IM->CopyStart;
- }
- }
- }
- else {
- GLuint i;
-
- if (IM->BeginState & VERT_ERROR_0)
- _mesa_error( ctx, GL_INVALID_OPERATION, "glBegin/glEnd");
-
- if (IM->CopyStart == IM->Start &&
- IM->Flag[IM->Start] & (VERT_BIT_END | VERT_BIT_END_VB))
- {
- /* nothing */
- }
- else
- {
- IM->Primitive[IM->CopyStart] = ctx->Driver.CurrentExecPrimitive;
- if (tnl->ExecParity)
- IM->Primitive[IM->CopyStart] |= PRIM_PARITY;
-
- /* one of these should be true, else we'll be in an infinite loop
- */
- ASSERT(IM->PrimitiveLength[IM->Start] > 0 ||
- IM->Flag[IM->Start] & (VERT_BIT_END | VERT_BIT_END_VB));
-
- for (i = IM->Start ; i <= IM->Count ; i += IM->PrimitiveLength[i]) {
- if (IM->Flag[i] & (VERT_BIT_END | VERT_BIT_END_VB)) {
- IM->PrimitiveLength[IM->CopyStart] = i - IM->CopyStart;
- if (IM->Flag[i] & VERT_BIT_END_VB) {
- IM->Primitive[IM->CopyStart] |= PRIM_LAST;
- IM->LastPrimitive = IM->CopyStart;
- }
- if (IM->Flag[i] & VERT_BIT_END) {
- IM->Primitive[IM->CopyStart] |= PRIM_END;
- }
- break;
- }
- }
- }
- }
-}
-
-
-/* Undo any changes potentially made to the immediate in the range
- * IM->Start..IM->Count above.
- */
-static void
-restore_compiled_primitives( GLcontext *ctx, struct immediate *IM )
-{
- TNLcontext *tnl = TNL_CONTEXT(ctx);
- IM->Primitive[IM->Start] = tnl->DlistPrimitive;
- IM->PrimitiveLength[IM->Start] = tnl->DlistPrimitiveLength;
-}
-
-
-static void
-execute_compiled_cassette( GLcontext *ctx, void *data )
-{
- TNLcontext *tnl = TNL_CONTEXT(ctx);
- TNLvertexcassette *node = (TNLvertexcassette *)data;
- struct immediate *IM = node->IM;
-
-/* _mesa_debug("%s\n", __FUNCTION__); */
-
- IM->Start = node->Start;
- IM->CopyStart = node->Start;
- IM->Count = node->Count;
- IM->BeginState = node->BeginState;
- IM->SavedBeginState = node->SavedBeginState;
- IM->OrFlag = node->OrFlag;
- IM->TexSize = node->TexSize;
- IM->AndFlag = node->AndFlag;
- IM->LastData = node->LastData;
- IM->LastPrimitive = node->LastPrimitive;
- IM->LastMaterial = node->LastMaterial;
- IM->MaterialOrMask = node->MaterialOrMask;
- IM->MaterialAndMask = node->MaterialAndMask;
-
- if ((MESA_VERBOSE & VERBOSE_DISPLAY_LIST) &&
- (MESA_VERBOSE & VERBOSE_IMMEDIATE))
- _tnl_print_cassette( IM );
-
- if (MESA_VERBOSE & VERBOSE_DISPLAY_LIST) {
- _mesa_debug(ctx, "Run cassette %d, rows %d..%d, beginstate %x ",
- IM->id, IM->Start, IM->Count, IM->BeginState);
- _tnl_print_vert_flags("orflag", IM->OrFlag);
- }
-
-
- /* Need to respect 'HardBeginEnd' even if the commands are looped
- * back to a driver tnl module.
- */
- if (IM->SavedBeginState) {
- if (ctx->Driver.CurrentExecPrimitive == GL_POLYGON+1)
- tnl->ReplayHardBeginEnd = 1;
- if (!tnl->ReplayHardBeginEnd) {
- /* This is a user error. Whatever operation (like glRectf)
- * decomposed to this hard begin/end pair is now being run
- * inside a begin/end object -- illegally. Reject it and
- * raise an error.
- */
- _mesa_error(ctx, GL_INVALID_OPERATION, "hard replay");
- return;
- }
- }
-
- if (tnl->LoopbackDListCassettes) {
-/* (tnl->IsolateMaterials && (IM->OrFlag & VERT_MATERIAL)) ) { */
- fixup_compiled_primitives( ctx, IM );
- loopback_compiled_cassette( ctx, IM );
- restore_compiled_primitives( ctx, IM );
- }
- else {
- if (ctx->NewState)
- _mesa_update_state(ctx);
-
- if (tnl->pipeline.build_state_changes)
- _tnl_validate_pipeline( ctx );
-
- _tnl_fixup_compiled_cassette( ctx, IM );
- fixup_compiled_primitives( ctx, IM );
-
- if (IM->Primitive[IM->LastPrimitive] & PRIM_END)
- ctx->Driver.CurrentExecPrimitive = GL_POLYGON+1;
- else if ((IM->Primitive[IM->LastPrimitive] & PRIM_BEGIN) ||
- (IM->Primitive[IM->LastPrimitive] & PRIM_MODE_MASK) ==
- PRIM_OUTSIDE_BEGIN_END) {
- ctx->Driver.CurrentExecPrimitive =
- IM->Primitive[IM->LastPrimitive] & PRIM_MODE_MASK;
- }
-
- _tnl_get_exec_copy_verts( ctx, IM );
-
- if (IM->NormalLengthPtr)
- fixup_normal_lengths( IM );
-
- if (IM->Count == IM->Start)
- _tnl_copy_to_current( ctx, IM, IM->OrFlag, IM->LastData );
- else {
-/* _tnl_print_cassette( IM ); */
- _tnl_run_cassette( ctx, IM );
- }
-
- restore_compiled_primitives( ctx, IM );
- }
-
- if (ctx->Driver.CurrentExecPrimitive == GL_POLYGON+1)
- tnl->ReplayHardBeginEnd = 0;
-}
-
-
-static void
-destroy_compiled_cassette( GLcontext *ctx, void *data )
-{
- TNLvertexcassette *node = (TNLvertexcassette *)data;
-
- if ( --node->IM->ref_count == 0 )
- _tnl_free_immediate( ctx, node->IM );
-}
-
-
-static void
-print_compiled_cassette( GLcontext *ctx, void *data )
-{
- TNLvertexcassette *node = (TNLvertexcassette *)data;
- struct immediate *IM = node->IM;
-
- _mesa_debug(ctx, "TNL-VERTEX-CASSETTE, id %u, rows %u..%u\n",
- node->IM->id, node->Start, node->Count);
-
- IM->Start = node->Start;
- IM->CopyStart = node->Start;
- IM->Count = node->Count;
- IM->BeginState = node->BeginState;
- IM->OrFlag = node->OrFlag;
- IM->TexSize = node->TexSize;
- IM->AndFlag = node->AndFlag;
- IM->LastData = node->LastData;
- IM->LastPrimitive = node->LastPrimitive;
- IM->LastMaterial = node->LastMaterial;
- IM->MaterialOrMask = node->MaterialOrMask;
- IM->MaterialAndMask = node->MaterialAndMask;
-
- _tnl_print_cassette( node->IM );
-}
-
-
-void
-_tnl_BeginCallList( GLcontext *ctx, GLuint list )
-{
- (void) ctx;
- (void) list;
- FLUSH_CURRENT(ctx, 0);
-}
-
-
-/* Called at the tail of a CallList. Make current immediate aware of
- * any new to-be-copied vertices.
- */
-void
-_tnl_EndCallList( GLcontext *ctx )
-{
- GLuint beginstate = 0;
-
- if (ctx->Driver.CurrentExecPrimitive != PRIM_OUTSIDE_BEGIN_END)
- beginstate = VERT_BEGIN_0|VERT_BEGIN_1;
-
- _tnl_reset_exec_input( ctx, TNL_CURRENT_IM(ctx)->Start, beginstate, 0 );
-}
-
-
-void
-_tnl_EndList( GLcontext *ctx )
-{
- struct immediate *IM = TNL_CURRENT_IM(ctx);
-
- ctx->swtnl_im = 0;
- IM->ref_count--;
-
- /* outside begin/end, even in COMPILE_AND_EXEC,
- * so no vertices to copy, right?
- */
- ASSERT(TNL_CONTEXT(ctx)->ExecCopyCount == 0);
-
- /* If this one isn't free, get a clean one. (Otherwise we'll be
- * using one that's already half full).
- */
- if (IM->ref_count != 0)
- IM = _tnl_alloc_immediate( ctx );
-
- ASSERT(IM->ref_count == 0);
-
- SET_IMMEDIATE( ctx, IM );
- IM->ref_count++;
-
- _tnl_reset_exec_input( ctx, IMM_MAX_COPIED_VERTS, 0, 0 );
-}
-
-
-void
-_tnl_NewList( GLcontext *ctx, GLuint list, GLenum mode )
-{
- struct immediate *IM = TNL_CURRENT_IM(ctx);
-
- /* Use the installed immediate struct. No vertices in the current
- * immediate, no copied vertices in the system.
- */
- ASSERT(TNL_CURRENT_IM(ctx));
- ASSERT(TNL_CURRENT_IM(ctx)->Start == IMM_MAX_COPIED_VERTS);
- ASSERT(TNL_CURRENT_IM(ctx)->Start == TNL_CURRENT_IM(ctx)->Count);
- ASSERT(TNL_CONTEXT(ctx)->ExecCopyCount == 0);
-
- /* Set current Begin/End state to unknown:
- */
- IM->BeginState = VERT_BEGIN_0;
- ctx->Driver.CurrentSavePrimitive = PRIM_UNKNOWN;
-}
-
-
-void
-_tnl_dlist_init( GLcontext *ctx )
-{
- TNLcontext *tnl = TNL_CONTEXT(ctx);
-
- tnl->opcode_vertex_cassette =
- _mesa_alloc_opcode( ctx,
- sizeof(TNLvertexcassette),
- execute_compiled_cassette,
- destroy_compiled_cassette,
- print_compiled_cassette );
-}
-
-
-/**
- * Call glMaterialfv for the attributes specified by bitmask, using the
- * material colors in src.
- */
-static void
-emit_material( const struct gl_material *src, GLuint bitmask )
-{
- const GLfloat (*attr)[4] = src->Attrib;
-
- if (bitmask & MAT_BIT_FRONT_EMISSION)
- glMaterialfv( GL_FRONT, GL_EMISSION, attr[MAT_ATTRIB_FRONT_EMISSION] );
-
- if (bitmask & MAT_BIT_BACK_EMISSION)
- glMaterialfv( GL_BACK, GL_EMISSION, attr[MAT_ATTRIB_BACK_EMISSION] );
-
- if (bitmask & MAT_BIT_FRONT_AMBIENT)
- glMaterialfv( GL_FRONT, GL_AMBIENT, attr[MAT_ATTRIB_FRONT_AMBIENT] );
-
- if (bitmask & MAT_BIT_BACK_AMBIENT)
- glMaterialfv( GL_BACK, GL_AMBIENT, attr[MAT_ATTRIB_BACK_AMBIENT] );
-
- if (bitmask & MAT_BIT_FRONT_DIFFUSE)
- glMaterialfv( GL_FRONT, GL_DIFFUSE, attr[MAT_ATTRIB_FRONT_DIFFUSE] );
-
- if (bitmask & MAT_BIT_BACK_DIFFUSE)
- glMaterialfv( GL_BACK, GL_DIFFUSE, attr[MAT_ATTRIB_BACK_DIFFUSE] );
-
- if (bitmask & MAT_BIT_FRONT_SPECULAR)
- glMaterialfv( GL_FRONT, GL_SPECULAR, attr[MAT_ATTRIB_FRONT_SPECULAR] );
-
- if (bitmask & MAT_BIT_BACK_SPECULAR)
- glMaterialfv( GL_BACK, GL_SPECULAR, attr[MAT_ATTRIB_BACK_SPECULAR] );
-
- if (bitmask & MAT_BIT_FRONT_SHININESS)
- glMaterialfv( GL_FRONT, GL_SHININESS, attr[MAT_ATTRIB_FRONT_SHININESS] );
-
- if (bitmask & MAT_BIT_BACK_SHININESS)
- glMaterialfv( GL_BACK, GL_SHININESS, attr[MAT_ATTRIB_BACK_SHININESS] );
-
- if (bitmask & MAT_BIT_FRONT_INDEXES)
- glMaterialfv( GL_FRONT, GL_COLOR_INDEXES, attr[MAT_ATTRIB_FRONT_INDEXES]);
-
- if (bitmask & MAT_BIT_BACK_INDEXES)
- glMaterialfv( GL_BACK, GL_COLOR_INDEXES, attr[MAT_ATTRIB_BACK_INDEXES] );
-}
-
-
-/* Low-performance helper function to allow driver-supplied tnl
- * modules to process tnl display lists. This is primarily supplied
- * to avoid fallbacks if CallList is invoked inside a Begin/End pair.
- * For higher performance, drivers should fallback to tnl (if outside
- * begin/end), or (for tnl hardware) implement their own display list
- * mechanism.
- */
-static void
-loopback_compiled_cassette( GLcontext *ctx, struct immediate *IM )
-{
- const GLuint *flags = IM->Flag;
- const GLuint orflag = IM->OrFlag;
- void (GLAPIENTRY *vertex)( const GLfloat * );
- void (GLAPIENTRY *texcoordfv[MAX_TEXTURE_COORD_UNITS])( GLenum, const GLfloat * );
- GLuint i, j, p, length, prim = 0, maxtex = 0;
-
- if (orflag & VERT_BITS_OBJ_234)
- vertex = (void (GLAPIENTRY *)(const GLfloat *)) glVertex4fv;
- else
- vertex = (void (GLAPIENTRY *)(const GLfloat *)) glVertex3fv;
-
- if (orflag & VERT_BITS_TEX_ANY) {
- for (j = 0 ; j < ctx->Const.MaxTextureCoordUnits ; j++) {
- if (orflag & VERT_BIT_TEX(j)) {
- maxtex = j+1;
- if ((IM->TexSize & TEX_SIZE_4(j)) == TEX_SIZE_4(j))
- texcoordfv[j] = glMultiTexCoord4fvARB;
- else if (IM->TexSize & TEX_SIZE_3(j))
- texcoordfv[j] = glMultiTexCoord3fvARB;
- else
- texcoordfv[j] = glMultiTexCoord2fvARB;
- }
- }
- }
-
- for (p = IM->Start ; !(prim & PRIM_LAST) ; p += length)
- {
- prim = IM->Primitive[p];
- length= IM->PrimitiveLength[p];
- ASSERT(length || (prim & PRIM_LAST));
- ASSERT((prim & PRIM_MODE_MASK) <= GL_POLYGON+1);
-
- if (prim & PRIM_BEGIN) {
- glBegin(prim & PRIM_MODE_MASK);
- }
-
- for ( i = p ; i <= p+length ; i++) {
- if (flags[i] & VERT_BITS_TEX_ANY) {
- GLuint k;
- for (k = 0 ; k < maxtex ; k++) {
- if (flags[i] & VERT_BIT_TEX(k)) {
- texcoordfv[k]( GL_TEXTURE0_ARB + k,
- IM->Attrib[VERT_ATTRIB_TEX0 + k][i] );
- }
- }
- }
-
- /* XXX Maybe we should jump through _glapi->Dispatch all the time?? */
- if (flags[i] & VERT_BIT_NORMAL)
- glNormal3fv(IM->Attrib[VERT_ATTRIB_NORMAL][i]);
-
- if (flags[i] & VERT_BIT_COLOR0)
- glColor4fv( IM->Attrib[VERT_ATTRIB_COLOR0][i] );
-
- if (flags[i] & VERT_BIT_COLOR1)
- _glapi_Dispatch->SecondaryColor3fvEXT( IM->Attrib[VERT_ATTRIB_COLOR1][i] );
-
- if (flags[i] & VERT_BIT_FOG)
- _glapi_Dispatch->FogCoordfEXT( IM->Attrib[VERT_ATTRIB_FOG][i][0] );
-
- if (flags[i] & VERT_BIT_INDEX)
- glIndexi( IM->Index[i] );
-
- if (flags[i] & VERT_BIT_EDGEFLAG)
- glEdgeFlag( IM->EdgeFlag[i] );
-
- if (flags[i] & VERT_BIT_MATERIAL)
- emit_material( &IM->Material[i], IM->MaterialMask[i] );
-
- if (flags[i]&VERT_BITS_OBJ_234)
- vertex( IM->Attrib[VERT_ATTRIB_POS][i] );
- else if (flags[i] & VERT_BIT_EVAL_C1)
- glEvalCoord1f( IM->Attrib[VERT_ATTRIB_POS][i][0] );
- else if (flags[i] & VERT_BIT_EVAL_P1)
- glEvalPoint1( (GLint) IM->Attrib[VERT_ATTRIB_POS][i][0] );
- else if (flags[i] & VERT_BIT_EVAL_C2)
- glEvalCoord2f( IM->Attrib[VERT_ATTRIB_POS][i][0],
- IM->Attrib[VERT_ATTRIB_POS][i][1] );
- else if (flags[i] & VERT_BIT_EVAL_P2)
- glEvalPoint2( (GLint) IM->Attrib[VERT_ATTRIB_POS][i][0],
- (GLint) IM->Attrib[VERT_ATTRIB_POS][i][1] );
- }
-
- if (prim & PRIM_END) {
- glEnd();
- }
- }
-}