head	3.39;
access;
symbols
	merge-1:3.33.2.3
	autoconf:3.33.0.4
	experimental-1:3.33.0.2
	mesa-3-1-with-kw3:3.20
	mesa-3-1-prior-to-kw3:3.19;
locks; strict;
comment	@ * @;


3.39
date	99.08.03.14.42.03;	author keithw;	state Exp;
branches;
next	3.38;

3.38
date	99.07.30.17.13.51;	author brianp;	state Exp;
branches;
next	3.37;

3.37
date	99.07.23.17.33.17;	author miklos;	state Exp;
branches;
next	3.36;

3.36
date	99.07.12.15.14.47;	author brianp;	state Exp;
branches;
next	3.35;

3.35
date	99.07.12.12.05.25;	author keithw;	state Exp;
branches;
next	3.34;

3.34
date	99.06.19.02.10.43;	author brianp;	state Exp;
branches;
next	3.33;

3.33
date	99.05.16.17.09.59;	author keithw;	state Exp;
branches
	3.33.2.1;
next	3.32;

3.32
date	99.05.11.19.01.33;	author brianp;	state Exp;
branches;
next	3.31;

3.31
date	99.05.11.17.43.00;	author keithw;	state Exp;
branches;
next	3.30;

3.30
date	99.05.06.01.31.55;	author brianp;	state Exp;
branches;
next	3.29;

3.29
date	99.05.02.00.59.24;	author keithw;	state Exp;
branches;
next	3.28;

3.28
date	99.04.24.01.08.02;	author keithw;	state Exp;
branches;
next	3.27;

3.27
date	99.04.23.16.14.22;	author keithw;	state Exp;
branches;
next	3.26;

3.26
date	99.04.07.22.57.04;	author brianp;	state Exp;
branches;
next	3.25;

3.25
date	99.04.06.01.11.49;	author keithw;	state Exp;
branches;
next	3.24;

3.24
date	99.03.31.20.18.41;	author keithw;	state Exp;
branches;
next	3.23;

3.23
date	99.03.20.18.58.12;	author brianp;	state Exp;
branches;
next	3.22;

3.22
date	99.03.17.16.51.17;	author keithw;	state Exp;
branches;
next	3.21;

3.21
date	99.03.17.12.08.22;	author keithw;	state Exp;
branches;
next	3.20;

3.20
date	99.02.25.14.12.32;	author keithw;	state Exp;
branches;
next	3.19;

3.19
date	99.02.24.22.48.08;	author jens;	state Exp;
branches;
next	3.18;

3.18
date	99.02.14.03.46.34;	author brianp;	state Exp;
branches;
next	3.17;

3.17
date	99.01.30.04.33.01;	author brianp;	state Exp;
branches;
next	3.16;

3.16
date	98.11.17.01.52.47;	author brianp;	state Exp;
branches;
next	3.15;

3.15
date	98.11.08.22.36.27;	author brianp;	state Exp;
branches;
next	3.14;

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

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

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

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

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

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

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

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

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

3.5
date	98.03.28.04.01.53;	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.02.03.09.34;	author brianp;	state Exp;
branches;
next	3.1;

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

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

3.33.2.1
date	99.05.21.21.29.28;	author keithw;	state Exp;
branches;
next	3.33.2.2;

3.33.2.2
date	99.05.22.19.14.40;	author keithw;	state Exp;
branches;
next	3.33.2.3;

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


desc
@vertex buffer transformation
@


3.39
log
@fixes for bugs from eero and miklos
@
text
@/* $Id: vbxform.c,v 3.38 1999/07/30 17:13:51 brianp 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 <stdlib.h>
#include <stdio.h>
#include "context.h"
#include "cva.h"
#include "clip.h"
#include "eval.h"
#include "dlist.h"
#include "fog.h"
#include "light.h"
#include "macros.h"
#include "matrix.h"
#include "mmath.h"
#include "pipeline.h"
#include "shade.h"
#include "texture.h"
#include "types.h"
#include "varray.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


void gl_maybe_transform_vb( struct immediate *IM )
{
   GLcontext *ctx = IM->backref;

   gl_compute_orflag( IM );

   if (ctx->CompileFlag) {
      gl_fixup_input( ctx, IM );
      gl_compile_cassette( ctx );   
   }

   /* This is now the general case, and pure immediate is a special
    * case where there is no precalculated data.
    */
   if (ctx->ExecuteFlag) 
      gl_cva_compile_cassette( ctx );

   gl_reset_input( ctx );
}


void gl_flush_vb( GLcontext *ctx, const char *where )
{
   struct immediate *IM = ctx->input;

   if (MESA_VERBOSE&VERBOSE_PIPELINE)
      fprintf(stderr, "gl_flush_vb: %s\n", where);

   gl_maybe_transform_vb( IM );
}



#define CLIP_ALL_BITS    0x3f
#define RESET_VEC(v, t, s) (v.start = t v.data[s], v.count = 0)  

/* 
 *
 */
void gl_reset_vb( struct vertex_buffer *VB )
{
   GLuint copy;
   GLuint dst;
   GLuint start;
   struct immediate *IM = VB->IM;
   GLubyte clipor = VB->ClipOrMask;

   if (!VB->CullDone)
      gl_fast_copy_vb( VB );
      
   copy = VB->CopyCount;
   start = 3-copy;

   VB->CopyStart = start;
   VB->ClipOrMask = 0;
   VB->ClipAndMask = CLIP_ALL_BITS;

   if (IM) 
   {
      RESET_VEC(IM->v.Obj, (GLfloat *), VB_START);
      RESET_VEC(IM->v.Normal, (GLfloat *), VB_START);
      RESET_VEC(IM->v.TexCoord[0], (GLfloat *), VB_START);
      RESET_VEC(IM->v.TexCoord[1], (GLfloat *), VB_START);
      RESET_VEC(IM->v.Index, &, VB_START);
      RESET_VEC(IM->v.Elt, &, VB_START);
      RESET_VEC(IM->v.Color, (GLubyte *), VB_START);
      RESET_VEC(VB->Clip, (GLfloat *), VB_START);
      RESET_VEC(VB->Eye, (GLfloat *), VB_START);
      RESET_VEC(VB->Win, (GLfloat *), VB_START);
      RESET_VEC(VB->BColor, (GLubyte *), VB_START); 
      RESET_VEC(VB->BIndex, &, VB_START);
      
      for (dst = start ; dst < VB_START ; dst++) 
      {
	 GLuint src = VB->Copy[dst];
 
	 if (0)
	    fprintf(stderr, "copying vertex %u to %u\n", src, dst);

	 COPY_4FV( VB->Clip.data[dst], VEC_ELT(VB->ClipPtr, GLfloat, src) ); 
	 COPY_4FV( VB->Win.data[dst], VB->Win.data[src] ); 


	 VB->UserClipMask[dst] = VB->UserClipMask[src];
	 VB->ClipMask[dst] = VB->ClipMask[src] & ~CLIP_CULLED_BIT;   
	 VB->ClipAndMask &= VB->ClipMask[dst];
	 VB->ClipOrMask  |= VB->ClipMask[dst];
	 VB->ClipMask[src] = 0;	/* hack for bounds_cull_vb */

	 COPY_4UBV( IM->Color[dst], IM->Color[src] );
	 COPY_4UBV( VB->Spec[0][dst], VB->Spec[0][src] );
	 COPY_4UBV( VB->Spec[1][dst], VB->Spec[1][src] );
	 COPY_4UBV( VB->BColor.data[dst], VB->BColor.data[src] );
	 IM->Index[dst] = IM->Index[src];
	 VB->BIndex.data[dst] = VB->BIndex.data[src];

	 if (VB->TexCoordPtr[0] == &IM->v.TexCoord[0])
	    COPY_4FV( IM->TexCoord[0][dst], IM->TexCoord[0][src] );
	    
	 if (VB->TexCoordPtr[1] == &IM->v.TexCoord[1])
	    COPY_4FV( IM->TexCoord[1][dst], IM->TexCoord[1][src] );

	 IM->Elt[dst] = IM->Elt[src];
	 VB->SavedOrFlag |= IM->Flag[src];
      } 
      
      VB->CullDone = 0;
   }

   if (clipor & CLIP_USER_BIT) 
      MEMSET(VB->UserClipMask + VB->Start, 0, VB->Count);

   VB->NormCullStart = 0;
   VB->Parity = (VB->LastPrimitive^VB->Count)&1;
   VB->LastPrimitive = VB_START; 
   VB->PurgeFlags = 0;
   VB->EarlyCull = 1;
   VB->Culled = 0;
   VB->BoundsPtr = 0;
   VB->NormalLengthPtr = 0;  
   VB->Indirect = 0;
   VB->LastCount = VB->Count;
   VB->Culled = 0;
}




/* Copy the untransformed parts of the overlapping vertices from one
 * immediate struct to another (or possibly the same one).  
 *
 * Only copy those elements which are genuinely untransformed.  Others
 * are done in gl_reset_vb.
 */
void gl_copy_prev_vertices( struct vertex_buffer *VB,
			    struct immediate *prev,
			    struct immediate *next )
{
   GLuint dst;
   GLuint flags = VB->pipeline->inputs;

   for (dst = VB->CopyStart ; dst < VB_START ; dst++) 
   {
      GLuint src = VB->Copy[dst];

      COPY_4FV( next->Obj[dst], prev->Obj[src] );

      if ((flags&VERT_TEX0_ANY) && VB->TexCoordPtr[0] == &prev->v.TexCoord[0])
	 COPY_4FV( next->TexCoord[0][dst], prev->TexCoord[0][src] );
	    
      if ((flags&VERT_TEX1_ANY) && VB->TexCoordPtr[1] == &prev->v.TexCoord[1])
	 COPY_4FV( next->TexCoord[1][dst], prev->TexCoord[1][src] );

      COPY_4UBV( next->Color[dst], prev->Color[src] );
      next->Index[dst] = prev->Index[src];
      next->EdgeFlag[dst] = prev->EdgeFlag[src];

      next->Elt[dst] = prev->Elt[src];
      VB->SavedOrFlag |= prev->Flag[src];
   }
}



void RESET_IMMEDIATE( GLcontext *ctx ) 
{
   if (ctx->VB->prev_buffer != ctx->VB->IM) {
      /* Should only get here if we are trying to use the internal
       * interfaces, eg gl_Vertex3f(), gl_Begin() from inside a
       * display list.  In this case, it is necessary to pull the
       * current values into the ctx->VB.store buffer, because this
       * may not have been done.
       */
      gl_reset_input( ctx );
   }
}


/* Called to initialize new buffers, and to recycle old ones.
 */
void gl_reset_input( GLcontext *ctx )
{
   struct immediate *IM = ctx->input;

   MEMSET(IM->Flag, 0, sizeof(GLuint) * (IM->Count+2));

   RESET_VEC(IM->v.Obj, (GLfloat *), VB_START);
   RESET_VEC(IM->v.Normal, (GLfloat *), VB_START);
   RESET_VEC(IM->v.Color, (GLubyte *), VB_START);
   RESET_VEC(IM->v.Index, &, VB_START);
   RESET_VEC(IM->v.Elt, &, VB_START);
   RESET_VEC(IM->v.TexCoord[0], (GLfloat *), VB_START);
   RESET_VEC(IM->v.TexCoord[1], (GLfloat *), VB_START);

   IM->Start = VB_START;
   IM->Count = VB_START;
   IM->LastMaterial = (GLuint) (-1);
   IM->LastPrimitive = VB_START;
   IM->Primitive[VB_START] = ctx->Current.Primitive;
   IM->BeginState = VERT_BEGIN_0;         
   IM->ArrayOrFlags = (ctx->Array.Flags & VERT_OBJ_ANY) | VERT_ELT;
   IM->ArrayAndFlags = ~ctx->Array.Flags;
   IM->ArrayIncr = ctx->Array.Vertex.Enabled;
}


/* Preserves size information as well.
 */
void 
fixup_4f( GLfloat data[][4], GLuint flag[], GLuint start, GLuint match )
{
   GLuint i = start;

   for (;;) {
      if ((flag[++i] & match) == 0) {
	 COPY_4FV(data[i], data[i-1]);
	 flag[i] |= (flag[i-1] & match);
	 if (flag[i] & VERT_END_VB) break;
      } 
   }
}



/* Only needed for buffers with eval coords.
 */
void
fixup_3f( float data[][3], GLuint flag[], GLuint start, GLuint match )
{
   GLuint i = start;

   for (;;) {
      if ((flag[++i] & match) == 0) {
	 COPY_3V(data[i], data[i-1]);
	 flag[i] |= match;
	 if (flag[i] & VERT_END_VB) break;
      } 
   }
}


void
fixup_1ui( GLuint *data, GLuint flag[], GLuint start, GLuint match )
{
   GLuint i = start;

   for (;;) {
      if ((flag[++i] & match) == 0) {
	 data[i] = data[i-1];
	 if (flag[i] & VERT_END_VB) break;
      } 
   }
   flag[i] |= match;
}

void
fixup_1ub( GLubyte *data, GLuint flag[], GLuint start, GLuint match )
{
   GLuint i = start;

   for (;;) {
      if ((flag[++i] & match) == 0) {
	 data[i] = data[i-1];
	 if (flag[i] & VERT_END_VB) break;
      } 
   }
   flag[i] |= match;
}


void
fixup_4ub( GLubyte data[][4], GLuint flag[], GLuint start, GLuint match )
{
   GLuint i = start;

   for (;;) {
      if ((flag[++i] & match) == 0) {
	 COPY_4UBV(data[i], data[i-1]);
	 if (flag[i] & VERT_END_VB) break;
      } 
   }
   flag[i] |= match;
}


/* Do this instead of fixup for shared normals.
 */
void
find_last_3f( float data[][3], GLuint flag[], GLuint match, GLuint count )
{
   GLuint i = count;

   for (;;) 
      if ((flag[--i] & match) != 0) {
	 COPY_3V(data[count], data[i]);	 
	 return;      
      }
}

void
fixup_first_4v( GLfloat data[][4], GLuint flag[], GLuint match, 
		GLuint start, GLfloat *dflt )
{
   GLuint i = start-1;
   match |= VERT_END_VB;

   while ((flag[++i]&match) == 0)
      COPY_4FV(data[i], dflt);
}


void
fixup_first_1ui( GLuint data[], GLuint flag[], GLuint match,
		 GLuint start, GLuint dflt )
{
   GLuint i = start-1;
   match |= VERT_END_VB;

   while ((flag[++i]&match) == 0)
      data[i] = dflt;
}


void
fixup_first_1ub( GLubyte data[], GLuint flag[], GLuint match,
		 GLuint start, GLubyte dflt )
{
   GLuint i = start-1;
   match |= VERT_END_VB;

   while ((flag[++i]&match) == 0)
      data[i] = dflt;
}


void
fixup_first_4ub( GLubyte data[][4], GLuint flag[], GLuint match,
		 GLuint start, GLubyte dflt[4] )
{
   GLuint i = start-1;
   match |= VERT_END_VB;

   while ((flag[++i]&match) == 0)
      COPY_4UBV(data[i], dflt);
}




static GLuint vertex_sizes[16] = { 0, 
				   1, 
				   2, 2, 
				   3, 3, 3, 3, 
				   4, 4, 4, 4, 4, 4, 4, 4 };



GLuint gl_texcoord_size( GLuint flag, GLuint unit )
{
   flag >>= VERT_TEX0_SHIFT + unit * NR_TEXSIZE_BITS;
   return vertex_sizes[flag & 0xf];
}


static void set_vec_sizes( struct immediate *IM, GLuint orflag )
{
   GLuint i;

   if (orflag & VERT_OBJ_ANY) {
      GLuint szflag = orflag & VERT_OBJ_234;
      IM->v.Obj.size = vertex_sizes[szflag<<1];
   }

   for (i = 0 ; i < MAX_TEXTURE_UNITS ; i++) {
      if (orflag & VERT_TEX_ANY(i)) {
	 GLuint szflag = ((orflag>>(VERT_TEX0_SHIFT+i*NR_TEXSIZE_BITS))
			  & 0xf);
	 IM->v.TexCoord[i].size = vertex_sizes[szflag];
      }
   }
}


void gl_compute_orflag( struct immediate *IM )
{
   GLuint count = IM->Count;
   GLuint orflag = 0;
   GLuint andflag = ~0;
   GLuint i;

   IM->LastData = count-1;

   /* This was previously done inside the immediate API functions 
    */
   for (i = VB_START ; i < count ; i++) {
      andflag &= IM->Flag[i];
      orflag |= IM->Flag[i];
   }

   if (IM->Flag[i] & VERT_DATA) {
      IM->LastData++;
      andflag &= IM->Flag[i];
      orflag |= IM->Flag[i];
   }      

   IM->Flag[IM->LastData+1] |= VERT_END_VB;
   IM->AndFlag = andflag;
   IM->OrFlag = orflag;
}

void gl_fixup_input( GLcontext *ctx, struct immediate *IM )
{
   GLuint count = IM->Count;
   GLuint start = VB_START;
   GLuint fixup, diff;
   GLuint andflag = IM->AndFlag;
   GLuint orflag = IM->OrFlag;

   IM->Primitive[count] = IM->Primitive[IM->LastPrimitive];
   IM->NextPrimitive[IM->LastPrimitive] = count;
   IM->NextPrimitive[count] = count+1;

   if (MESA_VERBOSE&VERBOSE_IMMEDIATE) {
      fprintf(stderr, "Count: %u LastData: %u\n", IM->Count, IM->LastData);
      gl_print_vert_flags("Orflag", orflag);
      gl_print_vert_flags("Andflag", andflag);
   }

   /* Array elements modify the current state - must do this before
    * fixup.
    */
   if (orflag & VERT_ELT) 
   {
      if (ctx->CompileCVAFlag && !(andflag & VERT_ELT)) 
	 gl_rescue_cva( ctx, IM );

      if (!ctx->CompileCVAFlag)
	 gl_exec_array_elements( ctx, IM );

      orflag = IM->OrFlag;
      andflag = IM->AndFlag;
      start = IM->Start;
   }
   
   fixup = ~andflag & VERT_FIXUP;

   if (!ctx->CompileFlag) 
      fixup &= ctx->CVA.elt.inputs; 
   
   if (!ctx->ExecuteFlag)
      fixup &= orflag;

   if (ctx->CompileCVAFlag)
      fixup &= ~ctx->CVA.pre.outputs;

   if (IM->LastData == VB_START)
      fixup = 0;

   if (fixup) 
   {

      if (ctx->ExecuteFlag && (fixup & ~IM->Flag[VB_START])) {
	 GLuint copy = fixup & ~IM->Flag[VB_START];

	 if (copy & VERT_NORM) 	 
	    COPY_3V( IM->Normal[VB_START], ctx->Current.Normal );
	 
	 if (copy & VERT_RGBA)
	    COPY_4UBV( IM->Color[VB_START], ctx->Current.ByteColor);
      
	 if (copy & VERT_INDEX)
	    IM->Index[VB_START] = ctx->Current.Index;
	 
	 if (copy & VERT_EDGE)
	    IM->EdgeFlag[VB_START] = ctx->Current.EdgeFlag;

	 if (copy & VERT_TEX0_ANY)
	    COPY_4FV( IM->TexCoord[0][VB_START], ctx->Current.Texcoord[0] ); 
	 
	 if (copy & VERT_TEX1_ANY)
	    COPY_4FV( IM->TexCoord[1][VB_START], ctx->Current.Texcoord[1] ); 
      }


      if (MESA_VERBOSE&VERBOSE_IMMEDIATE)
	 gl_print_vert_flags("fixup", fixup);
      
      if (fixup & VERT_TEX0_ANY) {
	 if (orflag & VERT_TEX0_ANY)
	    fixup_4f( IM->TexCoord[0], IM->Flag, start, VERT_TEX0_1234 );
	 else 
	    fixup_first_4v( IM->TexCoord[0], IM->Flag, 0, start, 
			    IM->TexCoord[0][3]);
      }

      if (fixup & VERT_TEX1_ANY) {
	 if (orflag & VERT_TEX1_ANY)
	    fixup_4f( IM->TexCoord[1], IM->Flag, start, VERT_TEX1_1234 );
	 else 
	    fixup_first_4v( IM->TexCoord[1], IM->Flag, 0, start, 
			    IM->TexCoord[1][3] );
      }

      if (fixup & VERT_EDGE) {
	 if (orflag & VERT_EDGE)
	    fixup_1ub( IM->EdgeFlag, IM->Flag, start, VERT_EDGE );
	 else 
	    fixup_first_1ub( IM->EdgeFlag, IM->Flag, 0, start, 
			     IM->EdgeFlag[3] );
      }

      if (fixup & VERT_INDEX) {
	 if (orflag & VERT_INDEX)
	    fixup_1ui( IM->Index, IM->Flag, start, VERT_INDEX );
	 else 
	    fixup_first_1ui( IM->Index, IM->Flag, 0, start, IM->Index[3] );
      }

      if (fixup & VERT_RGBA) {
	 if (orflag & VERT_RGBA) 
	    fixup_4ub( IM->Color, IM->Flag, start, VERT_RGBA );      
	 else 
	    fixup_first_4ub( IM->Color, IM->Flag, 0, start, IM->Color[3] );
      }

      if (fixup & VERT_NORM) {
	 if (IM->OrFlag & VERT_EVAL_ANY)
	    fixup_3f( IM->Normal, IM->Flag, start, VERT_NORM );
	 else if (!(IM->Flag[IM->LastData] & VERT_NORM)) 
 	    find_last_3f( IM->Normal, IM->Flag, VERT_NORM, IM->LastData );
      }
   }

   diff = count - start;
   IM->v.Obj.count = diff;
   IM->v.Normal.count = diff;
   IM->v.TexCoord[0].count = diff;
   IM->v.TexCoord[1].count = diff;
   IM->v.EdgeFlag.count = diff;
   IM->v.Color.count = diff;
   IM->v.Index.count = diff;
 
   /* Prune possible half-filled slot.
    */
   IM->Flag[IM->LastData+1] &= ~VERT_END_VB;
   IM->Flag[IM->Count] |= VERT_END_VB;

/*    gl_print_cassette( IM, 0, ~0 ); */
}


static void calc_normal_lengths( GLfloat *dest, 
				 CONST GLfloat (*data)[3],
				 const GLuint *flags,
				 GLuint count )
{
   GLuint i;

   for (i = VB_START ; i < count ; i++ )
      if (flags[i] & VERT_NORM) {
	 GLfloat tmp = LEN_3FV( data[i] );
	 dest[i] = 0;
	 if (tmp > 0)
	    dest[i] = 1.0 / tmp;
      }      
}


/* Revive a compiled immediate struct - propogate new 'Current'
 * values.  Often this is redundant because the current values were
 * known and fixed up at compile time.
 */
void gl_fixup_cassette( GLcontext *ctx, struct immediate *IM )
{
   GLuint fixup;
   
   if (IM->Count == VB_START) 
      return;

   if (ctx->NewState)
      gl_update_state( ctx );

   fixup = ctx->CVA.elt.inputs & ~IM->AndFlag & VERT_FIXUP;

   if (ctx->Transform.Normalize && !IM->NormalLengths) {
      IM->NormalLengths = (GLfloat *)malloc(sizeof(GLfloat) * (IM->Count+1));
      calc_normal_lengths( IM->NormalLengths, 
			   (const GLfloat (*)[3])IM->Normal, 
			   IM->Flag, IM->Count);
   }

   if (fixup) {

      if (MESA_VERBOSE & VERBOSE_IMMEDIATE)
	 gl_print_vert_flags("fixup_cassette", fixup);

      if (fixup & VERT_TEX0_ANY) 
	 fixup_first_4v( IM->TexCoord[0], IM->Flag, VERT_TEX0_ANY, VB_START,
			 ctx->Current.Texcoord[0] );

      if (fixup & VERT_TEX1_ANY) 
	 fixup_first_4v( IM->TexCoord[1], IM->Flag, VERT_TEX1_ANY, VB_START,
			 ctx->Current.Texcoord[1] );

      if (fixup & VERT_EDGE)
	 fixup_first_1ub(IM->EdgeFlag, IM->Flag, VERT_EDGE, VB_START,
			 ctx->Current.EdgeFlag );

      if (fixup & VERT_INDEX)
	 fixup_first_1ui(IM->Index, IM->Flag, VERT_INDEX, VB_START,
			 ctx->Current.Index );
   
      if (fixup & VERT_RGBA) 
	 fixup_first_4ub(IM->Color, IM->Flag, VERT_RGBA, VB_START,
			 ctx->Current.ByteColor );      

      if ((fixup & VERT_NORM) && !(IM->Flag[VB_START] & VERT_NORM)) {
	 COPY_3V(IM->Normal[VB_START], ctx->Current.Normal);
	 if (ctx->Transform.Normalize)
	    IM->NormalLengths[VB_START] = 1.0 / LEN_3FV(ctx->Current.Normal);
      }
   }  
}



