stage. (Materials now treated more like colors, etc.). Continue whipping the dd templates into shape. Remove old NormalLength code; may come back as a driver helper, but not useful for, eg. hardware t&l drivers.tags/mesa_3_5
/* $Id: dd.h,v 1.51 2001/02/06 21:42:48 brianp Exp $ */ | |||||
/* $Id: dd.h,v 1.52 2001/02/15 01:33:52 keithw Exp $ */ | |||||
/* | /* | ||||
* Mesa 3-D graphics library | * Mesa 3-D graphics library | ||||
void (*EdgeFlagPointer)(GLcontext *ctx, GLsizei stride, const GLvoid *ptr); | void (*EdgeFlagPointer)(GLcontext *ctx, GLsizei stride, const GLvoid *ptr); | ||||
/*** | |||||
*** TNL Pipeline | |||||
***/ | |||||
void (*PipelineStart)(GLcontext *ctx); | |||||
void (*PipelineFinish)(GLcontext *ctx); | |||||
/* Called before and after all pipeline stages. | |||||
* These are a suitable place for grabbing/releasing hardware locks. | |||||
*/ | |||||
/*** | /*** | ||||
*** Rendering | *** Rendering |
/* $Id: light.c,v 1.36 2001/02/13 23:55:30 brianp Exp $ */ | |||||
/* $Id: light.c,v 1.37 2001/02/15 01:33:52 keithw Exp $ */ | |||||
/* | /* | ||||
* Mesa 3-D graphics library | * Mesa 3-D graphics library | ||||
} | } | ||||
/* Perform a straight copy between pairs of materials. | |||||
*/ | |||||
void gl_copy_material_pairs( struct gl_material dst[2], | |||||
const struct gl_material src[2], | |||||
GLuint bitmask ) | |||||
{ | |||||
if (bitmask & FRONT_EMISSION_BIT) { | |||||
COPY_4FV( dst[0].Emission, src[0].Emission ); | |||||
} | |||||
if (bitmask & BACK_EMISSION_BIT) { | |||||
COPY_4FV( dst[1].Emission, src[1].Emission ); | |||||
} | |||||
if (bitmask & FRONT_AMBIENT_BIT) { | |||||
COPY_4FV( dst[0].Ambient, src[0].Ambient ); | |||||
} | |||||
if (bitmask & BACK_AMBIENT_BIT) { | |||||
COPY_4FV( dst[1].Ambient, src[1].Ambient ); | |||||
} | |||||
if (bitmask & FRONT_DIFFUSE_BIT) { | |||||
COPY_4FV( dst[0].Diffuse, src[0].Diffuse ); | |||||
} | |||||
if (bitmask & BACK_DIFFUSE_BIT) { | |||||
COPY_4FV( dst[1].Diffuse, src[1].Diffuse ); | |||||
} | |||||
if (bitmask & FRONT_SPECULAR_BIT) { | |||||
COPY_4FV( dst[0].Specular, src[0].Specular ); | |||||
} | |||||
if (bitmask & BACK_SPECULAR_BIT) { | |||||
COPY_4FV( dst[1].Specular, src[1].Specular ); | |||||
} | |||||
if (bitmask & FRONT_SHININESS_BIT) { | |||||
dst[0].Shininess = src[0].Shininess; | |||||
} | |||||
if (bitmask & BACK_SHININESS_BIT) { | |||||
dst[1].Shininess = src[1].Shininess; | |||||
} | |||||
if (bitmask & FRONT_INDEXES_BIT) { | |||||
dst[0].AmbientIndex = src[0].AmbientIndex; | |||||
dst[0].DiffuseIndex = src[0].DiffuseIndex; | |||||
dst[0].SpecularIndex = src[0].SpecularIndex; | |||||
} | |||||
if (bitmask & BACK_INDEXES_BIT) { | |||||
dst[1].AmbientIndex = src[1].AmbientIndex; | |||||
dst[1].DiffuseIndex = src[1].DiffuseIndex; | |||||
dst[1].SpecularIndex = src[1].SpecularIndex; | |||||
} | |||||
} | |||||
/* | /* | ||||
* Check if the global material has to be updated with info that was | * Check if the global material has to be updated with info that was | ||||
* | * | ||||
* src[0] is front material, src[1] is back material | * src[0] is front material, src[1] is back material | ||||
* | * | ||||
* 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. | |||||
* Additionally keeps the precomputed lighting state uptodate. | |||||
*/ | */ | ||||
void gl_update_material( GLcontext *ctx, | void gl_update_material( GLcontext *ctx, | ||||
const struct gl_material src[2], | const struct gl_material src[2], | ||||
if (bitmask & FRONT_DIFFUSE_BIT) { | if (bitmask & FRONT_DIFFUSE_BIT) { | ||||
struct gl_material *mat = &ctx->Light.Material[0]; | struct gl_material *mat = &ctx->Light.Material[0]; | ||||
COPY_4FV( mat->Diffuse, src[0].Diffuse ); | COPY_4FV( mat->Diffuse, src[0].Diffuse ); | ||||
/* fprintf(stderr, "FRONT_DIFFUSE %f %f %f %f\n", */ | |||||
/* mat->Diffuse[0], mat->Diffuse[1], */ | |||||
/* mat->Diffuse[2], mat->Diffuse[3]); */ | |||||
foreach (light, list) { | foreach (light, list) { | ||||
SCALE_3V( light->_MatDiffuse[0], light->Diffuse, mat->Diffuse ); | SCALE_3V( light->_MatDiffuse[0], light->Diffuse, mat->Diffuse ); | ||||
} | } | ||||
if (bitmask & BACK_DIFFUSE_BIT) { | if (bitmask & BACK_DIFFUSE_BIT) { | ||||
struct gl_material *mat = &ctx->Light.Material[1]; | struct gl_material *mat = &ctx->Light.Material[1]; | ||||
COPY_4FV( mat->Diffuse, src[1].Diffuse ); | COPY_4FV( mat->Diffuse, src[1].Diffuse ); | ||||
/* fprintf(stderr, "BACK_DIFFUSE %f %f %f %f\n", */ | |||||
/* mat->Diffuse[0], mat->Diffuse[1], */ | |||||
/* mat->Diffuse[2], mat->Diffuse[3]); */ | |||||
foreach (light, list) { | foreach (light, list) { | ||||
SCALE_3V( light->_MatDiffuse[1], light->Diffuse, mat->Diffuse ); | SCALE_3V( light->_MatDiffuse[1], light->Diffuse, mat->Diffuse ); | ||||
} | } | ||||
} | } | ||||
if (bitmask & FRONT_SHININESS_BIT) { | if (bitmask & FRONT_SHININESS_BIT) { | ||||
/* fprintf(stderr, "FRONT_SHININESS_BIT %f\n", src[0].Shininess); */ | |||||
ctx->Light.Material[0].Shininess = src[0].Shininess; | ctx->Light.Material[0].Shininess = src[0].Shininess; | ||||
gl_invalidate_shine_table( ctx, 0 ); | gl_invalidate_shine_table( ctx, 0 ); | ||||
} | } | ||||
/* | /* | ||||
* Update the current materials from the given rgba color | * Update the current materials from the given rgba color | ||||
* according to the bitmask in ColorMaterialBitmask, which is | * according to the bitmask in ColorMaterialBitmask, which is |
/* $Id: light.h,v 1.9 2001/02/06 04:06:35 keithw Exp $ */ | |||||
/* $Id: light.h,v 1.10 2001/02/15 01:33:52 keithw Exp $ */ | |||||
/* | /* | ||||
* Mesa 3-D graphics library | * Mesa 3-D graphics library | ||||
const struct gl_material src[2], | const struct gl_material src[2], | ||||
GLuint bitmask ); | GLuint bitmask ); | ||||
extern void gl_copy_material_pairs( struct gl_material dst[2], | |||||
const struct gl_material src[2], | |||||
GLuint bitmask ); | |||||
extern void gl_update_color_material( GLcontext *ctx, const GLchan rgba[4] ); | extern void gl_update_color_material( GLcontext *ctx, const GLchan rgba[4] ); | ||||
/* $Id: t_array_api.c,v 1.5 2001/02/04 00:44:36 keithw Exp $ */ | |||||
/* $Id: t_array_api.c,v 1.6 2001/02/15 01:33:52 keithw Exp $ */ | |||||
/* | /* | ||||
* Mesa 3-D graphics library | * Mesa 3-D graphics library | ||||
} | } | ||||
static void _tnl_draw_elements( GLcontext *ctx, GLenum mode, GLsizei count, | |||||
const GLuint *indices) | |||||
{ | |||||
#if 1 | |||||
/* Optimized code that fakes the effect of calling | |||||
* _tnl_array_element for each index in the list. | |||||
*/ | |||||
if (_tnl_hard_begin( ctx, mode )) { | |||||
GLuint i,j; | |||||
for (j = 0 ; j < count ; ) { | |||||
struct immediate *IM = TNL_CURRENT_IM(ctx); | |||||
GLuint start = IM->Start; | |||||
GLuint nr = MIN2( IMM_MAXDATA - start, count - j ) + start; | |||||
GLuint sf = IM->Flag[start]; | |||||
IM->FlushElt |= 1; | |||||
for (i = start ; i < nr ; i++) { | |||||
IM->Elt[i] = (GLuint) *indices++; | |||||
IM->Flag[i] = VERT_ELT; | |||||
} | |||||
if (j == 0) IM->Flag[start] |= sf; | |||||
IM->Count = nr; | |||||
j += nr - start; | |||||
if (j == count) | |||||
_tnl_end( ctx ); | |||||
_tnl_flush_immediate( IM ); | |||||
} | |||||
} | |||||
#else | |||||
/* Simple version of the above code. | |||||
*/ | |||||
if (_tnl_hard_begin(ctx, mode)) { | |||||
GLuint i; | |||||
for (i = 0 ; i < count ; i++) | |||||
_tnl_array_element( ctx, indices[i] ); | |||||
_tnl_end( ctx ); | |||||
} | |||||
#endif | |||||
} | |||||
static void _tnl_draw_range_elements( GLcontext *ctx, GLenum mode, | |||||
GLuint start, GLuint end, | |||||
GLsizei count, const GLuint *indices ) | |||||
{ | |||||
TNLcontext *tnl = TNL_CONTEXT(ctx); | |||||
FLUSH_CURRENT( ctx, 0 ); | |||||
_tnl_vb_bind_arrays( ctx, start, end ); | |||||
tnl->vb.FirstPrimitive = 0; | |||||
tnl->vb.Primitive[0] = mode | PRIM_BEGIN | PRIM_END | PRIM_LAST; | |||||
tnl->vb.PrimitiveLength[0] = count; | |||||
tnl->vb.Elts = (GLuint *)indices; | |||||
if (ctx->Array.LockCount) | |||||
_tnl_run_pipeline( ctx ); | |||||
else { | |||||
/* Note that arrays may have changed before/after execution. | |||||
*/ | |||||
tnl->pipeline.run_input_changes |= ctx->Array._Enabled; | |||||
_tnl_run_pipeline( ctx ); | |||||
tnl->pipeline.run_input_changes |= ctx->Array._Enabled; | |||||
} | |||||
} | |||||
void | void | ||||
_tnl_DrawArrays(GLenum mode, GLint start, GLsizei count) | _tnl_DrawArrays(GLenum mode, GLint start, GLsizei count) | ||||
} | } | ||||
static void _tnl_draw_range_elements( GLcontext *ctx, GLenum mode, | |||||
GLuint start, GLuint end, | |||||
GLsizei count, const GLuint *indices ) | |||||
{ | |||||
TNLcontext *tnl = TNL_CONTEXT(ctx); | |||||
FLUSH_CURRENT( ctx, 0 ); | |||||
_tnl_vb_bind_arrays( ctx, start, end ); | |||||
tnl->vb.FirstPrimitive = 0; | |||||
tnl->vb.Primitive[0] = mode | PRIM_BEGIN | PRIM_END | PRIM_LAST; | |||||
tnl->vb.PrimitiveLength[0] = count; | |||||
tnl->vb.Elts = (GLuint *)indices; | |||||
if (ctx->Array.LockCount) | |||||
_tnl_run_pipeline( ctx ); | |||||
else { | |||||
/* Note that arrays may have changed before/after execution. | |||||
*/ | |||||
tnl->pipeline.run_input_changes |= ctx->Array._Enabled; | |||||
_tnl_run_pipeline( ctx ); | |||||
tnl->pipeline.run_input_changes |= ctx->Array._Enabled; | |||||
} | |||||
} | |||||
static void _tnl_draw_elements( GLcontext *ctx, GLenum mode, GLsizei count, | |||||
const GLuint *indices) | |||||
{ | |||||
#if 1 | |||||
/* Optimized code that fakes the effect of calling | |||||
* _tnl_array_element for each index in the list. | |||||
*/ | |||||
if (_tnl_hard_begin( ctx, mode )) { | |||||
GLuint i,j; | |||||
for (j = 0 ; j < count ; ) { | |||||
struct immediate *IM = TNL_CURRENT_IM(ctx); | |||||
GLuint start = IM->Start; | |||||
GLuint nr = MIN2( IMM_MAXDATA - start, count - j ) + start; | |||||
GLuint sf = IM->Flag[start]; | |||||
IM->FlushElt |= 1; | |||||
for (i = start ; i < nr ; i++) { | |||||
IM->Elt[i] = (GLuint) *indices++; | |||||
IM->Flag[i] = VERT_ELT; | |||||
} | |||||
if (j == 0) IM->Flag[start] |= sf; | |||||
IM->Count = nr; | |||||
j += nr - start; | |||||
if (j == count) | |||||
_tnl_end( ctx ); | |||||
_tnl_flush_immediate( IM ); | |||||
} | |||||
} | |||||
#else | |||||
/* Simple version of the above code. | |||||
*/ | |||||
if (_tnl_hard_begin(ctx, mode)) { | |||||
GLuint i; | |||||
for (i = 0 ; i < count ; i++) | |||||
_tnl_array_element( ctx, indices[i] ); | |||||
_tnl_end( ctx ); | |||||
} | |||||
#endif | |||||
} | |||||
void | void | ||||
_tnl_DrawRangeElements(GLenum mode, | _tnl_DrawRangeElements(GLenum mode, | ||||
GLuint start, GLuint end, | GLuint start, GLuint end, | ||||
* May be able to get away with just setting LockCount==0, | * May be able to get away with just setting LockCount==0, | ||||
* though this raises the problems of dependent state. May | * though this raises the problems of dependent state. May | ||||
* have to call glUnlockArrays() directly? | * have to call glUnlockArrays() directly? | ||||
* | |||||
* Or scan the list and replace bad indices? | |||||
*/ | */ | ||||
gl_problem( ctx, | gl_problem( ctx, | ||||
"DrawRangeElements references " | "DrawRangeElements references " | ||||
} | } | ||||
} | } | ||||
else if (end + 1 - start < ctx->Const.MaxArrayLockSize) { | else if (end + 1 - start < ctx->Const.MaxArrayLockSize) { | ||||
/* The arrays aren't locked but we can still fit them inside a single | |||||
* vertexbuffer. | |||||
/* The arrays aren't locked but we can still fit them inside a | |||||
* single vertexbuffer. | |||||
*/ | */ | ||||
_tnl_draw_range_elements( ctx, mode, start, end + 1, count, ui_indices ); | _tnl_draw_range_elements( ctx, mode, start, end + 1, count, ui_indices ); | ||||
} else { | } else { | ||||
ui_indices = (GLuint *)_ac_import_elements( ctx, GL_UNSIGNED_INT, | ui_indices = (GLuint *)_ac_import_elements( ctx, GL_UNSIGNED_INT, | ||||
count, type, indices ); | count, type, indices ); | ||||
#if 1 | |||||
if (ctx->Array.LockCount) { | if (ctx->Array.LockCount) { | ||||
_tnl_draw_range_elements( ctx, mode, | _tnl_draw_range_elements( ctx, mode, | ||||
ctx->Array.LockFirst, | ctx->Array.LockFirst, | ||||
if (max_elt < ctx->Const.MaxArrayLockSize && /* can we use it? */ | if (max_elt < ctx->Const.MaxArrayLockSize && /* can we use it? */ | ||||
max_elt < count) /* do we want to use it? */ | max_elt < count) /* do we want to use it? */ | ||||
_tnl_draw_range_elements( ctx, mode, 0, max_elt + 1, count, ui_indices ); | |||||
_tnl_draw_range_elements( ctx, mode, 0, max_elt+1, count, ui_indices ); | |||||
else | else | ||||
_tnl_draw_elements( ctx, mode, count, ui_indices ); | _tnl_draw_elements( ctx, mode, count, ui_indices ); | ||||
} | } | ||||
#else | |||||
_tnl_draw_elements( ctx, mode, count, ui_indices ); | |||||
#endif | |||||
} | } | ||||
/* $Id: t_array_import.c,v 1.7 2001/01/24 00:04:59 brianp Exp $ */ | |||||
/* $Id: t_array_import.c,v 1.8 2001/02/15 01:33:52 keithw Exp $ */ | |||||
/* | /* | ||||
* Mesa 3-D graphics library | * Mesa 3-D graphics library | ||||
GLuint imports; | GLuint imports; | ||||
struct vertex_arrays *tmp = &tnl->array_inputs; | struct vertex_arrays *tmp = &tnl->array_inputs; | ||||
/* fprintf(stderr, "_tnl_vb_bind_arrays %d..%d // %d..%d\n", */ | |||||
/* start, count, ctx->Array.LockFirst, ctx->Array.LockCount); */ | |||||
if (ctx->Array.LockCount) { | if (ctx->Array.LockCount) { | ||||
ASSERT(start == ctx->Array.LockFirst); | ASSERT(start == ctx->Array.LockFirst); | ||||
ASSERT(count == ctx->Array.LockCount); | ASSERT(count == ctx->Array.LockCount); |
/* $Id: t_context.h,v 1.13 2001/01/29 20:47:39 keithw Exp $ */ | |||||
/* $Id: t_context.h,v 1.14 2001/02/15 01:33:52 keithw Exp $ */ | |||||
/* | /* | ||||
* Mesa 3-D graphics library | * Mesa 3-D graphics library | ||||
*/ | */ | ||||
struct gl_material (*Material)[2]; | struct gl_material (*Material)[2]; | ||||
GLuint *MaterialMask; | GLuint *MaterialMask; | ||||
GLfloat *NormalLengths; | |||||
GLuint LastMaterial; | |||||
GLuint MaterialOrMask; | |||||
GLfloat (*TexCoord[MAX_TEXTURE_UNITS])[4]; | GLfloat (*TexCoord[MAX_TEXTURE_UNITS])[4]; | ||||
GLuint Primitive[IMM_SIZE]; /* BEGIN/END */ | GLuint Primitive[IMM_SIZE]; /* BEGIN/END */ | ||||
GLubyte ClipOrMask; /* VERT_CLIP (3) */ | GLubyte ClipOrMask; /* VERT_CLIP (3) */ | ||||
GLubyte *ClipMask; /* VERT_CLIP (4) */ | GLubyte *ClipMask; /* VERT_CLIP (4) */ | ||||
GLvector3f *NormalPtr; /* VERT_NORM */ | GLvector3f *NormalPtr; /* VERT_NORM */ | ||||
GLfloat *NormalLengthPtr; /* VERT_NORM (optional) */ | |||||
GLboolean *EdgeFlag; /* VERT_EDGE */ | GLboolean *EdgeFlag; /* VERT_EDGE */ | ||||
GLvector4f *TexCoordPtr[MAX_TEXTURE_UNITS]; /* VERT_TEX_0..n */ | GLvector4f *TexCoordPtr[MAX_TEXTURE_UNITS]; /* VERT_TEX_0..n */ | ||||
GLvector1ui *IndexPtr[2]; /* VERT_INDEX */ | GLvector1ui *IndexPtr[2]; /* VERT_INDEX */ |
/* $Id: t_imm_alloc.c,v 1.2 2000/12/28 22:11:05 keithw Exp $ */ | |||||
/* $Id: t_imm_alloc.c,v 1.3 2001/02/15 01:33:52 keithw Exp $ */ | |||||
/* | /* | ||||
* Mesa 3-D graphics library | * Mesa 3-D graphics library | ||||
IM->id = id++; | IM->id = id++; | ||||
IM->ref_count = 0; | IM->ref_count = 0; | ||||
IM->backref = ctx; | IM->backref = ctx; | ||||
IM->NormalLengths = 0; | |||||
IM->FlushElt = 0; | IM->FlushElt = 0; | ||||
IM->LastPrimitive = IMM_MAX_COPIED_VERTS; | IM->LastPrimitive = IMM_MAX_COPIED_VERTS; | ||||
IM->Count = IMM_MAX_COPIED_VERTS; | IM->Count = IMM_MAX_COPIED_VERTS; | ||||
static int freed = 0; | static int freed = 0; | ||||
GLuint j; | GLuint j; | ||||
if (IM->NormalLengths) { | |||||
FREE( IM->NormalLengths ); | |||||
IM->NormalLengths = 0; | |||||
} | |||||
if (IM->Material) { | if (IM->Material) { | ||||
FREE( IM->Material ); | FREE( IM->Material ); | ||||
FREE( IM->MaterialMask ); | FREE( IM->MaterialMask ); |
if (bitmask == 0) | if (bitmask == 0) | ||||
return; | return; | ||||
if (!IM->Material) { | |||||
IM->Material = (GLmaterial (*)[2]) MALLOC( sizeof(GLmaterial) * | |||||
IMM_SIZE * 2 ); | |||||
IM->MaterialMask = (GLuint *) MALLOC( sizeof(GLuint) * IMM_SIZE ); | |||||
} | |||||
if (!(IM->Flag[count] & VERT_MATERIAL)) { | if (!(IM->Flag[count] & VERT_MATERIAL)) { | ||||
if (!IM->Material) { | |||||
IM->Material = (GLmaterial (*)[2]) MALLOC( sizeof(GLmaterial) * | |||||
IMM_SIZE * 2 ); | |||||
IM->MaterialMask = (GLuint *) MALLOC( sizeof(GLuint) * IMM_SIZE ); | |||||
} | |||||
else if (IM->MaterialOrMask & ~bitmask) { | |||||
gl_copy_material_pairs( IM->Material[count], | |||||
IM->Material[IM->LastMaterial], | |||||
IM->MaterialOrMask & ~bitmask ); | |||||
} | |||||
IM->Flag[count] |= VERT_MATERIAL; | IM->Flag[count] |= VERT_MATERIAL; | ||||
IM->LastMaterial = count; | |||||
IM->MaterialMask[count] = 0; | IM->MaterialMask[count] = 0; | ||||
} | } | ||||
IM->MaterialOrMask |= bitmask; | |||||
IM->MaterialMask[count] |= bitmask; | IM->MaterialMask[count] |= bitmask; | ||||
mat = IM->Material[count]; | mat = IM->Material[count]; | ||||
/* $Id: t_imm_dlist.c,v 1.7 2001/02/13 23:51:34 brianp Exp $ */ | |||||
/* $Id: t_imm_dlist.c,v 1.8 2001/02/15 01:33:52 keithw Exp $ */ | |||||
/* | /* | ||||
* Mesa 3-D graphics library | * Mesa 3-D graphics library | ||||
GLuint TexSize; | GLuint TexSize; | ||||
GLuint LastData; | GLuint LastData; | ||||
GLuint LastPrimitive; | GLuint LastPrimitive; | ||||
GLboolean have_normal_lengths; | |||||
GLuint LastMaterial; | |||||
GLuint MaterialOrMask; | |||||
} TNLvertexcassette; | } TNLvertexcassette; | ||||
static void execute_compiled_cassette( GLcontext *ctx, void *data ); | static void execute_compiled_cassette( GLcontext *ctx, void *data ); | ||||
node->AndFlag = im->AndFlag; | node->AndFlag = im->AndFlag; | ||||
node->LastData = im->LastData; | node->LastData = im->LastData; | ||||
node->LastPrimitive = im->LastPrimitive; | node->LastPrimitive = im->LastPrimitive; | ||||
node->have_normal_lengths = GL_FALSE; | |||||
node->LastMaterial = im->LastMaterial; | |||||
node->MaterialOrMask = im->MaterialOrMask; | |||||
if (ctx->ExecuteFlag) { | if (ctx->ExecuteFlag) { | ||||
execute_compiled_cassette( ctx, (void *)node ); | execute_compiled_cassette( ctx, (void *)node ); | ||||
} | } | ||||
#if 0 | |||||
/* Drivers to turn this on? | |||||
*/ | |||||
static void calc_normal_lengths( GLfloat *dest, | |||||
CONST GLfloat (*data)[3], | |||||
GLuint *flags, | |||||
GLuint count ) | |||||
{ | |||||
GLuint i; | |||||
GLint tmpflag = flags[0]; | |||||
flags[0] |= VERT_NORM; | |||||
for (i = 0 ; i < count ; i++ ) | |||||
if (flags[i] & VERT_NORM) { | |||||
GLfloat tmp = (GLfloat) LEN_3FV( data[i] ); | |||||
dest[i] = 0; | |||||
if (tmp > 0) | |||||
dest[i] = 1.0F / tmp; | |||||
} else | |||||
dest[i] = dest[i-1]; | |||||
flags[0] = tmpflag; | |||||
} | |||||
#endif | |||||
static void | static void | ||||
execute_compiled_cassette( GLcontext *ctx, void *data ) | execute_compiled_cassette( GLcontext *ctx, void *data ) | ||||
{ | { | ||||
} | } | ||||
if (IM->Count == IM->Start) { | if (IM->Count == IM->Start) { | ||||
_tnl_run_empty_cassette( ctx, IM ); | |||||
_tnl_copy_to_current( ctx, IM, IM->OrFlag ); | |||||
return; | return; | ||||
} | } | ||||
if (ctx->Driver.CurrentExecPrimitive == GL_POLYGON+1) | if (ctx->Driver.CurrentExecPrimitive == GL_POLYGON+1) | ||||
tnl->ReplayHardBeginEnd = 1; | tnl->ReplayHardBeginEnd = 1; | ||||
if (!tnl->ReplayHardBeginEnd) { | if (!tnl->ReplayHardBeginEnd) { | ||||
/* XXX is this really an OpenGL error or an implementation problem? */ | |||||
/* This is a user error. Whatever operation (like glRectf) | |||||
* decomposed to this hard begin/end pair is now being run | |||||
* inside a begin/end object -- illegally. Reject it and | |||||
* raise an error. | |||||
*/ | |||||
gl_error(ctx, GL_INVALID_OPERATION, "hard replay"); | gl_error(ctx, GL_INVALID_OPERATION, "hard replay"); | ||||
return; | return; | ||||
} | } | ||||
} | } | ||||
/* Lazy optimization of the cassette. Need to make these switchable | |||||
* or otherwise more useful for t&l cards. | |||||
*/ | |||||
#if 0 | |||||
if (ctx->Transform.Normalize && !node->have_normal_lengths) { | |||||
if (!IM->NormalLengths) | |||||
IM->NormalLengths = (GLfloat *)MALLOC(sizeof(GLfloat) * IMM_SIZE); | |||||
calc_normal_lengths( IM->NormalLengths + IM->Start, | |||||
(const GLfloat (*)[3])(IM->Normal + IM->Start), | |||||
IM->Flag + IM->Start, | |||||
IM->Count - IM->Start); | |||||
node->have_normal_lengths = GL_TRUE; | |||||
} | |||||
#endif | |||||
#if 0 | |||||
if (0 && im->v.Obj.size < 4 && im->Count > 15) { | |||||
im->Bounds = (GLfloat (*)[3]) MALLOC(6 * sizeof(GLfloat)); | |||||
(_tnl_calc_bound_tab[im->v.Obj.size])( im->Bounds, &im->v.Obj ); | |||||
} | |||||
#endif | |||||
_tnl_fixup_compiled_cassette( ctx, IM ); | _tnl_fixup_compiled_cassette( ctx, IM ); | ||||
_tnl_get_exec_copy_verts( ctx, IM ); | _tnl_get_exec_copy_verts( ctx, IM ); | ||||
_tnl_run_cassette( ctx, IM ); | _tnl_run_cassette( ctx, IM ); | ||||
{ | { | ||||
TNLvertexcassette *node = (TNLvertexcassette *)data; | TNLvertexcassette *node = (TNLvertexcassette *)data; | ||||
/* fprintf(stderr, "destroy_compiled_cassette node->IM id %d ref_count: %d\n", */ | |||||
/* node->IM->id, */ | |||||
/* node->IM->ref_count-1); */ | |||||
if ( --node->IM->ref_count == 0 ) | if ( --node->IM->ref_count == 0 ) | ||||
_tnl_free_immediate( node->IM ); | _tnl_free_immediate( node->IM ); | ||||
} | } | ||||
IM->AndFlag = node->AndFlag; | IM->AndFlag = node->AndFlag; | ||||
IM->LastData = node->LastData; | IM->LastData = node->LastData; | ||||
IM->LastPrimitive = node->LastPrimitive; | IM->LastPrimitive = node->LastPrimitive; | ||||
IM->LastMaterial = node->LastMaterial; | |||||
IM->MaterialOrMask = node->MaterialOrMask; | |||||
_tnl_print_cassette( node->IM ); | _tnl_print_cassette( node->IM ); | ||||
} | } | ||||
tnl->ExecCopySource = IM; | tnl->ExecCopySource = IM; | ||||
IM->ref_count++; | IM->ref_count++; | ||||
SET_IMMEDIATE( ctx, IM ); | SET_IMMEDIATE( ctx, IM ); | ||||
IM->ref_count++; | IM->ref_count++; | ||||
/* $Id: t_imm_exec.c,v 1.10 2001/02/06 21:42:49 brianp Exp $ */ | |||||
/* $Id: t_imm_exec.c,v 1.11 2001/02/15 01:33:52 keithw Exp $ */ | |||||
/* | /* | ||||
* Mesa 3-D graphics library | * Mesa 3-D graphics library | ||||
static void copy_to_current( GLcontext *ctx, struct immediate *IM, | |||||
GLuint flag ) | |||||
void _tnl_copy_to_current( GLcontext *ctx, struct immediate *IM, | |||||
GLuint flag ) | |||||
{ | { | ||||
GLuint count = IM->LastData; | GLuint count = IM->LastData; | ||||
if (flag & VERT_EDGE) | if (flag & VERT_EDGE) | ||||
ctx->Current.EdgeFlag = IM->EdgeFlag[count]; | ctx->Current.EdgeFlag = IM->EdgeFlag[count]; | ||||
if (flag & VERT_RGBA) | |||||
if (flag & VERT_RGBA) { | |||||
COPY_4UBV(ctx->Current.Color, IM->Color[count]); | COPY_4UBV(ctx->Current.Color, IM->Color[count]); | ||||
if (ctx->Light.ColorMaterialEnabled) { | |||||
gl_update_color_material( ctx, ctx->Current.Color ); | |||||
gl_validate_all_lighting_tables( ctx ); | |||||
} | |||||
} | |||||
if (flag & VERT_SPEC_RGB) | if (flag & VERT_SPEC_RGB) | ||||
COPY_4UBV(ctx->Current.SecondaryColor, IM->SecondaryColor[count]); | COPY_4UBV(ctx->Current.SecondaryColor, IM->SecondaryColor[count]); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
if (flag & VERT_MATERIAL) { | |||||
gl_update_material( ctx, | |||||
IM->Material[IM->LastMaterial], | |||||
IM->MaterialOrMask ); | |||||
gl_validate_all_lighting_tables( ctx ); | |||||
} | |||||
} | } | ||||
/* It is possible there will be data in the buffer arising from | /* It is possible there will be data in the buffer arising from | ||||
* calls like 'glNormal', 'glMaterial' that occur after the final | * calls like 'glNormal', 'glMaterial' that occur after the final | ||||
* glVertex, glEval, etc. Additionally, a buffer can consist of | * glVertex, glEval, etc. Additionally, a buffer can consist of | ||||
* only a single glMaterial call, in which case IM->Start == | |||||
* IM->Count, but the buffer is definitely not empty. | |||||
* eg. a single glMaterial call, in which case IM->Start == | |||||
* IM->Count, but the buffer is definitely not empty. | |||||
*/ | */ | ||||
if (IM->Flag[i] & VERT_DATA) { | if (IM->Flag[i] & VERT_DATA) { | ||||
IM->LastData++; | IM->LastData++; | ||||
/* TexCoordPtr's are zeroed in loop below. | /* TexCoordPtr's are zeroed in loop below. | ||||
*/ | */ | ||||
VB->NormalPtr = 0; | VB->NormalPtr = 0; | ||||
VB->NormalLengthPtr = 0; | |||||
VB->FogCoordPtr = 0; | VB->FogCoordPtr = 0; | ||||
VB->EdgeFlag = 0; | VB->EdgeFlag = 0; | ||||
VB->IndexPtr[0] = 0; | VB->IndexPtr[0] = 0; | ||||
tmp->Normal.start = (GLfloat *)(IM->Normal + start); | tmp->Normal.start = (GLfloat *)(IM->Normal + start); | ||||
tmp->Normal.count = count; | tmp->Normal.count = count; | ||||
VB->NormalPtr = &tmp->Normal; | VB->NormalPtr = &tmp->Normal; | ||||
if (IM->NormalLengths) | |||||
VB->NormalLengthPtr = IM->NormalLengths + start; | |||||
} | } | ||||
if (inputs & VERT_INDEX) { | if (inputs & VERT_INDEX) { | ||||
_tnl_run_pipeline( ctx ); | _tnl_run_pipeline( ctx ); | ||||
tnl->pipeline.run_input_changes |= tnl->pipeline.inputs; | tnl->pipeline.run_input_changes |= tnl->pipeline.inputs; | ||||
copy_to_current( ctx, IM, IM->OrFlag ); | |||||
_tnl_copy_to_current( ctx, IM, IM->OrFlag ); | |||||
} | } | ||||
*/ | */ | ||||
if (ctx->Driver.CurrentExecPrimitive == GL_POLYGON+1) { | if (ctx->Driver.CurrentExecPrimitive == GL_POLYGON+1) { | ||||
_tnl_translate_array_elts( ctx, IM, IM->LastData, IM->LastData ); | _tnl_translate_array_elts( ctx, IM, IM->LastData, IM->LastData ); | ||||
copy_to_current( ctx, IM, ctx->Array._Enabled ); | |||||
_tnl_copy_to_current( ctx, IM, ctx->Array._Enabled ); | |||||
} | } | ||||
} | } | ||||
/* Called for cassettes where CopyStart == Count -- no need to run the | |||||
* pipeline. | |||||
*/ | |||||
void _tnl_run_empty_cassette( GLcontext *ctx, struct immediate *IM ) | |||||
{ | |||||
copy_to_current( ctx, IM, IM->OrFlag ); | |||||
if (IM->OrFlag & (VERT_RGBA|VERT_MATERIAL)) { | |||||
GLuint start = IM->CopyStart; | |||||
if (IM->OrFlag & VERT_MATERIAL) | |||||
gl_update_material( ctx, IM->Material[start], | |||||
IM->MaterialMask[start] ); | |||||
if (IM->OrFlag & VERT_RGBA) | |||||
if (ctx->Light.ColorMaterialEnabled) | |||||
gl_update_color_material( ctx, ctx->Current.Color ); | |||||
gl_validate_all_lighting_tables( ctx ); | |||||
} | |||||
} | |||||
/* Called for regular vertex cassettes. | /* Called for regular vertex cassettes. | ||||
_tnl_compute_orflag( IM ); | _tnl_compute_orflag( IM ); | ||||
/* _tnl_print_cassette( IM ); */ | |||||
/* Mark the last primitive: | /* Mark the last primitive: | ||||
*/ | */ | ||||
IM->PrimitiveLength[IM->LastPrimitive] = IM->Count - IM->LastPrimitive; | IM->PrimitiveLength[IM->LastPrimitive] = IM->Count - IM->LastPrimitive; | ||||
ASSERT(IM->Primitive[IM->LastPrimitive] & PRIM_LAST); | ASSERT(IM->Primitive[IM->LastPrimitive] & PRIM_LAST); | ||||
if (tnl->pipeline.build_state_changes) | if (tnl->pipeline.build_state_changes) | ||||
_tnl_validate_pipeline( ctx ); | _tnl_validate_pipeline( ctx ); | ||||
if (IM->OrFlag & VERT_ELT) | if (IM->OrFlag & VERT_ELT) | ||||
_tnl_translate_array_elts( ctx, IM, IM->CopyStart, IM->CopyStart ); | _tnl_translate_array_elts( ctx, IM, IM->CopyStart, IM->CopyStart ); | ||||
_tnl_fixup_input( ctx, IM ); /* shouldn't be needed? (demos/fire) */ | |||||
_tnl_run_empty_cassette( ctx, IM ); | |||||
_tnl_copy_to_current( ctx, IM, IM->OrFlag ); | |||||
} | } | ||||
else if ((IM->OrFlag & VERT_DATA) == VERT_ELT && | else if ((IM->OrFlag & VERT_DATA) == VERT_ELT && | ||||
ctx->Array.LockCount && | ctx->Array.LockCount && |
/* $Id: t_imm_exec.h,v 1.2 2000/12/27 21:49:40 keithw Exp $ */ | |||||
/* $Id: t_imm_exec.h,v 1.3 2001/02/15 01:33:52 keithw Exp $ */ | |||||
/* | /* | ||||
* Mesa 3-D graphics library | * Mesa 3-D graphics library | ||||
/* Called from imm_dlist.c and _tnl_flush_immediate: | /* Called from imm_dlist.c and _tnl_flush_immediate: | ||||
*/ | */ | ||||
extern void _tnl_run_cassette( GLcontext *ctx, struct immediate *IM ); | extern void _tnl_run_cassette( GLcontext *ctx, struct immediate *IM ); | ||||
extern void _tnl_run_empty_cassette( GLcontext *ctx, struct immediate *IM ); | |||||
extern void _tnl_copy_to_current( GLcontext *ctx, struct immediate *IM, | |||||
GLuint flag ); | |||||
/* Initialize some stuff: | /* Initialize some stuff: | ||||
*/ | */ | ||||
extern void _tnl_execute_cassette( GLcontext *ctx, struct immediate *IM ); | extern void _tnl_execute_cassette( GLcontext *ctx, struct immediate *IM ); | ||||
#endif | #endif |
/* $Id: t_imm_fixup.c,v 1.6 2001/02/13 23:51:34 brianp Exp $ */ | |||||
/* $Id: t_imm_fixup.c,v 1.7 2001/02/15 01:33:52 keithw Exp $ */ | |||||
/* | /* | ||||
* Mesa 3-D graphics library | * Mesa 3-D graphics library | ||||
next->CopyAndFlag &= prev->Flag[src]; /* redundant for current_im */ | next->CopyAndFlag &= prev->Flag[src]; /* redundant for current_im */ | ||||
} | } | ||||
/* Only needed when copying to a compiled cassette | |||||
*/ | |||||
if (next->NormalLengths) { | |||||
for (i = 0 ; i < count ; i++) | |||||
{ | |||||
GLuint src = elts[i+offset]; | |||||
GLuint dst = next->CopyStart+i; | |||||
if (prev->NormalLengths) | |||||
next->NormalLengths[dst] = prev->NormalLengths[src]; | |||||
else | |||||
next->NormalLengths[dst] = 1.0/LEN_3FV(prev->Normal[src]); | |||||
} | |||||
} | |||||
ASSERT(prev == tnl->ExecCopySource); | ASSERT(prev == tnl->ExecCopySource); | ||||
if (fixup & VERT_NORM) { | if (fixup & VERT_NORM) { | ||||
fixup_first_3f(IM->Normal, IM->Flag, VERT_NORM, start, | fixup_first_3f(IM->Normal, IM->Flag, VERT_NORM, start, | ||||
ctx->Current.Normal ); | ctx->Current.Normal ); | ||||
if (IM->NormalLengths) | |||||
fixup_first_1f(IM->NormalLengths, IM->Flag, VERT_NORM, start, | |||||
1.0F / (GLfloat) LEN_3FV(ctx->Current.Normal) ); | |||||
} | } | ||||
} | } | ||||
/* $Id: t_pipeline.c,v 1.11 2001/01/29 20:47:39 keithw Exp $ */ | |||||
/* $Id: t_pipeline.c,v 1.12 2001/02/15 01:33:52 keithw Exp $ */ | |||||
/* | /* | ||||
* Mesa 3-D graphics library | * Mesa 3-D graphics library | ||||
ASSERT(pipe->build_state_changes == 0); | ASSERT(pipe->build_state_changes == 0); | ||||
START_FAST_MATH(__tmp); | START_FAST_MATH(__tmp); | ||||
if (ctx->Driver.PipelineStart) | |||||
ctx->Driver.PipelineStart( ctx ); | |||||
/* If something changes in the pipeline, tag all subsequent stages | /* If something changes in the pipeline, tag all subsequent stages | ||||
* using this value for recalculation. | * using this value for recalculation. | ||||
} | } | ||||
} | } | ||||
} | } | ||||
if (ctx->Driver.PipelineFinish) | |||||
ctx->Driver.PipelineFinish( ctx ); | |||||
END_FAST_MATH(__tmp); | END_FAST_MATH(__tmp); | ||||
pipe->run_state_changes = 0; | pipe->run_state_changes = 0; |
/* $Id: t_vb_normals.c,v 1.2 2000/12/27 19:57:37 keithw Exp $ */ | |||||
/* $Id: t_vb_normals.c,v 1.3 2001/02/15 01:33:52 keithw Exp $ */ | |||||
/* | /* | ||||
* Mesa 3-D graphics library | * Mesa 3-D graphics library | ||||
ASSERT(store->NormalTransform); | ASSERT(store->NormalTransform); | ||||
if (VB->NormalLengthPtr) { | |||||
GLfloat diff = VB->NormalLengthPtr[0] - | |||||
1.0/LEN_3FV(VB->NormalPtr->data[0]); | |||||
(void)diff; | |||||
ASSERT((diff*diff) < .01); | |||||
} | |||||
if (stage->changed_inputs) | if (stage->changed_inputs) | ||||
(store->NormalTransform[0])(&ctx->ModelView, | (store->NormalTransform[0])(&ctx->ModelView, | ||||
ctx->_ModelViewInvScale, | ctx->_ModelViewInvScale, | ||||
VB->NormalPtr, | VB->NormalPtr, | ||||
VB->NormalLengthPtr, | |||||
0, | |||||
0, | 0, | ||||
&store->normal); | &store->normal); | ||||