gl_mesh ein weiteres Mal aufgeräumt

This commit is contained in:
Yamagi Burmeister 2010-10-21 08:04:45 +00:00
parent 88ecb77a51
commit b8526fe6ae

View file

@ -1,63 +1,56 @@
/* $Id: gl_mesh.c,v 1.3 2002/09/25 13:22:55 bburns Exp $
*
* triangle model functions
*
/*
* Copyright (C) 1997-2001 Id Software, Inc.
* Copyright (c) 2002 The Quakeforge Project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* =======================================================================
*
* Mesh handling
*
* =======================================================================
*/
#include "header/local.h"
/*
=============================================================
ALIAS MODELS
=============================================================
*/
#define NUMVERTEXNORMALS 162
#define SHADEDOT_QUANT 16
float r_avertexnormals [ NUMVERTEXNORMALS ] [ 3 ] = {
#include "constants/anorms.h"
};
typedef float vec4_t[4];
static vec4_t s_lerped[MAX_VERTS];
//static vec3_t lerped[MAX_VERTS];
vec3_t shadevector;
float shadelight[3];
// precalculated dot products for quantized angles
#define SHADEDOT_QUANT 16
/* precalculated dot products for quantized angles */
float r_avertexnormal_dots [ SHADEDOT_QUANT ] [ 256 ] =
#include "constants/anormtab.h"
;
typedef float vec4_t [ 4 ];
static vec4_t s_lerped [ MAX_VERTS ];
vec3_t shadevector;
float shadelight [ 3 ];
float *shadedots = r_avertexnormal_dots [ 0 ];
extern vec3_t lightspot;
extern qboolean have_stencil;
void GL_LerpVerts( int nverts, dtrivertx_t *v, dtrivertx_t *ov, dtrivertx_t *verts, float *lerp, float move[3], float frontv[3], float backv[3] )
void
GL_LerpVerts ( int nverts, dtrivertx_t *v, dtrivertx_t *ov, dtrivertx_t *verts, float *lerp, float move [ 3 ], float frontv [ 3 ], float backv [ 3 ] )
{
int i;
//PMM -- added RF_SHELL_DOUBLE, RF_SHELL_HALF_DAM
if ( currententity->flags & ( RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE | RF_SHELL_DOUBLE | RF_SHELL_HALF_DAM ) )
{
for ( i = 0; i < nverts; i++, v++, ov++, lerp += 4 )
@ -78,18 +71,13 @@ void GL_LerpVerts( int nverts, dtrivertx_t *v, dtrivertx_t *ov, dtrivertx_t *ver
lerp [ 2 ] = move [ 2 ] + ov->v [ 2 ] * backv [ 2 ] + v->v [ 2 ] * frontv [ 2 ];
}
}
}
/*
=============
GL_DrawAliasFrameLerp
interpolates between two frames and origins
FIXME: batch lerp all vertexes
=============
* Interpolates between two frames and origins
*/
void GL_DrawAliasFrameLerp (dmdl_t *paliashdr, float backlerp)
void
GL_DrawAliasFrameLerp ( dmdl_t *paliashdr, float backlerp )
{
float l;
daliasframe_t *frame, *oldframe;
@ -115,23 +103,28 @@ void GL_DrawAliasFrameLerp (dmdl_t *paliashdr, float backlerp)
order = (int *) ( (byte *) paliashdr + paliashdr->ofs_glcmds );
if ( currententity->flags & RF_TRANSLUCENT )
{
alpha = currententity->alpha;
}
else
{
alpha = 1.0;
}
// PMM - added double shell
if ( currententity->flags & ( RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE | RF_SHELL_DOUBLE | RF_SHELL_HALF_DAM ) )
{
qglDisable( GL_TEXTURE_2D );
}
frontlerp = 1.0 - backlerp;
// move should be the delta back to the previous frame * backlerp
/* move should be the delta back to the previous frame * backlerp */
VectorSubtract( currententity->oldorigin, currententity->origin, delta );
AngleVectors( currententity->angles, vectors [ 0 ], vectors [ 1 ], vectors [ 2 ] );
move[0] = DotProduct (delta, vectors[0]); // forward
move[1] = -DotProduct (delta, vectors[1]); // left
move[2] = DotProduct (delta, vectors[2]); // up
move [ 0 ] = DotProduct( delta, vectors [ 0 ] ); /* forward */
move [ 1 ] = -DotProduct( delta, vectors [ 1 ] ); /* left */
move [ 2 ] = DotProduct( delta, vectors [ 2 ] ); /* up */
VectorAdd( move, oldframe->translate, move );
@ -155,9 +148,8 @@ void GL_DrawAliasFrameLerp (dmdl_t *paliashdr, float backlerp)
float colorArray [ MAX_VERTS * 4 ];
qglEnableClientState( GL_VERTEX_ARRAY );
qglVertexPointer( 3, GL_FLOAT, 16, s_lerped ); // padded for SIMD
qglVertexPointer( 3, GL_FLOAT, 16, s_lerped );
// PMM - added double damage shell
if ( currententity->flags & ( RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE | RF_SHELL_DOUBLE | RF_SHELL_HALF_DAM ) )
{
qglColor4f( shadelight [ 0 ], shadelight [ 1 ], shadelight [ 2 ], alpha );
@ -167,9 +159,7 @@ void GL_DrawAliasFrameLerp (dmdl_t *paliashdr, float backlerp)
qglEnableClientState( GL_COLOR_ARRAY );
qglColorPointer( 3, GL_FLOAT, 0, colorArray );
//
// pre light everything
//
/* pre light everything */
for ( i = 0; i < paliashdr->num_xyz; i++ )
{
float l = shadedots [ verts [ i ].lightnormalindex ];
@ -181,14 +171,20 @@ void GL_DrawAliasFrameLerp (dmdl_t *paliashdr, float backlerp)
}
if ( qglLockArraysEXT != 0 )
{
qglLockArraysEXT( 0, paliashdr->num_xyz );
}
while ( 1 )
{
// get the vertex count and primitive type
/* get the vertex count and primitive type */
count = *order++;
if ( !count )
break; // done
{
break; /* done */
}
if ( count < 0 )
{
count = -count;
@ -199,7 +195,6 @@ void GL_DrawAliasFrameLerp (dmdl_t *paliashdr, float backlerp)
qglBegin( GL_TRIANGLE_STRIP );
}
// PMM - added double damage shell
if ( currententity->flags & ( RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE | RF_SHELL_DOUBLE | RF_SHELL_HALF_DAM ) )
{
do
@ -208,37 +203,44 @@ void GL_DrawAliasFrameLerp (dmdl_t *paliashdr, float backlerp)
order += 3;
qglVertex3fv( s_lerped [ index_xyz ] );
} while (--count);
}
while ( --count );
}
else
{
do
{
// texture coordinates come from the draw list
/* texture coordinates come from the draw list */
qglTexCoord2f( ( (float *) order ) [ 0 ], ( (float *) order ) [ 1 ] );
index_xyz = order [ 2 ];
order += 3;
qglArrayElement( index_xyz );
} while (--count);
}
while ( --count );
}
qglEnd();
}
if ( qglUnlockArraysEXT != 0 )
{
qglUnlockArraysEXT();
}
}
else
{
while ( 1 )
{
// get the vertex count and primitive type
/* get the vertex count and primitive type */
count = *order++;
if ( !count )
break; // done
{
break; /* done */
}
if ( count < 0 )
{
count = -count;
@ -258,46 +260,39 @@ void GL_DrawAliasFrameLerp (dmdl_t *paliashdr, float backlerp)
qglColor4f( shadelight [ 0 ], shadelight [ 1 ], shadelight [ 2 ], alpha );
qglVertex3fv( s_lerped [ index_xyz ] );
} while (--count);
}
while ( --count );
}
else
{
do
{
// texture coordinates come from the draw list
/* texture coordinates come from the draw list */
qglTexCoord2f( ( (float *) order ) [ 0 ], ( (float *) order ) [ 1 ] );
index_xyz = order [ 2 ];
order += 3;
// normals and vertexes come from the frame list
/* normals and vertexes come from the frame list */
l = shadedots [ verts [ index_xyz ].lightnormalindex ];
qglColor4f( l * shadelight [ 0 ], l * shadelight [ 1 ], l * shadelight [ 2 ], alpha );
qglVertex3fv( s_lerped [ index_xyz ] );
} while (--count);
}
while ( --count );
}
qglEnd();
}
}
// PMM - added double damage shell
if ( currententity->flags & ( RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE | RF_SHELL_DOUBLE | RF_SHELL_HALF_DAM ) )
{
qglEnable( GL_TEXTURE_2D );
}
}
/*
=============
GL_DrawAliasShadow
=============
*/
extern vec3_t lightspot;
/* stencilbuffer shadows */
extern qboolean have_stencil;
void GL_DrawAliasShadow (dmdl_t *paliashdr, int posenum)
void
GL_DrawAliasShadow ( dmdl_t *paliashdr, int posenum )
{
dtrivertx_t *verts;
int *order;
@ -319,7 +314,8 @@ void GL_DrawAliasShadow (dmdl_t *paliashdr, int posenum)
height = -lheight + 0.1f;
/* stencilbuffer shadows */
if (have_stencil && gl_stencilshadow->value) {
if ( have_stencil && gl_stencilshadow->value )
{
qglEnable( GL_STENCIL_TEST );
qglStencilFunc( GL_EQUAL, 1, 2 );
qglStencilOp( GL_KEEP, GL_KEEP, GL_INCR );
@ -327,21 +323,27 @@ void GL_DrawAliasShadow (dmdl_t *paliashdr, int posenum)
while ( 1 )
{
// get the vertex count and primitive type
/* get the vertex count and primitive type */
count = *order++;
if ( !count )
break; // done
{
break; /* done */
}
if ( count < 0 )
{
count = -count;
qglBegin( GL_TRIANGLE_FAN );
}
else
{
qglBegin( GL_TRIANGLE_STRIP );
}
do
{
// normals and vertexes come from the frame list
/* normals and vertexes come from the frame list */
memcpy( point, s_lerped [ order [ 2 ] ], sizeof ( point ) );
point [ 0 ] -= shadevector [ 0 ] * ( point [ 2 ] + lheight );
@ -350,20 +352,21 @@ void GL_DrawAliasShadow (dmdl_t *paliashdr, int posenum)
qglVertex3fv( point );
order += 3;
} while (--count);
}
while ( --count );
qglEnd();
}
/* stencilbuffer shadows */
if ( have_stencil && gl_stencilshadow->value )
{
qglDisable( GL_STENCIL_TEST );
}
}
/*
** R_CullAliasModel
*/
static qboolean R_CullAliasModel( vec3_t bbox[8], entity_t *e )
static qboolean
R_CullAliasModel ( vec3_t bbox [ 8 ], entity_t *e )
{
int i;
vec3_t mins, maxs;
@ -381,6 +384,7 @@ static qboolean R_CullAliasModel( vec3_t bbox[8], entity_t *e )
currentmodel->name, e->frame );
e->frame = 0;
}
if ( ( e->oldframe >= paliashdr->num_frames ) || ( e->oldframe < 0 ) )
{
ri.Con_Printf( PRINT_ALL, "R_CullAliasModel %s: no such oldframe %d\n",
@ -396,9 +400,7 @@ static qboolean R_CullAliasModel( vec3_t bbox[8], entity_t *e )
paliashdr->ofs_frames +
e->oldframe * paliashdr->framesize );
/*
** compute axially aligned mins and maxs
*/
/* compute axially aligned mins and maxs */
if ( pframe == poldframe )
{
for ( i = 0; i < 3; i++ )
@ -418,45 +420,61 @@ static qboolean R_CullAliasModel( vec3_t bbox[8], entity_t *e )
oldmaxs [ i ] = oldmins [ i ] + poldframe->scale [ i ] * 255;
if ( thismins [ i ] < oldmins [ i ] )
{
mins [ i ] = thismins [ i ];
}
else
{
mins [ i ] = oldmins [ i ];
}
if ( thismaxs [ i ] > oldmaxs [ i ] )
{
maxs [ i ] = thismaxs [ i ];
}
else
{
maxs [ i ] = oldmaxs [ i ];
}
}
}
/*
** compute a full bounding box
*/
/* compute a full bounding box */
for ( i = 0; i < 8; i++ )
{
vec3_t tmp;
if ( i & 1 )
{
tmp [ 0 ] = mins [ 0 ];
}
else
{
tmp [ 0 ] = maxs [ 0 ];
}
if ( i & 2 )
{
tmp [ 1 ] = mins [ 1 ];
}
else
{
tmp [ 1 ] = maxs [ 1 ];
}
if ( i & 4 )
{
tmp [ 2 ] = mins [ 2 ];
}
else
{
tmp [ 2 ] = maxs [ 2 ];
}
VectorCopy( tmp, bbox [ i ] );
}
/*
** rotate the bounding box
*/
/* rotate the bounding box */
VectorCopy( e->angles, angles );
angles [ YAW ] = -angles [ YAW ];
AngleVectors( angles, vectors [ 0 ], vectors [ 1 ], vectors [ 2 ] );
@ -496,20 +514,15 @@ static qboolean R_CullAliasModel( vec3_t bbox[8], entity_t *e )
if ( aggregatemask )
{
return true;
return ( true );
}
return false;
return ( false );
}
}
/*
=================
R_DrawAliasModel
=================
*/
void R_DrawAliasModel (entity_t *e)
void
R_DrawAliasModel ( entity_t *e )
{
int i;
dmdl_t *paliashdr;
@ -520,74 +533,92 @@ void R_DrawAliasModel (entity_t *e)
if ( !( e->flags & RF_WEAPONMODEL ) )
{
if ( R_CullAliasModel( bbox, e ) )
{
return;
}
}
if ( e->flags & RF_WEAPONMODEL )
{
if ( r_lefthand->value == 2 )
{
return;
}
}
paliashdr = (dmdl_t *) currentmodel->extradata;
//
// get lighting information
//
// PMM - rewrote, reordered to handle new shells & mixing
// PMM - 3.20 code .. replaced with original way of doing it to keep mod authors happy
//
/* get lighting information */
if ( currententity->flags & ( RF_SHELL_HALF_DAM | RF_SHELL_GREEN | RF_SHELL_RED | RF_SHELL_BLUE | RF_SHELL_DOUBLE ) )
{
VectorClear( shadelight );
if ( currententity->flags & RF_SHELL_HALF_DAM )
{
shadelight [ 0 ] = 0.56;
shadelight [ 1 ] = 0.59;
shadelight [ 2 ] = 0.45;
}
if ( currententity->flags & RF_SHELL_DOUBLE )
{
shadelight [ 0 ] = 0.9;
shadelight [ 1 ] = 0.7;
}
if ( currententity->flags & RF_SHELL_RED )
{
shadelight [ 0 ] = 1.0;
}
if ( currententity->flags & RF_SHELL_GREEN )
{
shadelight [ 1 ] = 1.0;
}
if ( currententity->flags & RF_SHELL_BLUE )
{
shadelight [ 2 ] = 1.0;
}
}
else if ( currententity->flags & RF_FULLBRIGHT )
{
for ( i = 0; i < 3; i++ )
{
shadelight [ i ] = 1.0;
}
}
else
{
R_LightPoint( currententity->origin, shadelight );
// player lighting hack for communication back to server
// big hack!
/* player lighting hack for communication back to server */
if ( currententity->flags & RF_WEAPONMODEL )
{
// pick the greatest component, which should be the same
// as the mono value returned by software
/* pick the greatest component, which should be the same
as the mono value returned by software */
if ( shadelight [ 0 ] > shadelight [ 1 ] )
{
if ( shadelight [ 0 ] > shadelight [ 2 ] )
{
r_lightlevel->value = 150 * shadelight [ 0 ];
}
else
{
r_lightlevel->value = 150 * shadelight [ 2 ];
}
}
else
{
if ( shadelight [ 1 ] > shadelight [ 2 ] )
{
r_lightlevel->value = 150 * shadelight [ 1 ];
}
else
{
r_lightlevel->value = 150 * shadelight [ 2 ];
}
}
}
if ( gl_monolightmap->string [ 0 ] != '0' )
@ -595,9 +626,14 @@ void R_DrawAliasModel (entity_t *e)
float s = shadelight [ 0 ];
if ( s < shadelight [ 1 ] )
{
s = shadelight [ 1 ];
}
if ( s < shadelight [ 2 ] )
{
s = shadelight [ 2 ];
}
shadelight [ 0 ] = s;
shadelight [ 1 ] = s;
@ -608,8 +644,13 @@ void R_DrawAliasModel (entity_t *e)
if ( currententity->flags & RF_MINLIGHT )
{
for ( i = 0; i < 3; i++ )
{
if ( shadelight [ i ] > 0.1 )
{
break;
}
}
if ( i == 3 )
{
shadelight [ 0 ] = 0.1;
@ -619,32 +660,35 @@ void R_DrawAliasModel (entity_t *e)
}
if ( currententity->flags & RF_GLOW )
{ // bonus items will pulse with time
{
/* bonus items will pulse with time */
float scale;
float min;
scale = 0.1 * sin( r_newrefdef.time * 7 );
for ( i = 0; i < 3; i++ )
{
min = shadelight [ i ] * 0.8;
shadelight [ i ] += scale;
if ( shadelight [ i ] < min )
{
shadelight [ i ] = min;
}
}
}
// =================
// PGM ir goggles color override
/* ir goggles color override */
if ( r_newrefdef.rdflags & RDF_IRGOGGLES && currententity->flags & RF_IR_VISIBLE )
{
shadelight [ 0 ] = 1.0;
shadelight [ 1 ] = 0.0;
shadelight [ 2 ] = 0.0;
}
// PGM
// =================
shadedots = r_avertexnormal_dots[((int)(currententity->angles[1] * (SHADEDOT_QUANT / 360.0))) & (SHADEDOT_QUANT - 1)];
shadedots =
r_avertexnormal_dots [ ( (int) ( currententity->angles [ 1 ] * ( SHADEDOT_QUANT / 360.0 ) ) ) & ( SHADEDOT_QUANT - 1 ) ];
an = currententity->angles [ 1 ] / 180 * M_PI;
shadevector [ 0 ] = cos( -an );
@ -652,17 +696,14 @@ void R_DrawAliasModel (entity_t *e)
shadevector [ 2 ] = 1;
VectorNormalize( shadevector );
//
// locate the proper data
//
/* locate the proper data */
c_alias_polys += paliashdr->num_tris;
//
// draw all the triangles
//
if (currententity->flags & RF_DEPTHHACK) // hack the depth range to prevent view model from poking into walls
/* draw all the triangles */
if ( currententity->flags & RF_DEPTHHACK ) /* hack the depth range to prevent view model from poking into walls */
{
qglDepthRange( gldepthmin, gldepthmin + 0.3 * ( gldepthmax - gldepthmin ) );
}
if ( ( currententity->flags & RF_WEAPONMODEL ) && ( r_lefthand->value == 1.0F ) )
{
@ -679,41 +720,51 @@ void R_DrawAliasModel (entity_t *e)
}
qglPushMatrix();
e->angles[PITCH] = -e->angles[PITCH]; // sigh.
e->angles [ PITCH ] = -e->angles [ PITCH ];
R_RotateForEntity( e );
e->angles[PITCH] = -e->angles[PITCH]; // sigh.
e->angles [ PITCH ] = -e->angles [ PITCH ];
// select skin
/* select skin */
if ( currententity->skin )
skin = currententity->skin; // custom player skin
{
skin = currententity->skin; /* custom player skin */
}
else
{
if ( currententity->skinnum >= MAX_MD2SKINS )
{
skin = currentmodel->skins [ 0 ];
}
else
{
skin = currentmodel->skins [ currententity->skinnum ];
if ( !skin )
{
skin = currentmodel->skins [ 0 ];
}
}
}
if ( !skin )
skin = r_notexture; // fallback...
{
skin = r_notexture; /* fallback... */
}
GL_Bind( skin->texnum );
// draw it
/* draw it */
qglShadeModel( GL_SMOOTH );
GL_TexEnv( GL_MODULATE );
if ( currententity->flags & RF_TRANSLUCENT )
{
qglEnable( GL_BLEND );
}
if ( (currententity->frame >= paliashdr->num_frames)
|| (currententity->frame < 0) )
if ( ( currententity->frame >= paliashdr->num_frames ) ||
( currententity->frame < 0 ) )
{
ri.Con_Printf( PRINT_ALL, "R_DrawAliasModel %s: no such frame %d\n",
currentmodel->name, currententity->frame );
@ -721,8 +772,8 @@ void R_DrawAliasModel (entity_t *e)
currententity->oldframe = 0;
}
if ( (currententity->oldframe >= paliashdr->num_frames)
|| (currententity->oldframe < 0))
if ( ( currententity->oldframe >= paliashdr->num_frames ) ||
( currententity->oldframe < 0 ) )
{
ri.Con_Printf( PRINT_ALL, "R_DrawAliasModel %s: no such oldframe %d\n",
currentmodel->name, currententity->oldframe );
@ -731,7 +782,10 @@ void R_DrawAliasModel (entity_t *e)
}
if ( !r_lerpmodels->value )
{
currententity->backlerp = 0;
}
GL_DrawAliasFrameLerp( paliashdr, currententity->backlerp );
GL_TexEnv( GL_REPLACE );
@ -753,10 +807,13 @@ void R_DrawAliasModel (entity_t *e)
}
if ( currententity->flags & RF_DEPTHHACK )
{
qglDepthRange( gldepthmin, gldepthmax );
}
if ( gl_shadows->value &&
!(currententity->flags & (RF_TRANSLUCENT|RF_WEAPONMODEL|RF_NOSHADOW))) {
!( currententity->flags & ( RF_TRANSLUCENT | RF_WEAPONMODEL | RF_NOSHADOW ) ) )
{
qglPushMatrix();
/* don't rotate shadows on ungodly axes */
@ -771,7 +828,7 @@ void R_DrawAliasModel (entity_t *e)
qglDisable( GL_BLEND );
qglPopMatrix();
}
qglColor4f( 1, 1, 1, 1 );
}