static void fixup_primitives( GLcontext *ctx, struct immediate *IM )
{
   static GLuint increment[GL_POLYGON+2] = { 1,2,1,1,3,1,1,4,2,1,1 };
   static GLuint intro[GL_POLYGON+2]     = { 0,0,2,2,0,2,2,0,2,2,0 };
   struct vertex_buffer *VB = ctx->VB;
   const GLuint *flags = IM->Flag;
   const GLuint *in_prim = IM->Primitive;
   const GLuint *in_nextprim = IM->NextPrimitive;
   GLuint *out_prim = VB->IM->Primitive;
   GLuint *out_nextprim = VB->IM->NextPrimitive;
   GLuint count = VB->Count;
   GLuint in, out, last;
   GLuint incr, prim;   
   GLuint transition;
   GLuint interesting;
   GLuint err;
   
/*     printf("IM: %d prim[3]: %d\n", IM->id, IM->Primitive[3]); */

   if (ctx->Current.Primitive == GL_POLYGON+1) {
      transition = VERT_BEGIN;
      err = IM->BeginState & VERT_ERROR_1;
   } else {
      transition = VERT_END;
      err = IM->BeginState & VERT_ERROR_0;
   }

   if (err) {
      /* Occurred somewhere inside the vb.  Don't know/care where/why.
       */
      gl_error( ctx, GL_INVALID_OPERATION, "begin/end");
   }

   interesting = transition | VERT_END_VB;


   for (in = VB_START ; in <= count ; in = in_nextprim[in]) 
      if (flags[in] & interesting) 
	 break;

   out = VB->CopyStart;

   if (in == out) {
      out_nextprim[out] = in_nextprim[in];
      out_prim[out] = in_prim[in];
      last = IM->LastPrimitive;
   } else if (flags[in] & transition) {
      out_nextprim[out] = in;
      out_prim[out] = ctx->Current.Primitive;
      out = in;
      last = IM->LastPrimitive;
   } else {
      out_nextprim[out] = in;
      out_prim[out] = ctx->Current.Primitive;
      in++;
      last = out;
   }

   for ( ; in <= count ; in = in_nextprim[in] ) {
      out_prim[in] = in_prim[in];
      out_nextprim[in] = in_nextprim[in];
   }
	  

   VB->Primitive = out_prim;
   VB->NextPrimitive = out_nextprim;
   VB->LastPrimitive = last;
   prim = ctx->Current.Primitive = (GLenum) out_prim[last];


   /* Calculate whether the primitive finished on a 'good number' of
    * vertices, or whether there are overflowing vertices we have to
    * copy to the next buffer (in addition to the normal ones required
    * by a continuing primitive).
    *
    * Note that GL_POLYGON+1, ie outside begin/end, has increment 1.
    */

   incr = increment[prim];
  
   if (incr != 1 && (count - last - intro[prim])) 
      VB->Ovf = (count - last - intro[prim]) % incr; 
   else
      VB->Ovf = 0;

   if (0) 
      fprintf(stderr, "prim: %s count %u last %u incr %u ovf: %u\n",
	      gl_prim_name[prim], count, last, incr, VB->Ovf);
}


void gl_copy_to_current( GLcontext *ctx, struct immediate *IM )
{
   GLuint count = IM->LastData;
   GLuint flag = IM->OrFlag;
   GLuint mask = 0;

   if (MESA_VERBOSE&VERBOSE_IMMEDIATE)
      gl_print_vert_flags("copy to current", flag);

   if (flag & VERT_NORM) 
      COPY_3FV( ctx->Current.Normal, IM->Normal[count]);   
   
   if (flag & VERT_INDEX)
      ctx->Current.Index = IM->Index[count];

   if (flag & VERT_EDGE)
      ctx->Current.EdgeFlag = IM->EdgeFlag[count];

   if (flag & VERT_RGBA) 
      COPY_4UBV(ctx->Current.ByteColor, IM->Color[count]);

   if (flag & VERT_TEX0_ANY) {
      mask |= VERT_TEX0_1234;
      COPY_4FV( ctx->Current.Texcoord[0], IM->TexCoord[0][count]);
   }
      
   if (flag & VERT_TEX1_ANY) {
      mask |= VERT_TEX1_1234;
      COPY_4FV( ctx->Current.Texcoord[1], IM->TexCoord[1][count]);
   }

   /* Save the texcoord size information as well.
    */
   ctx->Current.Flag &= ~mask;
   ctx->Current.Flag |= IM->Flag[count] & mask;
}


void gl_execute_cassette( GLcontext *ctx, struct immediate *IM )
{
   struct vertex_buffer *VB = ctx->VB;
   struct immediate *prev = VB->prev_buffer;


   IM->ref_count++;

   if (prev != IM || IM != VB->IM ) {
      gl_copy_prev_vertices( VB, VB->prev_buffer, IM );
   }

   if (! --prev->ref_count ) 
      gl_immediate_free( prev );

   VB->prev_buffer = IM;
   VB->Start = IM->Start;
   VB->Count = IM->Count;
   VB->Flag = IM->Flag;
   VB->AndFlag = IM->AndFlag;
   VB->OrFlag = IM->OrFlag | VB->SavedOrFlag;
   VB->EltPtr = &IM->v.Elt;
   VB->MaterialMask = IM->MaterialMask;
   VB->Material = IM->Material;
   VB->CullMode = (IM->AndFlag & VERT_NORM) ? 0 : COMPACTED_NORMALS;
   VB->ObjPtr = &IM->v.Obj;
   VB->NormalPtr = &IM->v.Normal;
   VB->ColorPtr = &IM->v.Color;
   VB->Color[0] = VB->Color[1] = VB->ColorPtr;
   VB->IndexPtr = &IM->v.Index;
   VB->EdgeFlagPtr = &IM->v.EdgeFlag;
   VB->TexCoordPtr[0] = &IM->v.TexCoord[0];
   VB->TexCoordPtr[1] = &IM->v.TexCoord[1];
   VB->BoundsPtr = IM->Bounds;
   VB->NormalLengthPtr = IM->NormalLengths;
   VB->IndirectCount = VB->Count;
   VB->SavedOrFlag = 0;

   ctx->CVA.orflag |= VB->OrFlag;

   gl_copy_to_current( ctx, IM );

   set_vec_sizes( IM, VB->OrFlag );

   if (MESA_VERBOSE&VERBOSE_IMMEDIATE) 
      fprintf(stderr,
	      "executing cassette, rows %u tc0->size == %u tc1->size == %u\n",
	      VB->Count,
	      VB->TexCoordPtr[0]->size,
	      VB->TexCoordPtr[1]->size);

   if (MESA_VERBOSE&VERBOSE_IMMEDIATE) 
      gl_print_cassette( IM, 1, ~0 );

   
   if (IM->OrFlag & VERT_EVAL_ANY) 
      gl_eval_vb( VB );

   if (IM->Count > VB_START || 
       (IM->Flag[VB_START] & (VERT_END|VERT_BEGIN)))
      fixup_primitives( ctx, IM );

   if (VB->IndirectCount > VB_START) 
      gl_run_pipeline( VB );      
   else 
      gl_update_materials( VB );

   gl_reset_vb( VB );
}



void gl_print_cassette( struct immediate *IM, GLboolean fixed_up, GLuint req ) 
{
   GLuint i;
   GLuint andflag = IM->AndFlag;
   GLuint orflag = IM->OrFlag;
   GLuint state = IM->BeginState;
   GLuint *flags = IM->Flag;
   static const char *tplate[5] = { "%s ", 
				    "%s: %f ",
				    "%s: %f %f ",
				    "%s: %f %f %f ",
				    "%s: %f %f %f %f " };
   (void) fixed_up;

   printf("Cassette, %u rows.\n", IM->Count);

   gl_print_vert_flags("Contains at least one", orflag);

   if (IM->Count != VB_START) 
   {
      gl_print_vert_flags("Contains a full complement of", andflag);
   
      printf("Final begin/end state %s/%s, errors %s/%s\n",
	     (state & VERT_BEGIN_0) ? "in" : "out", 
	     (state & VERT_BEGIN_1) ? "in" : "out", 
	     (state & VERT_ERROR_0) ? "y" : "n", 
	     (state & VERT_ERROR_1) ? "y" : "n");

      printf("Obj size: %u, TexCoord0 size: %u, TexCoord1 size: %u\n",
	     IM->v.Obj.size,
	     IM->v.TexCoord[0].size,
	     IM->v.TexCoord[1].size);
   }

   if (!req) return;

   for (i = 0 ; i <= IM->Count ; i++) {
      printf("%u: ", i);
      if (req & VERT_OBJ_ANY) {
	 if (flags[i] & VERT_EVAL_C1) 
	    printf("EvalCoord %f ", IM->Obj[i][0]);
	 else if (flags[i] & VERT_EVAL_P1) 
	    printf("EvalPoint %.0f ", IM->Obj[i][0]);
	 else if (flags[i] & VERT_EVAL_C2) 
	    printf("EvalCoord %f %f ", IM->Obj[i][0], IM->Obj[i][1]);
	 else if (flags[i] & VERT_EVAL_P2) 
	    printf("EvalPoint %.0f %.0f ", IM->Obj[i][0], IM->Obj[i][1]);
	 else if ((flags[i] & (VERT_ELT|VERT_OBJ_ANY)) == (VERT_ELT)) 
	    printf("Array elt %u\t", IM->Elt[i]);
	 else if (i < IM->Count)
	    printf(tplate[vertex_sizes[(flags[i]&VERT_OBJ_ANY)<<1]],
		   "Obj",
		   IM->Obj[i][0], IM->Obj[i][1], IM->Obj[i][2], IM->Obj[i][3]);
      }

      if (req & flags[i] & VERT_NORM)
	 printf(" Norm %f %f %f ", 
		IM->Normal[i][0], IM->Normal[i][1], IM->Normal[i][2]);

      if (req & flags[i] & VERT_TEX0_ANY)
	 printf(tplate[vertex_sizes[(flags[i]>>VERT_TEX0_SHIFT)&7]], 
		"TC0",
		IM->TexCoord[0][i][0], IM->TexCoord[0][i][1], 
		IM->TexCoord[0][i][2], IM->TexCoord[0][i][2]);


      if (req & flags[i] & VERT_TEX1_ANY)
	 printf(tplate[vertex_sizes[(flags[i]>>(VERT_TEX0_SHIFT+4))&7]], 
		"TC1",
		IM->TexCoord[1][i][0], IM->TexCoord[1][i][1], 
		IM->TexCoord[1][i][2], IM->TexCoord[1][i][2]);

      if (req & flags[i] & VERT_RGBA)
	 printf(" Rgba %d %d %d %d ", 
		IM->Color[i][0], IM->Color[i][1], 
		IM->Color[i][2], IM->Color[i][3]);

      if (req & flags[i] & VERT_INDEX)
	 printf(" Index %u ", IM->Index[i]);
      
      if (req & flags[i] & VERT_EDGE)
	 printf(" Edgeflag %d ", IM->EdgeFlag[i]);

      /* The order of these two is not easily knowable, but this is
       * the usually correct way to look at them.
       */
      if (req & flags[i] & VERT_END) 
	 printf(" END ");

      if (req & flags[i] & VERT_BEGIN) 
	 printf(" BEGIN(%s) ", gl_prim_name[IM->Primitive[i]]);

      printf("\n");  
   }      
}













@


3.38
log
@removed unused vars
@
text
@d1 1
a1 1
/* $Id: vbxform.c,v 3.37 1999/07/23 17:33:17 miklos Exp $ */
d200 1
a200 1
   GLuint flags = VB->ctx->Flags;
d508 1
a508 1
      fixup &= ctx->Flags; 
d643 1
a643 1
   fixup = ctx->Flags & ~IM->AndFlag & VERT_FIXUP;
d867 4
@


3.37
log
@Bug fix with generated texture coords+VB overflow.
@
text
@d1 1
a1 1
/* $Id: vbxform.c,v 3.36 1999/07/12 15:14:47 brianp Exp $ */
a105 2
   GLcontext *ctx = VB->ctx;
   GLuint flags = ctx->Flags;
@


3.36
log
@silenced compiler warnings
@
text
@d1 1
a1 1
/* $Id: vbxform.c,v 3.35 1999/07/12 12:05:25 keithw Exp $ */
d159 1
a159 2
	 if ((flags & VERT_TEX0_ANY) && 
	     VB->TexCoordPtr[0] == &IM->v.TexCoord[0])
d162 1
a162 2
	 if ((flags & VERT_TEX1_ANY) && 
	     VB->TexCoordPtr[1] == &IM->v.TexCoord[1])
@


3.35
log
@merge from experimental branch upto merge-1 tag
@
text
@d1 1
a1 1
/* $Id: vbxform.c,v 3.34 1999/06/19 02:10:43 brianp Exp $ */
d140 1
a140 1
	    fprintf(stderr, "copying vertex %d to %d\n", src, dst);
d777 1
a777 1
      fprintf(stderr, "prim: %s count %d last %d incr %d ovf: %d\n",
d936 1
a936 1
	    printf("Array elt %d\t", IM->Elt[i]);
@


3.34
log
@added some braces to silence compiler warnings
@
text
@d1 1
a1 1
/* $Id: vbxform.c,v 3.33 1999/05/16 17:09:59 keithw Exp $ */
d65 1
a65 1
   gl_fixup_input( ctx );
d67 2
a68 1
   if (ctx->CompileFlag) 
d70 1
d72 4
a75 1
   if (ctx->CompileCVAFlag)
d77 1
a77 3
   else if (ctx->ExecuteFlag) 
      gl_execute_cassette( ctx, IM, PIPE_IMMEDIATE );
         
d85 4
a88 1
   (void) where;
d102 1
a102 1
   GLuint copy = VB->CopyCount;
d104 1
a104 1
   GLuint start = 3-copy;
d108 7
d127 1
a134 1
      
d139 3
d145 2
d167 1
a167 1
	 IM->ArrayElt[dst] = IM->ArrayElt[src];
d170 2
d174 2
a175 4

   if (VB->CullMode & (CULL_MASK_ACTIVE|CLIP_MASK_ACTIVE)) {
      MEMSET(VB->ClipMask + VB_START, 0, VB_MAX); /*VB->Count - VB_START);*/
   }
d210 2
d222 1
a222 1
      next->ArrayElt[dst] = prev->ArrayElt[src];
a247 1
   GLuint i;
a250 6
   IM->Start = VB_START;
   IM->Count = VB_START;
   IM->LastMaterial = (GLuint) (-1);
   IM->LastPrimitive = VB_START;


d255 1
d259 4
a262 6
   IM->CurrentTexSet = ctx->Current.TexSet;

   COPY_3V( IM->Normal[VB_START], ctx->Current.Normal );
   COPY_4UBV( IM->Color[VB_START], ctx->Current.ByteColor);
   IM->Index[VB_START] = ctx->Current.Index;
   IM->EdgeFlag[VB_START] = ctx->Current.EdgeFlag;
d264 1
a264 16
   for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++) 
      COPY_4FV( IM->TexCoord[i][VB_START], ctx->Current.Texcoord[i] ); 


#if 0
   if (ctx->CompileFlag) 
      IM->BeginState = VERT_BEGIN_0;
   else if (ctx->Current.Primitive != GL_POLYGON+1)
      IM->BeginState = (VERT_BEGIN_0|VERT_BEGIN_1);
   else
      IM->BeginState = 0;
#endif

   IM->BeginState = VERT_BEGIN_0;
      
   
d422 5
d448 1
a448 1
void gl_fixup_input( GLcontext *ctx )
a449 1
   struct immediate *IM = ctx->input;
d451 3
a453 3
   GLuint start = VB_START;
   GLuint fixup, diff, i;
   GLuint andflag, orflag;
a454 3
   IM->Primitive[count] = IM->Primitive[IM->LastPrimitive];
   IM->NextPrimitive[IM->LastPrimitive] = count;
   IM->NextPrimitive[count] = count+1;
