head	3.19;
access;
symbols
	merge-1:3.18.2.2
	autoconf:3.18.0.4
	experimental-1:3.18.0.2
	mesa-3-1-with-kw3:3.16
	mesa-3-1-prior-to-kw3:3.15;
locks; strict;
comment	@ * @;


3.19
date	99.07.12.12.05.25;	author keithw;	state Exp;
branches;
next	3.18;

3.18
date	99.04.29.14.43.16;	author keithw;	state Exp;
branches
	3.18.2.1;
next	3.17;

3.17
date	99.03.31.20.18.41;	author keithw;	state Exp;
branches;
next	3.16;

3.16
date	99.02.25.14.12.32;	author keithw;	state Exp;
branches;
next	3.15;

3.15
date	99.02.24.22.48.08;	author jens;	state Exp;
branches;
next	3.14;

3.14
date	99.02.14.03.46.34;	author brianp;	state Exp;
branches;
next	3.13;

3.13
date	98.11.25.04.18.19;	author brianp;	state Exp;
branches;
next	3.12;

3.12
date	98.11.17.01.52.47;	author brianp;	state Exp;
branches;
next	3.11;

3.11
date	98.11.08.22.36.34;	author brianp;	state Exp;
branches;
next	3.10;

3.10
date	98.11.03.02.40.40;	author brianp;	state Exp;
branches;
next	3.9;

3.9
date	98.10.31.17.06.15;	author brianp;	state Exp;
branches;
next	3.8;

3.8
date	98.10.29.03.57.11;	author brianp;	state Exp;
branches;
next	3.7;

3.7
date	98.10.29.02.28.13;	author brianp;	state Exp;
branches;
next	3.6;

3.6
date	98.06.07.22.18.52;	author brianp;	state Exp;
branches;
next	3.5;

3.5
date	98.04.18.05.00.42;	author brianp;	state Exp;
branches;
next	3.4;

3.4
date	98.03.27.04.26.44;	author brianp;	state Exp;
branches;
next	3.3;

3.3
date	98.02.20.04.53.07;	author brianp;	state Exp;
branches;
next	3.2;

3.2
date	98.02.08.20.17.42;	author brianp;	state Exp;
branches;
next	3.1;

3.1
date	98.02.02.03.09.34;	author brianp;	state Exp;
branches;
next	3.0;

3.0
date	98.01.31.21.06.45;	author brianp;	state Exp;
branches;
next	;

3.18.2.1
date	99.05.21.21.29.28;	author keithw;	state Exp;
branches;
next	3.18.2.2;

3.18.2.2
date	99.06.19.15.04.15;	author keithw;	state Exp;
branches;
next	;


desc
@vertex buffer filling functions
@


3.19
log
@merge from experimental branch upto merge-1 tag
@
text
@/* $Id: vbfill.c,v 3.18.2.2 1999/06/19 15:04:15 keithw Exp $ */

/*
 * Mesa 3-D graphics library
 * Version:  3.1
 * 
 * Copyright (C) 1999  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.
 */



#ifdef PC_HEADER
#include "all.h"
#else
#include <assert.h>
#include <stdio.h>
#include "context.h"
#include "enums.h"
#include "light.h"
#include "macros.h"
#include "matrix.h"
#include "mmath.h"
#include "types.h"
#include "vb.h"
#include "vbcull.h"
#include "vbfill.h"
#include "vbrender.h"
#include "vbxform.h"
#include "xform.h"
#ifdef XFree86Server
#include "GL/xf86glx.h"
#endif
#endif



/* KW: The work of most of the functions which were in this file are
 *     now done directly by the GLVertex, GLTexCoord, GLIndex, ...,
 *     functions in api{1,2}.c.  This is made possible by the fact
 *     that display lists and vertex buffers are now built the same
 *     way, so there is no need for the indirection and overhead of a
 *     function pointer.  
 */


GLuint gl_prim_rast_flags[GL_POLYGON+1] = {
   DD_POINT_SW_RASTERIZE,
   DD_LINE_SW_RASTERIZE,
   DD_LINE_SW_RASTERIZE,
   DD_LINE_SW_RASTERIZE,
   DD_TRI_SW_RASTERIZE,
   DD_TRI_SW_RASTERIZE,
   DD_TRI_SW_RASTERIZE,
   DD_QUAD_SW_RASTERIZE,
   DD_QUAD_SW_RASTERIZE,
   DD_TRI_SW_RASTERIZE
};


void gl_Begin( GLcontext *ctx, GLenum p )
{
   struct immediate *IM = ctx->input;
   GLuint inflags, state;

   if (MESA_VERBOSE&VERBOSE_API)
      fprintf(stderr, "glBegin %s\n", gl_lookup_enum_by_nr(p));
   
   if (ctx->NewState) 
      gl_update_state( ctx );	/* should already be flushed */
       
   /* if only a very few slots left, might as well flush now
    */
   if (IM->Count > VB_MAX-4) {	      
      IM->maybe_transform_vb( IM );
      IM = ctx->input;
   }

   state = IM->BeginState;
   inflags = state & (VERT_BEGIN_0|VERT_BEGIN_1);
   state |= inflags << 2;	/* set error conditions */

   if (inflags != (VERT_BEGIN_0|VERT_BEGIN_1))
   {
      GLuint count = IM->Count;
      state |= (VERT_BEGIN_0|VERT_BEGIN_1);
      IM->ReducedPrimitives |= gl_prim_rast_flags[p];
      IM->Flag[count] |= VERT_BEGIN; 
      IM->Primitive[count] = p;
      IM->NextPrimitive[IM->LastPrimitive] = count;
      IM->LastPrimitive = count;
   }

   IM->BeginState = state;
}



@


3.18
log
@fixes for xlockmore problems
@
text
@d1 1
a1 1
/* $Id: vbfill.c,v 3.17 1999/03/31 20:18:41 keithw Exp $ */
d33 1
d35 1
d63 12
a74 55

/**********************************************************************/
/******                   Mangement functions                    *****/
/**********************************************************************/


/* No longer does this, but forms part of the update_state processing.
 * Should go somewhere else.
 */
void gl_set_vertex_function( GLcontext *ctx )
{
   GLuint state = 0;

   if (ctx->RenderMode==GL_FEEDBACK) 
   {
      state = (VERT_RGBA|VERT_INDEX|
	       VERT_NORM|VERT_EDGE|
	       VERT_TEX0_ANY|VERT_TEX1_ANY);
   }
   else
   {	 
      if (ctx->Light.Enabled || ctx->Texture.NeedNormals)
      {
	 state |= VERT_NORM;
      } 

      if (!ctx->Light.Enabled) 
      {
	 if (ctx->Visual->RGBAflag) 
	    state |= VERT_RGBA;
	 else 
	    state |= VERT_INDEX;
      }
      
      if (ctx->Light.ColorMaterialEnabled)
	 state |= VERT_RGBA;

      if (ctx->Texture.Enabled) {
	 if (ctx->Texture.Enabled & TEXTURE0_ANY) state |= VERT_TEX0_ANY;
	 if (ctx->Texture.Enabled & TEXTURE1_ANY) state |= VERT_TEX1_ANY;
      }

      if (ctx->Polygon.Unfilled) {
	 state |= VERT_EDGE;
      }
   }

   ctx->Flags = state;
}


/**********************************************************************/
/*****                    glBegin / glEnd                         *****/
/**********************************************************************/

d82 4
a85 9
   /* Only INVALID_OPERATION errors handled via the flags.  Some
    * ordering issues, so this might have to change.
    */
   if (p < GL_POINTS || p > GL_POLYGON) {
      gl_compile_error( ctx, GL_INVALID_ENUM, "glBegin" );
      return;		     
   }

   if (ctx->NewState) {
a86 1
   }
a94 2


a98 1
   
d103 1
@


3.18.2.1
log
@Quake3 inspired optimizations
@
text
@d1 1
a1 1
/* $Id: vbfill.c,v 3.18 1999/04/29 14:43:16 keithw Exp $ */
d61 55
a115 12
GLuint gl_prim_rast_flags[GL_POLYGON+1] = {
   DD_POINT_SW_RASTERIZE,
   DD_LINE_SW_RASTERIZE,
   DD_LINE_SW_RASTERIZE,
   DD_LINE_SW_RASTERIZE,
   DD_TRI_SW_RASTERIZE,
   DD_TRI_SW_RASTERIZE,
   DD_TRI_SW_RASTERIZE,
   DD_QUAD_SW_RASTERIZE,
   DD_QUAD_SW_RASTERIZE,
   DD_TRI_SW_RASTERIZE
};
d123 9
a131 1
   if (ctx->NewState) 
d133 1
d142 2
d148 1
a152 1
      IM->ReducedPrimitives |= gl_prim_rast_flags[p];
