mirror of
https://github.com/YGGverse/xash3d-fwgs.git
synced 2025-01-17 18:40:02 +00:00
Port r_studio_drawelements render
This commit is contained in:
parent
bccc0e63d5
commit
d913ef0fc4
@ -102,13 +102,22 @@ typedef struct
|
||||
vec4_t lightpos[MAXSTUDIOVERTS][MAX_LOCALLIGHTS];
|
||||
vec3_t lightbonepos[MAXSTUDIOBONES][MAX_LOCALLIGHTS];
|
||||
float locallightR2[MAX_LOCALLIGHTS];
|
||||
|
||||
// drawelements renderer
|
||||
vec3_t arrayverts[MAXSTUDIOVERTS];
|
||||
vec2_t arraycoord[MAXSTUDIOVERTS];
|
||||
unsigned short arrayelems[MAXSTUDIOVERTS*6];
|
||||
GLubyte arraycolor[MAXSTUDIOVERTS][4];
|
||||
uint numverts;
|
||||
uint numelems;
|
||||
} studio_draw_state_t;
|
||||
|
||||
// studio-related cvars
|
||||
convar_t *r_studio_sort_textures;
|
||||
convar_t *r_drawviewmodel;
|
||||
static convar_t *r_studio_sort_textures;
|
||||
static convar_t *r_drawviewmodel;
|
||||
convar_t *cl_righthand = NULL;
|
||||
convar_t *cl_himodels;
|
||||
static convar_t *cl_himodels;
|
||||
static convar_t *r_studio_drawelements;
|
||||
|
||||
static r_studio_interface_t *pStudioDraw;
|
||||
static studio_draw_state_t g_studio; // global studio state
|
||||
@ -135,6 +144,7 @@ void R_StudioInit( void )
|
||||
cl_himodels = Cvar_Get( "cl_himodels", "1", FCVAR_ARCHIVE, "draw high-resolution player models in multiplayer" );
|
||||
r_studio_sort_textures = Cvar_Get( "r_studio_sort_textures", "0", FCVAR_ARCHIVE, "change draw order for additive meshes" );
|
||||
r_drawviewmodel = Cvar_Get( "r_drawviewmodel", "1", 0, "draw firstperson weapon model" );
|
||||
r_studio_drawelements = Cvar_Get( "r_studio_drawelements", "1", FCVAR_ARCHIVE, "use glDrawElements for studiomodels" );
|
||||
|
||||
Matrix3x4_LoadIdentity( g_studio.rotationmatrix );
|
||||
Cvar_RegisterVariable( &r_glowshellfreq );
|
||||
@ -1723,7 +1733,7 @@ R_LightLambert
|
||||
|
||||
====================
|
||||
*/
|
||||
void R_LightLambert( vec4_t light[MAX_LOCALLIGHTS], vec3_t normal, vec3_t color )
|
||||
void R_LightLambert( vec4_t light[MAX_LOCALLIGHTS], vec3_t normal, vec3_t color, byte *out )
|
||||
{
|
||||
vec3_t finalLight;
|
||||
vec3_t localLight;
|
||||
@ -1761,7 +1771,53 @@ void R_LightLambert( vec4_t light[MAX_LOCALLIGHTS], vec3_t normal, vec3_t color
|
||||
}
|
||||
}
|
||||
|
||||
pglColor4f( finalLight[0], finalLight[1], finalLight[2], tr.blend );
|
||||
out[0] = finalLight[0] * 255;
|
||||
out[1] = finalLight[1] * 255;
|
||||
out[2] = finalLight[2] * 255;
|
||||
}
|
||||
|
||||
static void R_StudioSetColorBegin(short *ptricmds, vec3_t *pstudionorms )
|
||||
{
|
||||
float *lv = (float *)g_studio.lightvalues[ptricmds[1]];
|
||||
rgba_t color;
|
||||
|
||||
if( g_studio.numlocallights )
|
||||
{
|
||||
color[3] = tr.blend * 255;
|
||||
R_LightLambert( g_studio.lightpos[ptricmds[0]], pstudionorms[ptricmds[1]], lv, color );
|
||||
pglColor4ubv( color );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( RI.currententity->curstate.rendermode == kRenderTransColor )
|
||||
{
|
||||
color[3] = tr.blend * 255;
|
||||
VectorCopy( (byte*)&RI.currententity->curstate.rendercolor, color );
|
||||
pglColor4ubv( color );
|
||||
}
|
||||
else pglColor4f( lv[0], lv[1], lv[2], tr.blend );
|
||||
}
|
||||
}
|
||||
|
||||
static void R_StudioSetColorArray(short *ptricmds, vec3_t *pstudionorms, byte *color )
|
||||
{
|
||||
float *lv = (float *)g_studio.lightvalues[ptricmds[1]];
|
||||
|
||||
color[3] = tr.blend * 255;
|
||||
|
||||
if( g_studio.numlocallights )
|
||||
R_LightLambert( g_studio.lightpos[ptricmds[0]], pstudionorms[ptricmds[1]], lv, color );
|
||||
else
|
||||
{
|
||||
if( RI.currententity->curstate.rendermode == kRenderTransColor )
|
||||
VectorCopy( (byte*)&RI.currententity->curstate.rendercolor, color );
|
||||
else
|
||||
{
|
||||
color[0] = lv[0] * 255;
|
||||
color[1] = lv[1] * 255;
|
||||
color[2] = lv[2] * 255;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1934,11 +1990,8 @@ _inline void R_StudioDrawNormalMesh( short *ptricmds, vec3_t *pstudionorms, floa
|
||||
|
||||
for( ; i > 0; i--, ptricmds += 4 )
|
||||
{
|
||||
lv = (float *)g_studio.lightvalues[ptricmds[1]];
|
||||
R_StudioSetColorBegin( ptricmds, pstudionorms );
|
||||
|
||||
if( g_studio.numlocallights )
|
||||
R_LightLambert( g_studio.lightpos[ptricmds[0]], pstudionorms[ptricmds[1]], lv );
|
||||
else pglColor4f( lv[0], lv[1], lv[2], tr.blend );
|
||||
pglTexCoord2f( ptricmds[2] * s, ptricmds[3] * t );
|
||||
pglVertex3fv( g_studio.verts[ptricmds[0]] );
|
||||
}
|
||||
@ -1970,10 +2023,7 @@ _inline void R_StudioDrawFloatMesh( short *ptricmds, vec3_t *pstudionorms )
|
||||
|
||||
for( ; i > 0; i--, ptricmds += 4 )
|
||||
{
|
||||
lv = (float *)g_studio.lightvalues[ptricmds[1]];
|
||||
if( g_studio.numlocallights )
|
||||
R_LightLambert( g_studio.lightpos[ptricmds[0]], pstudionorms[ptricmds[1]], lv );
|
||||
else pglColor4f( lv[0], lv[1], lv[2], tr.blend );
|
||||
R_StudioSetColorBegin( ptricmds, pstudionorms );
|
||||
pglTexCoord2f( HalfToFloat( ptricmds[2] ), HalfToFloat( ptricmds[3] ));
|
||||
pglVertex3fv( g_studio.verts[ptricmds[0]] );
|
||||
}
|
||||
@ -2009,10 +2059,13 @@ _inline void R_StudioDrawChromeMesh( short *ptricmds, vec3_t *pstudionorms, floa
|
||||
{
|
||||
if( glowShell )
|
||||
{
|
||||
color24 *clr = &RI.currententity->curstate.rendercolor;
|
||||
|
||||
idx = g_studio.normaltable[ptricmds[0]];
|
||||
av = g_studio.verts[ptricmds[0]];
|
||||
lv = g_studio.norms[ptricmds[0]];
|
||||
VectorMA( av, scale, lv, vert );
|
||||
pglColor4ub( clr->r, clr->g, clr->b, 255 );
|
||||
pglTexCoord2f( g_studio.chrome[idx][0] * s, g_studio.chrome[idx][1] * t );
|
||||
pglVertex3fv( vert );
|
||||
}
|
||||
@ -2020,9 +2073,7 @@ _inline void R_StudioDrawChromeMesh( short *ptricmds, vec3_t *pstudionorms, floa
|
||||
{
|
||||
idx = ptricmds[1];
|
||||
lv = (float *)g_studio.lightvalues[ptricmds[1]];
|
||||
if( g_studio.numlocallights )
|
||||
R_LightLambert( g_studio.lightpos[ptricmds[0]], pstudionorms[ptricmds[1]], lv );
|
||||
else pglColor4f( lv[0], lv[1], lv[2], tr.blend );
|
||||
R_StudioSetColorBegin( ptricmds, pstudionorms );
|
||||
pglTexCoord2f( g_studio.chrome[idx][0] * s, g_studio.chrome[idx][1] * t );
|
||||
pglVertex3fv( g_studio.verts[ptricmds[0]] );
|
||||
}
|
||||
@ -2032,6 +2083,220 @@ _inline void R_StudioDrawChromeMesh( short *ptricmds, vec3_t *pstudionorms, floa
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
_inline int R_StudioBuildIndices( qboolean tri_strip, int vertexState )
|
||||
{
|
||||
// build in indices
|
||||
if( vertexState++ < 3 )
|
||||
{
|
||||
g_studio.arrayelems[g_studio.numelems++] = g_studio.numverts;
|
||||
}
|
||||
else if( tri_strip )
|
||||
{
|
||||
// flip triangles between clockwise and counter clockwise
|
||||
if( vertexState & 1 )
|
||||
{
|
||||
// draw triangle [n-2 n-1 n]
|
||||
g_studio.arrayelems[g_studio.numelems++] = g_studio.numverts - 2;
|
||||
g_studio.arrayelems[g_studio.numelems++] = g_studio.numverts - 1;
|
||||
g_studio.arrayelems[g_studio.numelems++] = g_studio.numverts;
|
||||
}
|
||||
else
|
||||
{
|
||||
// draw triangle [n-1 n-2 n]
|
||||
g_studio.arrayelems[g_studio.numelems++] = g_studio.numverts - 1;
|
||||
g_studio.arrayelems[g_studio.numelems++] = g_studio.numverts - 2;
|
||||
g_studio.arrayelems[g_studio.numelems++] = g_studio.numverts;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// draw triangle fan [0 n-1 n]
|
||||
g_studio.arrayelems[g_studio.numelems++] = g_studio.numverts - ( vertexState - 1 );
|
||||
g_studio.arrayelems[g_studio.numelems++] = g_studio.numverts - 1;
|
||||
g_studio.arrayelems[g_studio.numelems++] = g_studio.numverts;
|
||||
}
|
||||
|
||||
return vertexState;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
R_StudioDrawNormalMesh
|
||||
|
||||
generic path
|
||||
===============
|
||||
*/
|
||||
_inline void R_StudioBuildArrayNormalMesh( short *ptricmds, vec3_t *pstudionorms, float s, float t )
|
||||
{
|
||||
float *lv;
|
||||
int i;
|
||||
float alpha = tr.blend;
|
||||
|
||||
while( i = *( ptricmds++ ))
|
||||
{
|
||||
int vertexState = 0;
|
||||
qboolean tri_strip = true;
|
||||
|
||||
if( i < 0 )
|
||||
{
|
||||
tri_strip = false;
|
||||
i = -i;
|
||||
}
|
||||
|
||||
for( ; i > 0; i--, ptricmds += 4 )
|
||||
{
|
||||
GLubyte *cl;
|
||||
cl = g_studio.arraycolor[g_studio.numverts];
|
||||
lv = (float *)g_studio.lightvalues[ptricmds[1]];
|
||||
|
||||
vertexState = R_StudioBuildIndices( tri_strip, vertexState );
|
||||
|
||||
R_StudioSetColorArray( ptricmds, pstudionorms, cl );
|
||||
|
||||
g_studio.arraycoord[g_studio.numverts][0] = ptricmds[2] * s;
|
||||
g_studio.arraycoord[g_studio.numverts][1] = ptricmds[3] * t;
|
||||
|
||||
VectorCopy( g_studio.verts[ptricmds[0]], g_studio.arrayverts[g_studio.numverts] );
|
||||
g_studio.numverts++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
R_StudioDrawNormalMesh
|
||||
|
||||
generic path
|
||||
===============
|
||||
*/
|
||||
_inline void R_StudioBuildArrayFloatMesh( short *ptricmds, vec3_t *pstudionorms )
|
||||
{
|
||||
float *lv;
|
||||
int i;
|
||||
float alpha = tr.blend;
|
||||
|
||||
while( i = *( ptricmds++ ))
|
||||
{
|
||||
int vertexState = 0;
|
||||
qboolean tri_strip = true;
|
||||
|
||||
if( i < 0 )
|
||||
{
|
||||
tri_strip = false;
|
||||
i = -i;
|
||||
}
|
||||
|
||||
for( ; i > 0; i--, ptricmds += 4 )
|
||||
{
|
||||
GLubyte *cl;
|
||||
cl = g_studio.arraycolor[g_studio.numverts];
|
||||
lv = (float *)g_studio.lightvalues[ptricmds[1]];
|
||||
|
||||
vertexState = R_StudioBuildIndices( tri_strip, vertexState );
|
||||
|
||||
R_StudioSetColorArray( ptricmds, pstudionorms, cl );
|
||||
|
||||
g_studio.arraycoord[g_studio.numverts][0] = HalfToFloat( ptricmds[2] );
|
||||
g_studio.arraycoord[g_studio.numverts][1] = HalfToFloat( ptricmds[3] );
|
||||
|
||||
VectorCopy( g_studio.verts[ptricmds[0]], g_studio.arrayverts[g_studio.numverts] );
|
||||
g_studio.numverts++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
R_StudioDrawNormalMesh
|
||||
|
||||
generic path
|
||||
===============
|
||||
*/
|
||||
_inline void R_StudioBuildArrayChromeMesh( short *ptricmds, vec3_t *pstudionorms, float s, float t, float scale )
|
||||
{
|
||||
float *lv, *av;
|
||||
int i, idx;
|
||||
qboolean glowShell = (scale > 0.0f) ? true : false;
|
||||
vec3_t vert;
|
||||
float alpha = tr.blend;
|
||||
|
||||
while( i = *( ptricmds++ ))
|
||||
{
|
||||
int vertexState = 0;
|
||||
qboolean tri_strip = true;
|
||||
|
||||
if( i < 0 )
|
||||
{
|
||||
tri_strip = false;
|
||||
i = -i;
|
||||
}
|
||||
|
||||
for( ; i > 0; i--, ptricmds += 4 )
|
||||
{
|
||||
GLubyte *cl;
|
||||
cl = g_studio.arraycolor[g_studio.numverts];
|
||||
lv = (float *)g_studio.lightvalues[ptricmds[1]];
|
||||
|
||||
vertexState = R_StudioBuildIndices( tri_strip, vertexState );
|
||||
|
||||
if( glowShell )
|
||||
{
|
||||
idx = g_studio.normaltable[ptricmds[0]];
|
||||
av = g_studio.verts[ptricmds[0]];
|
||||
lv = g_studio.norms[ptricmds[0]];
|
||||
|
||||
cl[0] = RI.currententity->curstate.rendercolor.r;
|
||||
cl[1] = RI.currententity->curstate.rendercolor.g;
|
||||
cl[2] = RI.currententity->curstate.rendercolor.b;
|
||||
cl[3] = 255;
|
||||
|
||||
VectorMA( av, scale, lv, vert );
|
||||
VectorCopy( vert, g_studio.arrayverts[g_studio.numverts] );
|
||||
}
|
||||
else
|
||||
{
|
||||
idx = ptricmds[1];
|
||||
R_StudioSetColorArray( ptricmds, pstudionorms, cl );
|
||||
|
||||
VectorCopy( g_studio.verts[ptricmds[0]], g_studio.arrayverts[g_studio.numverts] );
|
||||
}
|
||||
|
||||
g_studio.arraycoord[g_studio.numverts][0] = g_studio.chrome[idx][0] * s;
|
||||
g_studio.arraycoord[g_studio.numverts][1] = g_studio.chrome[idx][1] * t;
|
||||
|
||||
g_studio.numverts++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_inline void R_StudioDrawArrays( uint startverts, uint startelems )
|
||||
{
|
||||
pglEnableClientState( GL_VERTEX_ARRAY );
|
||||
pglVertexPointer( 3, GL_FLOAT, 12, g_studio.arrayverts );
|
||||
|
||||
pglEnableClientState( GL_TEXTURE_COORD_ARRAY );
|
||||
pglTexCoordPointer( 2, GL_FLOAT, 0, g_studio.arraycoord );
|
||||
|
||||
if( !( g_nForceFaceFlags & STUDIO_NF_CHROME ) )
|
||||
{
|
||||
pglEnableClientState( GL_COLOR_ARRAY );
|
||||
pglColorPointer( 4, GL_UNSIGNED_BYTE, 0, g_studio.arraycolor );
|
||||
}
|
||||
|
||||
#if !defined XASH_NANOGL || defined XASH_WES && defined __EMSCRIPTEN__ // WebGL need to know array sizes
|
||||
if( pglDrawRangeElements )
|
||||
pglDrawRangeElements( GL_TRIANGLES, startverts, g_studio.numverts,
|
||||
g_studio.numelems - startelems, GL_UNSIGNED_SHORT, &g_studio.arrayelems[startelems] );
|
||||
else
|
||||
#endif
|
||||
pglDrawElements( GL_TRIANGLES, g_studio.numelems - startelems, GL_UNSIGNED_SHORT, &g_studio.arrayelems[startelems] );
|
||||
pglDisableClientState( GL_VERTEX_ARRAY );
|
||||
pglDisableClientState( GL_TEXTURE_COORD_ARRAY );
|
||||
if( !( g_nForceFaceFlags & STUDIO_NF_CHROME ) )
|
||||
pglDisableClientState( GL_COLOR_ARRAY );
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
R_StudioDrawPoints
|
||||
@ -2054,6 +2319,9 @@ static void R_StudioDrawPoints( void )
|
||||
|
||||
if( !m_pStudioHeader ) return;
|
||||
|
||||
|
||||
g_studio.numverts = g_studio.numelems = 0;
|
||||
|
||||
// safety bounding the skinnum
|
||||
m_skinnum = bound( 0, RI.currententity->curstate.skin, ( m_pStudioHeader->numskinfamilies - 1 ));
|
||||
ptexture = (mstudiotexture_t *)((byte *)m_pStudioHeader + m_pStudioHeader->textureindex);
|
||||
@ -2151,6 +2419,8 @@ static void R_StudioDrawPoints( void )
|
||||
for( j = 0; j < m_pSubModel->nummesh; j++ )
|
||||
{
|
||||
float oldblend = tr.blend;
|
||||
uint startArrayVerts = g_studio.numverts;
|
||||
uint startArrayElems = g_studio.numelems;
|
||||
short *ptricmds;
|
||||
float s, t;
|
||||
|
||||
@ -2184,11 +2454,24 @@ static void R_StudioDrawPoints( void )
|
||||
|
||||
R_StudioSetupSkin( m_pStudioHeader, pskinref[pmesh->skinref] );
|
||||
|
||||
if( FBitSet( g_nFaceFlags, STUDIO_NF_CHROME ))
|
||||
R_StudioDrawChromeMesh( ptricmds, pstudionorms, s, t, shellscale );
|
||||
else if( FBitSet( g_nFaceFlags, STUDIO_NF_UV_COORDS ))
|
||||
R_StudioDrawFloatMesh( ptricmds, pstudionorms );
|
||||
else R_StudioDrawNormalMesh( ptricmds, pstudionorms, s, t );
|
||||
if( CVAR_TO_BOOL(r_studio_drawelements) )
|
||||
{
|
||||
if( FBitSet( g_nFaceFlags, STUDIO_NF_CHROME ))
|
||||
R_StudioBuildArrayChromeMesh( ptricmds, pstudionorms, s, t, shellscale );
|
||||
else if( FBitSet( g_nFaceFlags, STUDIO_NF_UV_COORDS ))
|
||||
R_StudioBuildArrayFloatMesh( ptricmds, pstudionorms );
|
||||
else R_StudioBuildArrayNormalMesh( ptricmds, pstudionorms, s, t );
|
||||
|
||||
R_StudioDrawArrays( startArrayVerts, startArrayElems );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( FBitSet( g_nFaceFlags, STUDIO_NF_CHROME ))
|
||||
R_StudioDrawChromeMesh( ptricmds, pstudionorms, s, t, shellscale );
|
||||
else if( FBitSet( g_nFaceFlags, STUDIO_NF_UV_COORDS ))
|
||||
R_StudioDrawFloatMesh( ptricmds, pstudionorms );
|
||||
else R_StudioDrawNormalMesh( ptricmds, pstudionorms, s, t );
|
||||
}
|
||||
|
||||
if( FBitSet( g_nFaceFlags, STUDIO_NF_MASKED ))
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user