d459 1
a459 1
   for (andflag = ~0, orflag = 0, i = VB_START ; i < count ; i++) {
d473 13
d488 1
a488 1
      printf("Count: %u LastData: %u\n", IM->Count, IM->LastData);
d525 24
d651 3
a653 1
      calc_normal_lengths( IM->NormalLengths, IM->Normal, IM->Flag, IM->Count);
d707 2
d775 4
d788 3
d820 1
a820 3
void gl_execute_cassette( GLcontext *ctx, 
			  struct immediate *IM, 
			  GLuint pipe )
d841 1
a841 1
   VB->Elt = IM->ArrayElt;
a856 1
   VB->LastPipe = pipe;
d865 5
a869 4
      printf("executing cassette, rows %u tc0->size == %u tc1->size == %u\n",
	     VB->Count,
	     VB->TexCoordPtr[0]->size,
	     VB->TexCoordPtr[1]->size);
d879 1
a879 1
      gl_run_pipeline( VB, pipe );      
d926 1
a926 1
      if (req & VERT_OBJ_ANY)
d936 1
a936 1
	    printf("Array elt %u\t", IM->ArrayElt[i]);
d941 1
@


3.33
log
@misc. bug fixes
@
text
@d1 1
a1 1
/* $Id: vbxform.c,v 3.32 1999/05/11 19:01:33 brianp Exp $ */
d517 1
a517 1
      if (fixup & VERT_TEX0_ANY)
d523 1
d525 1
a525 1
      if (fixup & VERT_TEX1_ANY)
d531 1
d533 1
a533 1
      if (fixup & VERT_EDGE)
d539 1
d541 1
a541 1
      if (fixup & VERT_INDEX)
d546 1
d548 1
a548 1
      if (fixup & VERT_RGBA) 
d553 1
d555 1
a555 1
      if (fixup & VERT_NORM)
d560 1
@


3.33.2.1
log
@Quake3 inspired optimizations
@
text
@d1 1
a1 1
/* $Id: vbxform.c,v 3.33 1999/05/16 17:09:59 keithw Exp $ */
d65 3
a67 2
   if (ctx->CompileFlag) {
      gl_fixup_input( ctx, IM );
a68 1
   }
d70 1
a70 4
   /* This is now the general case, and pure immediate is a special
    * case where there is no precalculated data.
    */
   if (ctx->ExecuteFlag) 
d72 3
a74 1

d96 1
a96 1
   GLuint copy;
d98 1
a98 1
   GLuint start;
a101 7
   GLubyte clipor = VB->ClipOrMask;

   if (!VB->CullDone)
      gl_fast_copy_vb( VB );
      
   copy = VB->CopyCount;
   start = 3-copy;
a113 1
      RESET_VEC(IM->v.Elt, &, VB_START);
d121 1
a128 1
	 VB->UserClipMask[dst] = VB->UserClipMask[src];
d149 1
a149 1
	 IM->Elt[dst] = IM->Elt[src];
a151 2
      
      VB->CullDone = 0;
d156 1
a156 1
      MEMSET(VB->ClipMask + VB->Start, 0, VB->Count);
a158 4
   if (clipor & CLIP_USER_BIT) 
      MEMSET(VB->UserClipMask + VB->Start, 0, VB->Count);


a191 2
      COPY_4FV( next->Obj[dst], prev->Obj[src] );

d202 1
a202 1
      next->Elt[dst] = prev->Elt[src];
d228 1
a241 1
   RESET_VEC(IM->v.Elt, &, VB_START);
a245 1
   IM->Primitive[VB_START] = ctx->Current.Primitive;
a246 1
#if 0
d251 1
d254 1
a254 1
#endif
a424 5
GLuint gl_texcoord_size( GLuint flag, GLuint unit )
{
   flag >>= VERT_TEX0_SHIFT + unit * NR_TEXSIZE_BITS;
   return vertex_sizes[flag & 0xf];
}
d446 1
a446 1
void gl_fixup_input( GLcontext *ctx, struct immediate *IM )
d448 1
a513 24

      if (ctx->ExecuteFlag && (fixup & ~IM->Flag[VB_START])) {
	 GLuint copy = fixup & ~IM->Flag[VB_START];

	 if (copy & VERT_NORM) 	 
	    COPY_3V( IM->Normal[VB_START], ctx->Current.Normal );
	 
	 if (copy & VERT_RGBA)
	    COPY_4UBV( IM->Color[VB_START], ctx->Current.ByteColor);
      
	 if (copy & VERT_INDEX)
	    IM->Index[VB_START] = ctx->Current.Index;
	 
	 if (copy & VERT_EDGE)
	    IM->EdgeFlag[VB_START] = ctx->Current.EdgeFlag;

	 if (copy & VERT_TEX0_ANY)
	    COPY_4FV( IM->TexCoord[0][VB_START], ctx->Current.Texcoord[0] ); 
	 
	 if (copy & VERT_TEX1_ANY)
	    COPY_4FV( IM->TexCoord[1][VB_START], ctx->Current.Texcoord[1] ); 
      }


d517 1
a517 1
      if (fixup & VERT_TEX0_ANY) {
a522 1
      }
d524 1
a524 1
      if (fixup & VERT_TEX1_ANY) {
a529 1
      }
d531 1
a531 1
      if (fixup & VERT_EDGE) {
a536 1
      }
d538 1
a538 1
      if (fixup & VERT_INDEX) {
a542 1
      }
d544 1
a544 1
      if (fixup & VERT_RGBA) {
a548 1
      }
d550 1
a550 1
      if (fixup & VERT_NORM) {
a554 1
      }
d610 1
a610 3
      calc_normal_lengths( IM->NormalLengths, 
			   (const GLfloat (*)[3])IM->Normal, 
			   IM->Flag, IM->Count);
a663 2
   
/*     printf("IM: %d prim[3]: %d\n", IM->id, IM->Primitive[3]); */
d768 3
a770 1
void gl_execute_cassette( GLcontext *ctx, struct immediate *IM )
d791 1
a791 1
   VB->EltPtr = &IM->v.Elt;
d807 1
d829 1
a829 1
      gl_run_pipeline( VB );      
d876 1
a876 1
      if (req & VERT_OBJ_ANY) {
d886 1
a886 1
	    printf("Array elt %d\t", IM->Elt[i]);
a890 1
      }
@


3.33.2.2
log
@q2, q3 bugfixes
@
text
@d1 1
a1 1
/* $Id: vbxform.c,v 3.33.2.1 1999/05/21 21:29:28 keithw Exp $ */
a64 2
   gl_compute_orflag( IM );

d469 1
a469 1
void gl_compute_orflag( struct immediate *IM )
d472 3
a474 3
   GLuint orflag = 0;
   GLuint andflag = ~0;
   GLuint i;
d476 3
d483 1
a483 1
   for (i = VB_START ; i < count ; i++) {
a496 13
}

void gl_fixup_input( GLcontext *ctx, struct immediate *IM )
{
   GLuint count = IM->Count;
   GLuint start = VB_START;
   GLuint fixup, diff;
   GLuint andflag = IM->AndFlag;
   GLuint orflag = IM->OrFlag;

   IM->Primitive[count] = IM->Primitive[IM->LastPrimitive];
   IM->NextPrimitive[IM->LastPrimitive] = count;
   IM->NextPrimitive[count] = count+1;
d499 1
a499 1
      fprintf(stderr, "Count: %u LastData: %u\n", IM->Count, IM->LastData);
d869 4
a872 5
      fprintf(stderr,
	      "executing cassette, rows %u tc0->size == %u tc1->size == %u\n",
	      VB->Count,
	      VB->TexCoordPtr[0]->size,
	      VB->TexCoordPtr[1]->size);
@


3.33.2.3
log
@Removed SGIS multitexture, added FX/X86 assm directory
@
text
@d1 1
a1 1
/* $Id: vbxform.c,v 3.33.2.2 1999/05/22 19:14:40 keithw Exp $ */
a135 3
	 if (0)
	    fprintf(stderr, "copying vertex %d to %d\n", src, dst);

a138 3

/*  	 COPY_4FV( VB->Clip.data[dst], VB->CopyClip[dst] );  */

d168 3
a170 3
/*     if (VB->CullMode & (CULL_MASK_ACTIVE|CLIP_MASK_ACTIVE)) { */
/*        MEMSET(VB->ClipMask + VB->Start, 0, VB->Count); */
/*     } */
a797 4

   if (0) 
      fprintf(stderr, "prim: %s count %d last %d incr %d ovf: %d\n",
	      gl_prim_name[prim], count, last, incr, VB->Ovf);
@


3.32
log
@fixed a few printf warnings (use %u instead of %d)
@
text
@d1 1
a1 1
/* $Id: vbxform.c,v 3.31 1999/05/11 17:43:00 keithw Exp $ */
d614 4
d726 2
a727 2
   if (incr != 1 && (count - out - intro[prim])) 
      VB->Ovf = (count - out - intro[prim]) % incr; 
@


3.31
log
@miscellaneous bug fixes
@
text
@d1 1
a1 1
/* $Id: vbxform.c,v 3.30 1999/05/06 01:31:55 brianp Exp $ */
d477 1
a477 1
      printf("Count: %d LastData: %d\n", IM->Count, IM->LastData);
d812 1
a812 1
      printf("executing cassette, rows %d tc0->size == %d tc1->size == %d\n",
@


3.30
log
@added cast to fix g++ warning
@
text
@d1 1
a1 1
/* $Id: vbxform.c,v 3.29 1999/05/02 00:59:24 keithw Exp $ */
d274 1
a274 2
/* Checks for mixed sizes, and if present cleans all entries to size 4.
 * Otherwise, does normal fixup.
a316 1
	 flag[i] |= match;
d320 1
a330 1
	 flag[i] |= match;
d334 1
a345 1
	 flag[i] |= match;
d349 1
@


3.29
log
@FX polygon offset and debugging changes
@
text
@d1 1
a1 1
/* $Id: vbxform.c,v 3.28 1999/04/24 01:08:02 keithw Exp $ */
d234 1
a234 1
   IM->LastMaterial = -1;
@


3.28
log
@another attempt to solve Eero's cva problem
@
text
@d1 1
a1 1
/* $Id: vbxform.c,v 3.27 1999/04/23 16:14:22 keithw Exp $ */
d477 5
a481 4
/*    printf("Count: %d LastData: %d\n", IM->Count, IM->LastData); */
/*    gl_print_vert_flags("Orflag", orflag); */
/*    gl_print_vert_flags("Andflag", andflag); */

d515 2
a516 1
/*        gl_print_vert_flags("fixup", fixup); */
d723 1
a723 1
   if (incr != 1)
d812 6
d871 1
a871 1
   for (i = VB_START ; i <= IM->Count ; i++) {
@


3.27
log
@fix for Eero's cva problem
@
text
@d1 1
a1 1
/* $Id: vbxform.c,v 3.26 1999/04/07 22:57:04 brianp Exp $ */
a125 2
/* 	 printf("reset vb: copy %d to %d\n", src, dst); */
 
a148 2
/* 	 printf("Copying array elt %d from %d:%d to self:%d\n",  */
/* 		IM->ArrayElt[src], IM->id, src, dst ); */
a149 1
/* 	 IM->Flag[dst] = IM->Flag[src]; */
a191 2
/*       printf("copy_prev_verts: copy %d to %d\n", src, dst); */

a246 6
/*    printf("copy current normal %f %f %f to IM:%d:VB_START\n", */
/* 	  ctx->Current.Normal[0], */
/* 	  ctx->Current.Normal[1], */
/* 	  ctx->Current.Normal[2], */
/* 	  IM->id); */

d506 3
a633 7

/* 	 printf("fixup cassette: current normal %f %f %f to IM:%d:VB_START\n", */
/* 		ctx->Current.Normal[0], */
/* 		ctx->Current.Normal[1], */
/* 		ctx->Current.Normal[2], */
/* 		IM->id); */

@


3.26
log
@fixed IRIX warnings
@
text
@d1 1
a1 1
/* $Id: vbxform.c,v 3.25 1999/04/06 01:11:49 keithw Exp $ */
d524 1
a524 1
/*       gl_print_vert_flags("fixup", fixup); */
d820 2
@


3.25
log
@user-clip bug fixes, faster FX vertex snapping
@
text
@d1 1
a1 1
/* $Id: vbxform.c,v 3.24 1999/03/31 20:18:41 keithw Exp $ */
d82 1
a82 1

d585 1
a585 1
				 const GLfloat (*data)[3],
d725 1
a725 1
   prim = ctx->Current.Primitive = out_prim[last];
d854 1
d856 1
a856 2

   printf("Cassette, %d rows.\n", IM->Count);
d870 1
a870 1
      printf("Obj size: %d, TexCoord0 size: %d, TexCoord1 size: %d\n",
d879 1
a879 1
      printf("%d: ", i);
d890 1
a890 1
	    printf("Array elt %d\t", IM->ArrayElt[i]);
d919 1
a919 1
	 printf(" Index %d ", IM->Index[i]);
@


3.24
log
@Compiled vertex arrays
@
text
@d1 1
a1 1
/* $Id: vbxform.c,v 3.23 1999/03/20 18:58:12 brianp Exp $ */
d160 1
a160 1
   if (VB->CullMode & (CULL_MASK_ACTIVE|CLIP_MASK_ACTIVE))  
d162 1
@


3.23
log
@fixed IRIX compiler warnings
@
text
@d1 1
a1 1
/* $Id: vbxform.c,v 3.22 1999/03/17 16:51:17 keithw Exp $ */
a28 6
/*
 * This file implements transformation, clip testing and projection of
 * vertices in the vertex buffer.
 */


d35 1
d44 1
a60 549
/*
 * Implemented object space lighting - Keith Whitwell, Oct. 1998
 * 
 * Object space lighting is a win if we can light a large number of
 * vertices/normals between changes to the modelview matrix or
 * other state changes which would force us to recompute the 
 * additional state to support this mechanism.  
 *  
 * Currently a full matrix inversion is performed to get the matrix to
 * transform light positions into object space.  This is overkill and
 * an easy future optimization target.
 *
 * There are several operations which are or must be performed in
 * eye space.  When enabled these disable object space lighting.
 * These include texture coordinate generation and fog calculation.
 *
 * Additionally, object space lighting is disabled when the
 * analysis of the modelview matrix reveals it to be non-angle
 * preserving.
 *
 * The variables recalculated on state changes include:
 *
 *       - object space light directions
 *       - object space light positions
 *       - (eventually) object space linear attenuation factors
 *       - combined model/projection matrix
 *       - lighting function 
 *
 * Given this information, we are able under various circumstances to
 *       - skip the model transformation entirely, or
 *       - skip vertex transform and only transform the normals, or
 *       - skip vertex and normal transforms and just normalize the normals, or
 *       - perform the full three-stage tranformation in the worst case...
 *  
 */


GLmatrix gl_identity_mat;


void gl_init_vbxform()
{
   gl_matrix_ctr( &gl_identity_mat );
}



/*
 * Compute shading for vertices in vertex buffer.
 */
static void shade( GLcontext *ctx )
{
   struct vertex_buffer *VB = ctx->VB;
   GLubyte flags = VB->CullMode & (CULL_MASK_ACTIVE|COMPACTED_NORMALS);
   gl_shade_func_tab[ctx->shade_func_flags | flags]( ctx );
}

/* KW: Even if all the vertices are clipped or culled, still need to
 *     execute the material changes.
 * 
 *     TODO: Do this backwards, from count to start.  
 */
static void update_materials( GLcontext *ctx )
{
   struct vertex_buffer *VB = ctx->VB;
   GLuint i;
   GLuint cm_flag, interesting;
   GLubyte (*CMcolor)[4];
   GLuint *flag = VB->Flag;
   struct gl_material (*new_material)[2] = VB->Material;
   GLuint *new_material_mask = VB->MaterialMask;

   if (ctx->Light.ColorMaterialEnabled) {
      cm_flag = VERT_RGBA;
      interesting = VERT_END_VB | VERT_RGBA | VERT_MATERIAL;
      CMcolor = (GLubyte (*)[4])VB->ColorPtr[0].start - VB_START;
   }
   else 
   {
      CMcolor = 0;
      cm_flag = 0;
      interesting = VERT_END_VB | VERT_MATERIAL;
   }

   for ( i = VB_START ; i <= VB->Count ; i++ ) 
   {
      while (!(flag[i] & interesting)) i++;

      if ( flag[i] & cm_flag ) 
	 gl_update_color_material( ctx, CMcolor[i] );
	 
      if ( flag[i] & VERT_MATERIAL )
	 gl_update_material( ctx, new_material[i], new_material_mask[i] );
   }
}


static GLubyte ignore_bits[5] = {
   ~0,				/* not possible */
   ~0, 
   ~VEC_DIRTY_1, 
   ~(VEC_DIRTY_1|VEC_DIRTY_2), 
   ~(VEC_DIRTY_1|VEC_DIRTY_2|VEC_DIRTY_3)
};


/* Todo: work this out in advance.
 */
static void import_outstanding_data( GLcontext *ctx )
{
   struct vertex_buffer *VB = ctx->VB;
   GLuint i;

   /* Can happen if ModelView and Projection matrices are both the
    * identity - GL is just the rasterizer.  Unfortunately we need to
    * copy the data for clipping or because a primitive overlapped the
    * end of the VB last time around.
    */
   if (!(VB->ClipPtr->flags & VEC_WRITABLE)) {      
      VB->ClipPtr = Transform( &VB->Clip,
			       &gl_identity_mat,
			       VB->ClipPtr,
			       VB->ClipMask + VB_START,
			       VB->CullFlag[0]);
   }

   if ((ctx->Flags & VERT_RGBA) &&
       !(VB->ColorPtr->flags & VEC_WRITABLE)) 
   {
      GLuint stride = VB->ColorPtr->stride;
      GLubyte *ptr = (GLubyte *)VB->ColorPtr->start;
      for (i = VB_START ; i < VB->Count ; i++, ptr += stride) {
	 COPY_4UBV( VB->store.Color[i], ptr );
      }
      VB->ColorPtr = &VB->store.vColor;
   }

   if ((ctx->Flags & VERT_INDEX) &&
       !(VB->IndexPtr->flags & VEC_WRITABLE)) 
   {
      GLuint stride = VB->IndexPtr->stride;
      GLuint *ptr = VB->IndexPtr->start;
      for (i = VB_START ; i < VB->Count ; i++, 
	      ptr = (GLuint *)((GLubyte*)ptr + stride)) {
	 VB->store.Index[i] = *ptr;
      }
      VB->IndexPtr = &VB->store.vIndex;
   }

   if ((ctx->Flags & VERT_TEX0) &&
       !(VB->TexCoordPtr[0]->flags & VEC_WRITABLE)) 
   {
      VB->TexCoordPtr[0] = Transform(&VB->store.vTexCoord[0],
				     &gl_identity_mat, 
				     VB->TexCoordPtr[0],
				     VB->ClipMask + VB_START,
				     VB->CullFlag[0]);      
   }

   if ((ctx->Flags & VERT_TEX1) && 
       !(VB->TexCoordPtr[1]->flags & VEC_WRITABLE)) 
   {
      VB->TexCoordPtr[1] = Transform(&VB->store.vTexCoord[1],
				     &gl_identity_mat, 
				     VB->TexCoordPtr[1],
				     VB->ClipMask + VB_START,
				     VB->CullFlag[0]);      
   }
}



/* Figure this is too rare to update via UpdateState, so give it a
 * flag of its own.  Will be fixed when I have magic state mechanism
 * (TM) in place.
 */
#if 0
static void gl_calculate_model_project_win_matrix( GLcontext *ctx )
{
    gl_matrix_mul( &ctx->ModelProjectWinMatrix,
		   &ctx->Viewport.WindowMap,
		   &ctx->ModelProjectMatrix );

   gl_matrix_analyze( &ctx->ModelProjectWinMatrix );
   ctx->ModelProjectWinMatrixUptodate = GL_TRUE;
}
#endif

static void bound_cull_vb( GLcontext *ctx )
{
   struct vertex_buffer *VB = ctx->VB;
   VB->Projected = &VB->Win;
   VB->ClipPtr = &VB->Clip;

   gl_dont_cull_vb( ctx );

   {
      GLuint start = 3 - VB->CopyCount;
      GLuint dst;
      GLuint *copy = VB->Copy;
      GLmatrix *mat = &ctx->ModelProjectMatrix;
      
      for (dst = start ; dst < VB_START ; dst++) {
	 GLfloat *src = VEC_ELT(VB->ObjPtr, GLfloat, copy[dst]);
	 GLfloat *clip = VB->Clip.data[copy[dst]];
	 gl_transform_point_sz( clip, mat->m, src, VB->ObjPtr->size );
	 {
	    const GLfloat cw = clip[3];
	    const GLfloat cx = clip[0];
	    const GLfloat cy = clip[1];
	    const GLfloat cz = clip[2]; 
	    GLuint mask = 0;
	    if (cx >  cw) mask |= CLIP_RIGHT_BIT;
	    if (cx < -cw) mask |= CLIP_LEFT_BIT;
	    if (cy >  cw) mask |= CLIP_TOP_BIT;
	    if (cy < -cw) mask |= CLIP_BOTTOM_BIT;
	    if (cz >  cw) mask |= CLIP_FAR_BIT;
	    if (cz < -cw) mask |= CLIP_NEAR_BIT;
	    VB->ClipMask[copy[dst]] = mask;
	 }
      }
   }
}



/* Actually run the pipeline.  
 * 
 * New features since 3.1-beta1 include:
 *    - multiple primitives in the vertex buffer, of multiple types.
 *    - full support for size-2 verts, and size-1 texcoords
 *    - cull testing of primitives early in the pipeline, allowing
 *      lighting, fogging, texgen, etc to be skipped for culled vertices.
 *    - support for a 'packed' normal array format, produced by glNormal()
 *      functions, which eliminates many duplicate normals.
 *    - potential to skip a transform when the matrix is the identity.
 *
 */
void gl_transform_vb( GLcontext *ctx )
{
   struct vertex_buffer *VB = ctx->VB;
   GLuint cullcount = 0;
   GLuint copycount = VB->CopyCount;
   GLboolean needclip;
   GLmatrix *proj_mat = VB->ProjMatrix;
   GLvector4f *proj_dest = &VB->Clip;
   GLboolean need_window_transform = (1 || ctx->DoViewportMapping);


    START_FAST_MATH;/*    __setfpucw( _FPU_DEFAULT & ~0x1f ); */

#define ADJ_VEC_STRIDE(v, c) (STRIDE_F((v)->start, -(c)*(v)->stride), (v)->count+=(c))


   if (VB->BoundsPtr) {
      GLubyte andmask = VB->ClipAndMask, ormask = VB->ClipOrMask;

      if (VB->ObjPtr->size == 3)
	 gl_transform_bounds3( &ormask, &andmask, 
			       &ctx->ModelProjectMatrix, 
			       VB->BoundsPtr );
      else
	 gl_transform_bounds2( &ormask, &andmask, 
			       &ctx->ModelProjectMatrix, 
			       VB->BoundsPtr );

      if (andmask) {
	 bound_cull_vb( ctx );
	 goto cleanup;
      }

      /* Maybe combine the window transform into the clip transform.
       */
#if 0
      if (!ormask && !ctx->NeedEyeCoords && !ctx->NeedClipCoords) {
	 if (!ctx->ModelProjectWinMatrixUptodate) 
	    gl_calculate_model_project_win_matrix( ctx );
	 proj_mat = &ctx->ModelProjectWinMatrix;
	 proj_dest = &VB->Win;
	 need_window_transform = 0;
      }
#endif

      needclip = ormask;
   } 
   else 
      needclip = 1;
      



   /* If necessary, apply modelview matrix to transform vertexes
    * from Object to Eye coords.  Otherwise, we are able to skip the
    * obj->eye transform, and we fix up pointers to enable the
    * obj->clip transform below.
    *
    * We could do this after vertex culling, but to do so would mean
    * using the more complex combined model-project matrix all the
    * time.  
    */
   if (ctx->NeedEyeCoords)
   {
      if (ctx->ModelView.type != MATRIX_IDENTITY) {
 	 VB->EyePtr = VB->Unprojected = TransformRaw( &VB->Eye,
						      &ctx->ModelView, 
						      VB->ObjPtr );
      } else
	 VB->EyePtr = VB->Unprojected = VB->ObjPtr;
   }
   else 
      VB->Unprojected = VB->ObjPtr;



   /* If we have skipped the obj->eye transform, we apply here the
    * combined obj->clip projection matrix.  Otherwise we apply the
    * bare projection matrix to vertices in eye space, ending up again
    * in clip coordinates.
    *
    * In both cases, we compute the ClipMask and do the perspective 
    * division for each vertex.  
    * 
    * Culling isn't yet stride aware, so sometimes we have to force a 
    * copy even when the transform is identity.  ( fix me )
    */
   if (proj_mat->type != MATRIX_IDENTITY ||
       (ctx->NeedCull && VB->Unprojected->stride != 4*sizeof(GLfloat))) 
   {
      VB->ClipPtr = TransformRaw(proj_dest, proj_mat, VB->Unprojected );
   } 
   else
      VB->ClipPtr = VB->Unprojected;





   if (needclip)
   {
      VB->Projected = gl_clip_tab[VB->ClipPtr->size]( VB->ClipPtr,
						      &VB->Win,
						      VB->ClipMask + VB_START,
						      &VB->ClipOrMask, 
						      &VB->ClipAndMask );

      if (VB->ClipAndMask) {
	 gl_dont_cull_vb( ctx );
	 goto cleanup;
      }
   } 
   else if (VB->ClipPtr->size == 4) 
   {
      /* Just do the perspective divide.  Would be better done
       * somewhere with opportunities for fpu overlap.
       * 
       * Note that we could also do the window mapping prior to 
       * the divide, combined with the projection matrix above.
       */
      VB->Projected = gl_project_points( &VB->Win, VB->ClipPtr );
   }
   else
   {
      VB->Projected = VB->ClipPtr;

      /* Set invW to 1 if need be.
       */
      if (VB->Win.flags & VEC_DIRTY_3) 
	 gl_clean_elem(3, &VB->Win);
   }


   /* KW: Now performed against clip-space coordinates.
    */
   if (ctx->Transform.AnyClip) 
      if (!gl_user_cliptest(ctx)) {
	 gl_dont_cull_vb( ctx );
	 goto cleanup;
      }

   /* KW: Cull vertices.  All transformations from this point
    * downwards are short-circuited according to VB->CullMask.  
    */
   if ((VB->ClipOrMask || ctx->NeedCull) && !VB->NeedPurge)
   {
      cullcount = gl_cull_vb( ctx );
      if (cullcount == VB->Count) 
	 goto cleanup;
   }
   else 
   {
      /* Still need to setup to copy vertices later on */
      gl_dont_cull_vb( ctx );
   }



   if (ctx->NeedNormals) {      
      GLuint tmp = 0;

      /* KW: condense cull information onto shared normals.
       */
      if (VB->CullMode & (COMPACTED_NORMALS|CULL_MASK_ACTIVE)) {
	 tmp = 1;
	 gl_make_normal_cullmask( ctx );
      }
      
      /* Similarly, transform normals to eye space or normalize
       * them inplace, as required.   VB->NormalPtr will then point
       * to normals in the same space as VB->Unprojected.
       */
      if (ctx->NormalTransform) {
	 (ctx->NormalTransform[tmp])(&ctx->ModelView,
				     VB->rescale_factor,
				     VB->NormalPtr,
				     VB->NormalLengthPtr,
				     VB->NormCullStart,
				     &VB->store.vNormal);

	 VB->NormalPtr = &VB->store.vNormal;
      }

      /* Lighting 
       */
      if (ctx->Light.Enabled) {
	 shade(ctx);
      } else {
	 update_materials(ctx);
      }
   } else {
      update_materials(ctx);
   }
   
   /* Per-vertex fog - in eye coords.
    */
   if (ctx->Fog.Enabled && ctx->FogMode==FOG_VERTEX) {
      gl_fog_vertices(ctx);
   }

   /* Generate/transform texture coords 
    */
   if (ctx->Texture.Enabled || ctx->RenderMode==GL_FEEDBACK) {
      GLuint i;
      static GLuint tex_enabled[2] = { 0x7, 0x70 };

      for (i = 0; i < ctx->Const.MaxTextureUnits; i++) 
      {
	 if (!(ctx->Texture.Enabled & tex_enabled[i]))
	    continue;

	 if (ctx->Texture.Unit[i].TexGenEnabled) 
	 {
	    /* KW: Coordinate size is set according to the enabled
	     * texgen bits and the size of any pre-existing texture
	     * data.
	     */
	    (ctx->Texture.Unit[i].func[VB->CullMode])( ctx, i );
	 }

	 if (VB->TexCoordPtr[i]->stride != 4*sizeof(GLfloat) ||
	     ctx->TextureMatrix[i].type != MATRIX_IDENTITY) 
	 {
	    /* KW: Also note that this is used to copy non-4-stride
	     *     data into the fallback storage.  Need to get drivers
	     *     to say whether they are stride-aware and could thus
	     *     cope without the copy.
	     */
	    VB->TexCoordPtr[i] = Transform( &VB->store.vTexCoord[i],
					    &ctx->TextureMatrix[i], 
					    VB->TexCoordPtr[i], 
					    VB->ClipMask + VB_START,
					    VB->CullFlag[0]);
	 }

	 if (0 && (VB->TexCoordPtr[i]->flags & VEC_DIRTY_3 & 
		   ignore_bits[VB->TexCoordPtr[i]->size])) 
	 {
	    gl_clean_elem(3, VB->TexCoordPtr[i]);
	 }
      }
   }


   /*
   if ((VB->ClipOrMask || ctx->NeedCull) && !VB->NeedPurge)
      gl_build_clip_vert_bits( VB->CullMask, VB->ClipMask );
    */



   /* Use the viewport parameters to transform vertices from projected
    * Clip coordinates to Window coordinates.  
    *
    * KW: Because the projective divide is already done, this is just
    * another matrix transform.  This transform also guarentees that
    * the data is stride 4, and ends up in VB->Win, as the drivers
    * expect.  
    */
   if (need_window_transform) {

      /* Have to retransform the copied vertices because
       * of the hack of reusing Win to hold the projected
       * coordinates.
       */
      ADJ_VEC_STRIDE( VB->Projected, copycount );
      VB->Win.start = (GLfloat *)VB->Win.data[VB->CopyStart];

      (void) Transform( &VB->Win,
			&ctx->Viewport.WindowMap, 
			VB->Projected, 
			VB->ClipMask + VB->CopyStart,
			VB->CullFlag[1]);
   }
      
   /* Clean Z, because the drivers can't cope with size 2 verts.
    */
   if (VB->Win.flags & VEC_DIRTY_2 & ignore_bits[VB->Win.size]) {
      gl_clean_elem(2, &VB->Win);
   }

   if (VB->ClipOrMask || VB->CopyCount != 0) {
      /* Need to bring any data remaining client-side into the vertex
       * buffer because we are going to manipulate it via clipping or
       * vertex copy.  Hard to see any alternative to this copy.
       */
      import_outstanding_data( ctx ); /* affects array data only */
   } 

      

   if (ctx->Driver.RasterSetup) {
      (*ctx->Driver.RasterSetup)( ctx, VB->CopyStart, VB->Count );
   }

   /* Now we're ready to rasterize the vertex buffer.  
    */
   gl_render_vb( ctx );   

   END_FAST_MATH;/*  __setfpucw( _FPU_DEFAULT & ~0x1f ); */
   return;

 cleanup:
   update_materials(ctx);
   END_FAST_MATH;/*  __setfpucw( _FPU_DEFAULT & ~0x1f ); */
   return;
}




d70 5
a74 4
   if (ctx->ExecuteFlag) {
      gl_execute_cassette( ctx, IM );
   }
      
a78 2


d83 1
a83 13
   gl_fixup_input( ctx );

   if (ctx->NewState)
      gl_update_state(ctx);

   if (ctx->CompileFlag) 
      gl_compile_cassette( ctx );   

   if (ctx->ExecuteFlag) {
      gl_execute_cassette( ctx, IM );
   }
      
   gl_reset_input( ctx );
d89 1
a89 1
#define RESET_VEC(v, t) (v.start = t v.data[3], v.count = 0)  /* THREE */
d94 1
a94 1
void gl_reset_vb( GLcontext *ctx, struct immediate *IM )
a95 2
   struct vertex_buffer *VB = ctx->VB;
   GLubyte ormask = VB->ClipOrMask;
d99 2
a100 1
   struct immediate *store = &VB->store;
d104 2
d107 1
a107 3
   /* If these are the same, the reset gets done in gl_reset_input().
    */
   if (1) 
d109 48
a156 6
      RESET_VEC(store->vObj, (GLfloat *));
      RESET_VEC(store->vNormal, (GLfloat *));
      RESET_VEC(store->vTexCoord[0], (GLfloat *));
      RESET_VEC(store->vTexCoord[1], (GLfloat *));
      RESET_VEC(store->vIndex, &);
      RESET_VEC(store->vColor, (GLubyte *));
a158 5
   RESET_VEC(VB->Clip, (GLfloat *));
   RESET_VEC(VB->Eye, (GLfloat *));
   RESET_VEC(VB->Win, (GLfloat *));
   RESET_VEC(VB->BColor, (GLubyte *)); 
   RESET_VEC(VB->BIndex, &);
d160 4
a164 2
   VB->ClipOrMask = 0;
   VB->ClipAndMask = CLIP_ALL_BITS;
d166 3
a168 1
   VB->NeedPurge = 0;
d170 4
a173 32
   VB->NormalLengthPtr = 0;

   for (dst = start ; dst < VB_START ; dst++) 
   {
      GLuint src = VB->Copy[dst];

      COPY_4V( VB->Clip.data[dst], VEC_ELT(VB->ClipPtr, GLfloat, src) ); 
      COPY_4V( VB->Win.data[dst], VB->Win.data[src] ); 

      VB->ClipMask[dst] = VB->ClipMask[src];   
      VB->ClipAndMask &= VB->ClipMask[dst];
      VB->ClipOrMask  |= VB->ClipMask[dst];

      COPY_4UBV( VB->store.Color[dst], VB->store.Color[src] );
      COPY_4UBV( VB->Spec[0][dst], VB->Spec[0][src] );
      COPY_4UBV( VB->Spec[1][dst], VB->Spec[1][src] );
      COPY_4UBV( VB->BColor.data[dst], VB->BColor.data[src] );
      VB->store.Index[dst] = VB->store.Index[src];
      VB->BIndex.data[dst] = VB->BIndex.data[src];

      if ((flags & VERT_TEX0) && VB->TexCoordPtr[0] == &VB->store.vTexCoord[0])
	 COPY_4V( VB->store.TexCoord[0][dst], VB->store.TexCoord[0][src] );
	    
      if ((flags & VERT_TEX1) && VB->TexCoordPtr[1] == &VB->store.vTexCoord[1])
	 COPY_4V( VB->store.TexCoord[1][dst], VB->store.TexCoord[1][src] );
   } 

   /* always going to be overwritten */
   VB->Count = store->Count = VB_START; 

   if (ormask) 
      MEMSET(VB->ClipMask + VB_START, 0, VB_SIZE - VB_START);
a178 1

d185 1
a185 1
void gl_copy_prev_vertices( GLcontext *ctx,
a188 1
   struct vertex_buffer *VB = ctx->VB;
d190 1
a190 1
   GLuint flags = ctx->Flags;
d196 4
a199 2
      if ((flags & VERT_TEX0) && VB->TexCoordPtr[0] == &prev->vTexCoord[0])
	 COPY_4V( next->TexCoord[0][dst], prev->TexCoord[0][src] );
d201 2
a202 2
      if ((flags & VERT_TEX1) && VB->TexCoordPtr[1] == &prev->vTexCoord[1])
	 COPY_4V( next->TexCoord[1][dst], prev->TexCoord[1][src] );
d207 3
a210 5

   next->ref_count++;

   if (! --prev->ref_count ) 
      gl_free_immediate( prev );
d217 1
a217 1
   if (ctx->VB->prev_buffer != &ctx->VB->store) {
d236 3
a239 8

   IM->LastArrayElement = -1;
   IM->LastNormal = -1;
   IM->LastTexCoord[0] = -1;
   IM->LastTexCoord[1] = -1;
   IM->LastIndex = -1;
   IM->LastEdgeFlag = -1;
   IM->LastColor = -1;
d243 7
a249 6
   RESET_VEC(IM->vObj, (GLfloat *));
   RESET_VEC(IM->vNormal, (GLfloat *));
   RESET_VEC(IM->vColor, (GLubyte *));
   RESET_VEC(IM->vIndex, &);
   RESET_VEC(IM->vTexCoord[0], (GLfloat *));
   RESET_VEC(IM->vTexCoord[1], (GLfloat *));
d253 6
d264 2
a266 4
   for (i = 0 ; i < MAX_TEXTURE_UNITS ; i++) 
   {
      GLfloat *tc = ctx->Current.Texcoord[i];
      GLubyte flag;
d268 8
a275 4
      if (tc[3] == 1) 
	 flag = (tc[2] == 0) ? 0 : 1;
      else 
	 flag = 0x3;
d277 4
a280 11
      IM->TexCoordSize[i] = flag;
      COPY_4V( IM->TexCoord[i][VB_START], tc ); 
   }

   /* Initial state - no errors, stream 0 inside begin/end, stream 1 outside,
    *               - no eval
    *               - object size 2.
    */
   IM->AndFlag = ~(VERT_BEGIN_1|VERT_ERROR_0|VERT_ERROR_1|VERT_ANY_EVAL);

   IM->ArrayOrFlags = (ctx->Array.Flags & VERT_OBJ) | VERT_ELT;
d282 1
a282 2

   MEMSET(IM->Flag, 0, sizeof(GLuint) * VB_SIZE);
d286 5
a290 2
void
fixup_4v( GLfloat data[][4], GLuint flag[], GLuint match )
d292 1
a292 1
   GLuint i;
d294 1
a294 1
   for ( i = VB_START ; !(flag[i] & VERT_END_VB) ; ) {
d296 4
a299 2
	 COPY_4V(data[i], data[i-1]);
      }
d304 1
d308 1
a308 1
fixup_3v( GLfloat data[][3], GLuint flag[], GLuint match )
d310 1
a310 1
   GLuint i;
d312 1
a312 1
   for ( i = VB_START ; !(flag[i] & VERT_END_VB) ; ) {
d315 3
a317 1
      }
d321 1
d323 1
a323 1
fixup_1ui( GLuint *data, GLuint *flag, const GLuint match )
d325 1
a325 1
   GLuint i;
d327 1
a327 1
   for ( i = VB_START ; !(flag[i] & VERT_END_VB) ; ) {
d330 3
a332 1
      }
d337 1
a337 1
fixup_1ub( GLubyte data[], GLuint flag[], GLuint match )
d339 1
a339 1
   GLuint i;
d341 1
a341 1
   for ( i = VB_START ; !(flag[i] & VERT_END_VB) ; ) {
d344 3
a346 1
      }
d350 1
d352 1
a352 1
fixup_4ub( GLubyte data[][4], GLuint flag[], GLuint match )
d354 1
a354 1
   GLuint i;
d356 1
a356 1
   for ( i = VB_START ; !(flag[i] & VERT_END_VB) ; ) {
d359 3
a361 1
      }
d366 20
d387 3
a390 2
static GLuint texcoord_sizes[4] = { 2, 3, 4, 4 }; 
static GLuint vertex_sizes[4] = { 4, 3, 0, 2 }; /* ind 2 isn't possible  */
d392 3
a394 1
void gl_fixup_input( GLcontext *ctx )
d396 2
a397 5
   struct immediate *IM = ctx->input;
   GLuint count = IM->Count;
   GLuint fixup, diff;
   
   IM->Flag[count] |= VERT_END_VB;
d399 3
a401 4
   if (IM->LastPrimitive != count) {
      IM->NextPrimitive[IM->LastPrimitive] = count;
      IM->Primitive[count] = IM->Primitive[IM->LastPrimitive];
   }
a402 1
   IM->NextPrimitive[count] = count+1;
d404 6
d411 3
a413 5
   /* Array elements modify the current state - must do this before
    * fixup.
    */
   if (IM->LastArrayElement != -1) 
      gl_exec_array_elements( ctx );   
a414 2
   fixup = ~IM->AndFlag & VERT_FIXUP;
   if (!ctx->CompileFlag) fixup &= ctx->Flags;
d416 6
a421 4
   if (fixup) 
   {
      if (fixup & VERT_TEX0) 
	 fixup_4v( IM->TexCoord[0], IM->Flag, VERT_TEX0 );
d423 3
a425 2
      if (fixup & VERT_TEX1) 
	 fixup_4v( IM->TexCoord[1], IM->Flag, VERT_TEX1 );
a426 2
      if (fixup & VERT_EDGE)
	 fixup_1ub( IM->EdgeFlag, IM->Flag, VERT_EDGE );
a427 2
      if (fixup & VERT_INDEX)
	 fixup_1ui( IM->Index, IM->Flag, VERT_INDEX );
a428 3
      if (fixup & VERT_RGBA) {
	 fixup_4ub( IM->Color, IM->Flag, VERT_RGBA );
      }
d430 5
a434 3
      if ((fixup & VERT_NORM) && (IM->AndFlag & VERT_ANY_EVAL)) 
	 fixup_3v( IM->Normal, IM->Flag, VERT_NORM );
   }
a436 13
   diff = count - VB_START;
   IM->vObj.count = diff;
   IM->vNormal.count = diff;
   IM->vTexCoord[0].count = diff;
   IM->vTexCoord[1].count = diff;
   IM->vEdgeFlag.count = diff;
   IM->vColor.count = diff;
   IM->vIndex.count = diff;

   IM->vObj.size = vertex_sizes[(IM->AndFlag>>VERT_OBJ_SHIFT)&0x3];
   IM->vTexCoord[0].size = texcoord_sizes[IM->TexCoordSize[0]];
   IM->vTexCoord[1].size = texcoord_sizes[IM->TexCoordSize[1]];
}
d440 1
a440 3
void
fixup_first_4v( GLfloat data[][4], GLuint flag[], GLuint match, 
		GLfloat *dflt )
d442 6
a447 1
   GLuint i = VB_START;
d449 6
a454 4
   for ( ; !(flag[i] & VERT_END_VB) ; i++ ) {
      if ((flag[i]&match) == 0)
	 COPY_4V(data[0], dflt);
      else return;
d459 1
a459 3
void
fixup_first_1ui( GLuint data[], GLuint flag[], GLuint match,
		 GLuint dflt )
d461 5
a465 1
   GLuint i = VB_START;
d467 10
a476 4
   for ( ; !(flag[i] & VERT_END_VB) ; i++ ) {
      if ((flag[i]&match) == 0)
	 data[i] = dflt;
      else return;
a477 1
}
d479 22
d502 2
a503 5
void
fixup_first_1ub( GLubyte data[], GLuint flag[], GLuint match,
		 GLubyte dflt )
{
   GLuint i = VB_START;
d505 3
a507 4
   for ( ; !(flag[i] & VERT_END_VB) ; i++ ) {
      if ((flag[i]&match) == 0)
	 data[i] = dflt;
      else return;
d509 11
a519 1
}
d521 17
d539 6
d546 32
a577 5
void
fixup_first_4ub( GLubyte data[][4], GLuint flag[], GLuint match,
		 GLubyte dflt[4] )
{
   GLuint i = VB_START;
d579 1
a579 6
   for ( ; !(flag[i] & VERT_END_VB) ; i++ ) {
      if ((flag[i] & match) == 0) {
	 COPY_4UBV(data[i], dflt);
      } 
      else return;
   }
d593 1
d595 1
a595 3
	    dest[i-VB_START] = 1.0 / tmp;
	 else
	    dest[i-VB_START] = 0;
d600 3
a602 1
/* Revive a compiled immediate struct - propogate new 'Current' values.
d607 3
d614 1
a614 1
   fixup = ctx->Flags & ~IM->AndFlag;
d617 1
a617 1
      IM->NormalLengths = (GLfloat *)malloc(sizeof(GLfloat) * IM->Count);
d622 2
a623 2
      if (fixup & VERT_TEX0) 
	 fixup_first_4v( IM->TexCoord[0], IM->Flag, VERT_TEX0, 
d626 2
a627 2
      if (fixup & VERT_TEX1) 
	 fixup_first_4v( IM->TexCoord[1], IM->Flag, VERT_TEX1,
d631 1
a631 1
	 fixup_first_1ub(IM->EdgeFlag, IM->Flag, VERT_EDGE,
d635 1
a635 1
	 fixup_first_1ui(IM->Index, IM->Flag, VERT_INDEX,
d638 3
a640 4
      if (fixup & VERT_RGBA) {
	 fixup_first_4ub(IM->Color, IM->Flag, VERT_RGBA,
			 ctx->Current.ByteColor );
      }
d643 7
d652 1
a652 1
	    IM->NormalLengths[0] = 1.0 / LEN_3FV(ctx->Current.Normal);
d667 2
a668 2
   GLuint *out_prim = VB->store.Primitive;
   GLuint *out_nextprim = VB->store.NextPrimitive;
d677 2
a678 2
      transition = VERT_BEGIN_0;
      err = IM->AndFlag & VERT_ERROR_1;
d681 1
a681 1
      err = IM->AndFlag & VERT_ERROR_0;
a740 1

d746 3
a748 2
  if (IM->LastNormal != -1) 
      COPY_3V( ctx->Current.Normal, IM->Normal[IM->LastNormal]);
d750 8
a757 5
   if (IM->LastTexCoord[0] != -1)
      COPY_4V( ctx->Current.Texcoord[0], IM->TexCoord[0][IM->LastTexCoord[0]]);
      
   if (IM->LastTexCoord[1] != -1)
      COPY_4V( ctx->Current.Texcoord[1], IM->TexCoord[1][IM->LastTexCoord[1]]);
d759 2
a760 2
   if (IM->LastIndex != -1)
      ctx->Current.Index = IM->Index[IM->LastIndex];
d762 9
a770 2
   if (IM->LastEdgeFlag != -1)
      ctx->Current.EdgeFlag = IM->EdgeFlag[IM->LastEdgeFlag];
d772 4
a775 2
   if (IM->LastColor != -1) 
      COPY_4UBV(ctx->Current.ByteColor, IM->Color[IM->LastColor]);
d779 3
a781 1
void gl_execute_cassette( GLcontext *ctx, struct immediate *IM )
d784 4
d789 2
a790 3
   if ( VB->prev_buffer != &VB->store || IM != &VB->store ) {
      gl_copy_prev_vertices( ctx, VB->prev_buffer, IM );
      VB->prev_buffer = IM;
d793 2
a794 1
/*    gl_print_cassette(IM, ~0); */
d796 2
d801 2
d806 9
a814 8
   VB->ObjPtr = &IM->vObj;
   VB->NormalPtr = &IM->vNormal;
   VB->ColorPtr = &IM->vColor;
   VB->IndexPtr = &IM->vIndex;
   VB->EdgeFlagPtr = &IM->vEdgeFlag;
   VB->TexCoordPtr[0] = &IM->vTexCoord[0];
   VB->TexCoordPtr[1] = &IM->vTexCoord[1];
   VB->BoundsPtr = IM->Bounds;	/* may be zero */
d816 3
a819 1
   /* Do this before transform as the values may be clobbered.  */
d822 4
a825 4
   if (IM->AndFlag & VERT_ANY_EVAL) 
      gl_eval_vb( ctx );
   else
      VB->PurgeCount = VB->Count;
d828 1
a828 1
       (IM->Flag[VB_START] & (VERT_END|VERT_BEGIN_0|VERT_BEGIN_1)))
d831 4
a834 6
   if (VB->PurgeCount > VB_START) {
      gl_transform_vb( ctx );
   } else
      update_materials( ctx );

   gl_reset_vb( ctx, IM );
d836 1
d841 1
a841 2

void gl_print_cassette( struct immediate *IM, GLuint req ) 
d845 2
d854 1
d857 1
a857 7
   printf("Contains at least one: %s%s%s%s%s%s\n",
	  (IM->LastTexCoord[0] != -1) ? "texcoord0, " : "",
	  (IM->LastTexCoord[1] != -1) ? "texcoord1, " : "",
	  (IM->LastColor != -1)       ? "color, " : "",
	  (IM->LastNormal != -1)      ? "normal, " : "",
	  (IM->LastIndex != -1)       ? "index, " : "",
	  (IM->LastEdgeFlag != -1)    ? "edgeflag, " : "");
d861 1
a861 18
      printf("Contains a full complement of: %s%s%s%s%s%s\n",
	     (andflag & VERT_TEX0)  ? "texcoord0, " : "",
	     (andflag & VERT_TEX1)  ? "texcoord1, " : "",
	     (andflag & VERT_RGBA)  ? "colors, " : "",
	     (andflag & VERT_NORM)  ? "normals, " : "",
	     (andflag & VERT_INDEX) ? "index, " : "",
	     (andflag & VERT_EDGE)  ? "edgeflag." : "" );   
   
      printf("Any eval %s,%s,%s,%s - array_elt %s obj ?\n",
	     (andflag & VERT_EVAL_C1) ? "y" : "n",
	     (andflag & VERT_EVAL_P1) ? "y" : "n",
	     (andflag & VERT_EVAL_C2) ? "y" : "n",
	     (andflag & VERT_EVAL_P2) ? "y" : "n",
	     (IM->LastArrayElement != -1) ? "y" : "n");
   
      printf("All eval: %s  All array: %s\n",
	     (andflag & VERT_EVAL) ? "y" : "n",
	     (andflag & VERT_ELT) ? "y" : "n");
d864 9
a872 9
	     (andflag & VERT_BEGIN_0) ? "in" : "out", 
	     (andflag & VERT_BEGIN_1) ? "in" : "out", 
	     (andflag & VERT_ERROR_0) ? "y" : "n", 
	     (andflag & VERT_ERROR_1) ? "y" : "n");

      printf("Obj size: %d, tc0 size: %d, tc1 size: %d\n",
	     vertex_sizes[(IM->AndFlag>>VERT_OBJ_SHIFT)&0x3],
	     texcoord_sizes[IM->TexCoordSize[0]],
	     texcoord_sizes[IM->TexCoordSize[1]]);
d879 1
a879 1
      if (req & VERT_OBJ)
d888 1
a888 1
	 else if ((flags[i] & (VERT_ELT|VERT_OBJ)) == (VERT_ELT|VERT_OBJ)) 
d891 1
a891 1
	    printf(tplate[vertex_sizes[(IM->AndFlag>>VERT_OBJ_SHIFT)&0x3]],
d899 2
a900 2
      if (req & flags[i] & VERT_TEX0)
	 printf(tplate[texcoord_sizes[IM->TexCoordSize[0]]], 
d906 2
a907 2
      if (req & flags[i] & VERT_TEX1)
	 printf(tplate[texcoord_sizes[IM->TexCoordSize[1]]], 
a911 1

d921 1
a921 1
	 printf(" Index %d ", IM->EdgeFlag[i]);
d929 1
a929 1
      if (req & flags[i] & (VERT_BEGIN_1|VERT_BEGIN_0)) 
a933 2


@


3.22
log
@Fix for culling shared normals.
@
text
@d1 1
a1 1
/* $Id: vbxform.c,v 3.21 1999/03/17 12:08:22 keithw Exp $ */
d241 1
d251 1
@


3.21
log
@Removed CLIP_4D_BIT, added CLIP_CULLED_BIT.  Clipmask is now used
to drive culling in vertex transformation, allowing us to skip
both clipped and culled vertices with a single test.
@
text
@d1 1
a1 1
/* $Id: vbxform.c,v 3.20 1999/02/25 14:12:32 keithw Exp $ */
d312 1
a312 1
    START_FAST_MATH;   
d460 2
d464 2
a465 1
      if (VB->CullMode & CULL_MASK_ACTIVE)
d467 1
d474 6
a479 6
	 (ctx->NormalTransform[VB->CullMode&1])(&ctx->ModelView,
						VB->rescale_factor,
						VB->NormalPtr,
						VB->NormalLengthPtr,
						VB->NormCullStart,
						&VB->store.vNormal);
d600 1
a600 1
   END_FAST_MATH; 
d605 1
a605 1
   END_FAST_MATH; 
@


3.20
log
@Merged in kw3 patch
@
text
@d1 1
a1 1
/* $Id: vbxform.c,v 3.19 1999/02/24 22:48:08 jens Exp $ */
d187 2
a188 2
			       VB->CullMask + VB_START,
			       VB->CullMode & 1);
d220 2
a221 2
				     VB->CullMask + VB_START,
				     VB->CullMode & 1);      
d230 2
a231 2
				     VB->CullMask + VB_START,
				     VB->CullMode & 1);      
d251 5
d257 29
d312 2
a313 1
   START_FAST_MATH;
a316 23
   /* If necessary, apply modelview matrix to transform vertexes
    * from Object to Eye coords.  Otherwise, we are able to skip the
    * obj->eye transform, and we fix up pointers to enable the
    * obj->clip transform below.
    *
    * We could do this after culling, but to do so would mean using
    * the more complex combined model-project matrix all the time.
    */
   if (ctx->NeedEyeCoords)
   {
      if (ctx->ModelView.type != MATRIX_IDENTITY) {
 	 VB->EyePtr = VB->Unprojected = TransformRaw( &VB->Eye,
						      &ctx->ModelView, 
						      VB->ObjPtr );
      } else
	 VB->EyePtr = VB->Unprojected = VB->ObjPtr;
   }
   else 
      VB->Unprojected = VB->ObjPtr;




d318 1
a318 1
      GLubyte andmask, ormask;
d330 1
a330 8
	 GLuint start = 3 - VB->CopyCount;
	 GLuint dst;
	 VB->Projected = VB->ClipPtr = &VB->Win;
	 gl_dont_cull_vb( ctx );
	 
	 /* Don't skip clip planes for copied triangles */
	 for (dst = start ; dst < VB_START ; dst++)
	    VB->ClipMask[VB->Copy[dst]] = CLIP_4D;
d353 24
a384 6
    * The cliptest could be skipped in the case of display lists if
    * those lists calculated a bounding box for their contents.
    * Further, if such a bounding box were available and we knew that
    * clipping was not required, we could push the clip->window
    * transform from map_vertices into this transform.  
    *
d448 2
a449 6
      
      if (cullcount == VB->Count) goto cleanup;
      if (cullcount > 0 || ctx->LightTwoSide) {
	 VB->CullMode |= CULL_MASK_ACTIVE;
      }
      if (VB->ClipOrMask) VB->CullMode |= CLIP_MASK_ACTIVE;      
d528 2
a529 2
					    VB->CullMask + VB_START,
					    VB->CullMode & 1);
d541 7
d568 2
a569 2
			VB->CullMask + VB->CopyStart,
			VB->CullMode & 1);
d596 1
a596 1
   END_FAST_MATH;
d601 1
a601 1
   END_FAST_MATH;
@


3.19
log
@Added header file to get XMesa to compile standalone and inside XFree86
@
text
@d1 1
a1 1
/* $Id: vbxform.c,v 3.18 1999/02/14 03:46:34 brianp Exp $ */
a27 61
/*
 * $Log: vbxform.c,v $
 * Revision 3.18  1999/02/14 03:46:34  brianp
 * new copyright
 *
 * Revision 3.17  1999/01/30 04:33:01  brianp
 * gl_texgen() now takes a stride parameter
 *
 * Revision 3.16  1998/11/17 01:52:47  brianp
 * implemented GL_NV_texgen_reflection extension (MJK)
 *
 * Revision 3.15  1998/11/08 22:36:27  brianp
 * renamed texture sets to texture units
 *
 * Revision 3.14  1998/11/03 02:40:40  brianp
 * new ctx->RenderVB function pointer
 *
 * Revision 3.13  1998/10/31 17:08:00  brianp
 * variety of multi-texture changes
 *
 * Revision 3.12  1998/10/29 03:57:11  brianp
 * misc clean-up of new vertex transformation code
 *
 * Revision 3.11  1998/10/29 02:28:13  brianp
 * incorporated Keith Whitwell's transformation optimizations
 *
 * Revision 3.10  1998/08/23 22:19:30  brianp
 * added DoViewportMapping to context struct
 *
 * Revision 3.9  1998/07/09 03:15:41  brianp
 * include asm_386.h instead of asm-386.h
 *
 * Revision 3.8  1998/06/22 03:16:28  brianp
 * added MITS code
 *
 * Revision 3.7  1998/06/07 22:18:52  brianp
 * implemented GL_EXT_multitexture extension
 *
 * Revision 3.6  1998/04/18 05:01:18  brianp
 * renamed USE_ASM to USE_X86_ASM
 *
 * Revision 3.5  1998/03/28 04:01:53  brianp
 * added CONST macro to fix IRIX compilation problems
 *
 * 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/02 03:09:34  brianp
 * added GL_LIGHT_MODEL_COLOR_CONTROL (separate specular color interpolation)
 *
 * Revision 3.1  1998/02/01 16:37:19  brianp
 * added GL_EXT_rescale_normal extension
 *
 * Revision 3.0  1998/01/31 21:06:45  brianp
 * initial rev
 *
 */

d39 1
d41 3
d49 1
d52 1
d54 2
a64 4

/* This value matches the one in clip.c, used to cope with numeric error. */
#define MAGIC_NUMBER -0.8e-03F

d66 34
a99 15
 * Test an array of vertices against the user-defined clipping planes.
 * Input:  ctx - the context
 *         n - number of vertices
 *         vEye - array [n] of vertices, in eye coordinate system
 * Output:  clipMask - array [n] of clip values: 0=not clipped, !0=clipped
 * Return:  CLIP_ALL - if all vertices are clipped by one of the planes
 *          CLIP_NONE - if no vertices were clipped
 *          CLIP_SOME - if some vertices were clipped
 */
static GLuint userclip_test_vertices( GLcontext *ctx, GLuint n,
                                      CONST GLfloat vEye[][4],
                                      GLubyte clipMask[] )
{
   GLboolean anyClipped = GL_FALSE;
   GLuint p;
a100 1
   ASSERT(ctx->Transform.AnyClip);
d102 1
a102 28
   START_FAST_MATH;

   for (p=0;p<MAX_CLIP_PLANES;p++) {
      if (ctx->Transform.ClipEnabled[p]) {
         GLfloat a = ctx->Transform.ClipEquation[p][0];
         GLfloat b = ctx->Transform.ClipEquation[p][1];
         GLfloat c = ctx->Transform.ClipEquation[p][2];
         GLfloat d = ctx->Transform.ClipEquation[p][3];
         GLboolean allClipped = GL_TRUE;
         GLuint i;
         for (i=0;i<n;i++) {
            GLfloat dot = vEye[i][0] * a + vEye[i][1] * b
                        + vEye[i][2] * c + vEye[i][3] * d;
            if (dot < MAGIC_NUMBER) {
               /* this vertex is clipped */
               clipMask[i] = CLIP_USER_BIT;
               anyClipped = GL_TRUE;
            }
            else {
               /* vertex not clipped */
               allClipped = GL_FALSE;
            }
         }
         if (allClipped) {
            return CLIP_ALL;
         }
      }
   }
a103 1
   END_FAST_MATH;
d105 3
a107 95
   return anyClipped ? CLIP_SOME : CLIP_NONE;
}


/*
 * Transform an array of vertices from clip coordinate space to window
 * coordinates.
 * Input:  ctx - the context
 *         n - number of vertices to transform
 *         vClip - array [n] of input vertices
 *         clipMask - array [n] of vertex clip masks.  NULL = no clipped verts
 * Output:  vWin - array [n] of vertices in window coordinate system
 */
static void viewport_map_vertices( GLcontext *ctx,
                                   GLuint n, 
				   CONST GLfloat vClip[][4],
                                   const GLubyte clipMask[], 
				   GLfloat vWin[][3],
				   GLuint vertex_size)
{
   GLfloat sx = ctx->Viewport.Sx;
   GLfloat tx = ctx->Viewport.Tx;
   GLfloat sy = ctx->Viewport.Sy;
   GLfloat ty = ctx->Viewport.Ty;
   GLfloat sz = ctx->Viewport.Sz;
   GLfloat tz = ctx->Viewport.Tz;

   START_FAST_MATH;

   if (vertex_size < 4) {
      /* don't need to divide by W */
      if (clipMask) {
         /* one or more vertices are clipped */
         GLuint i;
         for (i=0;i<n;i++) {
            if (clipMask[i]==0) {
               vWin[i][0] = vClip[i][0] * sx + tx;
               vWin[i][1] = vClip[i][1] * sy + ty;
               vWin[i][2] = vClip[i][2] * sz + tz;
            }
         }
      }
      else {
         /* no vertices are clipped */
         GLuint i;
         for (i=0;i<n;i++) {
            vWin[i][0] = vClip[i][0] * sx + tx;
            vWin[i][1] = vClip[i][1] * sy + ty;
            vWin[i][2] = vClip[i][2] * sz + tz;
         }
      }
   }
   else {
      /* need to divide by W */
      if (clipMask) {
         /* one or more vertices are clipped */
         GLuint i;
         for (i=0;i<n;i++) {
            if (clipMask[i] == 0) {
               if (vClip[i][3] != 0.0F) {
                  GLfloat wInv = 1.0F / vClip[i][3];
                  vWin[i][0] = vClip[i][0] * wInv * sx + tx;
                  vWin[i][1] = vClip[i][1] * wInv * sy + ty;
                  vWin[i][2] = vClip[i][2] * wInv * sz + tz;
               }
               else {
                  /* Div by zero!  Can't set window coords to infinity, so...*/
                  vWin[i][0] = 0.0F;
                  vWin[i][1] = 0.0F;
                  vWin[i][2] = 0.0F;
               }
            }
         }
      }
      else {
         /* no vertices are clipped */
         GLuint i;
         for (i=0;i<n;i++) {
            if (vClip[i][3] != 0.0F) {
               GLfloat wInv = 1.0F / vClip[i][3];
               vWin[i][0] = vClip[i][0] * wInv * sx + tx;
               vWin[i][1] = vClip[i][1] * wInv * sy + ty;
               vWin[i][2] = vClip[i][2] * wInv * sz + tz;
            }
            else {
               /* Divide by zero!  Can't set window coords to infinity, so...*/
               vWin[i][0] = 0.0F;
               vWin[i][1] = 0.0F;
               vWin[i][2] = 0.0F;
            }
         }
      }
   }

   END_FAST_MATH;
d113 1
a113 11
 * Check if the global material has to be updated with info that was
 * associated with a vertex via glMaterial.
 * This function is used when any material values get changed between
 * glBegin/glEnd either by calling glMaterial() or by calling glColor()
 * when GL_COLOR_MATERIAL is enabled.
 *
 * KW: Added code here to keep the precomputed variables uptodate.
 *     This means we can use the faster shade functions when using
 *     GL_COLOR_MATERIAL, and we can also now use the precomputed 
 *     values in the slower shading functions, which further offsets
 *     the cost of doing this here.
d115 1
a115 1
static void update_material( GLcontext *ctx, GLuint i )
d118 2
a119 99
   struct gl_light *light, *first = ctx->Light.FirstEnabled;
   GLfloat tmp[4];
   
   if (VB->MaterialMask[i] & FRONT_AMBIENT_BIT) {
      struct gl_material *mat = &ctx->Light.Material[0];
      SUB_3V( tmp, VB->Material[i][0].Ambient, mat->Ambient );
      ACC_SCALE_3V( ctx->Light.BaseColor[0], ctx->Light.Model.Ambient, tmp);
      for (light = first; light; light = light->NextEnabled) {
	 ACC_SCALE_3V( ctx->Light.BaseColor[0], light->Ambient, tmp );
      }
      COPY_4V( mat->Ambient, VB->Material[i][0].Ambient );
   }

   if (VB->MaterialMask[i] & BACK_AMBIENT_BIT) {
      struct gl_material *mat = &ctx->Light.Material[1];
      SUB_3V( tmp, VB->Material[i][1].Ambient, mat->Ambient );
      ACC_SCALE_3V( ctx->Light.BaseColor[1], ctx->Light.Model.Ambient, tmp);
      for (light = first; light; light = light->NextEnabled) {
	 ACC_SCALE_3V( ctx->Light.BaseColor[0], light->Ambient, tmp );
      }
      COPY_4V( mat->Ambient, VB->Material[i][1].Ambient );
   }

   if (VB->MaterialMask[i] & FRONT_DIFFUSE_BIT) {
      struct gl_material *mat = &ctx->Light.Material[0];
      SUB_3V( tmp, VB->Material[i][0].Diffuse, mat->Diffuse );
      for (light = first; light; light = light->NextEnabled) {
	 ACC_SCALE_3V( light->MatDiffuse[0], light->Diffuse, tmp );
      }
      ctx->Light.BaseColor[0][3] = MIN2( mat->Diffuse[3], 1.0F );
      COPY_4V( mat->Diffuse, VB->Material[i][0].Diffuse );
   }

   if (VB->MaterialMask[i] & BACK_DIFFUSE_BIT) {
      struct gl_material *mat = &ctx->Light.Material[1];
      SUB_3V( tmp, VB->Material[i][1].Diffuse, mat->Diffuse );
      for (light = first; light; light = light->NextEnabled) {
	 ACC_SCALE_3V( light->MatDiffuse[1], light->Diffuse, tmp );
      }
      ctx->Light.BaseColor[1][3] = MIN2( mat->Diffuse[3], 1.0F );
      COPY_4V( mat->Diffuse, VB->Material[i][1].Diffuse );
   }

   if (VB->MaterialMask[i] & FRONT_SPECULAR_BIT) {
      struct gl_material *mat = &ctx->Light.Material[0];
      SUB_3V( tmp, VB->Material[i][0].Specular, mat->Specular );
      for (light = first; light; light = light->NextEnabled) {
	 if (light->IsSpecular) {
	    ACC_SCALE_3V( light->MatSpecular[0], light->Specular, tmp );
	    light->IsMatSpecular[0] = 
	       (LEN_SQUARED_3FV(light->MatSpecular[0]) > 1e-16);
	 }
      }
      COPY_4V( mat->Specular, VB->Material[i][0].Specular );
   }
   if (VB->MaterialMask[i] & BACK_SPECULAR_BIT) {
      struct gl_material *mat = &ctx->Light.Material[1];
      SUB_3V( tmp, VB->Material[i][1].Specular, mat->Specular );
      for (light = first; light; light = light->NextEnabled) {
	 if (light->IsSpecular) {
	    ACC_SCALE_3V( light->MatSpecular[1], light->Specular, tmp );
	    light->IsMatSpecular[1] = 
	       (LEN_SQUARED_3FV(light->MatSpecular[1]) > 1e-16);
	 }
      }
      COPY_4V( mat->Specular, VB->Material[i][1].Specular );
   }
   if (VB->MaterialMask[i] & FRONT_EMISSION_BIT) {
      struct gl_material *mat = &ctx->Light.Material[0];
      SUB_3V( tmp, VB->Material[i][0].Emission, mat->Emission );
      ACC_3V( ctx->Light.BaseColor[0], tmp );
      COPY_4V( mat->Emission, VB->Material[i][0].Emission );
   }
   if (VB->MaterialMask[i] & BACK_EMISSION_BIT) {
      struct gl_material *mat = &ctx->Light.Material[1];
      SUB_3V( tmp, VB->Material[i][1].Emission, mat->Emission );
      ACC_3V( ctx->Light.BaseColor[1], tmp );
      COPY_4V( mat->Emission, VB->Material[i][1].Emission );
   }
   if (VB->MaterialMask[i] & FRONT_SHININESS_BIT) {
      ctx->Light.Material[0].Shininess = VB->Material[i][0].Shininess;
      gl_compute_material_shine_table( &ctx->Light.Material[0] );
   }
   if (VB->MaterialMask[i] & BACK_SHININESS_BIT) {
      ctx->Light.Material[1].Shininess = VB->Material[i][1].Shininess;
      gl_compute_material_shine_table( &ctx->Light.Material[1] );
   }
   if (VB->MaterialMask[i] & FRONT_INDEXES_BIT) {
      ctx->Light.Material[0].AmbientIndex = VB->Material[i][0].AmbientIndex;
      ctx->Light.Material[0].DiffuseIndex = VB->Material[i][0].DiffuseIndex;
      ctx->Light.Material[0].SpecularIndex = VB->Material[i][0].SpecularIndex;
   }
   if (VB->MaterialMask[i] & BACK_INDEXES_BIT) {
      ctx->Light.Material[1].AmbientIndex = VB->Material[i][1].AmbientIndex;
      ctx->Light.Material[1].DiffuseIndex = VB->Material[i][1].DiffuseIndex;
      ctx->Light.Material[1].SpecularIndex = VB->Material[i][1].SpecularIndex;
   }

   VB->MaterialMask[i] = 0;  /* reset now */
d122 4
a125 3

/*
 * Compute shading for vertices in vertex buffer.
d127 1
a127 1
static void shade( GLcontext *ctx, GLuint vbStart, GLuint vbCount )
d130 18
a147 1
   GLuint i,j;
d149 3
a151 5
   for ( i = vbStart ; i < vbCount ; i = j ) {
      j = VB->NextMaterial[i];
	    
      if (VB->MaterialMask[i])
	 update_material( ctx, i );
d153 5
a157 1
      (ctx->shade_func)( ctx, &ctx->shade_context, i, j - i );
a158 3
      
   if (VB->MaterialMask[vbCount])
      update_material( ctx, i );
d162 8
d171 1
a171 3
/*
 * Compute shading for vertices in vertex buffer when they all share
 * the same normal vector.
d173 1
a173 2
static void shade_mononormal( GLcontext *ctx, GLuint vbStart, 
			      GLuint vbCount )
d176 1
a176 2
   GLuint i,j,k;
   GLuint side_flags = ctx->shade_context.side_flags;
d178 12
a189 5
   for ( i = vbStart ; i < vbCount ; i = j ) {
      j = VB->NextMaterial[i];
	    
      if (VB->MaterialMask[i])
	 update_material( ctx, i );
d191 10
a200 1
      (ctx->shade_func)( ctx, &ctx->shade_context, i, 1 );
d202 8
a209 9
      if (side_flags & 2) {
	 for ( k = i+1 ; k < j ; k++ ) {
	    COPY_4V( VB->Fcolor[k], VB->Fcolor[i] );
	    COPY_4V( VB->Bcolor[k], VB->Bcolor[i] );
	 }
      } else {
	 for ( k = i+1 ; k < j ; k++ ) {
	    COPY_4V( VB->Fcolor[k], VB->Fcolor[i] );
	 }
d211 21
a232 3
      
   if (VB->MaterialMask[vbCount])
      update_material( ctx, i );
d237 3
a239 3

/*
 * Compute fog for the vertices in the vertex buffer.
d241 1
a241 1
static void fog_vertices( GLcontext *ctx, GLuint vbStart, GLuint vbCount )
d243 3
a245 1
   struct vertex_buffer *VB = ctx->VB;
d247 2
a248 22
   if (ctx->Visual->RGBAflag) {
      /* Fog RGB colors */
      gl_fog_rgba_vertices( ctx, vbCount - vbStart,
                            VB->Eye + vbStart,
                            VB->Fcolor + vbStart );
      if (ctx->LightTwoSide) {
         gl_fog_rgba_vertices( ctx, vbCount - vbStart,
                               VB->Eye + vbStart,
                               VB->Bcolor + vbStart );
      }
   }
   else {
      /* Fog color indexes */
      gl_fog_ci_vertices( ctx, vbCount - vbStart,
                          VB->Eye + vbStart,
                          VB->Findex + vbStart );
      if (ctx->LightTwoSide) {
         gl_fog_ci_vertices( ctx, vbCount - vbStart,
                             VB->Eye + vbStart,
                             VB->Bindex + vbStart );
      }
   }
d252 4
a255 27
/*
 * In the glbegin code it is necessary to:
 * 1) determine whether we need eye coords:
 *       - fog
 *       - texture generation
 *       - positional lights & attenuation & ~length preserving
 *       - any lights & ~fast_light_mode & ~angle preserving
 *       - (temporarily) user clip planes
 *
 * 2) determine whether we need eye normals:
 *       - need eye coords && need normals
 *       - any lights & fast_light_mode & ~angle preserving
 * 3) if we don't need one or both of these, 
 *    determine whether we need:
 *       - object space light directions
 *       - object space light positions
 *       - (eventually) object space linear attenuation factors
 *       - (eventually) object space user clip planes
 *       - combined model/projection matrix
 *       - fast lighting function (also in update-material)
 *    and compute/repair those we do.
 *
 * Given this information, we are able under various circumstances to
 *       - skip the model transformation entirely, or
 *       - skip vertex transform and only transform the normals, or
 *       - skip vertex and normal transforms and just normalize the normals, or
 *       - perform the full three-stage tranformation in the worst case...
d257 8
a264 9
 * This function returns the clipOrMask and clipAndMask values 
 * for the given VB range.  
 *
 * ... Could actually calculate positional lights with a matrix
 * containing a uniform scale, as long as we adjusted the distance
 * calculations accordingly.
 *
 * Anyway, fix this later...
 *
d267 1
a267 6
static void gl_transform_vb_range( GLcontext *ctx, 
				   GLuint vbStart, 
				   GLuint vbCount,
				   GLubyte *clipOrMask, 
				   GLubyte *clipAndMask,
				   GLboolean firstPartToDo)
d270 6
a275 5
   GLuint vertex_size = ((VB->VertexSizeMask&VERTEX4_BIT) ? 4 : 3);
   GLboolean have_eye_coords = ctx->NeedEyeCoords;
   const GLfloat *from;
   GLuint from_stride;
   GLmatrix *mat;
d278 2
a279 3
/*    printf("gl_t_v_r: %d-%d need: eyecoords: %d  eyenormals: %d sz: %d\n", */
/* 	   vbStart, vbCount, ctx->NeedEyeCoords, ctx->NeedEyeNormals, */
/* 	   vertex_size);  */
d283 6
a288 1
    * from Object to Eye coords.  
d290 1
a290 1
   if (ctx->NeedEyeCoords) 
d292 54
a345 6
      gl_transform_points( &ctx->ModelView, 
			   vbCount - vbStart,
			   VB->ObjPtr + vbStart * VB->ObjStride, 
			   VB->Eye + vbStart,
			   VB->ObjStride, 
			   vertex_size);
a346 3
      if (!TEST_MAT_FLAGS( &ctx->ModelView, MAT_FLAGS_3D))
	 vertex_size = 4;
   }
d348 16
a363 2
   /* Similarly, transform normals to eye space or normalize
    * them inplace, as required. 
d365 2
a366 1
   if (ctx->NeedEyeNormals) 
d368 1
a368 7
      gl_transform_normals_3fv( vbCount - vbStart,
				VB->NormalPtr + vbStart * VB->NormalStride, 
				VB->NormalStride,
				ctx->ModelView.inv,
				VB->Normal + vbStart, 
				ctx->Transform.Normalize,
				ctx->Transform.RescaleNormals);
d370 8
a377 1
   else if (ctx->NeedNormals) 
d379 9
a387 15
      if (ctx->Transform.Normalize) 
      {
	 gl_normalize_3fv( vbCount - vbStart,
			   VB->NormalPtr + vbStart * VB->NormalStride,
			   VB->NormalStride,
			   VB->Normal + vbStart);
      }
      else if (!ctx->Transform.RescaleNormals &&
	       ctx->rescale_factor != 1.0) 
      {
	 gl_scale_3fv( vbCount - vbStart,
		       VB->NormalPtr + vbStart * VB->NormalStride,
		       VB->NormalStride,
		       VB->Normal + vbStart,
		       ctx->rescale_factor );
d389 19
d411 6
a416 9
   if (ctx->Transform.AnyClip) {
      GLuint result = userclip_test_vertices( ctx, 
                                              vbCount - vbStart,
                                              VB->Eye + vbStart,
                                              VB->ClipMask + vbStart );
      if (result==CLIP_ALL) {
	 *clipOrMask = CLIP_ALL_BITS; 
	 *clipAndMask = CLIP_ALL_BITS;
	 return;
d418 11
a428 5
      else if (result==CLIP_SOME) {
	 *clipOrMask = CLIP_USER_BIT;
      }
      else {
	 *clipAndMask = 0;
d430 6
a437 36
   /* If we have skipped the obj->eye transform, we apply here the
    * combined obj->clip projection matrix.  Otherwise we apply the
    * bare projection matrix to vertices in eye space, ending up again
    * in clip coordinates.
    *
    * In both cases, we compute the ClipMask for each vertex.  This
    * could be skipped in the case of display lists if those lists
    * calculated a bounding box for their contents.  Further, if such
    * a bounding box were available and we knew that clipping was not
    * required, we could push the clip->window transform from
    * map_vertices into this transform, leaving only the perpective
    * division to do.
    */
   if (have_eye_coords) {
      from = (GLfloat *) (VB->Eye + vbStart);
      from_stride = 4;
      mat = &ctx->ProjectionMatrix;
   }
   else {
      from = VB->ObjPtr + vbStart * VB->ObjStride;
      from_stride = VB->ObjStride;
      mat = &ctx->ModelProjectMatrix;
   }

   gl_project_and_cliptest_points( mat, 
				   vbCount - vbStart, 
				   from,
				   VB->Clip + vbStart,
				   from_stride, 
				   VB->ClipMask + vbStart,
				   clipOrMask, 
				   clipAndMask,
				   vertex_size );
   
   if (!TEST_MAT_FLAGS(mat, MAT_FLAGS_3D))
      vertex_size = 4;
a438 4
   if (*clipAndMask) {
      *clipOrMask = CLIP_ALL_BITS; 
      return;
   }
d440 30
a469 7
   /* Lighting */
   if (ctx->Light.Enabled) {
      VB->NextMaterial[VB->LastMaterial] = VB->Count;
      if (ctx->VB->MonoNormal)
	 shade_mononormal(ctx, vbStart, vbCount);
      else
	 shade(ctx, vbStart, vbCount);
d471 3
a473 2

   /* Per-vertex fog */
d475 1
a475 2
      /* KW: Requires eye coordinates */
      fog_vertices(ctx, vbStart, vbCount);
d478 2
a479 1
   /* Generate/transform texture coords */
d481 15
a495 17
      GLuint texUnit;
      for (texUnit = 0; texUnit < ctx->Const.MaxTextureUnits; texUnit++) {
	 if (ctx->Texture.Unit[texUnit].TexGenEnabled) {
	    /* KW: Requires eye coordinates and eye normals */
	    gl_texgen( ctx, 
		       vbCount - vbStart,
		       (const GLfloat *) VB->Obj + vbStart, 4,
		       VB->Eye + vbStart,
		       VB->Normal + vbStart,
		       VB->MultiTexCoord[texUnit] + vbStart,
		       texUnit );
            /* When R or Q is texgen'ed, R may be non-zero and Q may
             * be non-one. (MJK)
             */
            if (ctx->Texture.Unit[texUnit].TexGenEnabled & (R_BIT|Q_BIT)) {
               VB->TexCoordSize = 4;
            }
d498 7
a504 2
	 if (ctx->TextureMatrix[texUnit].type != MATRIX_IDENTITY) {
	    /* KW: Using texture coord size...
d506 11
a516 12
	    gl_transform_points( &ctx->TextureMatrix[texUnit], 
				 vbCount - vbStart,
				 (GLfloat *)(VB->MultiTexCoord[texUnit] + 
					     vbStart),
				 VB->MultiTexCoord[texUnit] + vbStart,
				 4,
				 ctx->VB->TexCoordSize);

            /* The texture matrix can make R non-zero and Q non-one so
             * switch to 4-component texture mode now. (MJK)
             */
            ctx->VB->TexCoordSize = 4;
a519 1
  
d521 26
a546 2
   /* Use the viewport parameters to transform vertices from Clip
    * coordinates to Window coordinates.
d548 2
a549 9
   if (ctx->DoViewportMapping) {
      viewport_map_vertices( ctx, 
			     vbCount - vbStart, 
			     VB->Clip + vbStart,
			     ( (*clipOrMask) 
			       ? VB->ClipMask + vbStart 
			       : (GLubyte*) NULL ),
			     VB->Win + vbStart,
			     vertex_size);
d552 10
a561 1
   /* Device driver rasterization setup.  3Dfx driver, for example. */
d563 1
a563 1
      (*ctx->Driver.RasterSetup)( ctx, vbStart, vbCount );
d565 12
d582 3
a584 1
#ifdef MITS
d586 1
a586 6
#include <pthread.h>
#include <semaphore.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <sched.h>
#include <unistd.h>
d588 2
d591 6
a596 2
/* Flag to indicate first time through */
static int firsttime=1;
a597 2
/* Semaphores for the vertex buffer processing threads */
static sem_t tDone1, tDone2;
a598 2
pthread_attr_t attr1, attr2;
pthread_t thread1, thread2;
d601 5
a605 8
typedef struct {
   GLuint start;
   GLuint count;
   GLcontext *ctx;
   GLboolean firstPartToDo;
   sem_t *thread_sem;
   volatile int tsync;
} GLtsched;
d607 2
d610 2
a611 1
static GLtsched set1, set2;
d613 6
d620 9
a628 2
/* These are the processing threads for the vertex buffer */
void *gl_transform_vb_range_scheduler(void *s) 
d630 7
a636 2
   struct vertex_buffer *VB;
   GLtsched *set=(GLtsched *)s;
d638 1
a638 1
   int sval;
d640 25
a664 1
   while(1) {
d666 3
a668 2
      /* Sleep until main thread wakes us up again */
      sem_wait( set->thread_sem );
d670 2
a671 1
      VB = set->ctx->VB;
d673 10
a682 4
      gl_transform_vb_range( set->ctx, set->start, set->count,
                             &VB->ClipOrMask, &VB->ClipAndMask,
                             set->firstPartToDo );
      set->tsync = 1;
d684 13
a696 1
   } /* end while */
a697 1
   return NULL;
a698 2
} /* end gl_transform_vb_range_scheduler */
#endif
d702 2
a703 6
/*
 * This is the main entry point for the vertex transformation stage.
 * The vertices, normals, colors, texcoords, etc, which have been
 * accumulated in the vertex buffer (or vertex arrays) will now be
 * transformed, lit, fogged, clip tested, etc and finally handed
 * off to the rasterization stage.
d705 2
a706 3
 * Input: ctx - the context
 *        allDone - TRUE if we're calling from glEnd
 *                  FALSE if we the vertex buffer is filled and more to come
d708 3
a710 1
void gl_transform_vb( GLcontext *ctx, GLboolean allDone )
d712 46
a757 1
   GLboolean firstPartToDo = GL_TRUE;
a758 4
   struct vertex_buffer *VB = ctx->VB;
#ifdef MITS
   struct sched_param sparam1, sparam2, mparams;
#endif
d760 97
a856 3
#ifdef PROFILE
   GLdouble t0 = gl_time();
#endif
d858 6
a863 1
   ASSERT( VB->Count>0 );
d865 8
a872 8
#ifdef PROFILE
   ctx->VertexTime += gl_time() - t0;
   ctx->VertexCount += VB->Count - VB->Start;
#endif
  
   if (ctx->Texture.Enabled || ctx->RenderMode==GL_FEEDBACK) {
      for (i = 0 ; i < ctx->Const.MaxTextureUnits; i++) {
         gl_matrix_analyze( &ctx->TextureMatrix[i] );
d875 50
d926 2
a927 2
   if (ctx->Driver.RasterSetup && VB->Start) {
      (*ctx->Driver.RasterSetup)( ctx, 0, VB->Start );
a929 1
#ifdef MITS
d931 8
a938 1
   if (VB->Count > 72) {
d940 4
a943 8
      if( firsttime ) {
         int policy;
         if( !getuid() ) {
            policy = SCHED_FIFO;
         }
         else {
            policy = SCHED_OTHER;
         }
a944 2
         mparams.sched_priority = sched_get_priority_max(policy) - 1;
         sched_setscheduler(0, policy, &mparams);
a945 2
         sparam1.sched_priority = sched_get_priority_max(policy);
         sparam2.sched_priority = sched_get_priority_max(policy);
d947 5
a951 2
         sem_init( &tDone1, 0, 0);
         sem_init( &tDone2, 0, 0);	    
d953 6
a958 6
         /* Set up threads with OTHER policy and maximum priority */
         pthread_attr_init( &attr1 );
         pthread_attr_setscope( &attr1, PTHREAD_SCOPE_SYSTEM);
         pthread_attr_setschedpolicy( &attr1, policy );
         pthread_attr_setdetachstate( &attr1, PTHREAD_CREATE_DETACHED);
         pthread_attr_setschedparam( &attr1, &sparam1 );
a959 5
         pthread_attr_init( &attr2 );
         pthread_attr_setscope( &attr2, PTHREAD_SCOPE_SYSTEM);
         pthread_attr_setschedpolicy( &attr2, policy );
         pthread_attr_setdetachstate( &attr2, PTHREAD_CREATE_DETACHED);
         pthread_attr_setschedparam( &attr2, &sparam2 );
d961 5
a965 2
         set1.thread_sem = &tDone1;
         set2.thread_sem = &tDone2;
d967 6
a972 3
         pthread_create( &thread1, &attr1, gl_transform_vb_range_scheduler, &set1);
         pthread_create( &thread2, &attr2, gl_transform_vb_range_scheduler, &set2); 
         firsttime = 0;
a973 1
      } /* end if */
d975 5
a979 4
      set1.ctx = ctx;
      set1.start = VB->Start;
      set1.count = VB->Start + (VB->Count-VB->Start)/2;
      set1.firstPartToDo = firstPartToDo;
d981 6
a986 4
      set2.ctx = ctx;
      set2.start = VB->Start + (VB->Count - VB->Start)/2;
      set2.count = VB->Count;
      set2.firstPartToDo = firstPartToDo;
a987 1
      set1.tsync = set2.tsync = 0;
d990 5
a994 4
      /* Wake the vertex buffer processing threads */
      sem_post( &tDone1 );
      sem_post( &tDone2 );
      sched_yield();
d996 5
a1000 3
      /* Spin until both are done */
      while( !set1.tsync && !set2.tsync)
         ;
d1002 1
a1002 1
   else {
a1003 3
      gl_transform_vb_range( ctx, VB->Start, VB->Count,
                             &VB->ClipOrMask, &VB->ClipAndMask,
                             firstPartToDo );
d1005 16
a1020 1
   } /* end if */
a1021 1
#else
d1023 8
a1030 3
   gl_transform_vb_range( ctx, VB->Start, VB->Count,
                          &VB->ClipOrMask, &VB->ClipAndMask,
                          firstPartToDo );
d1032 1
a1032 1
#endif
d1034 3
a1036 4
   if (VB->ClipAndMask) {
      /* all vertices are clipped by one plane- nothing to be rendered! */
      gl_reset_vb( ctx, allDone );
      return;
d1039 31
a1069 4
#ifdef PROFILE
   ctx->VertexTime += gl_time() - t0;
   ctx->VertexCount += VB->Count - VB->Start;
#endif
d1071 72
a1142 2
   /*
    * Now we're ready to rasterize the Vertex Buffer!!!
d1144 1
a1144 2
    * If the device driver can't rasterize the vertex buffer then we'll
    * do it ourselves.
a1145 3
   if (!ctx->Driver.RenderVB || !(*ctx->Driver.RenderVB)(ctx,allDone)) {
      (*ctx->RenderVB)( ctx, allDone );
   }
d1147 199
a1345 5
   /*
    * Reset vertex buffer to default state or do setup for continuing
    * a very long primitive.
    */
   gl_reset_vb( ctx, allDone );
d1347 13
@


3.18
log
@new copyright
@
text
@d1 1
a1 1
/* $Id: vbxform.c,v 3.17 1999/01/30 04:33:01 brianp Exp brianp $ */
d30 3
d112 3
@


3.17
log
@gl_texgen() now takes a stride parameter
@
text
@d1 1
a1 1
/* $Id: vbxform.c,v 3.16 1998/11/17 01:52:47 brianp Exp brianp $ */
d6 19
a24 15
 * Copyright (C) 1995-1999  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.16
log
@implemented GL_NV_texgen_reflection extension (MJK)
@
text
@d1 1
a1 1
/* $Id: vbxform.c,v 3.15 1998/11/08 22:36:27 brianp Exp brianp $ */
d6 1
a6 1
 * Copyright (C) 1995-1998  Brian Paul
d26 3
d661 1
a661 1
		       VB->Obj + vbStart,
@


3.15
log
@renamed texture sets to texture units
@
text
@d1 1
a1 1
/* $Id: vbxform.c,v 3.14 1998/11/03 02:40:40 brianp Exp brianp $ */
d26 3
d663 6
d681 5
@


3.14
log
@new ctx->RenderVB function pointer
@
text
@d1 1
a1 1
/* $Id: vbxform.c,v 3.13 1998/10/31 17:08:00 brianp Exp brianp $ */
d26 3
d649 3
a651 3
      GLuint texSet;
      for (texSet = 0; texSet < ctx->Const.MaxTextureUnits; texSet++) {
	 if (ctx->Texture.Set[texSet].TexGenEnabled) {
d658 2
a659 2
		       VB->MultiTexCoord[texSet] + vbStart,
		       texSet );
d662 1
a662 1
	 if (ctx->TextureMatrix[texSet].type != MATRIX_IDENTITY) {
d665 1
a665 1
	    gl_transform_points( &ctx->TextureMatrix[texSet], 
d667 1
a667 1
				 (GLfloat *)(VB->MultiTexCoord[texSet] + 
d669 1
a669 1
				 VB->MultiTexCoord[texSet] + vbStart,
@


3.13
log
@variety of multi-texture changes
@
text
@d1 1
a1 1
/* $Id: vbxform.c,v 3.12 1998/10/29 03:57:11 brianp Exp brianp $ */
d26 3
a96 24


/*
 * Apply the projection matrix to an array of vertices in Eye coordinates
 * resulting in Clip coordinates.  Also, compute the ClipMask bitfield for
 * each vertex.
 *
 * NOTE: the volatile keyword is used in this function to ensure that the
 * FP computations are computed to low-precision.  If high precision is
 * used (ala 80-bit X86 arithmetic) then the clipMask results may be
 * inconsistant with the computations in clip.c.  Later, clipped polygons
 * may be rendered incorrectly.
 *
 * Input:  ctx - the context
 *         n - number of vertices
 *         vEye - array [n][4] of Eye coordinates
 * Output:  vClip - array [n][4] of Clip coordinates
 *          clipMask - array [n] of clip masks
 */





d110 3
a112 3
static GLuint userclip_vertices( GLcontext *ctx, GLuint n,
                                 CONST GLfloat vEye[][4],
                                 GLubyte clipMask[] )
d367 3
d390 4
a393 1

d570 4
a573 4
      GLuint result = userclip_vertices( ctx, 
					 vbCount - vbStart,
					 VB->Eye + vbStart,
					 VB->ClipMask + vbStart );
d600 1
a600 2
   if (have_eye_coords) 
   {
d604 2
a605 3
   } 
   else 
   {
a623 1
			    
d630 1
a630 2
   if (ctx->Light.Enabled) 
   {
d639 1
a639 1
   if (ctx->Fog.Enabled && ctx->Hint.Fog!=GL_NICEST) {
a657 1
      }
a658 1
      for (texSet = 0; texSet < ctx->Const.MaxTextureUnits; texSet++) {
a696 1

d718 6
a723 8

  GLuint start;
  GLuint count;
  GLcontext *ctx;
  GLboolean firstPartToDo;
  sem_t *thread_sem;
  volatile int tsync;

d727 1
a727 1
static  GLtsched set1, set2;
d733 2
a734 2
  struct vertex_buffer *VB;
  GLtsched *set=(GLtsched *)s;
d736 1
a736 1
  int sval;
d738 1
a738 1
  while(1) {
d740 2
a741 2
    /* Sleep until main thread wakes us up again */
    sem_wait( set->thread_sem );
d743 1
a743 1
    VB = set->ctx->VB;
d745 4
a748 4
    gl_transform_vb_range( set->ctx, set->start, set->count,
                           &VB->ClipOrMask, &VB->ClipAndMask,
                           set->firstPartToDo );
    set->tsync = 1;
d750 1
a750 1
  } /* end while */
d752 1
a752 1
  return NULL;
d773 2
a774 2
  GLuint i;
  struct vertex_buffer *VB = ctx->VB;
d776 1
a776 1
  struct sched_param sparam1, sparam2, mparams;
d780 1
a780 1
  GLdouble t0 = gl_time();
d783 1
a783 1
  ASSERT( VB->Count>0 );
d786 2
a787 2
  ctx->VertexTime += gl_time() - t0;
  ctx->VertexCount += VB->Count - VB->Start;
d790 5
a794 5
  if (ctx->Texture.Enabled || ctx->RenderMode==GL_FEEDBACK) {
     for (i = 0 ; i < ctx->Const.MaxTextureUnits; i++) {
	gl_matrix_analyze( &ctx->TextureMatrix[i] );
     }
  }
d796 1
a796 1
  if (ctx->Driver.RasterSetup && VB->Start) {
d798 1
a798 1
  }
d802 1
a802 1
  if (VB->Count > 72) {
d804 8
a811 1
    if( firsttime ) {
d813 2
a814 2
      int policy;
     
d816 2
a817 6
      if( !getuid() ) {
	policy = SCHED_FIFO;
      }
      else {
	policy = SCHED_OTHER;
      }
d819 2
d822 45
a866 38
      mparams.sched_priority = sched_get_priority_max(policy) - 1;
      sched_setscheduler(0, policy, &mparams);

      sparam1.sched_priority = sched_get_priority_max(policy);
      sparam2.sched_priority = sched_get_priority_max(policy);


      sem_init( &tDone1, 0, 0);
      sem_init( &tDone2, 0, 0);	    


      /* Set up threads with OTHER policy and maximum priority */
      pthread_attr_init( &attr1 );
      pthread_attr_setscope( &attr1, PTHREAD_SCOPE_SYSTEM);
      pthread_attr_setschedpolicy( &attr1, policy );
      pthread_attr_setdetachstate( &attr1, PTHREAD_CREATE_DETACHED);
      pthread_attr_setschedparam( &attr1, &sparam1 );

      pthread_attr_init( &attr2 );
      pthread_attr_setscope( &attr2, PTHREAD_SCOPE_SYSTEM);
      pthread_attr_setschedpolicy( &attr2, policy );
      pthread_attr_setdetachstate( &attr2, PTHREAD_CREATE_DETACHED);
      pthread_attr_setschedparam( &attr2, &sparam2 );

      set1.thread_sem = &tDone1;
      set2.thread_sem = &tDone2;

      pthread_create( &thread1, &attr1, gl_transform_vb_range_scheduler, &set1);
      pthread_create( &thread2, &attr2, gl_transform_vb_range_scheduler, &set2); 
      firsttime = 0;

    } /* end if */


    set1.ctx = ctx;
    set1.start = VB->Start;
    set1.count = VB->Start + (VB->Count-VB->Start)/2;
    set1.firstPartToDo = firstPartToDo;
d868 3
d872 1
a872 27
    set2.ctx = ctx;
    set2.start = VB->Start + (VB->Count - VB->Start)/2;
    set2.count = VB->Count;
    set2.firstPartToDo = firstPartToDo;
    
    set1.tsync = set2.tsync = 0;


    /* Wake the vertex buffer processing threads */
    sem_post( &tDone1 );
    sem_post( &tDone2 );
    sched_yield();


    /* Spin until both are done */
    while( !set1.tsync && !set2.tsync);


  }
  else {


    gl_transform_vb_range( ctx, VB->Start, VB->Count,
			 &VB->ClipOrMask, &VB->ClipAndMask,
			 firstPartToDo );

  } /* end if */
d876 3
a878 3
    gl_transform_vb_range( ctx, VB->Start, VB->Count,
			 &VB->ClipOrMask, &VB->ClipAndMask,
			 firstPartToDo );
d882 5
a886 5
  if (VB->ClipAndMask) {
    gl_reset_vb( ctx, allDone );
    return;
  }

d889 2
a890 2
  ctx->VertexTime += gl_time() - t0;
  ctx->VertexCount += VB->Count - VB->Start;
d893 15
a907 9
  /*
   * Now we're ready to rasterize the Vertex Buffer!!!
   *
   * If the device driver can't rasterize the vertex buffer then we'll
   * do it ourselves.
   */
  if (!ctx->Driver.RenderVB || !(*ctx->Driver.RenderVB)(ctx,allDone)) {
    gl_render_vb( ctx, allDone );
  }
@


3.12
log
@misc clean-up of new vertex transformation code
@
text
@d1 1
a1 1
/* $Id: vbxform.c,v 3.11 1998/10/29 02:28:13 brianp Exp brianp $ */
d26 3
a77 1
#include "asm_386.h"
d666 1
a666 1
      for (texSet=0; texSet<MAX_TEX_COORD_SETS; texSet++) {
d679 1
a679 1
      for (texSet=0; texSet<MAX_TEX_COORD_SETS; texSet++) {
d815 1
a815 1
     for (i = 0 ; i < MAX_TEX_SETS ; i++) {
@


3.11
log
@incorporated Keith Whitwell's transformation optimizations
@
text
@d1 1
a1 1
/* $Id: vbxform.c,v 3.10 1998/08/23 22:19:30 brianp Exp brianp $ */
d26 3
a67 4
 *
 * The entry points to this file are the functions:
 *    gl_transform_vb_part1() - first stage of vertex transformation
 *    gl_transform_vb_part2() - second stage of vertex transformation
a188 1

a195 1

d522 1
a522 1
   GLfloat *from;
d539 1
a539 1
			   VB->objp + vbStart * VB->obj_stride, 
d541 1
a541 1
			   VB->obj_stride, 
d554 2
a555 2
				VB->normp + vbStart * VB->norm_stride, 
				VB->norm_stride,
d566 2
a567 2
			   VB->normp + vbStart * VB->norm_stride,
			   VB->norm_stride,
d574 2
a575 2
		       VB->normp + vbStart * VB->norm_stride,
		       VB->norm_stride,
a582 2
      /* KW: Currently only works in eye coords - fix me...
       */
d621 2
a622 2
      from = VB->objp + vbStart * VB->obj_stride;
      from_stride = VB->obj_stride;
d780 13
a792 1
void gl_transform_vb( GLcontext *ctx, GLboolean firstPartToDo, GLboolean allDone )
d794 1
a935 30


/*
 * When the Vertex Buffer is full, this function applies the modelview
 * matrix to transform vertices and normals from object coordinates to
 * eye coordinates.  Next, we'll call gl_transform_vb_part2()...
 * This function might not be called when using vertex arrays.
 */
void gl_transform_vb_part1( GLcontext *ctx, GLboolean allDone )
{
  gl_transform_vb( ctx, GL_TRUE, allDone );
}


/*
 * Part 2 of Vertex Buffer transformation:  compute lighting, clipflags,
 * fog, texture coords, etc.
 * Before this function is called the VB->Eye coordinates must have
 * already been computed.
 * Callers:  gl_transform_vb_part1(), glDrawArraysEXT()
 */

/* KW: Not used - ever */
#if 0
void gl_transform_vb_part2( GLcontext *ctx, GLboolean allDone )
{
  gl_transform_vb( ctx, GL_FALSE, allDone );
}
#endif

@


3.10
log
@added DoViewportMapping to context struct
@
text
@d1 1
a1 1
/* $Id: vbxform.c,v 3.9 1998/07/09 03:15:41 brianp Exp brianp $ */
d5 1
a5 1
 * Version:  3.0
d26 3
a82 1
#include "shade.h"
a91 428
#if 0  /* NOT USED AT THIS TIME */
/*
 * Use the current modelview matrix to transform XY vertices from object
 * to eye coordinates.
 * Input:  ctx - the context
 *         n - number of vertices to transform
 *         vObj - array [n][4] of object coordinates
 * In/Out;  vEye - array [n][4] of eye coordinates
 */
static void transform_points2( GLcontext *ctx, GLuint n,
                               const GLfloat vObj[][4], GLfloat vEye[][4] )
{
   switch (ctx->ModelViewMatrixType) {
      case MATRIX_GENERAL:
         {
            const GLfloat *m = ctx->ModelViewMatrix;
            GLfloat m0 = m[0],  m4 = m[4],  m12 = m[12];
            GLfloat m1 = m[1],  m5 = m[5],  m13 = m[13];
            GLfloat m2 = m[2],  m6 = m[6],  m14 = m[14];
            GLfloat m3 = m[3],  m7 = m[7],  m15 = m[15];
            GLuint i;
            for (i=0;i<n;i++) {
               GLfloat ox = vObj[i][0], oy = vObj[i][1];
               vEye[i][0] = m0 * ox + m4 * oy + m12;
               vEye[i][1] = m1 * ox + m5 * oy + m13;
               vEye[i][2] = m2 * ox + m6 * oy + m14;
               vEye[i][3] = m3 * ox + m7 * oy + m15;
            }
         }
         break;
      case MATRIX_IDENTITY:
         {
            GLuint i;
            for (i=0;i<n;i++) {
               vEye[i][0] = vObj[i][0];
               vEye[i][1] = vObj[i][1];
               vEye[i][2] = 0.0F;
               vEye[i][3] = 1.0F;
            }
         }
         break;
      case MATRIX_2D:
         {
            const GLfloat *m = ctx->ModelViewMatrix;
            GLfloat m0 = m[0], m1 = m[1], m4 = m[4], m5 = m[5];
            GLfloat m12 = m[12], m13 = m[13];
            GLuint i;
            for (i=0;i<n;i++) {
               GLfloat ox = vObj[i][0], oy = vObj[i][1];
               vEye[i][0] = m0 * ox + m4 * oy + m12;
               vEye[i][1] = m1 * ox + m5 * oy + m13;
               vEye[i][2] = 0.0F;
               vEye[i][3] = 1.0F;
            }
         }
         break;
      case MATRIX_2D_NO_ROT:
         {
            const GLfloat *m = ctx->ModelViewMatrix;
            GLfloat m0 = m[0], m5 = m[5], m12 = m[12], m13 = m[13];
            GLuint i;
            for (i=0;i<n;i++) {
               GLfloat ox = vObj[i][0], oy = vObj[i][1];
               vEye[i][0] = m0 * ox           + m12;
               vEye[i][1] =           m5 * oy + m13;
               vEye[i][2] = 0.0F;
               vEye[i][3] = 1.0F;
            }
         }
         break;
      case MATRIX_3D:
         {
            const GLfloat *m = ctx->ModelViewMatrix;
            GLfloat m0 = m[0], m1 = m[1], m2 = m[2], m4 = m[4], m5 = m[5];
            GLfloat m6 = m[6], m12 = m[12], m13 = m[13], m14 = m[14];
            GLuint i;
            for (i=0;i<n;i++) {
               GLfloat ox = vObj[i][0], oy = vObj[i][1];
               vEye[i][0] = m0 * ox + m4 * oy + m12;
               vEye[i][1] = m1 * ox + m5 * oy + m13;
               vEye[i][2] = m2 * ox + m6 * oy + m14;
               vEye[i][3] = 1.0F;
            }
         }
         break;
      default:
         /* should never get here */
         gl_problem( NULL, "invalid matrix type in transform_points3()" );
         return;
   }
}
#endif


/*
 * Use the current modelview matrix to transform XYZ vertices from object
 * to eye coordinates.
 * Input:  ctx - the context
 *         n - number of vertices to transform
 *         vObj - array [n][4] of object coordinates
 * In/Out;  vEye - array [n][4] of eye coordinates
 */
static void transform_points3( GLcontext *ctx, GLuint n,
                               CONST GLfloat vObj[][4], GLfloat vEye[][4] )
{
#ifndef USE_X86_ASM
   START_FAST_MATH;
   switch (ctx->ModelViewMatrixType) {
      case MATRIX_GENERAL:
         {
            const GLfloat *m = ctx->ModelViewMatrix;
            GLfloat m0 = m[0],  m4 = m[4],  m8 = m[8],  m12 = m[12];
            GLfloat m1 = m[1],  m5 = m[5],  m9 = m[9],  m13 = m[13];
            GLfloat m2 = m[2],  m6 = m[6],  m10 = m[10],  m14 = m[14];
            GLfloat m3 = m[3],  m7 = m[7],  m11 = m[11],  m15 = m[15];
            GLuint i;
            for (i=0;i<n;i++) {
               GLfloat ox = vObj[i][0], oy = vObj[i][1], oz = vObj[i][2];
               vEye[i][0] = m0 * ox + m4 * oy + m8  * oz + m12;
               vEye[i][1] = m1 * ox + m5 * oy + m9  * oz + m13;
               vEye[i][2] = m2 * ox + m6 * oy + m10 * oz + m14;
               vEye[i][3] = m3 * ox + m7 * oy + m11 * oz + m15;
            }
         }
         break;
      case MATRIX_IDENTITY:
         {
            GLuint i;
            for (i=0;i<n;i++) {
               vEye[i][0] = vObj[i][0];
               vEye[i][1] = vObj[i][1];
               vEye[i][2] = vObj[i][2];
               vEye[i][3] = 1.0F;
            }
         }
         break;
      case MATRIX_2D:
         {
            const GLfloat *m = ctx->ModelViewMatrix;
            GLfloat m0 = m[0], m1 = m[1], m4 = m[4], m5 = m[5];
            GLfloat m12 = m[12], m13 = m[13];
            GLuint i;
            for (i=0;i<n;i++) {
               GLfloat ox = vObj[i][0], oy = vObj[i][1], oz = vObj[i][2];
               vEye[i][0] = m0 * ox + m4 * oy            + m12       ;
               vEye[i][1] = m1 * ox + m5 * oy            + m13       ;
               vEye[i][2] =                   +       oz             ;
               vEye[i][3] =                                      1.0F;
            }
         }
         break;
      case MATRIX_2D_NO_ROT:
         {
            const GLfloat *m = ctx->ModelViewMatrix;
            GLfloat m0 = m[0], m5 = m[5], m12 = m[12], m13 = m[13];
            GLuint i;
            for (i=0;i<n;i++) {
               GLfloat ox = vObj[i][0], oy = vObj[i][1], oz = vObj[i][2];
               vEye[i][0] = m0 * ox                      + m12       ;
               vEye[i][1] =           m5 * oy            + m13       ;
               vEye[i][2] =                   +       oz             ;
               vEye[i][3] =                                      1.0F;
            }
         }
         break;
      case MATRIX_3D:
         {
            const GLfloat *m = ctx->ModelViewMatrix;
            GLfloat m0 = m[0], m1 = m[1], m2 = m[2], m4 = m[4], m5 = m[5];
            GLfloat m6 = m[6], m8 = m[8], m9 = m[9], m10 = m[10];
            GLfloat m12 = m[12], m13 = m[13], m14 = m[14];
            GLuint i;
            for (i=0;i<n;i++) {
               GLfloat ox = vObj[i][0], oy = vObj[i][1], oz = vObj[i][2];
               vEye[i][0] = m0 * ox + m4 * oy +  m8 * oz + m12       ;
               vEye[i][1] = m1 * ox + m5 * oy +  m9 * oz + m13       ;
               vEye[i][2] = m2 * ox + m6 * oy + m10 * oz + m14       ;
               vEye[i][3] =                                      1.0F;
            }
         }
         break;
      default:
         /* should never get here */
         gl_problem( NULL, "invalid matrix type in transform_points3()" );
   }
   END_FAST_MATH;
#else
   switch (ctx->ModelViewMatrixType) {
      case MATRIX_GENERAL:
         asm_transform_points3_general( n, vEye, ctx->ModelViewMatrix, vObj );
         break;
      case MATRIX_IDENTITY:
         asm_transform_points3_identity( n, vEye, vObj );
         break;
      case MATRIX_2D:
         asm_transform_points3_2d( n, vEye, ctx->ModelViewMatrix, vObj );
         break;
      case MATRIX_2D_NO_ROT:
         asm_transform_points3_2d_no_rot( n, vEye, ctx->ModelViewMatrix,
                                          vObj );
         break;
      case MATRIX_3D:
         asm_transform_points3_3d( n, vEye, ctx->ModelViewMatrix, vObj );
         break;
      default:
         /* should never get here */
         gl_problem( NULL, "invalid matrix type in transform_points3()" );
         return;
   }
#endif
}



/*
 * Use the current modelview matrix to transform XYZW vertices from object
 * to eye coordinates.
 * Input:  ctx - the context
 *         n - number of vertices to transform
 *         vObj - array [n][4] of object coordinates
 * In/Out;  vEye - array [n][4] of eye coordinates
 */
static void transform_points4( GLcontext *ctx, GLuint n,
                               CONST GLfloat vObj[][4], GLfloat vEye[][4] )
{
#ifndef USE_X86_ASM
   START_FAST_MATH;
   switch (ctx->ModelViewMatrixType) {
      case MATRIX_GENERAL:
         {
            const GLfloat *m = ctx->ModelViewMatrix;
            GLfloat m0 = m[0],  m4 = m[4],  m8 = m[8],  m12 = m[12];
            GLfloat m1 = m[1],  m5 = m[5],  m9 = m[9],  m13 = m[13];
            GLfloat m2 = m[2],  m6 = m[6],  m10 = m[10],  m14 = m[14];
            GLfloat m3 = m[3],  m7 = m[7],  m11 = m[11],  m15 = m[15];
            GLuint i;
            for (i=0;i<n;i++) {
               GLfloat ox = vObj[i][0], oy = vObj[i][1];
               GLfloat oz = vObj[i][2], ow = vObj[i][3];
               vEye[i][0] = m0 * ox + m4 * oy + m8  * oz + m12 * ow;
               vEye[i][1] = m1 * ox + m5 * oy + m9  * oz + m13 * ow;
               vEye[i][2] = m2 * ox + m6 * oy + m10 * oz + m14 * ow;
               vEye[i][3] = m3 * ox + m7 * oy + m11 * oz + m15 * ow;
            }
         }
         break;
      case MATRIX_IDENTITY:
         {
            GLuint i;
            for (i=0;i<n;i++) {
               vEye[i][0] = vObj[i][0];
               vEye[i][1] = vObj[i][1];
               vEye[i][2] = vObj[i][2];
               vEye[i][3] = vObj[i][3];
            }
         }
         break;
      case MATRIX_2D:
         {
            const GLfloat *m = ctx->ModelViewMatrix;
            GLfloat m0 = m[0], m1 = m[1], m4 = m[4], m5 = m[5];
            GLfloat m12 = m[12], m13 = m[13];
            GLuint i;
            for (i=0;i<n;i++) {
               GLfloat ox = vObj[i][0], oy = vObj[i][1];
               GLfloat oz = vObj[i][2], ow = vObj[i][3];
               vEye[i][0] = m0 * ox + m4 * oy            + m12 * ow;
               vEye[i][1] = m1 * ox + m5 * oy            + m13 * ow;
               vEye[i][2] =                   +       oz           ;
               vEye[i][3] =                                      ow;
            }
         }
         break;
      case MATRIX_2D_NO_ROT:
         {
            const GLfloat *m = ctx->ModelViewMatrix;
            GLfloat m0 = m[0], m5 = m[5], m12 = m[12], m13 = m[13];
            GLuint i;
            for (i=0;i<n;i++) {
               GLfloat ox = vObj[i][0], oy = vObj[i][1];
               GLfloat oz = vObj[i][2], ow = vObj[i][3];
               vEye[i][0] = m0 * ox                      + m12 * ow;
               vEye[i][1] =           m5 * oy            + m13 * ow;
               vEye[i][2] =                   +       oz           ;
               vEye[i][3] =                                      ow;
            }
         }
         break;
      case MATRIX_3D:
         {
            const GLfloat *m = ctx->ModelViewMatrix;
            GLfloat m0 = m[0], m1 = m[1], m2 = m[2], m4 = m[4], m5 = m[5];
            GLfloat m6 = m[6], m8 = m[8], m9 = m[9], m10 = m[10];
            GLfloat m12 = m[12], m13 = m[13], m14 = m[14];
            GLuint i;
            for (i=0;i<n;i++) {
               GLfloat ox = vObj[i][0], oy = vObj[i][1];
               GLfloat oz = vObj[i][2], ow = vObj[i][3];
               vEye[i][0] = m0 * ox + m4 * oy +  m8 * oz + m12 * ow;
               vEye[i][1] = m1 * ox + m5 * oy +  m9 * oz + m13 * ow;
               vEye[i][2] = m2 * ox + m6 * oy + m10 * oz + m14 * ow;
               vEye[i][3] =                                      ow;
            }
         }
         break;
      default:
         /* should never get here */
         gl_problem( NULL, "invalid matrix type in transform_points4()" );
   }
   END_FAST_MATH;
#else
   switch (ctx->ModelViewMatrixType) {
      case MATRIX_GENERAL:
         asm_transform_points4_general( n, vEye, ctx->ModelViewMatrix, vObj );
         break;
      case MATRIX_IDENTITY:
         asm_transform_points4_identity( n, vEye, vObj );
         break;
      case MATRIX_2D:
         asm_transform_points4_2d( n, vEye, ctx->ModelViewMatrix, vObj );
         break;
      case MATRIX_2D_NO_ROT:
         asm_transform_points4_2d_no_rot( n, vEye, ctx->ModelViewMatrix,
                                          vObj );
         break;
      case MATRIX_3D:
         asm_transform_points4_3d( n, vEye, ctx->ModelViewMatrix, vObj );
         break;
      default:
         /* should never get here */
         gl_problem( NULL, "invalid matrix type in transform_points4()" );
         return;
   }
#endif
}



/*
 * Transform an array of texture coordinates by the current texture matrix.
 * Input:  ctx - the context
 *         n - number of texture coordinates in array
 *         texSet - which texture matrix to use
 * In/Out:  t - array [n][4] of texture coordinates to transform
 */
static void transform_texcoords( GLcontext *ctx, GLuint n, GLfloat t[][4],
                                 GLuint texSet )
{
#ifndef USE_X86_ASM
   START_FAST_MATH;
   switch (ctx->TextureMatrixType[texSet]) {
      case MATRIX_GENERAL:
         {
            const GLfloat *m = ctx->TextureMatrix[texSet];
            GLfloat m0 = m[0],  m4 = m[4],  m8 = m[8],  m12 = m[12];
            GLfloat m1 = m[1],  m5 = m[5],  m9 = m[9],  m13 = m[13];
            GLfloat m2 = m[2],  m6 = m[6],  m10 = m[10],  m14 = m[14];
            GLfloat m3 = m[3],  m7 = m[7],  m11 = m[11],  m15 = m[15];
            GLuint i;
            for (i=0;i<n;i++) {
               GLfloat t0 = t[i][0], t1 = t[i][1], t2 = t[i][2], t3 = t[i][3];
               t[i][0] = m0 * t0 + m4 * t1 + m8  * t2 + m12 * t3;
               t[i][1] = m1 * t0 + m5 * t1 + m9  * t2 + m13 * t3;
               t[i][2] = m2 * t0 + m6 * t1 + m10 * t2 + m14 * t3;
               t[i][3] = m3 * t0 + m7 * t1 + m11 * t2 + m15 * t3;
            }
         }
         break;
      case MATRIX_IDENTITY:
         /* Do nothing */
         break;
      case MATRIX_2D:
         {
            const GLfloat *m = ctx->TextureMatrix[texSet];
            GLfloat m0 = m[0], m1 = m[1], m4 = m[4], m5 = m[5];
            GLfloat m12 = m[12], m13 = m[13];
            GLuint i;
            for (i=0;i<n;i++) {
               GLfloat t0 = t[i][0], t1 = t[i][1], t2 = t[i][2], t3 = t[i][3];
               t[i][0] = m0 * t0 + m4 * t1            + m12 * t3;
               t[i][1] = m1 * t0 + m5 * t1            + m13 * t3;
               t[i][2] =                   +       t2           ;
               /*t[i][3] unchanged*/
            }
         }
         break;
      case MATRIX_3D:
         {
            const GLfloat *m = ctx->TextureMatrix[texSet];
            GLfloat m0 = m[0], m1 = m[1], m2 = m[2], m4 = m[4], m5 = m[5];
            GLfloat m6 = m[6], m8 = m[8], m9 = m[9], m10 = m[10];
            GLfloat m12 = m[12], m13 = m[13], m14 = m[14];
            GLuint i;
            for (i=0;i<n;i++) {
               GLfloat t0 = t[i][0], t1 = t[i][1], t2 = t[i][2], t3 = t[i][3];
               t[i][0] = m0 * t0 + m4 * t1 +  m8 * t2 + m12 * t3;
               t[i][1] = m1 * t0 + m5 * t1 +  m9 * t2 + m13 * t3;
               t[i][2] = m2 * t0 + m6 * t1 + m10 * t2 + m14 * t3;
               /*t[i][3] unchanged*/
            }
         }
         break;
      default:
         /* should never get here */
         gl_problem( NULL, "invalid matrix type in transform_texcoords()" );
   }
   END_FAST_MATH;
#else
   switch (ctx->TextureMatrixType[texSet]) {
      case MATRIX_GENERAL:
         asm_transform_points4_general( n, t, ctx->TextureMatrix[texSet], t );
         break;
      case MATRIX_IDENTITY:
         /* Do nothing */
         break;
      case MATRIX_2D:
         asm_transform_points4_2d( n, t, ctx->TextureMatrix[texSet], t );
         break;
      case MATRIX_3D:
         asm_transform_points4_3d( n, t, ctx->TextureMatrix[texSet], t );
         break;
      default:
         /* should never get here */
         gl_problem( NULL, "invalid matrix type in transform_texcoords()" );
         return;
   }
#endif
}
a111 9
static void project_and_cliptest( GLcontext *ctx,
                                  GLuint n, CONST GLfloat vEye[][4],
                                  GLfloat vClip[][4], GLubyte clipMask[],
                                  GLubyte *orMask, GLubyte *andMask )

{
#ifndef USE_X86_ASM
   GLubyte tmpOrMask = *orMask;
   GLubyte tmpAndMask = *andMask;
a112 1
   START_FAST_MATH;
a113 126
   switch (ctx->ProjectionMatrixType) {
      case MATRIX_GENERAL:
         {
            const GLfloat *m = ctx->ProjectionMatrix;
            GLfloat m0 = m[0],  m4 = m[4],  m8 = m[8],  m12 = m[12];
            GLfloat m1 = m[1],  m5 = m[5],  m9 = m[9],  m13 = m[13];
            GLfloat m2 = m[2],  m6 = m[6],  m10 = m[10],  m14 = m[14];
            GLfloat m3 = m[3],  m7 = m[7],  m11 = m[11],  m15 = m[15];
            GLuint i;
            for (i=0;i<n;i++) {
               GLfloat ex = vEye[i][0], ey = vEye[i][1];
               GLfloat ez = vEye[i][2], ew = vEye[i][3];
               GLfloat cx = m0 * ex + m4 * ey + m8  * ez + m12 * ew;
               GLfloat cy = m1 * ex + m5 * ey + m9  * ez + m13 * ew;
               GLfloat cz = m2 * ex + m6 * ey + m10 * ez + m14 * ew;
               GLfloat cw = m3 * ex + m7 * ey + m11 * ez + m15 * ew;
               GLubyte mask = 0;
               vClip[i][0] = cx;
               vClip[i][1] = cy;
               vClip[i][2] = cz;
               vClip[i][3] = cw;
               if (cx >  cw)       mask |= CLIP_RIGHT_BIT;
               else if (cx < -cw)  mask |= CLIP_LEFT_BIT;
               if (cy >  cw)       mask |= CLIP_TOP_BIT;
               else if (cy < -cw)  mask |= CLIP_BOTTOM_BIT;
               if (cz >  cw)       mask |= CLIP_FAR_BIT;
               else if (cz < -cw)  mask |= CLIP_NEAR_BIT;
               if (mask) {
                  clipMask[i] |= mask;
                  tmpOrMask |= mask;
               }
               tmpAndMask &= mask;
            }
         }
         break;
      case MATRIX_IDENTITY:
         {
            GLuint i;
            for (i=0;i<n;i++) {
               GLfloat cx = vClip[i][0] = vEye[i][0];
               GLfloat cy = vClip[i][1] = vEye[i][1];
               GLfloat cz = vClip[i][2] = vEye[i][2];
               GLfloat cw = vClip[i][3] = vEye[i][3];
               GLubyte mask = 0;
               if (cx >  cw)       mask |= CLIP_RIGHT_BIT;
               else if (cx < -cw)  mask |= CLIP_LEFT_BIT;
               if (cy >  cw)       mask |= CLIP_TOP_BIT;
               else if (cy < -cw)  mask |= CLIP_BOTTOM_BIT;
               if (cz >  cw)       mask |= CLIP_FAR_BIT;
               else if (cz < -cw)  mask |= CLIP_NEAR_BIT;
               if (mask) {
                  clipMask[i] |= mask;
                  tmpOrMask |= mask;
               }
               tmpAndMask &= mask;
            }
         }
         break;
      case MATRIX_ORTHO:
         {
            const GLfloat *m = ctx->ProjectionMatrix;
            GLfloat m0 = m[0], m5 = m[5], m10 = m[10], m12 = m[12];
            GLfloat m13 = m[13], m14 = m[14];
            GLuint i;
            for (i=0;i<n;i++) {
               GLfloat ex = vEye[i][0], ey = vEye[i][1];
               GLfloat ez = vEye[i][2], ew = vEye[i][3];
               volatile GLfloat cx = m0 * ex                      + m12 * ew;
               volatile GLfloat cy =           m5 * ey            + m13 * ew;
               volatile GLfloat cz =                     m10 * ez + m14 * ew;
               volatile GLfloat cw =                                      ew;
               GLubyte mask = 0;
               vClip[i][0] = cx;
               vClip[i][1] = cy;
               vClip[i][2] = cz;
               vClip[i][3] = cw;
               if (cx >  cw)       mask |= CLIP_RIGHT_BIT;
               else if (cx < -cw)  mask |= CLIP_LEFT_BIT;
               if (cy >  cw)       mask |= CLIP_TOP_BIT;
               else if (cy < -cw)  mask |= CLIP_BOTTOM_BIT;
               if (cz >  cw)       mask |= CLIP_FAR_BIT;
               else if (cz < -cw)  mask |= CLIP_NEAR_BIT;
               if (mask) {
                  clipMask[i] |= mask;
                  tmpOrMask |= mask;
               }
               tmpAndMask &= mask;
            }
         }
         break;
      case MATRIX_PERSPECTIVE:
         {
            const GLfloat *m = ctx->ProjectionMatrix;
            GLfloat m0 = m[0], m5 = m[5], m8 = m[8], m9 = m[9];
            GLfloat m10 = m[10], m14 = m[14];
            GLuint i;
            for (i=0;i<n;i++) {
               GLfloat ex = vEye[i][0], ey = vEye[i][1];
               GLfloat ez = vEye[i][2], ew = vEye[i][3];
               volatile GLfloat cx = m0 * ex           + m8  * ez           ;
               volatile GLfloat cy =           m5 * ey + m9  * ez           ;
               volatile GLfloat cz =                     m10 * ez + m14 * ew;
               volatile GLfloat cw =                          -ez           ;
               GLubyte mask = 0;
               vClip[i][0] = cx;
               vClip[i][1] = cy;
               vClip[i][2] = cz;
               vClip[i][3] = cw;
               if (cx >  cw)       mask |= CLIP_RIGHT_BIT;
               else if (cx < -cw)  mask |= CLIP_LEFT_BIT;
               if (cy >  cw)       mask |= CLIP_TOP_BIT;
               else if (cy < -cw)  mask |= CLIP_BOTTOM_BIT;
               if (cz >  cw)       mask |= CLIP_FAR_BIT;
               else if (cz < -cw)  mask |= CLIP_NEAR_BIT;
               if (mask) {
                  clipMask[i] |= mask;
                  tmpOrMask |= mask;
               }
               tmpAndMask &= mask;
            }
         }
         break;
      default:
         /* should never get here */
         gl_problem( NULL, "invalid matrix type in project_and_cliptest()" );
   }
a114 27
   *orMask = tmpOrMask;
   *andMask = tmpAndMask;
   END_FAST_MATH;
#else
   switch (ctx->ProjectionMatrixType) {
      case MATRIX_GENERAL:
         asm_project_and_cliptest_general( n, vClip, ctx->ProjectionMatrix, vEye, 
                                           clipMask, orMask, andMask );
         break;
      case MATRIX_IDENTITY:
         asm_project_and_cliptest_identity( n, vClip, vEye, clipMask, orMask, andMask );
         break;
      case MATRIX_ORTHO:
         asm_project_and_cliptest_ortho( n, vClip, ctx->ProjectionMatrix, vEye, 
                                         clipMask, orMask, andMask );
         break;
      case MATRIX_PERSPECTIVE:
         asm_project_and_cliptest_perspective( n, vClip, ctx->ProjectionMatrix,
                                               vEye, clipMask, orMask, andMask );
         break;
      default:
         /* should never get here */
         gl_problem( NULL, "invalid matrix type in project_and_cliptest()" );
         return;
   }
#endif
}
d184 5
a188 2
                                   GLuint n, CONST GLfloat vClip[][4],
                                   const GLubyte clipMask[], GLfloat vWin[][3])
d201 1
a201 4
   if ((ctx->ProjectionMatrixType==MATRIX_ORTHO || 
        ctx->ProjectionMatrixType==MATRIX_IDENTITY)
       && ctx->ModelViewMatrixType!=MATRIX_GENERAL
       && (ctx->VB->VertexSizeMask & VERTEX4_BIT)==0) {
d277 6
d287 12
d300 6
a305 3
   if (VB->MaterialMask[i]) {
      if (VB->MaterialMask[i] & FRONT_AMBIENT_BIT) {
         COPY_4V( ctx->Light.Material[0].Ambient, VB->Material[i][0].Ambient );
d307 8
a314 2
      if (VB->MaterialMask[i] & BACK_AMBIENT_BIT) {
         COPY_4V( ctx->Light.Material[1].Ambient, VB->Material[i][1].Ambient );
d316 9
a324 2
      if (VB->MaterialMask[i] & FRONT_DIFFUSE_BIT) {
         COPY_4V( ctx->Light.Material[0].Diffuse, VB->Material[i][0].Diffuse );
d326 13
a338 2
      if (VB->MaterialMask[i] & BACK_DIFFUSE_BIT) {
         COPY_4V( ctx->Light.Material[1].Diffuse, VB->Material[i][1].Diffuse );
d340 11
a350 2
      if (VB->MaterialMask[i] & FRONT_SPECULAR_BIT) {
         COPY_4V( ctx->Light.Material[0].Specular, VB->Material[i][0].Specular );
d352 31
a382 28
      if (VB->MaterialMask[i] & BACK_SPECULAR_BIT) {
         COPY_4V( ctx->Light.Material[1].Specular, VB->Material[i][1].Specular );
      }
      if (VB->MaterialMask[i] & FRONT_EMISSION_BIT) {
         COPY_4V( ctx->Light.Material[0].Emission, VB->Material[i][0].Emission );
      }
      if (VB->MaterialMask[i] & BACK_EMISSION_BIT) {
         COPY_4V( ctx->Light.Material[1].Emission, VB->Material[i][1].Emission );
      }
      if (VB->MaterialMask[i] & FRONT_SHININESS_BIT) {
         ctx->Light.Material[0].Shininess = VB->Material[i][0].Shininess;
         gl_compute_material_shine_table( &ctx->Light.Material[0] );
      }
      if (VB->MaterialMask[i] & BACK_SHININESS_BIT) {
         ctx->Light.Material[1].Shininess = VB->Material[i][1].Shininess;
         gl_compute_material_shine_table( &ctx->Light.Material[1] );
      }
      if (VB->MaterialMask[i] & FRONT_INDEXES_BIT) {
         ctx->Light.Material[0].AmbientIndex = VB->Material[i][0].AmbientIndex;
         ctx->Light.Material[0].DiffuseIndex = VB->Material[i][0].DiffuseIndex;
         ctx->Light.Material[0].SpecularIndex = VB->Material[i][0].SpecularIndex;
      }
      if (VB->MaterialMask[i] & BACK_INDEXES_BIT) {
         ctx->Light.Material[1].AmbientIndex = VB->Material[i][1].AmbientIndex;
         ctx->Light.Material[1].DiffuseIndex = VB->Material[i][1].DiffuseIndex;
         ctx->Light.Material[1].SpecularIndex = VB->Material[i][1].SpecularIndex;
      }
      VB->MaterialMask[i] = 0;  /* reset now */
d384 2
d389 1
a389 4
/*
 * Compute the shading (lighting) for the vertices in the vertex buffer.
 */
static void shade_vertices( GLcontext *ctx, GLuint vbStart, GLuint vbCount )
d392 1
d394 7
a400 37
   if (ctx->Visual->RGBAflag && ctx->Texture.Enabled
       && ctx->Light.Model.ColorControl==GL_SEPARATE_SPECULAR_COLOR) {
      /* Separate specular color */
      if (!VB->MonoMaterial) {
         /* Material may change with each vertex */
         GLuint i;
         for (i=vbStart; i<vbCount; i++) {
            update_material( ctx, i );
            gl_shade_rgba_spec( ctx, 0, 1, &VB->Eye[i],
                                &VB->Normal[i], &VB->Fcolor[i], &VB->Fspec[i]);
            if (ctx->Light.Model.TwoSide) {
               gl_shade_rgba_spec( ctx, 1, 1, &VB->Eye[i],
                                 &VB->Normal[i], &VB->Bcolor[i], &VB->Bspec[i]);
            }
         }
         /* Need this in case a glColor/glMaterial is called after the
          * last vertex between glBegin/glEnd.
          */
         update_material( ctx, vbCount );
      }
      else {
         /* call slower, full-featured shader */
         gl_shade_rgba_spec( ctx, 0,
                             vbCount - vbStart,
                             VB->Eye + vbStart,
                             VB->Normal + vbStart,
                             VB->Fcolor + vbStart,
                             VB->Fspec + vbStart );
         if (ctx->Light.Model.TwoSide) {
            gl_shade_rgba_spec( ctx, 1,
                                vbCount - vbStart,
                                VB->Eye + vbStart,
                                VB->Normal + vbStart,
                                VB->Bcolor + vbStart,
                                VB->Bspec + vbStart );
         }
      }
d402 14
a415 36
   else if (ctx->Visual->RGBAflag) {
      if (!VB->MonoMaterial) {
         /* Material may change with each vertex */
         GLuint i;
         for (i=vbStart; i<vbCount; i++) {
            update_material( ctx, i );
            gl_shade_rgba( ctx, 0, 1, &VB->Eye[i],
                           &VB->Normal[i], &VB->Fcolor[i]);
            if (ctx->Light.Model.TwoSide) {
               gl_shade_rgba( ctx, 1, 1, &VB->Eye[i],
                              &VB->Normal[i], &VB->Bcolor[i]);
            }
         }
         /* Need this in case a glColor/glMaterial is called after the
          * last vertex between glBegin/glEnd.
          */
         update_material( ctx, vbCount );
      }
      else {
         if (ctx->Light.Fast) {
            if (VB->MonoNormal) {
               /* call optimized shader */
               GLubyte color[1][4];
               GLuint i;
               gl_shade_rgba_fast( ctx, 0,  /* front side */
                                   1, VB->Normal + vbStart, color );
               for (i=vbStart; i<vbCount; i++) {
                  COPY_4V( VB->Fcolor[i], color[0] );
               }
               if (ctx->Light.Model.TwoSide) {
                  gl_shade_rgba_fast( ctx, 1,  /* back side */
                                      1, VB->Normal + vbStart, color );
                  for (i=vbStart; i<vbCount; i++) {
                     COPY_4V( VB->Bcolor[i], color[0] );
                  }
               }
d417 22
a438 69
            }
            else {
               /* call optimized shader */
               gl_shade_rgba_fast( ctx, 0,  /* front side */
                                   vbCount - vbStart,
                                   VB->Normal + vbStart,
                                   VB->Fcolor + vbStart );
               if (ctx->Light.Model.TwoSide) {
                  gl_shade_rgba_fast( ctx, 1,  /* back side */
                                      vbCount - vbStart,
                                      VB->Normal + vbStart,
                                      VB->Bcolor + vbStart );
               }
            }
         }
         else {
            /* call slower, full-featured shader */
            gl_shade_rgba( ctx, 0,
                           vbCount - vbStart,
                           VB->Eye + vbStart,
                           VB->Normal + vbStart,
                           VB->Fcolor + vbStart );
            if (ctx->Light.Model.TwoSide) {
               gl_shade_rgba( ctx, 1,
                              vbCount - vbStart,
                              VB->Eye + vbStart,
                              VB->Normal + vbStart,
                              VB->Bcolor + vbStart );
            }
         }
      }
   }
   else {
      /* Color index mode */
      if (!VB->MonoMaterial) {
         /* Material may change with each vertex */
         GLuint i;
         /* NOTE the <= here.  This is needed in case glColor/glMaterial
          * is called after the last glVertex inside a glBegin/glEnd pair.
          */
         for (i=vbStart; i<vbCount; i++) {
            update_material( ctx, i );
            gl_shade_ci( ctx, 0, 1, &VB->Eye[i],
                         &VB->Normal[i], &VB->Findex[i] );
            if (ctx->Light.Model.TwoSide) {
               gl_shade_ci( ctx, 1, 1, &VB->Eye[i],
                            &VB->Normal[i], &VB->Bindex[i] );
            }
         }
         /* Need this in case a glColor/glMaterial is called after the
          * last vertex between glBegin/glEnd.
          */
         update_material( ctx, vbCount );
      }
      else {
         gl_shade_ci( ctx, 0,
                      vbCount - vbStart,
                      VB->Eye + vbStart,
                      VB->Normal + vbStart,
                      VB->Findex + vbStart );
         if (ctx->Light.Model.TwoSide) {
            gl_shade_ci( ctx, 1,
                         vbCount - vbStart,
                         VB->Eye + vbStart,
                         VB->Normal + vbStart,
                         VB->Bindex + vbStart );
         }
      }
   }
d443 1
d477 36
a512 2
 * Transform vertices, compute lighting, clipflags,
 * fog, texture coords, etc.
a513 1
 * Return the clipOrMask and clipAndMask values for the given VB range
d515 5
a519 2
static void gl_transform_vb_range( GLcontext *ctx, GLuint vbStart, GLuint vbCount,
				   GLubyte *clipOrMask, GLubyte *clipAndMask,
d522 82
a603 1
  struct vertex_buffer *VB = ctx->VB;
d605 42
a646 31
  if (firstPartToDo) {
    /* Apply the modelview matrix to transform vertexes from Object
     * to Eye coords.
     */
    if (VB->VertexSizeMask==VERTEX4_BIT) {
      transform_points4( ctx, vbCount - vbStart,
			 VB->Obj + vbStart, VB->Eye + vbStart );
    }
    else {
      transform_points3( ctx, vbCount - vbStart,
			 VB->Obj + vbStart, VB->Eye + vbStart );
    }

    /* Now transform the normal vectors */
    if (ctx->NeedNormals) {
      gl_xform_normals_3fv( vbCount - vbStart,
			    VB->Normal + vbStart, ctx->ModelViewInv,
			    VB->Normal + vbStart, ctx->Transform.Normalize,
			    ctx->Transform.RescaleNormals );
    }
  }

  /* Test vertices in eye coordinate space against user clipping planes */
  if (ctx->Transform.AnyClip) {
    GLuint result = userclip_vertices( ctx, vbCount - vbStart,
				       VB->Eye + vbStart,
				       VB->ClipMask + vbStart );
    if (result==CLIP_ALL) {
      /* All vertices were outside one of the clip planes! */
      *clipOrMask = CLIP_ALL_BITS; /* force reset of clipping flags */
      *clipAndMask = CLIP_ALL_BITS;
d648 1
a648 8
    }
    else if (result==CLIP_SOME) {
      *clipOrMask = CLIP_USER_BIT;
    }
    else {
      *clipAndMask = 0;
    }
  }
d650 47
a696 12
  /* Apply the projection matrix to the Eye coordinates, resulting in
   * Clip coordinates.  Also, compute the ClipMask for each vertex.
   */
  project_and_cliptest( ctx, vbCount - vbStart, VB->Eye + vbStart,
			VB->Clip + vbStart, VB->ClipMask + vbStart,
			clipOrMask, clipAndMask );

  if (*clipAndMask) {
    /* All vertices clipped by one plane, all done! */
    *clipOrMask = CLIP_ALL_BITS; /* force reset of clipping flags */
    return;
  }
d698 19
a716 4
  /* Lighting */
  if (ctx->Light.Enabled) {
    shade_vertices(ctx, vbStart, vbCount);
  }
a717 4
  /* Per-vertex fog */
  if (ctx->Fog.Enabled && ctx->Hint.Fog!=GL_NICEST) {
    fog_vertices(ctx, vbStart, vbCount);
  }
a718 30
  /* Generate/transform texture coords */
  if (ctx->Texture.Enabled || ctx->RenderMode==GL_FEEDBACK) {
    GLuint texSet;
    for (texSet=0; texSet<MAX_TEX_COORD_SETS; texSet++) {
      if (ctx->Texture.Set[texSet].TexGenEnabled) {
	gl_texgen( ctx, vbCount - vbStart,
		   VB->Obj + vbStart,
		   VB->Eye + vbStart,
		   VB->Normal + vbStart,
		   VB->MultiTexCoord[texSet] + vbStart,
		   texSet );
      }
    }
    for (texSet=0; texSet<MAX_TEX_COORD_SETS; texSet++) {
      if (ctx->TextureMatrixType[texSet] != MATRIX_IDENTITY) {
	transform_texcoords( ctx, vbCount - vbStart,
			     VB->MultiTexCoord[texSet] + vbStart,
			     texSet );
      }
    }
  }
  
  /* Use the viewport parameters to transform vertices from Clip
   * coordinates to Window coordinates.
   */
  if (ctx->DoViewportMapping) {
     viewport_map_vertices( ctx, vbCount - vbStart, VB->Clip + vbStart,
                     (*clipOrMask) ? VB->ClipMask + vbStart : (GLubyte*) NULL,
		     VB->Win + vbStart );
  }
a719 5
  /* Device driver rasterization setup.  3Dfx driver, for example. */
  if (ctx->Driver.RasterSetup) {
    (*ctx->Driver.RasterSetup)( ctx, vbStart, vbCount );
  }
}
d787 1
d804 5
a808 3
  if ((ctx->Texture.Enabled || ctx->RenderMode==GL_FEEDBACK) &&
      ctx->NewTextureMatrix)
    gl_analyze_texture_matrix(ctx);
d949 3
d956 1
@


3.9
log
@include asm_386.h instead of asm-386.h
@
text
@d1 1
a1 1
/* $Id: vbxform.c,v 3.8 1998/06/22 03:16:28 brianp Exp brianp $ */
d26 3
a854 1

d1207 5
a1211 3
  viewport_map_vertices( ctx, vbCount - vbStart, VB->Clip + vbStart,
			 (*clipOrMask) ? VB->ClipMask + vbStart : (GLubyte*) NULL,
			 VB->Win + vbStart );
a1216 2


@


3.8
log
@added MITS code
@
text
@d1 1
a1 1
/* $Id: vbxform.c,v 3.7 1998/06/07 22:18:52 brianp Exp $ */
d26 3
d70 1
a70 1
#include "asm-386.h"
@


3.7
log
@implemented GL_EXT_multitexture extension
@
text
@d1 1
a1 1
/* $Id: vbxform.c,v 3.6 1998/04/18 05:01:18 brianp Exp brianp $ */
d26 3
a756 1

d770 1
d778 1
d849 1
d917 1
a917 1
static void shade_vertices( GLcontext *ctx )
d927 1
a927 1
         for (i=VB->Start; i<VB->Count; i++) {
d939 1
a939 1
         update_material( ctx, VB->Count );
d944 5
a948 5
                             VB->Count - VB->Start,
                             VB->Eye + VB->Start,
                             VB->Normal + VB->Start,
                             VB->Fcolor + VB->Start,
                             VB->Fspec + VB->Start );
d951 5
a955 5
                                VB->Count - VB->Start,
                                VB->Eye + VB->Start,
                                VB->Normal + VB->Start,
                                VB->Bcolor + VB->Start,
                                VB->Bspec + VB->Start );
d963 1
a963 1
         for (i=VB->Start; i<VB->Count; i++) {
d975 1
a975 1
         update_material( ctx, VB->Count );
d984 2
a985 2
                                   1, VB->Normal + VB->Start, color );
               for (i=VB->Start; i<VB->Count; i++) {
d990 2
a991 2
                                      1, VB->Normal + VB->Start, color );
                  for (i=VB->Start; i<VB->Count; i++) {
d1000 3
a1002 3
                                   VB->Count - VB->Start,
                                   VB->Normal + VB->Start,
                                   VB->Fcolor + VB->Start );
d1005 3
a1007 3
                                      VB->Count - VB->Start,
                                      VB->Normal + VB->Start,
                                      VB->Bcolor + VB->Start );
d1014 4
a1017 4
                           VB->Count - VB->Start,
                           VB->Eye + VB->Start,
                           VB->Normal + VB->Start,
                           VB->Fcolor + VB->Start );
d1020 4
a1023 4
                              VB->Count - VB->Start,
                              VB->Eye + VB->Start,
                              VB->Normal + VB->Start,
                              VB->Bcolor + VB->Start );
d1036 1
a1036 1
         for (i=VB->Start; i<VB->Count; i++) {
d1048 1
a1048 1
         update_material( ctx, VB->Count );
d1052 4
a1055 4
                      VB->Count - VB->Start,
                      VB->Eye + VB->Start,
                      VB->Normal + VB->Start,
                      VB->Findex + VB->Start );
d1058 4
a1061 4
                         VB->Count - VB->Start,
                         VB->Eye + VB->Start,
                         VB->Normal + VB->Start,
                         VB->Bindex + VB->Start );
d1072 1
a1072 1
static void fog_vertices( GLcontext *ctx )
d1078 3
a1080 3
      gl_fog_rgba_vertices( ctx, VB->Count - VB->Start,
                            VB->Eye + VB->Start,
                            VB->Fcolor + VB->Start );
d1082 3
a1084 3
         gl_fog_rgba_vertices( ctx, VB->Count - VB->Start,
                               VB->Eye + VB->Start,
                               VB->Bcolor + VB->Start );
d1089 3
a1091 3
      gl_fog_ci_vertices( ctx, VB->Count - VB->Start,
                          VB->Eye + VB->Start,
                          VB->Findex + VB->Start );
d1093 3
a1095 3
         gl_fog_ci_vertices( ctx, VB->Count - VB->Start,
                             VB->Eye + VB->Start,
                             VB->Bindex + VB->Start );
a1100 1

d1102 4
a1105 4
 * When the Vertex Buffer is full, this function applies the modelview
 * matrix to transform vertices and normals from object coordinates to
 * eye coordinates.  Next, we'll call gl_transform_vb_part2()...
 * This function might not be called when using vertex arrays.
d1107 145
a1251 1
void gl_transform_vb_part1( GLcontext *ctx, GLboolean allDone )
d1253 22
a1274 3
   struct vertex_buffer *VB = ctx->VB;
#ifdef PROFILE
   GLdouble t0 = gl_time();
a1276 1
   ASSERT( VB->Count>0 );
d1278 10
a1287 11
   /* Apply the modelview matrix to transform vertexes from Object
    * to Eye coords.
    */
   if (VB->VertexSizeMask==VERTEX4_BIT) {
      transform_points4( ctx, VB->Count - VB->Start,
                         VB->Obj + VB->Start, VB->Eye + VB->Start );
   }
   else {
      transform_points3( ctx, VB->Count - VB->Start,
                         VB->Obj + VB->Start, VB->Eye + VB->Start );
   }
d1289 1
a1289 7
   /* Now transform the normal vectors */
   if (ctx->NeedNormals) {
      gl_xform_normals_3fv( VB->Count - VB->Start,
                            VB->Normal + VB->Start, ctx->ModelViewInv,
                            VB->Normal + VB->Start, ctx->Transform.Normalize,
                            ctx->Transform.RescaleNormals );
   }
d1292 2
a1293 1
   ctx->VertexTime += gl_time() - t0;
d1295 4
d1300 3
a1302 3
   /* lighting, project, etc */
   gl_transform_vb_part2( ctx, allDone );
}
d1304 1
d1306 1
d1308 1
a1308 13
/*
 * Part 2 of Vertex Buffer transformation:  compute lighting, clipflags,
 * fog, texture coords, etc.
 * Before this function is called the VB->Eye coordinates must have
 * already been computed.
 * Callers:  gl_transform_vb_part1(), glDrawArraysEXT()
 */
void gl_transform_vb_part2( GLcontext *ctx, GLboolean allDone )
{
   struct vertex_buffer *VB = ctx->VB;
#ifdef PROFILE
   GLdouble t0 = gl_time();
#endif
d1310 2
a1311 1
   ASSERT( VB->Count>0 );
d1313 2
a1314 13
   /* Test vertices in eye coordinate space against user clipping planes */
   if (ctx->Transform.AnyClip) {
      GLuint result = userclip_vertices( ctx, VB->Count - VB->Start,
                                         VB->Eye + VB->Start,
                                         VB->ClipMask + VB->Start );
      if (result==CLIP_ALL) {
         /* All vertices were outside one of the clip planes! */
         VB->ClipOrMask = CLIP_ALL_BITS; /* force reset of clipping flags */
         gl_reset_vb( ctx, allDone );
         return;
      }
      else if (result==CLIP_SOME) {
         VB->ClipOrMask = CLIP_USER_BIT;
d1317 1
a1317 1
         VB->ClipAndMask = 0;
a1318 1
   }
a1319 14
   /* Apply the projection matrix to the Eye coordinates, resulting in
    * Clip coordinates.  Also, compute the ClipMask for each vertex.
    */
   project_and_cliptest( ctx, VB->Count - VB->Start, VB->Eye + VB->Start,
                         VB->Clip + VB->Start, VB->ClipMask + VB->Start,
                         &VB->ClipOrMask, &VB->ClipAndMask );

   if (VB->ClipAndMask) {
      /* All vertices clipped by one plane, all done! */
      /*assert(VB->ClipOrMask);*/
      VB->ClipOrMask = CLIP_ALL_BITS; /* force reset of clipping flags */
      gl_reset_vb( ctx, allDone );
      return;
   }
d1321 69
a1389 4
   /* Lighting */
   if (ctx->Light.Enabled) {
      shade_vertices(ctx);
   }
d1391 3
a1393 4
   /* Per-vertex fog */
   if (ctx->Fog.Enabled && ctx->Hint.Fog!=GL_NICEST) {
      fog_vertices(ctx);
   }
d1395 1
a1395 24
   /* Generate/transform texture coords */
   if (ctx->Texture.Enabled || ctx->RenderMode==GL_FEEDBACK) {
      GLuint texSet;
      for (texSet=0; texSet<MAX_TEX_COORD_SETS; texSet++) {
         if (ctx->Texture.Set[texSet].TexGenEnabled) {
            gl_texgen( ctx, VB->Count - VB->Start,
                       VB->Obj + VB->Start,
                       VB->Eye + VB->Start,
                       VB->Normal + VB->Start,
                       VB->MultiTexCoord[texSet] + VB->Start,
                       texSet );
         }
      }
      if (ctx->NewTextureMatrix) {
         gl_analyze_texture_matrix(ctx);
      }
      for (texSet=0; texSet<MAX_TEX_COORD_SETS; texSet++) {
         if (ctx->TextureMatrixType[texSet] != MATRIX_IDENTITY) {
            transform_texcoords( ctx, VB->Count - VB->Start,
                                 VB->MultiTexCoord[texSet] + VB->Start,
                                 texSet );
         }
      }
   }
d1397 4
a1400 11
   /* Use the viewport parameters to transform vertices from Clip
    * coordinates to Window coordinates.
    */
   viewport_map_vertices( ctx, VB->Count - VB->Start, VB->Clip + VB->Start,
                          VB->ClipOrMask ? VB->ClipMask + VB->Start : (GLubyte*) NULL,
                          VB->Win + VB->Start );

   /* Device driver rasterization setup.  3Dfx driver, for example. */
   if (ctx->Driver.RasterSetup) {
      (*ctx->Driver.RasterSetup)( ctx, 0, VB->Count );
   }
d1404 2
a1405 2
   ctx->VertexTime += gl_time() - t0;
   ctx->VertexCount += VB->Count - VB->Start;
d1408 34
a1441 9
   /*
    * Now we're ready to rasterize the Vertex Buffer!!!
    *
    * If the device driver can't rasterize the vertex buffer then we'll
    * do it ourselves.
    */
   if (!ctx->Driver.RenderVB || !(*ctx->Driver.RenderVB)(ctx,allDone)) {
      gl_render_vb( ctx, allDone );
   }
d1443 1
@


3.6
log
@renamed USE_ASM to USE_X86_ASM
@
text
@d1 1
a1 1
/* $Id: vbxform.c,v 3.5 1998/03/28 04:01:53 brianp Exp brianp $ */
d26 3
d423 1
a423 1
 *         texSet - which texture matrix set to use
d1205 1
a1205 1
      for (texSet=0; texSet<MAX_TEX_SETS; texSet++) {
d1218 1
a1218 1
      for (texSet=0; texSet<MAX_TEX_SETS; texSet++) {
@


3.5
log
@added CONST macro to fix IRIX compilation problems
@
text
@d1 1
a1 1
/* $Id: vbxform.c,v 3.4 1998/03/27 04:26:44 brianp Exp brianp $ */
d26 3
d183 1
a183 1
#ifndef USE_ASM
d303 1
a303 1
#ifndef USE_ASM
d426 1
a426 1
#ifndef USE_ASM
d532 1
a532 1
#ifndef USE_ASM
@


3.4
log
@fixed G++ warnings
@
text
@d1 1
a1 1
/* $Id: vbxform.c,v 3.3 1998/02/20 04:53:07 brianp Exp brianp $ */
d26 3
d178 1
a178 1
                               /*const*/ GLfloat vObj[][4], GLfloat vEye[][4] )
d298 1
a298 1
                               /*const*/ GLfloat vObj[][4], GLfloat vEye[][4] )
d524 1
a524 1
                                  GLuint n, /*const*/ GLfloat vEye[][4],
d705 1
a705 1
                                 /*const*/ GLfloat vEye[][4],
d759 1
a759 1
                                   GLuint n, /*const*/ GLfloat vClip[][4],
@


3.3
log
@implemented GL_SGIS_multitexture
@
text
@d1 1
a1 1
/* $Id: vbxform.c,v 3.2 1998/02/02 03:09:34 brianp Exp brianp $ */
d26 3
d1222 1
a1222 1
                          VB->ClipOrMask ? VB->ClipMask + VB->Start : NULL,
@


3.2
log
@added GL_LIGHT_MODEL_COLOR_CONTROL (separate specular color interpolation)
@
text
@d1 1
a1 1
/* $Id: vbxform.c,v 3.1 1998/02/01 16:37:19 brianp Exp brianp $ */
d26 3
d411 1
d414 2
a415 1
static void transform_texcoords( GLcontext *ctx, GLuint n, GLfloat t[][4] )
d419 1
a419 1
   switch (ctx->TextureMatrixType) {
d422 1
a422 1
            const GLfloat *m = ctx->TextureMatrix;
d442 1
a442 1
            const GLfloat *m = ctx->TextureMatrix;
d457 1
a457 1
            const GLfloat *m = ctx->TextureMatrix;
d477 1
a477 1
   switch (ctx->TextureMatrixType) {
d479 1
a479 1
         asm_transform_points4_general( n, t, ctx->TextureMatrix, t );
d485 1
a485 1
         asm_transform_points4_2d( n, t, ctx->TextureMatrix, t );
d488 1
a488 1
         asm_transform_points4_3d( n, t, ctx->TextureMatrix, t );
d1192 10
a1201 6
      if (ctx->Texture.TexGenEnabled) {
         gl_texgen( ctx, VB->Count - VB->Start,
                    VB->Obj + VB->Start,
                    VB->Eye + VB->Start,
                    VB->Normal + VB->Start,
                    VB->TexCoord + VB->Start );
d1206 6
a1211 3
      if (ctx->TextureMatrixType!=MATRIX_IDENTITY) {
         transform_texcoords( ctx, VB->Count - VB->Start,
                              VB->TexCoord + VB->Start );
@


3.1
log
@added GL_EXT_rescale_normal extension
@
text
@d1 1
a1 1
/* $Id: vbxform.c,v 3.0 1998/01/31 21:06:45 brianp Exp brianp $ */
d26 3
d899 39
a937 1
   if (ctx->Visual->RGBAflag) {
d943 2
a944 2
            gl_color_shade_vertices( ctx, 0, 1, &VB->Eye[i],
                                     &VB->Normal[i], &VB->Fcolor[i]);
d946 2
a947 2
               gl_color_shade_vertices( ctx, 1, 1, &VB->Eye[i],
                                        &VB->Normal[i], &VB->Bcolor[i]);
d961 2
a962 4
               gl_color_shade_vertices_fast( ctx, 0,  /* front side */
                                             1,
                                             VB->Normal + VB->Start,
                                             color );
d967 2
a968 4
                  gl_color_shade_vertices_fast( ctx, 1,  /* back side */
                                                1,
                                                VB->Normal + VB->Start,
                                                color );
d977 4
a980 4
               gl_color_shade_vertices_fast( ctx, 0,  /* front side */
                                             VB->Count - VB->Start,
                                             VB->Normal + VB->Start,
                                             VB->Fcolor + VB->Start );
d982 4
a985 4
                  gl_color_shade_vertices_fast( ctx, 1,  /* back side */
                                                VB->Count - VB->Start,
                                                VB->Normal + VB->Start,
                                                VB->Bcolor + VB->Start );
d991 5
a995 5
            gl_color_shade_vertices( ctx, 0,
                                     VB->Count - VB->Start,
                                     VB->Eye + VB->Start,
                                     VB->Normal + VB->Start,
                                     VB->Fcolor + VB->Start );
d997 5
a1001 5
               gl_color_shade_vertices( ctx, 1,
                                        VB->Count - VB->Start,
                                        VB->Eye + VB->Start,
                                        VB->Normal + VB->Start,
                                        VB->Bcolor + VB->Start );
d1016 2
a1017 2
            gl_index_shade_vertices( ctx, 0, 1, &VB->Eye[i],
                                     &VB->Normal[i], &VB->Findex[i] );
d1019 2
a1020 2
               gl_index_shade_vertices( ctx, 1, 1, &VB->Eye[i],
                                        &VB->Normal[i], &VB->Bindex[i] );
d1029 5
a1033 5
         gl_index_shade_vertices( ctx, 0,
                                  VB->Count - VB->Start,
                                  VB->Eye + VB->Start,
                                  VB->Normal + VB->Start,
                                  VB->Findex + VB->Start );
d1035 5
a1039 5
            gl_index_shade_vertices( ctx, 1,
                                     VB->Count - VB->Start,
                                     VB->Eye + VB->Start,
                                     VB->Normal + VB->Start,
                                     VB->Bindex + VB->Start );
@


3.0
log
@initial rev
@
text
@d1 1
a1 1
/* $Id$ */
d25 4
a28 1
 * $Log$
d1074 2
a1075 1
                            VB->Normal + VB->Start, ctx->Transform.Normalize );
@