@


3.18.2.2
log
@Removed SGIS multitexture, added FX/X86 assm directory
@
text
@d1 1
a1 1
/* $Id: vbfill.c,v 3.18.2.1 1999/05/21 21:29:28 keithw Exp $ */
a32 1
#include <stdio.h>
a33 1
#include "enums.h"
a79 3
   if (MESA_VERBOSE&VERBOSE_API)
      fprintf(stderr, "glBegin %s\n", gl_lookup_enum_by_nr(p));
   
@


3.17
log
@Compiled vertex arrays
@
text
@d1 1
a1 1
/* $Id: vbfill.c,v 1.3 1999/02/25 23:50:39 keithw Exp $ */
d136 2
a137 1
   if (IM->Count > VB_MAX-4) {	
d141 2
a142 1
 */
@


3.16
log
@Merged in kw3 patch
@
text
@d1 1
a1 1
/* $Id: vbfill.c,v 3.15 1999/02/24 22:48:08 jens Exp $ */
d57 1
a57 1
 *     function pointer & call.  
d78 1
a78 1
	       VERT_TEX0|VERT_TEX1);
d99 2
a100 2
	 if (ctx->Texture.Enabled & TEXTURE0_ANY) state |= VERT_TEX0;
	 if (ctx->Texture.Enabled & TEXTURE1_ANY) state |= VERT_TEX1;
a117 1

d121 1
a121 1
   GLuint inflags, andflag;
d134 4
a137 3
      
   if (IM->Count > VB_MAX-4) {
      FLUSH_VB( ctx, "glBegin");
d140 1
d142 3
a144 3
   andflag = IM->AndFlag;
   inflags = andflag & (VERT_BEGIN_0|VERT_BEGIN_1);
   andflag |= inflags << 2;	/* set error conditions */
d150 2
a151 2
      andflag |= (VERT_BEGIN_0|VERT_BEGIN_1);
      IM->Flag[count] |= /* ~inflags & */ (VERT_BEGIN_0|VERT_BEGIN_1); 
d157 1
a157 1
   IM->AndFlag = andflag;
@


3.15
log
@Added header file to get XMesa to compile standalone and inside XFree86
@
text
@d1 1
a1 1
/* $Id: vbfill.c,v 3.14 1999/02/14 03:46:34 brianp Exp $ */
a27 55
/*
 * $Log: vbfill.c,v $
 * Revision 3.14  1999/02/14 03:46:34  brianp
 * new copyright
 *
 * Revision 3.13  1998/11/25 04:18:19  brianp
 * fixed a few IRIX compiler warnings
 *
 * Revision 3.12  1998/11/17 01:52:47  brianp
 * implemented GL_NV_texgen_reflection extension (MJK)
 *
 * Revision 3.11  1998/11/08 22:36:34  brianp
 * renamed texture sets to texture units
 *
 * Revision 3.10  1998/11/03 02:40:40  brianp
 * new ctx->RenderVB function pointer
 *
 * Revision 3.9  1998/10/31 17:06:15  brianp
 * variety of multi-texture changes
 *
 * Revision 3.8  1998/10/29 03:57:11  brianp
 * misc clean-up of new vertex transformation code
 *
 * Revision 3.7  1998/10/29 02:28:13  brianp
 * incorporated Keith Whitwell's transformation optimizations
 *
 * Revision 3.6  1998/06/07 22:18:52  brianp
 * implemented GL_EXT_multitexture extension
 *
 * Revision 3.5  1998/04/18 05:00:42  brianp
 * moved FLOAT_COLOR_TO_UBYTE_COLOR macro to mmath.h
 *
 * Revision 3.4  1998/03/27 04:26:44  brianp
 * fixed G++ warnings
 *
 * Revision 3.3  1998/02/20 04:53:07  brianp
 * implemented GL_SGIS_multitexture
 *
 * Revision 3.2  1998/02/08 20:17:42  brianp
 * removed unneeded headers
 *
 * Revision 3.1  1998/02/02 03:09:34  brianp
 * added GL_LIGHT_MODEL_COLOR_CONTROL (separate specular color interpolation)
 *
 * Revision 3.0  1998/01/31 21:06:45  brianp
 * initial rev
 *
 */


/*
 * This file implements the functions for filling the vertex buffer:
 *   glVertex, glNormal, glColor, glIndex, glEdgeFlag, glTexCoord,
 */

a37 1
#include "pb.h"
d40 1
d52 6
a57 18
/**********************************************************************/
/******                    glNormal functions                     *****/
/**********************************************************************/

/*
 * Caller:  context->API.Normal3f pointer.
 */
void gl_Normal3f( GLcontext *ctx, GLfloat nx, GLfloat ny, GLfloat nz )
{
   ctx->Current.Normal[0] = nx;
   ctx->Current.Normal[1] = ny;
   ctx->Current.Normal[2] = nz;
   ctx->VB->MonoNormal = GL_FALSE;
}


/*
 * Caller:  context->API.Normal3fv pointer.
a58 7
void gl_Normal3fv( GLcontext *ctx, const GLfloat *n )
{
   ctx->Current.Normal[0] = n[0];
   ctx->Current.Normal[1] = n[1];
   ctx->Current.Normal[2] = n[2];
   ctx->VB->MonoNormal = GL_FALSE;
}
d63 1
a63 1
/******                    glIndex functions                      *****/
a65 9
/*
 * Caller:  context->API.Indexf pointer.
 */
void gl_Indexf( GLcontext *ctx, GLfloat c )
{
   ctx->Current.Index = (GLuint) (GLint) c;
   ctx->VB->MonoColor = GL_FALSE;
}

d67 2
a68 2
/*
 * Caller:  context->API.Indexi pointer.
d70 1
a70 1
void gl_Indexi( GLcontext *ctx, GLint c )
d72 1
a72 3
   ctx->Current.Index = (GLuint) c;
   ctx->VB->MonoColor = GL_FALSE;
}
d74 19
a92 937


/**********************************************************************/
/******                     glColor functions                     *****/
/**********************************************************************/


/*
 * Caller:  context->API.Color3f pointer.
 */
void gl_Color3f( GLcontext *ctx, GLfloat red, GLfloat green, GLfloat blue )
{
   FLOAT_COLOR_TO_UBYTE_COLOR(ctx->Current.ByteColor[0], red);
   FLOAT_COLOR_TO_UBYTE_COLOR(ctx->Current.ByteColor[1], green);
   FLOAT_COLOR_TO_UBYTE_COLOR(ctx->Current.ByteColor[2], blue);
   ctx->Current.ByteColor[3] = 255;
   ASSERT( !ctx->Light.ColorMaterialEnabled );
   ctx->VB->MonoColor = GL_FALSE;
}


/*
 * Caller:  context->API.Color3fv pointer.
 */
void gl_Color3fv( GLcontext *ctx, const GLfloat *c )
{
   FLOAT_COLOR_TO_UBYTE_COLOR(ctx->Current.ByteColor[0], c[0]);
   FLOAT_COLOR_TO_UBYTE_COLOR(ctx->Current.ByteColor[1], c[1]);
   FLOAT_COLOR_TO_UBYTE_COLOR(ctx->Current.ByteColor[2], c[2]);
   ctx->Current.ByteColor[3] = 255;
   ASSERT( !ctx->Light.ColorMaterialEnabled );
   ctx->VB->MonoColor = GL_FALSE;
}



/*
 * Caller:  context->API.Color4f pointer.
 */
void gl_Color4f( GLcontext *ctx,
                 GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha )
{
   FLOAT_COLOR_TO_UBYTE_COLOR(ctx->Current.ByteColor[0], red);
   FLOAT_COLOR_TO_UBYTE_COLOR(ctx->Current.ByteColor[1], green);
   FLOAT_COLOR_TO_UBYTE_COLOR(ctx->Current.ByteColor[2], blue);
   FLOAT_COLOR_TO_UBYTE_COLOR(ctx->Current.ByteColor[3], alpha);
   ASSERT( !ctx->Light.ColorMaterialEnabled );
   ctx->VB->MonoColor = GL_FALSE;
}


/*
 * Caller:  context->API.Color4fv pointer.
 */
void gl_Color4fv( GLcontext *ctx, const GLfloat *c )
{
   FLOAT_COLOR_TO_UBYTE_COLOR(ctx->Current.ByteColor[0], c[0]);
   FLOAT_COLOR_TO_UBYTE_COLOR(ctx->Current.ByteColor[1], c[1]);
   FLOAT_COLOR_TO_UBYTE_COLOR(ctx->Current.ByteColor[2], c[2]);
   FLOAT_COLOR_TO_UBYTE_COLOR(ctx->Current.ByteColor[3], c[3]);
   ASSERT( !ctx->Light.ColorMaterialEnabled );
   ctx->VB->MonoColor = GL_FALSE;
}


/*
 * Caller:  context->API.Color4ub pointer.
 */
void gl_Color4ub( GLcontext *ctx,
                  GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha )
{
   ASSIGN_4V( ctx->Current.ByteColor, red, green, blue, alpha );
   ASSERT( !ctx->Light.ColorMaterialEnabled );
   ctx->VB->MonoColor = GL_FALSE;
}


/*
 * Caller:  context->API.Color4ub pointer.
 */
void gl_Color4ubv( GLcontext *ctx, const GLubyte *c )
{
   COPY_4UBV( ctx->Current.ByteColor, c );
   ASSERT( !ctx->Light.ColorMaterialEnabled );
   ctx->VB->MonoColor = GL_FALSE;
}


/*
 * glColor() which modifies material(s).
 * Caller:  context->API.Color3f pointer.
 */
void gl_ColorMat3f( GLcontext *ctx, GLfloat red, GLfloat green, GLfloat blue )
{
   GLfloat color[4];
   FLOAT_COLOR_TO_UBYTE_COLOR(ctx->Current.ByteColor[0], red);
   FLOAT_COLOR_TO_UBYTE_COLOR(ctx->Current.ByteColor[1], green);
   FLOAT_COLOR_TO_UBYTE_COLOR(ctx->Current.ByteColor[2], blue);
   ctx->Current.ByteColor[3] = 255;
   /* update material */
   ASSERT( ctx->Light.ColorMaterialEnabled );
   ASSIGN_4V( color, red, green, blue, 1.0F );
   gl_set_material( ctx, ctx->Light.ColorMaterialBitmask, color );
   ctx->VB->MonoColor = GL_FALSE;
}


/*
 * glColor() which modifies material(s).
 * Caller:  context->API.Color3fv pointer.
 */
void gl_ColorMat3fv( GLcontext *ctx, const GLfloat *c )
{
   GLfloat color[4];
   FLOAT_COLOR_TO_UBYTE_COLOR(ctx->Current.ByteColor[0], c[0]);
   FLOAT_COLOR_TO_UBYTE_COLOR(ctx->Current.ByteColor[1], c[1]);
   FLOAT_COLOR_TO_UBYTE_COLOR(ctx->Current.ByteColor[2], c[2]);
   ctx->Current.ByteColor[3] = 255;
   /* update material */
   ASSERT( ctx->Light.ColorMaterialEnabled );
   ASSIGN_4V( color, c[0], c[1], c[2], 1.0F );
   gl_set_material( ctx, ctx->Light.ColorMaterialBitmask, color );
   ctx->VB->MonoColor = GL_FALSE;
}


/*
 * glColor() which modifies material(s).
 * Caller:  context->API.Color4f pointer.
 */
void gl_ColorMat4f( GLcontext *ctx,
                    GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha )
{
   GLfloat color[4];
   FLOAT_COLOR_TO_UBYTE_COLOR(ctx->Current.ByteColor[0], red);
   FLOAT_COLOR_TO_UBYTE_COLOR(ctx->Current.ByteColor[1], green);
   FLOAT_COLOR_TO_UBYTE_COLOR(ctx->Current.ByteColor[2], blue);
   FLOAT_COLOR_TO_UBYTE_COLOR(ctx->Current.ByteColor[3], alpha);
   /* update material */
   ASSERT( ctx->Light.ColorMaterialEnabled );
   ASSIGN_4V( color, red, green, blue, alpha );
   gl_set_material( ctx, ctx->Light.ColorMaterialBitmask, color );
   ctx->VB->MonoColor = GL_FALSE;
}


/*
 * glColor() which modifies material(s).
 * Caller:  context->API.Color4fv pointer.
 */
void gl_ColorMat4fv( GLcontext *ctx, const GLfloat *c )
{
   GLfloat color[4];
   FLOAT_COLOR_TO_UBYTE_COLOR(ctx->Current.ByteColor[0], c[0]);
   FLOAT_COLOR_TO_UBYTE_COLOR(ctx->Current.ByteColor[1], c[1]);
   FLOAT_COLOR_TO_UBYTE_COLOR(ctx->Current.ByteColor[2], c[2]);
   FLOAT_COLOR_TO_UBYTE_COLOR(ctx->Current.ByteColor[3], c[3]);
   /* update material */
   ASSERT( ctx->Light.ColorMaterialEnabled );
   ASSIGN_4V( color, c[0], c[1], c[2], c[3] );
   gl_set_material( ctx, ctx->Light.ColorMaterialBitmask, color );
   ctx->VB->MonoColor = GL_FALSE;
}


/*
 * glColor which modifies material(s).
 * Caller:  context->API.Color4ub pointer.
 */
void gl_ColorMat4ub( GLcontext *ctx,
                     GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha )
{
   GLfloat color[4];
   ASSIGN_4V( ctx->Current.ByteColor, red, green, blue, alpha );
   /* update material */
   ASSERT( ctx->Light.ColorMaterialEnabled );
   color[0] = red   * (1.0F/255.0F);
   color[1] = green * (1.0F/255.0F);
   color[2] = blue  * (1.0F/255.0F);
   color[3] = alpha * (1.0F/255.0F);
   gl_set_material( ctx, ctx->Light.ColorMaterialBitmask, color );
   ctx->VB->MonoColor = GL_FALSE;
}


/*
 * glColor which modifies material(s).
 * Caller:  context->API.Color4ub pointer.
 */
void gl_ColorMat4ubv( GLcontext *ctx, const GLubyte *c )
{
   gl_ColorMat4ub( ctx, c[0], c[1], c[2], c[3] );
}



/**********************************************************************/
/******                  glEdgeFlag functions                     *****/
/**********************************************************************/

/*
 * Caller:  context->API.EdgeFlag pointer.
 */
void gl_EdgeFlag( GLcontext *ctx, GLboolean flag )
{
   ctx->Current.EdgeFlag = flag;
}



/**********************************************************************/
/*****                    glVertex functions                      *****/
/**********************************************************************/

/*
 * Used when in feedback mode.
 * Caller:  context->API.Vertex4f pointer.
 */
static void vertex4f_feedback( GLcontext *ctx,
                               GLfloat x, GLfloat y, GLfloat z, GLfloat w )
{
   struct vertex_buffer *VB = ctx->VB;
   GLuint count = VB->Count;

   /* vertex */
   ASSIGN_4V( VB->Obj[count], x, y, z, w );

   /* color */
   COPY_4UBV( VB->Fcolor[count], ctx->Current.ByteColor );

   /* index */
   VB->Findex[count] = ctx->Current.Index;

   /* normal */
   COPY_3V( VB->Normal[count], ctx->Current.Normal );

   /* texcoord */
   COPY_4V( VB->TexCoord[count], ctx->Current.TexCoord );

   /* edgeflag */
   VB->Edgeflag[count] = ctx->Current.EdgeFlag;

   count++;
   VB->Count = count;
   if (count==VB_MAX) {
      gl_transform_vb( ctx, GL_FALSE );
   }
}


static void vertex3f_feedback( GLcontext *ctx, GLfloat x, GLfloat y, GLfloat z )
{
   vertex4f_feedback(ctx, x, y, z, 1.0F);
}


static void vertex2f_feedback( GLcontext *ctx, GLfloat x, GLfloat y )
{
   vertex4f_feedback(ctx, x, y, 0.0F, 1.0F);
}


static void vertex3fv_feedback( GLcontext *ctx, const GLfloat v[3] )
{
   vertex4f_feedback(ctx, v[0], v[1], v[2], 1.0F);
}



/*
 * Only one glVertex4 function since it's not too popular.
 * Caller:  context->API.Vertex4f pointer.
 */
static void vertex4( GLcontext *ctx,
                     GLfloat x, GLfloat y, GLfloat z, GLfloat w )
{
   struct vertex_buffer *VB = ctx->VB;
   GLuint count = VB->Count;

   ASSIGN_4V( VB->Obj[count], x, y, z, w );
   COPY_4UBV( VB->Fcolor[count], ctx->Current.ByteColor );
   COPY_3V( VB->Normal[count], ctx->Current.Normal );
   COPY_4V( VB->TexCoord[count], ctx->Current.TexCoord );
   VB->Edgeflag[count] = ctx->Current.EdgeFlag;
   VB->VertexSizeMask = VERTEX4_BIT;

   count++;
   VB->Count = count;
   if (count==VB_MAX) {
      gl_transform_vb( ctx, GL_FALSE );
   }
}



/*
 * XYZ vertex, RGB color, normal, ST texture coords.
 * Caller:  context->API.Vertex3f pointer.
 */
static void vertex3f_normal_color_tex2( GLcontext *ctx,
                                        GLfloat x, GLfloat y, GLfloat z )
{
   struct vertex_buffer *VB = ctx->VB;
   GLuint count = VB->Count;

   ASSIGN_3V( VB->Obj[count], x, y, z );
   COPY_4UBV( VB->Fcolor[count], ctx->Current.ByteColor );
   COPY_3V( VB->Normal[count], ctx->Current.Normal );
   COPY_2V( VB->TexCoord[count], ctx->Current.TexCoord );
   VB->Edgeflag[count] = ctx->Current.EdgeFlag;

   count++;
   VB->Count = count;
   if (count==VB_MAX) {
      gl_transform_vb( ctx, GL_FALSE );
   }
}


/*
 * XYZ vertex, RGB color, normal, STRQ texture coords.
 * Caller:  context->API.Vertex3f pointer.
 */
static void vertex3f_normal_color_tex4( GLcontext *ctx,
                                        GLfloat x, GLfloat y, GLfloat z )
{
   struct vertex_buffer *VB = ctx->VB;
   GLuint count = VB->Count;

   ASSIGN_3V( VB->Obj[count], x, y, z );
   COPY_4UBV( VB->Fcolor[count], ctx->Current.ByteColor );
   COPY_3V( VB->Normal[count], ctx->Current.Normal );
   /* GL_ARB_multitexture */
   COPY_4V( VB->MultiTexCoord[0][count], ctx->Current.MultiTexCoord[0] );
   COPY_4V( VB->MultiTexCoord[1][count], ctx->Current.MultiTexCoord[1] );
   VB->Edgeflag[count] = ctx->Current.EdgeFlag;

   count++;
   VB->Count = count;
   if (count==VB_MAX) {
      gl_transform_vb( ctx, GL_FALSE );
   }
}


/*
 * XYZ vertex, normal.
 * Caller:  context->API.Vertex3f pointer.
 */
static void vertex3f_normal( GLcontext *ctx, GLfloat x, GLfloat y, GLfloat z )
{
   struct vertex_buffer *VB = ctx->VB;
   GLuint count = VB->Count;

   ASSIGN_3V( VB->Obj[count], x, y, z );
   COPY_3V( VB->Normal[count], ctx->Current.Normal );
   VB->Edgeflag[count] = ctx->Current.EdgeFlag;

   count++;
   VB->Count = count;
   if (count==VB_MAX) {
      gl_transform_vb( ctx, GL_FALSE );
   }
}


/*
 * XYZ vertex, ST texture coords.
 * Caller:  context->API.Vertex3f pointer.
 */
static void vertex3f_color_tex2( GLcontext *ctx,
                                 GLfloat x, GLfloat y, GLfloat z )
{
   struct vertex_buffer *VB = ctx->VB;
   GLuint count = VB->Count;

   ASSIGN_3V( VB->Obj[count], x, y, z );
   COPY_4UBV( VB->Fcolor[count], ctx->Current.ByteColor );
   COPY_2V( VB->TexCoord[count], ctx->Current.TexCoord );
   VB->Edgeflag[count] = ctx->Current.EdgeFlag;

   count++;
   VB->Count = count;
   if (count==VB_MAX) {
      gl_transform_vb( ctx, GL_FALSE );
   }
}


/*
 * XYZ vertex, STRQ texture coords.
 * Caller:  context->API.Vertex3f pointer.
 */
static void vertex3f_color_tex4( GLcontext *ctx,
                                 GLfloat x, GLfloat y, GLfloat z )
{
   struct vertex_buffer *VB = ctx->VB;
   GLuint count = VB->Count;

   ASSIGN_3V( VB->Obj[count], x, y, z );
   COPY_4UBV( VB->Fcolor[count], ctx->Current.ByteColor );
   COPY_4V( VB->TexCoord[count], ctx->Current.TexCoord );
   VB->Edgeflag[count] = ctx->Current.EdgeFlag;

   count++;
   VB->Count = count;
   if (count==VB_MAX) {
      gl_transform_vb( ctx, GL_FALSE );
   }
}


/*
 * XYZ vertex, RGB color.
 * Caller:  context->API.Vertex3f pointer.
 */
static void vertex3f_color( GLcontext *ctx, GLfloat x, GLfloat y, GLfloat z )
{
   struct vertex_buffer *VB = ctx->VB;
   GLuint count = VB->Count;

   ASSIGN_3V( VB->Obj[count], x, y, z );
   COPY_4UBV( VB->Fcolor[count], ctx->Current.ByteColor );
   VB->Edgeflag[count] = ctx->Current.EdgeFlag;

   count++;
   VB->Count = count;
   if (count==VB_MAX) {
      gl_transform_vb( ctx, GL_FALSE );
   }
}


/*
 * XYZ vertex, color index.
 * Caller:  context->API.Vertex3f pointer.
 */
static void vertex3f_index( GLcontext *ctx, GLfloat x, GLfloat y, GLfloat z )
{
   struct vertex_buffer *VB = ctx->VB;
   GLuint count = VB->Count;

   ASSIGN_3V( VB->Obj[count], x, y, z );
   VB->Findex[count] = ctx->Current.Index;
   VB->Edgeflag[count] = ctx->Current.EdgeFlag;

   count++;
   VB->Count = count;
   if (count==VB_MAX) {
      gl_transform_vb( ctx, GL_FALSE );
   }
}



/*
 * XY vertex, RGB color, normal, ST texture coords.
 * Caller:  context->API.Vertex2f pointer.
 */
static void vertex2f_normal_color_tex2( GLcontext *ctx, GLfloat x, GLfloat y )
{
   struct vertex_buffer *VB = ctx->VB;
   GLuint count = VB->Count;

   ASSIGN_3V( VB->Obj[count], x, y, 0.0F );
   COPY_4UBV( VB->Fcolor[count], ctx->Current.ByteColor );
   COPY_3V( VB->Normal[count], ctx->Current.Normal );
   COPY_2V( VB->TexCoord[count], ctx->Current.TexCoord );
   VB->Edgeflag[count] = ctx->Current.EdgeFlag;

   count++;
   VB->Count = count;
   if (count==VB_MAX) {
      gl_transform_vb( ctx, GL_FALSE );
   }
}


/*
 * XY vertex, RGB color, normal, STRQ texture coords.
 * Caller:  context->API.Vertex2f pointer.
 */
static void vertex2f_normal_color_tex4( GLcontext *ctx, GLfloat x, GLfloat y )
{
   struct vertex_buffer *VB = ctx->VB;
   GLuint count = VB->Count;

   ASSIGN_3V( VB->Obj[count], x, y, 0.0F );
   COPY_4UBV( VB->Fcolor[count], ctx->Current.ByteColor );
   COPY_3V( VB->Normal[count], ctx->Current.Normal );
   /* GL_ARB_multitexture */
   COPY_4V( VB->MultiTexCoord[0][count], ctx->Current.MultiTexCoord[0] );
   COPY_4V( VB->MultiTexCoord[1][count], ctx->Current.MultiTexCoord[1] );
   VB->Edgeflag[count] = ctx->Current.EdgeFlag;

   count++;
   VB->Count = count;
   if (count==VB_MAX) {
      gl_transform_vb( ctx, GL_FALSE );
   }
}


/*
 * XY vertex, normal.
 * Caller:  context->API.Vertex2f pointer.
 */
static void vertex2f_normal( GLcontext *ctx, GLfloat x, GLfloat y )
{
   struct vertex_buffer *VB = ctx->VB;
   GLuint count = VB->Count;

   ASSIGN_3V( VB->Obj[count], x, y, 0.0F );
   COPY_3V( VB->Normal[count], ctx->Current.Normal );
   VB->Edgeflag[count] = ctx->Current.EdgeFlag;

   count++;
   VB->Count = count;
   if (count==VB_MAX) {
      gl_transform_vb( ctx, GL_FALSE );
   }
}


/*
 * XY vertex, ST texture coords.
 * Caller:  context->API.Vertex2f pointer.
 */
static void vertex2f_color_tex2( GLcontext *ctx, GLfloat x, GLfloat y )
{
   struct vertex_buffer *VB = ctx->VB;
   GLuint count = VB->Count;

   ASSIGN_3V( VB->Obj[count], x, y, 0.0F );
   COPY_4UBV( VB->Fcolor[count], ctx->Current.ByteColor );
   COPY_2V( VB->TexCoord[count], ctx->Current.TexCoord );
   VB->Edgeflag[count] = ctx->Current.EdgeFlag;

   count++;
   VB->Count = count;
   if (count==VB_MAX) {
      gl_transform_vb( ctx, GL_FALSE );
   }
}


/*
 * XY vertex, STRQ texture coords.
 * Caller:  context->API.Vertex2f pointer.
 */
static void vertex2f_color_tex4( GLcontext *ctx, GLfloat x, GLfloat y )
{
   struct vertex_buffer *VB = ctx->VB;
   GLuint count = VB->Count;

   ASSIGN_3V( VB->Obj[count], x, y, 0.0F );
   COPY_4UBV( VB->Fcolor[count], ctx->Current.ByteColor );
   COPY_4V( VB->TexCoord[count], ctx->Current.TexCoord );
   VB->Edgeflag[count] = ctx->Current.EdgeFlag;

   count++;
   VB->Count = count;
   if (count==VB_MAX) {
      gl_transform_vb( ctx, GL_FALSE );
   }
}


/*
 * XY vertex, RGB color.
 * Caller:  context->API.Vertex2f pointer.
 */
static void vertex2f_color( GLcontext *ctx, GLfloat x, GLfloat y )
{
   struct vertex_buffer *VB = ctx->VB;
   GLuint count = VB->Count;

   ASSIGN_3V( VB->Obj[count], x, y, 0.0F );
   COPY_4UBV( VB->Fcolor[count], ctx->Current.ByteColor );
   VB->Edgeflag[count] = ctx->Current.EdgeFlag;

   count++;
   VB->Count = count;
   if (count==VB_MAX) {
      gl_transform_vb( ctx, GL_FALSE );
   }
}


/*
 * XY vertex, color index.
 * Caller:  context->API.Vertex3f pointer.
 */
static void vertex2f_index( GLcontext *ctx, GLfloat x, GLfloat y )
{
   struct vertex_buffer *VB = ctx->VB;
   GLuint count = VB->Count;

   ASSIGN_3V( VB->Obj[count], x, y, 0.0F );
   VB->Findex[count] = ctx->Current.Index;
   VB->Edgeflag[count] = ctx->Current.EdgeFlag;

   count++;
   VB->Count = count;
   if (count==VB_MAX) {
      gl_transform_vb( ctx, GL_FALSE );
   }
}




/*
 * XYZ vertex, RGB color, normal, ST texture coords.
 * Caller:  context->API.Vertex3f pointer.
 */
static void vertex3fv_normal_color_tex2( GLcontext *ctx, const GLfloat v[3] )
{
   struct vertex_buffer *VB = ctx->VB;
   GLuint count = VB->Count;

   COPY_3V( VB->Obj[count], v );
   COPY_4UBV( VB->Fcolor[count], ctx->Current.ByteColor );
   COPY_3V( VB->Normal[count], ctx->Current.Normal );
   COPY_2V( VB->TexCoord[count], ctx->Current.TexCoord );
   VB->Edgeflag[count] = ctx->Current.EdgeFlag;

   count++;
   VB->Count = count;
   if (count==VB_MAX) {
      gl_transform_vb( ctx, GL_FALSE );
   }
}


/*
 * XYZ vertex, RGB color, normal, STRQ texture coords.
 * Caller:  context->API.Vertex3f pointer.
 */
static void vertex3fv_normal_color_tex4( GLcontext *ctx, const GLfloat v[3] )
{
   struct vertex_buffer *VB = ctx->VB;
   GLuint count = VB->Count;

   COPY_3V( VB->Obj[count], v );
   COPY_4UBV( VB->Fcolor[count], ctx->Current.ByteColor );
   COPY_3V( VB->Normal[count], ctx->Current.Normal );
   /* GL_ARB_multitexture */
   COPY_4V( VB->MultiTexCoord[0][count], ctx->Current.MultiTexCoord[0] );
   COPY_4V( VB->MultiTexCoord[1][count], ctx->Current.MultiTexCoord[1] );
   VB->Edgeflag[count] = ctx->Current.EdgeFlag;

   count++;
   VB->Count = count;
   if (count==VB_MAX) {
      gl_transform_vb( ctx, GL_FALSE );
   }
}


/*
 * XYZ vertex, normal.
 * Caller:  context->API.Vertex3f pointer.
 */
static void vertex3fv_normal( GLcontext *ctx, const GLfloat v[3] )
{
   struct vertex_buffer *VB = ctx->VB;
   GLuint count = VB->Count;

   COPY_3V( VB->Obj[count], v );
   COPY_3V( VB->Normal[count], ctx->Current.Normal );
   VB->Edgeflag[count] = ctx->Current.EdgeFlag;

   count++;
   VB->Count = count;
   if (count==VB_MAX) {
      gl_transform_vb( ctx, GL_FALSE );
   }
}


/*
 * XYZ vertex, ST texture coords.
 * Caller:  context->API.Vertex3f pointer.
 */
static void vertex3fv_color_tex2( GLcontext *ctx, const GLfloat v[3] )
{
   struct vertex_buffer *VB = ctx->VB;
   GLuint count = VB->Count;

   COPY_3V( VB->Obj[count], v );
   COPY_4UBV( VB->Fcolor[count], ctx->Current.ByteColor );
   COPY_2V( VB->TexCoord[count], ctx->Current.TexCoord );
   VB->Edgeflag[count] = ctx->Current.EdgeFlag;

   count++;
   VB->Count = count;
   if (count==VB_MAX) {
      gl_transform_vb( ctx, GL_FALSE );
   }
}


/*
 * XYZ vertex, STRQ texture coords.
 * Caller:  context->API.Vertex3f pointer.
 */
static void vertex3fv_color_tex4( GLcontext *ctx, const GLfloat v[3] )
{
   struct vertex_buffer *VB = ctx->VB;
   GLuint count = VB->Count;

   COPY_3V( VB->Obj[count], v );
   COPY_4UBV( VB->Fcolor[count], ctx->Current.ByteColor );
   COPY_4V( VB->TexCoord[count], ctx->Current.TexCoord );
   VB->Edgeflag[count] = ctx->Current.EdgeFlag;

   count++;
   VB->Count = count;
   if (count==VB_MAX) {
      gl_transform_vb( ctx, GL_FALSE );
   }
}


/*
 * XYZ vertex, RGB color.
 * Caller:  context->API.Vertex3f pointer.
 */
static void vertex3fv_color( GLcontext *ctx, const GLfloat v[3] )
{
   struct vertex_buffer *VB = ctx->VB;
   GLuint count = VB->Count;

   COPY_3V( VB->Obj[count], v );
   COPY_4UBV( VB->Fcolor[count], ctx->Current.ByteColor );
   VB->Edgeflag[count] = ctx->Current.EdgeFlag;

   count++;
   VB->Count = count;
   if (count==VB_MAX) {
      gl_transform_vb( ctx, GL_FALSE );
   }
}


/*
 * XYZ vertex, Color index
 * Caller:  context->API.Vertex3f pointer.
 */
static void vertex3fv_index( GLcontext *ctx, const GLfloat v[3] )
{
   struct vertex_buffer *VB = ctx->VB;
   GLuint count = VB->Count;

   COPY_3V( VB->Obj[count], v );
   VB->Findex[count] = ctx->Current.Index;
   VB->Edgeflag[count] = ctx->Current.EdgeFlag;

   count++;
   VB->Count = count;
   if (count==VB_MAX) {
      gl_transform_vb( ctx, GL_FALSE );
   }
}



/*
 * Called when outside glBegin/glEnd, raises an error.
 * Caller:  context->API.Vertex4f pointer.
 */
void gl_vertex4f_nop( GLcontext *ctx,
                      GLfloat x, GLfloat y, GLfloat z, GLfloat w )
{
   (void) x;
   (void) y;
   (void) z;
   (void) w;
   gl_error( ctx, GL_INVALID_OPERATION, "glVertex4" );
}

void gl_vertex3f_nop( GLcontext *ctx, GLfloat x, GLfloat y, GLfloat z )
{
   (void) x;
   (void) y;
   (void) z;
   gl_error( ctx, GL_INVALID_OPERATION, "glVertex3" );
}

void gl_vertex2f_nop( GLcontext *ctx, GLfloat x, GLfloat y )
{
   (void) x;
   (void) y;
   gl_error( ctx, GL_INVALID_OPERATION, "glVertex2" );
}

void gl_vertex3fv_nop( GLcontext *ctx, const GLfloat v[3] )
{
   (void) v;
   gl_error( ctx, GL_INVALID_OPERATION, "glVertex3v" );
}




/**********************************************************************/
/******                   glTexCoord functions                    *****/
/**********************************************************************/

/*
 * Caller:  context->API.TexCoord2f pointer.
 */
void gl_TexCoord2f( GLcontext *ctx, GLfloat s, GLfloat t )
{
   ctx->Current.TexCoord[0] = s;
   ctx->Current.TexCoord[1] = t;
}


/*
 * Caller:  context->API.TexCoord2f pointer.
 * This version of glTexCoord2 is called if glTexCoord[34] was a predecessor.
 */
void gl_TexCoord2f4( GLcontext *ctx, GLfloat s, GLfloat t )
{
   ctx->Current.TexCoord[0] = s;
   ctx->Current.TexCoord[1] = t;
   ctx->Current.TexCoord[2] = 0.0F;
   ctx->Current.TexCoord[3] = 1.0F;
}


/*
 * Caller:  context->API.TexCoord4f pointer.
 */
void gl_TexCoord4f( GLcontext *ctx, GLfloat s, GLfloat t, GLfloat r, GLfloat q)
{
   ctx->Current.TexCoord[0] = s;
   ctx->Current.TexCoord[1] = t;
   ctx->Current.TexCoord[2] = r;
   ctx->Current.TexCoord[3] = q;
   if (ctx->VB->TexCoordSize==2) {
      /* Have to switch to 4-component texture mode now */
      ctx->VB->TexCoordSize = 4;
      gl_set_vertex_function( ctx );
      ctx->Exec.TexCoord2f = ctx->API.TexCoord2f = gl_TexCoord2f4;
   }
}


/* GL_ARB_multitexture */
void gl_MultiTexCoord4f( GLcontext *ctx, GLenum target,
                         GLfloat s, GLfloat t, GLfloat r, GLfloat q )
{
   GLint texSet;
   if (target >= GL_TEXTURE0_SGIS && target <= GL_TEXTURE1_SGIS) {
      texSet = target - GL_TEXTURE0_SGIS;
   }
   else if (target >= GL_TEXTURE0_ARB && target <= GL_TEXTURE1_ARB) {
      texSet = target - GL_TEXTURE0_ARB;
   }
   else {
      gl_error(ctx, GL_INVALID_ENUM, "glMultiTexCoord(target)");
      return;
   }

   ctx->Current.MultiTexCoord[texSet][0] = s;
   ctx->Current.MultiTexCoord[texSet][1] = t;
   ctx->Current.MultiTexCoord[texSet][2] = r;
   ctx->Current.MultiTexCoord[texSet][3] = q;
}



/*
 * This function examines the current GL state and sets the
 * ctx->Exec.Vertex[34]f pointers to point at the appropriate vertex
 * processing functions.
 */
void gl_set_vertex_function( GLcontext *ctx )
{
   if (ctx->RenderMode==GL_FEEDBACK) {
      ctx->Exec.Vertex4f = vertex4f_feedback;
      ctx->Exec.Vertex3f = vertex3f_feedback;
      ctx->Exec.Vertex2f = vertex2f_feedback;
      ctx->Exec.Vertex3fv = vertex3fv_feedback;
   }
   else {
      ctx->Exec.Vertex4f = vertex4;
      if (ctx->Visual->RGBAflag) {
         if (ctx->Texture.Enabled >= TEXTURE1_1D) {
            /* Multi texture coords */
            ctx->Exec.Vertex2f = vertex2f_normal_color_tex4;
            ctx->Exec.Vertex3f = vertex3f_normal_color_tex4;
            ctx->Exec.Vertex3fv = vertex3fv_normal_color_tex4;
         }
         else if (ctx->NeedNormals) {
            /* lighting enabled, need normal vectors */
            if (ctx->Texture.Enabled) {
               if (ctx->VB->TexCoordSize==2) {
                  ctx->Exec.Vertex2f = vertex2f_normal_color_tex2;
                  ctx->Exec.Vertex3f = vertex3f_normal_color_tex2;
                  ctx->Exec.Vertex3fv = vertex3fv_normal_color_tex2;
               }
               else {
                  ctx->Exec.Vertex2f = vertex2f_normal_color_tex4;
                  ctx->Exec.Vertex3f = vertex3f_normal_color_tex4;
                  ctx->Exec.Vertex3fv = vertex3fv_normal_color_tex4;
               }
            }
            else {
               ctx->Exec.Vertex2f = vertex2f_normal;
               ctx->Exec.Vertex3f = vertex3f_normal;
               ctx->Exec.Vertex3fv = vertex3fv_normal;
            }
         }
         else {
            /* not lighting, need vertex color */
            if (ctx->Texture.Enabled) {
               if (ctx->VB->TexCoordSize==2) {
                  ctx->Exec.Vertex2f = vertex2f_color_tex2;
                  ctx->Exec.Vertex3f = vertex3f_color_tex2;
                  ctx->Exec.Vertex3fv = vertex3fv_color_tex2;
               }
               else {
                  ctx->Exec.Vertex2f = vertex2f_color_tex4;
                  ctx->Exec.Vertex3f = vertex3f_color_tex4;
                  ctx->Exec.Vertex3fv = vertex3fv_color_tex4;
               }
            }
            else {
               ctx->Exec.Vertex2f = vertex2f_color;
               ctx->Exec.Vertex3f = vertex3f_color;
               ctx->Exec.Vertex3fv = vertex3fv_color;
            }
         }
d94 7
a100 12
      else {
         /* color index mode */
         if (ctx->Light.Enabled) {
            ctx->Exec.Vertex2f = vertex2f_normal;
            ctx->Exec.Vertex3f = vertex3f_normal;
            ctx->Exec.Vertex3fv = vertex3fv_normal;
         }
         else {
            ctx->Exec.Vertex2f = vertex2f_index;
            ctx->Exec.Vertex3f = vertex3f_index;
            ctx->Exec.Vertex3fv = vertex3fv_index;
         }
a101 1
   }
d103 3
a105 91
   if (!ctx->CompileFlag) {
      ctx->API.Vertex2f = ctx->Exec.Vertex2f;
      ctx->API.Vertex3f = ctx->Exec.Vertex3f;
      ctx->API.Vertex4f = ctx->Exec.Vertex4f;
      ctx->API.Vertex3fv = ctx->Exec.Vertex3fv;
   }
}



/*
 * This function examines the current GL state and sets the
 * ctx->Exec.Color[34]* pointers to point at the appropriate vertex
 * processing functions.
 */
void gl_set_color_function( GLcontext *ctx )
{
   if (ctx->Light.ColorMaterialEnabled) {
      ctx->Exec.Color3f = gl_ColorMat3f;
      ctx->Exec.Color3fv = gl_ColorMat3fv;
      ctx->Exec.Color4f = gl_ColorMat4f;
      ctx->Exec.Color4fv = gl_ColorMat4fv;
      ctx->Exec.Color4ub = gl_ColorMat4ub;
      ctx->Exec.Color4ubv = gl_ColorMat4ubv;
   }
   else {
      ctx->Exec.Color3f = gl_Color3f;
      ctx->Exec.Color3fv = gl_Color3fv;
      ctx->Exec.Color4f = gl_Color4f;
      ctx->Exec.Color4fv = gl_Color4fv;
      ctx->Exec.Color4ub = gl_Color4ub;
      ctx->Exec.Color4ubv = gl_Color4ubv;
   }
   if (!ctx->CompileFlag) {
      ctx->API.Color3f = ctx->Exec.Color3f;
      ctx->API.Color3fv = ctx->Exec.Color3fv;
      ctx->API.Color4f = ctx->Exec.Color4f;
      ctx->API.Color4fv = ctx->Exec.Color4fv;
      ctx->API.Color4ub = ctx->Exec.Color4ub;
      ctx->API.Color4ubv = ctx->Exec.Color4ubv;
   }
}



/**********************************************************************/
/*****                    Evaluator vertices                      *****/
/**********************************************************************/


/*
 * Process a vertex produced by an evaluator.
 * Caller:  eval.c
 * Input:  vertex - the X,Y,Z,W vertex
 *         normal - normal vector
 *         color - 4 integer color components
 *         index - color index
 *         texcoord - texture coordinate
 */
void gl_eval_vertex( GLcontext *ctx,
                     const GLfloat vertex[4], const GLfloat normal[3],
		     const GLubyte color[4],
                     GLuint index,
                     const GLfloat texcoord[4] )
{
   struct vertex_buffer *VB = ctx->VB;
   GLuint count = VB->Count;  /* copy to local var to encourage optimization */
   GLuint texUnit = ctx->Texture.CurrentTransformUnit;
   GLuint j;

   VB->VertexSizeMask = VERTEX4_BIT;
   VB->MonoNormal = GL_FALSE;
   COPY_4V( VB->Obj[count], vertex );
   COPY_3V( VB->Normal[count], normal );
   COPY_4UBV( VB->Fcolor[count], color );
   
#ifdef GL_VERSION_1_1
   if (ctx->Light.ColorMaterialEnabled
       && (ctx->Eval.Map1Color4 || ctx->Eval.Map2Color4)) {
      GLfloat fcolor[4];
      fcolor[0] = color[0] * (1.0F / 255.0F);
      fcolor[1] = color[1] * (1.0F / 255.0F);
      fcolor[2] = color[2] * (1.0F / 255.0F);
      fcolor[3] = color[3] * (1.0F / 255.0F);
      gl_set_material( ctx, ctx->Light.ColorMaterialBitmask, fcolor );
   }
#endif
   VB->Findex[count] = index;
   /* copy the current texture coordinates */
   for (j=0;j<MAX_TEXTURE_UNITS;j++) {
      COPY_4V( VB->MultiTexCoord[j][count], ctx->Current.MultiTexCoord[j] );
a106 6
   /* overwrite one of the texture coordinates with the evaluated
    * texture coordinate
    * NOTE: ARB_multitexture does not allow texSet to be anything but zero
    */
   COPY_4V( VB->MultiTexCoord[texUnit][count], texcoord );
   VB->Edgeflag[count] = ctx->Current.EdgeFlag;
d108 1
a108 5
   count++;
   VB->Count = count;
   if (count==VB_MAX) {
      gl_transform_vb( ctx, GL_FALSE );
   }
a111 1

a116 3
#ifdef PROFILE
static GLdouble begin_time;
#endif
d121 2
a122 3
   struct vertex_buffer *VB = ctx->VB;
   struct pixel_buffer *PB = ctx->PB;
   GLenum reduced_primitive = 0;
d124 6
a129 72
#ifdef PROFILE
   begin_time = gl_time();
#endif

   if (INSIDE_BEGIN_END(ctx)) {
      gl_error( ctx, GL_INVALID_OPERATION, "glBegin" );
      return;
   }

   ctx->Primitive = p;

   switch (ctx->Primitive) 
   {
       case GL_POINTS:
          ctx->LightTwoSide = GL_FALSE;
          reduced_primitive = GL_POINT;
          ctx->RenderVB = gl_render_vb_points;
          break;
       case GL_LINES:
          ctx->LightTwoSide = GL_FALSE;
          ctx->StippleCounter = 0;
          reduced_primitive = GL_LINE;
          ctx->RenderVB = gl_render_vb_lines;
          break;
       case GL_LINE_STRIP:
          ctx->LightTwoSide = GL_FALSE;
          ctx->StippleCounter = 0;
          reduced_primitive = GL_LINE;
          ctx->RenderVB = gl_render_vb_line_strip;
          break;
       case GL_LINE_LOOP:
          ctx->LightTwoSide = GL_FALSE;
          ctx->StippleCounter = 0;
          reduced_primitive = GL_LINE;
          ctx->RenderVB = gl_render_vb_line_loop;
          break;
       case GL_TRIANGLES:
          reduced_primitive = GL_POLYGON;
          ctx->RenderVB = gl_render_vb_triangles;
          break;
       case GL_TRIANGLE_STRIP:
          reduced_primitive = GL_POLYGON;
          ctx->RenderVB = gl_render_vb_triangle_strip;
          break;
       case GL_TRIANGLE_FAN:
          reduced_primitive = GL_POLYGON;
          ctx->RenderVB = gl_render_vb_triangle_fan;
          break;
       case GL_QUADS:
          reduced_primitive = GL_POLYGON;
          ctx->RenderVB = gl_render_vb_quads;
          break;
       case GL_QUAD_STRIP:
          reduced_primitive = GL_POLYGON;
          ctx->RenderVB = gl_render_vb_quad_strip;
          break;
       case GL_POLYGON:
          reduced_primitive = GL_POLYGON;
          ctx->RenderVB = gl_render_vb_polygon;
          break;
       default:
          gl_error( ctx, GL_INVALID_ENUM, "glBegin" );
          ctx->RenderVB = gl_render_vb_no_op;
          ctx->Primitive = GL_BITMAP;
          break;
   }

   if (reduced_primitive == GL_POLYGON) {
      GLboolean tmp = (ctx->Light.Enabled && ctx->Light.Model.TwoSide);
      if (tmp && !ctx->LightTwoSide) 
         ctx->NewState |= NEW_LIGHTING; /* need backface precomputes */
      ctx->LightTwoSide = tmp;
a131 3
   VB->Start = VB->Count = 0;
   VB->LastMaterial = 0;

d133 1
a133 1
      gl_update_state( ctx );
d135 4
a138 2
   else if (ctx->Exec.Vertex3f==gl_vertex3f_nop) {
      gl_set_vertex_function(ctx);
d141 3
a143 3
   if (ctx->Driver.Begin) {
      (*ctx->Driver.Begin)( ctx, p );
   }
d145 9
a153 16
   VB->MonoColor = ctx->MonoPixels;
   VB->MonoNormal = GL_TRUE;
   if (VB->MonoColor) {
      /* All pixels generated are likely to be the same color so have
       * the device driver set the "monocolor" now.
       */
      if (ctx->Visual->RGBAflag) {
         GLubyte r = ctx->Current.ByteColor[0];
         GLubyte g = ctx->Current.ByteColor[1];
         GLubyte b = ctx->Current.ByteColor[2];
         GLubyte a = ctx->Current.ByteColor[3];
         (*ctx->Driver.Color)( ctx, r, g, b, a );
      }
      else {
         (*ctx->Driver.Index)( ctx, ctx->Current.Index );
      }
d156 1
a156 6
   /* By default use front color/index.  Two-sided lighting may override. */
   VB->Color = VB->Fcolor;
   VB->Index = VB->Findex;
   VB->Specular = VB->Fspec;

   PB_INIT( PB, reduced_primitive );
a160 30
void gl_End( GLcontext *ctx )
{
   struct pixel_buffer *PB = ctx->PB;
   struct vertex_buffer *VB = ctx->VB;

   if (ctx->Primitive==GL_BITMAP) {
      /* glEnd without glBegin */
      gl_error( ctx, GL_INVALID_OPERATION, "glEnd" );
      return;
   }

   if (VB->Count > VB->Start) {
      gl_transform_vb( ctx, GL_TRUE );
   }

   if (PB->count>0) {
      gl_flush_pb(ctx);
   }

   if (ctx->Driver.End) {
      (*ctx->Driver.End)(ctx);
   }

   PB->primitive = ctx->Primitive = GL_BITMAP;  /* Default mode */

#ifdef PROFILE
   ctx->BeginEndTime += gl_time() - begin_time;
   ctx->BeginEndCount++;
#endif
}
@


3.14
log
@new copyright
@
text
@d1 1
a1 1
/* $Id: vbfill.c,v 3.13 1998/11/25 04:18:19 brianp Exp brianp $ */
d30 3
d100 3
@


3.13
log
@fixed a few IRIX compiler warnings
@
text
@d1 1
a1 1
/* $Id: vbfill.c,v 3.12 1998/11/17 01:52:47 brianp Exp brianp $ */
d6 19
a24 15
 * Copyright (C) 1995-1998  Brian Paul
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the Free
 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
d30 3
@


3.12
log
@implemented GL_NV_texgen_reflection extension (MJK)
@
text
@d1 1
a1 1
/* $Id: vbfill.c,v 3.11 1998/11/08 22:36:34 brianp Exp brianp $ */
d26 3
d1221 1
a1221 1
   GLuint reduced_primitive = 0;
@


3.11
log
@renamed texture sets to texture units
@
text
@d1 1
a1 1
/* $Id: vbfill.c,v 3.10 1998/11/03 02:40:40 brianp Exp brianp $ */
d26 3
d1164 1
d1184 8
@


3.10
log
@new ctx->RenderVB function pointer
@
text
@d1 1
a1 1
/* $Id: vbfill.c,v 3.9 1998/10/31 17:06:15 brianp Exp brianp $ */
d26 3
d1160 1
a1160 1
   GLuint texSet = ctx->Texture.CurrentTransformSet;
d1180 1
a1180 1
   COPY_4V( VB->MultiTexCoord[texSet][count], texcoord );
@


3.9
log
@variety of multi-texture changes
@
text
@d1 1
a1 1
/* $Id: vbfill.c,v 3.8 1998/10/29 03:57:11 brianp Exp brianp $ */
d26 3
d78 1
a1106 2
/*   ASSERT( !INSIDE_BEGIN_END(ctx) );*/

d1218 55
a1272 18
   case GL_POINTS:
      ctx->LightTwoSide = GL_FALSE;
      reduced_primitive = GL_POINT;
      break;
   case GL_LINES:
   case GL_LINE_STRIP:
   case GL_LINE_LOOP:
      ctx->LightTwoSide = GL_FALSE;
      ctx->StippleCounter = 0;
      reduced_primitive = GL_LINE;
      break;
   case GL_TRIANGLES:
   case GL_TRIANGLE_STRIP:
   case GL_TRIANGLE_FAN:
   case GL_QUADS:
   case GL_QUAD_STRIP:
   case GL_POLYGON:
   {
d1275 1
a1275 1
	 ctx->NewState |= NEW_LIGHTING; /* need backface precomputes */
a1276 7
      reduced_primitive = GL_POLYGON;
      break;
   }
   default:
      gl_error( ctx, GL_INVALID_ENUM, "glBegin" );
      ctx->Primitive = GL_BITMAP;
      break;
d1284 2
a1285 1
   } else if (ctx->Exec.Vertex3f==gl_vertex3f_nop) {
a1310 1

d1335 1
@


3.8
log
@misc clean-up of new vertex transformation code
@
text
@d1 1
a1 1
/* $Id: vbfill.c,v 3.7 1998/10/29 02:28:13 brianp Exp brianp $ */
d26 3
d465 1
a465 1
   /* GL_SGIS_multitexture */
d623 1
a623 1
   /* GL_SGIS_multitexture */
d780 1
a780 1
   /* GL_SGIS_multitexture */
d984 1
a984 1
/* GL_SGIS_multitexture */
d991 3
@


3.7
log
@incorporated Keith Whitwell's transformation optimizations
@
text
@d1 1
a1 1
/* $Id: vbfill.c,v 3.6 1998/06/07 22:18:52 brianp Exp brianp $ */
d26 3
d375 1
a375 1
      gl_transform_vb_part1( ctx, GL_FALSE );
d419 1
a419 1
      gl_transform_vb_part1( ctx, GL_FALSE );
d444 1
a444 1
      gl_transform_vb_part1( ctx, GL_FALSE );
d470 1
a470 1
      gl_transform_vb_part1( ctx, GL_FALSE );
d491 1
a491 1
      gl_transform_vb_part1( ctx, GL_FALSE );
d514 1
a514 1
      gl_transform_vb_part1( ctx, GL_FALSE );
d537 1
a537 1
      gl_transform_vb_part1( ctx, GL_FALSE );
d558 1
a558 1
      gl_transform_vb_part1( ctx, GL_FALSE );
d579 1
a579 1
      gl_transform_vb_part1( ctx, GL_FALSE );
d603 1
a603 1
      gl_transform_vb_part1( ctx, GL_FALSE );
d628 1
a628 1
      gl_transform_vb_part1( ctx, GL_FALSE );
d649 1
a649 1
      gl_transform_vb_part1( ctx, GL_FALSE );
d671 1
a671 1
      gl_transform_vb_part1( ctx, GL_FALSE );
d693 1
a693 1
      gl_transform_vb_part1( ctx, GL_FALSE );
d714 1
a714 1
      gl_transform_vb_part1( ctx, GL_FALSE );
d735 1
a735 1
      gl_transform_vb_part1( ctx, GL_FALSE );
d760 1
a760 1
      gl_transform_vb_part1( ctx, GL_FALSE );
d785 1
a785 1
      gl_transform_vb_part1( ctx, GL_FALSE );
d806 1
a806 1
      gl_transform_vb_part1( ctx, GL_FALSE );
d828 1
a828 1
      gl_transform_vb_part1( ctx, GL_FALSE );
d850 1
a850 1
      gl_transform_vb_part1( ctx, GL_FALSE );
d871 1
a871 1
      gl_transform_vb_part1( ctx, GL_FALSE );
d892 1
a892 1
      gl_transform_vb_part1( ctx, GL_FALSE );
d1175 1
a1175 1
      gl_transform_vb_part1( ctx, GL_FALSE );
a1180 2


a1190 3



d1295 1
a1295 1
      gl_transform_vb_part1( ctx, GL_TRUE );
a1311 1

@


3.6
log
@implemented GL_EXT_multitexture extension
@
text
@d1 1
a1 1
/* $Id: vbfill.c,v 3.5 1998/04/18 05:00:42 brianp Exp brianp $ */
d5 1
a5 1
 * Version:  3.0
d26 3
d978 1
a978 1
/* GL_SGIS_multitexture / GL_EXT_multitexture */
a985 3
   else if (target >= GL_TEXTURE0_EXT && target <= GL_TEXTURE1_EXT) {
      texSet = target - GL_TEXTURE0_EXT;
   }
d1094 1
a1094 1
   ASSERT( !INSIDE_BEGIN_END(ctx) );
d1190 3
d1197 2
d1207 34
a1240 5
   if (ctx->NewModelViewMatrix) {
      gl_analyze_modelview_matrix(ctx);
   }
   if (ctx->NewProjectionMatrix) {
      gl_analyze_projection_matrix(ctx);
d1242 4
d1247 2
a1248 3
      gl_update_state(ctx);
   }
   else if (ctx->Exec.Vertex3f==gl_vertex3f_nop) {
a1255 3
   ctx->Primitive = p;
   VB->Start = VB->Count = 0;

d1274 1
d1280 1
a1280 25
   switch (ctx->Primitive) {
      case GL_POINTS:
	 ctx->LightTwoSide = GL_FALSE;
	 PB_INIT( PB, GL_POINT );
	 break;
      case GL_LINES:
      case GL_LINE_STRIP:
      case GL_LINE_LOOP:
	 ctx->LightTwoSide = GL_FALSE;
	 ctx->StippleCounter = 0;
	 PB_INIT( PB, GL_LINE );
         break;
      case GL_TRIANGLES:
      case GL_TRIANGLE_STRIP:
      case GL_TRIANGLE_FAN:
      case GL_QUADS:
      case GL_QUAD_STRIP:
      case GL_POLYGON:
	 ctx->LightTwoSide = ctx->Light.Enabled && ctx->Light.Model.TwoSide;
	 PB_INIT( PB, GL_POLYGON );
         break;
      default:
	 gl_error( ctx, GL_INVALID_ENUM, "glBegin" );
	 ctx->Primitive = GL_BITMAP;
   }
@


3.5
log
@moved FLOAT_COLOR_TO_UBYTE_COLOR macro to mmath.h
@
text
@d1 1
a1 1
/* $Id: vbfill.c,v 3.4 1998/03/27 04:26:44 brianp Exp brianp $ */
d26 3
d975 1
a975 1
/* GL_SGIS_multitexture */
d980 7
a986 1
   if (target < GL_TEXTURE0_SGIS || target > GL_TEXTURE1_SGIS) {
a990 1
   texSet = target - GL_TEXTURE0_SGIS;
d1146 1
d1166 1
a1166 1
   COPY_4V( VB->TexCoord[count], texcoord );
@


3.4
log
@fixed G++ warnings
@
text
@d1 1
a1 1
/* $Id: vbfill.c,v 3.3 1998/02/20 04:53:07 brianp Exp brianp $ */
d26 3
a125 30


#if defined(__i386__)
#define USE_IEEE
#endif

#if defined(USE_IEEE) && !defined(DEBUG)

#define IEEE_ONE 0x3f7f0000

/*
 * Optimization for:
 * GLfloat f;
 * GLubyte b = FloatToInt(CLAMP(f, 0, 1) * 255)
 */
#define FLOAT_COLOR_TO_UBYTE_COLOR(b, f)			\
	{							\
	   GLfloat tmp = f + 32768.0F;				\
	   b = ((*(GLuint *)&f >= IEEE_ONE)			\
	       ? (*(GLint *)&f < 0) ? (GLubyte)0 : (GLubyte)255	\
	       : (GLubyte)*(GLuint *)&tmp);			\
	}

#else

#define FLOAT_COLOR_TO_UBYTE_COLOR(b, f)			\
	b = FloatToInt(CLAMP(f, 0.0F, 1.0F) * 255.0F)

#endif

@


3.3
log
@implemented GL_SGIS_multitexture
@
text
@d1 1
a1 1
/* $Id: vbfill.c,v 3.2 1998/02/08 20:17:42 brianp Exp brianp $ */
d26 3
d923 4
d932 3
d940 2
d947 1
@


3.2
log
@removed unneeded headers
@
text
@d1 1
a1 1
/* $Id: vbfill.c,v 3.1 1998/02/02 03:09:34 brianp Exp brianp $ */
d26 3
d477 3
a479 1
   COPY_4V( VB->TexCoord[count], ctx->Current.TexCoord );
d635 3
a637 1
   COPY_4V( VB->TexCoord[count], ctx->Current.TexCoord );
d792 3
a794 1
   COPY_4V( VB->TexCoord[count], ctx->Current.TexCoord );
d986 17
d1021 7
a1027 1
         if (ctx->NeedNormals) {
@


3.1
log
@added GL_LIGHT_MODEL_COLOR_CONTROL (separate specular color interpolation)
@
text
@d1 1
a1 1
/* $Id: vbfill.c,v 3.0 1998/01/31 21:06:45 brianp Exp brianp $ */
d26 3
a46 3
#include "clip.h"
#include "dlist.h"
#include "feedback.h"
@


3.0
log
@initial rev
@
text
@d1 1
a1 1
/* $Id$ */
d25 4
a28 1
 * $Log$
d1216 1
@
