16 Nov 2008

This commit is contained in:
g-cont 2008-11-16 00:00:00 +03:00 committed by Alibek Omarov
parent 9cd0a7b95f
commit de33efc4a2
49 changed files with 3303 additions and 3211 deletions

View File

@ -1,16 +0,0 @@
<html>
<body>
<pre>
<h1>Build Log</h1>
<h3>
--------------------Configuration: baserc - Win32 Debug--------------------
</h3>
<h3>Command Lines</h3>
<h3>Results</h3>
baserc.dll - 0 error(s), 0 warning(s)
</pre>
</body>
</html>

File diff suppressed because it is too large Load Diff

View File

@ -30,13 +30,26 @@ setfont <fontname>
*/
void CL_SetFont_f( void )
{
if(Cmd_Argc() < 2)
if( Cmd_Argc() < 2 )
{
Msg( "Usage: setfont <fontname>\n" );
Msg( "Usage: setfont <fontname> <console>\n" );
return;
}
Cvar_Set( "con_font", Cmd_Argv(1));
cls.consoleFont = re->RegisterShader( va( "gfx/fonts/%s", con_font->string ), SHADER_FONT );
switch(Cmd_Argc( ))
{
case 2:
Cvar_Set( "cl_font", Cmd_Argv( 1 ));
cls.clientFont = re->RegisterShader( va( "gfx/fonts/%s", cl_font->string ), SHADER_FONT );
break;
case 3:
Cvar_Set( "con_font", Cmd_Argv( 1 ));
cls.consoleFont = re->RegisterShader( va( "gfx/fonts/%s", con_font->string ), SHADER_FONT );
break;
default:
Msg( "setfont: invalid aruments\n" );
break;
}
}
/*

View File

@ -486,7 +486,7 @@ void CL_GetEntitySoundSpatialization( int entnum, vec3_t origin, vec3_t velocity
if( VectorIsNull( origin ))
{
cmodel = cl.models[ent->priv.cl->current.model.index];
if(!cmodel) return;
if( !cmodel ) return;
VectorAverage( cmodel->mins, cmodel->maxs, midPoint );
VectorAdd( origin, midPoint, origin );
}
@ -514,7 +514,16 @@ void CL_AddLoopingSounds( void )
{
num = (cl.frame.parse_entities + i)&(MAX_PARSE_ENTITIES-1);
ent = &cl_parse_entities[num];
if(!ent->soundindex) continue;
switch( ent->ed_type )
{
case ED_MOVER:
case ED_AMBIENT:
case ED_NORMAL: break;
default: continue;
}
if( !ent->soundindex ) continue;
se->AddLoopingSound( ent->number, cl.sound_precache[ent->soundindex], 1.0f, ATTN_IDLE );
}
}

View File

@ -329,7 +329,7 @@ void CL_ClearState (void)
CL_FreeEdicts();
// wipe the entire cl structure
memset( &cl, 0, sizeof(cl));
Mem_Set( &cl, 0, sizeof( cl ));
MSG_Clear( &cls.netchan.message );
Cvar_SetValue( "scr_download", 0.0f );
@ -734,10 +734,12 @@ void CL_PrepVideo( void )
// setup default sky shader or custom skybox from progs
re->RegisterShader( cl.configstrings[CS_SKYNAME], SHADER_SKY );
Cvar_SetValue("scr_loading", 100.0f ); // all done
re->EndRegistration(); // the render can now free unneeded stuff
Con_ClearNotify(); // clear any lines of console text
Cvar_SetValue("scr_loading", 98.0f ); // load sky
SCR_RegisterShaders();
Cvar_SetValue("scr_loading", 100.0f ); // all done
re->EndRegistration(); // the render can now free unneeded stuff
Con_ClearNotify(); // clear any lines of console text
SCR_UpdateScreen();
cl.video_prepped = true;
cl.force_refdef = true;

View File

@ -20,6 +20,7 @@ cvar_t *cl_testentities;
cvar_t *cl_testlights;
cvar_t *cl_levelshot_name;
cvar_t *cl_envshot_size;
cvar_t *cl_font;
void SCR_TimeRefresh_f( void );
void SCR_Loading_f( void );
@ -108,7 +109,7 @@ void SCR_DrawChar( int x, int y, float w, float h, int ch )
fcol = (ch & 15)*0.0625f + (0.5f / 256.0f);
size = 0.0625f - (1.0f / 256.0f);
re->DrawStretchPic( ax, ay, aw, ah, fcol, frow, fcol + size, frow + size, cls.consoleFont );
re->DrawStretchPic( ax, ay, aw, ah, fcol, frow, fcol + size, frow + size, cls.clientFont );
}
/*
@ -116,6 +117,7 @@ void SCR_DrawChar( int x, int y, float w, float h, int ch )
SCR_DrawSmallChar
small chars are drawn at native screen resolution
console only
====================
*/
void SCR_DrawSmallChar( int x, int y, int ch )
@ -326,12 +328,20 @@ void SCR_UpdateScreen( void )
V_PostRender();
}
void SCR_RegisterShaders( void )
{
// register console images
cls.consoleFont = re->RegisterShader( va( "gfx/fonts/%s", con_font->string ), SHADER_FONT );
cls.clientFont = re->RegisterShader( va( "gfx/fonts/%s", cl_font->string ), SHADER_FONT );
cls.consoleBack = re->RegisterShader( "gfx/background/conback", SHADER_NOMIP );
}
/*
==================
SCR_Init
==================
*/
void SCR_Init (void)
void SCR_Init( void )
{
cls.mempool = Mem_AllocPool( "Client Static" );
@ -344,17 +354,16 @@ void SCR_Init (void)
cl_testentities = Cvar_Get ("cl_testentities", "0", 0, "test client entities" );
cl_testlights = Cvar_Get ("cl_testlights", "0", 0, "test dynamic lights" );
cl_envshot_size = Cvar_Get( "cl_envshot_size", "256", CVAR_ARCHIVE, "envshot size of cube side" );
cl_font = Cvar_Get( "cl_font", "default", CVAR_ARCHIVE, "in-game messages font" );
// register our commands
Cmd_AddCommand( "timerefresh", SCR_TimeRefresh_f, "turn quickly and print rendering statistcs" );
Cmd_AddCommand( "loading", SCR_Loading_f, "prepare client to a loading new map" );
Cmd_AddCommand( "skyname", CL_SetSky_f, "set new skybox by basename" );
Cmd_AddCommand( "setfont", CL_SetFont_f, "set new system font" );
Cmd_AddCommand( "setfont", CL_SetFont_f, "set console/messsages font" );
Cmd_AddCommand( "viewpos", SCR_Viewpos_f, "prints current player origin" );
// register console images
cls.consoleFont = re->RegisterShader( va( "gfx/fonts/%s", con_font->string ), SHADER_FONT );
cls.consoleBack = re->RegisterShader( "gfx/background/conback", SHADER_NOMIP );
SCR_RegisterShaders();
}
void SCR_Shutdown( void )

View File

@ -225,6 +225,7 @@ typedef struct
int challenge; // from the server to use for connecting
shader_t consoleFont; // current console font
shader_t clientFont; // current client font
shader_t consoleBack; // console background
file_t *download; // file transfer from server
@ -293,6 +294,7 @@ extern cvar_t *cl_yawspeed;
extern cvar_t *cl_pitchspeed;
extern cvar_t *cl_envshot_size;
extern cvar_t *cl_run;
extern cvar_t *cl_font;
extern cvar_t *cl_anglespeedkey;
@ -510,6 +512,7 @@ void SCR_Init( void );
void SCR_UpdateScreen( void );
void VID_Init( void );
void SCR_Shutdown( void );
void SCR_RegisterShaders( void );
void SCR_AdjustSize( float *x, float *y, float *w, float *h );
void SCR_DrawPic( float x, float y, float width, float height, shader_t shader );
void SCR_FillRect( float x, float y, float width, float height, const float *color );

View File

@ -239,7 +239,7 @@ void Con_Init (void)
// register our commands
con_notifytime = Cvar_Get ("con_notifytime", "3", 0, "notify time to live" );
con_speed = Cvar_Get ("con_speed", "3", 0, "console moving speed" );
con_font = Cvar_Get( "con_font", "conchars", CVAR_ARCHIVE, "path to console charset" );
con_font = Cvar_Get( "con_font", "default", CVAR_ARCHIVE, "path to console charset" );
Field_Clear( &g_consoleField );
g_consoleField.widthInChars = g_console_field_width;

View File

@ -1,77 +0,0 @@
<html>
<body>
<pre>
<h1>Build Log</h1>
<h3>
--------------------Configuration: engine - Win32 Debug--------------------
</h3>
<h3>Command Lines</h3>
Creating temporary file "C:\DOCUME~1\ÀÄÌÈÍÈ~1.9CC\LOCALS~1\Temp\RSP34F7.tmp" with contents
[
/nologo /MDd /W3 /Gm /Gi /GX /ZI /Od /I "./" /I "common" /I "server" /I "client" /I "../public" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR"..\temp\engine\!debug/" /Fo"..\temp\engine\!debug/" /Fd"..\temp\engine\!debug/" /FD /c
"D:\Xash3D\src_main\engine\server\sv_cmds.c"
"D:\Xash3D\src_main\engine\server\sv_progs.c"
]
Creating command line "cl.exe @"C:\DOCUME~1\ÀÄÌÈÍÈ~1.9CC\LOCALS~1\Temp\RSP34F7.tmp""
Creating temporary file "C:\DOCUME~1\ÀÄÌÈÍÈ~1.9CC\LOCALS~1\Temp\RSP34F8.tmp" with contents
[
user32.lib msvcrtd.lib /nologo /subsystem:windows /dll /incremental:yes /pdb:"..\temp\engine\!debug/engine.pdb" /debug /machine:I386 /nodefaultlib:"msvcrt.lib" /out:"..\temp\engine\!debug/engine.dll" /implib:"..\temp\engine\!debug/engine.lib" /pdbtype:sept
"\Xash3D\src_main\temp\engine\!debug\cinematic.obj"
"\Xash3D\src_main\temp\engine\!debug\cl_cmds.obj"
"\Xash3D\src_main\temp\engine\!debug\cl_demo.obj"
"\Xash3D\src_main\temp\engine\!debug\cl_frame.obj"
"\Xash3D\src_main\temp\engine\!debug\cl_fx.obj"
"\Xash3D\src_main\temp\engine\!debug\cl_input.obj"
"\Xash3D\src_main\temp\engine\!debug\cl_main.obj"
"\Xash3D\src_main\temp\engine\!debug\cl_parse.obj"
"\Xash3D\src_main\temp\engine\!debug\cl_pred.obj"
"\Xash3D\src_main\temp\engine\!debug\cl_progs.obj"
"\Xash3D\src_main\temp\engine\!debug\cl_scrn.obj"
"\Xash3D\src_main\temp\engine\!debug\cl_tent.obj"
"\Xash3D\src_main\temp\engine\!debug\cl_view.obj"
"\Xash3D\src_main\temp\engine\!debug\con_keys.obj"
"\Xash3D\src_main\temp\engine\!debug\con_main.obj"
"\Xash3D\src_main\temp\engine\!debug\con_utils.obj"
"\Xash3D\src_main\temp\engine\!debug\engfuncs.obj"
"\Xash3D\src_main\temp\engine\!debug\engine.obj"
"\Xash3D\src_main\temp\engine\!debug\host.obj"
"\Xash3D\src_main\temp\engine\!debug\infostring.obj"
"\Xash3D\src_main\temp\engine\!debug\input.obj"
"\Xash3D\src_main\temp\engine\!debug\menu.obj"
"\Xash3D\src_main\temp\engine\!debug\net_chan.obj"
"\Xash3D\src_main\temp\engine\!debug\net_huff.obj"
"\Xash3D\src_main\temp\engine\!debug\net_msg.obj"
"\Xash3D\src_main\temp\engine\!debug\sv_client.obj"
"\Xash3D\src_main\temp\engine\!debug\sv_cmds.obj"
"\Xash3D\src_main\temp\engine\!debug\sv_frame.obj"
"\Xash3D\src_main\temp\engine\!debug\sv_init.obj"
"\Xash3D\src_main\temp\engine\!debug\sv_main.obj"
"\Xash3D\src_main\temp\engine\!debug\sv_move.obj"
"\Xash3D\src_main\temp\engine\!debug\sv_phys.obj"
"\Xash3D\src_main\temp\engine\!debug\sv_progs.obj"
"\Xash3D\src_main\temp\engine\!debug\sv_spawn.obj"
"\Xash3D\src_main\temp\engine\!debug\sv_world.obj"
]
Creating command line "link.exe @"C:\DOCUME~1\ÀÄÌÈÍÈ~1.9CC\LOCALS~1\Temp\RSP34F8.tmp""
Creating temporary file "C:\DOCUME~1\ÀÄÌÈÍÈ~1.9CC\LOCALS~1\Temp\RSP34F9.bat" with contents
[
@echo off
copy \Xash3D\src_main\temp\engine\!debug\engine.dll "D:\Xash3D\bin\engine.dll"
]
Creating command line ""C:\DOCUME~1\ÀÄÌÈÍÈ~1.9CC\LOCALS~1\Temp\RSP34F9.bat""
Compiling...
sv_cmds.c
sv_progs.c
Generating Code...
Linking...
<h3>Output Window</h3>
Performing Custom Build Step on \Xash3D\src_main\temp\engine\!debug\engine.dll
‘ª®¯¨à®¢ ­® ä ©«®¢: 1.
<h3>Results</h3>
engine.dll - 0 error(s), 0 warning(s)
</pre>
</body>
</html>

View File

@ -92,7 +92,7 @@ void Host_InitRender( void )
CreateRender = (void *)render_dll.main;
re = CreateRender( &newcom, &ri );
if(re->Init()) result = true;
if( re->Init( true )) result = true;
}
// video system not started, run dedicated server
@ -101,10 +101,10 @@ void Host_InitRender( void )
void Host_FreeRender( void )
{
if(render_dll.link)
if( render_dll.link )
{
re->Shutdown();
Mem_Set( &re, 0, sizeof(re));
re->Shutdown( true );
Mem_Set( &re, 0, sizeof( re ));
}
Sys_FreeLibrary( &render_dll );
}
@ -123,7 +123,7 @@ void Host_InitVprogs( int argc, char **argv )
void Host_FreeVprogs( void )
{
if(vprogs_dll.link)
if( vprogs_dll.link )
{
vm->Free();
Mem_Set( &vm, 0, sizeof(vm));

View File

@ -242,7 +242,7 @@ typedef struct
//=============================================================================
extern netadr_t master_adr[MAX_MASTERS]; // address of the master server
extern const char *ed_name[];
extern server_static_t svs; // persistant server info
extern server_t sv; // local server
@ -295,16 +295,17 @@ void SV_InitGame (void);
void SV_Map( char *levelstring, char *savename );
void SV_SpawnServer( const char *server, const char *savename );
int SV_FindIndex (const char *name, int start, int end, bool create);
void SV_VM_Begin(void);
void SV_VM_End(void);
void SV_ClassifyEdict( edict_t *ent );
void SV_VM_Begin( void );
void SV_VM_End( void );
//
// sv_phys.c
//
void SV_Physics( void );
void SV_PlayerMove( sv_edict_t *ed );
void SV_DropToFloor (edict_t *ent);
void SV_CheckGround (edict_t *ent);
void SV_DropToFloor( edict_t *ent );
void SV_CheckGround( edict_t *ent );
bool SV_UnstickEntity( edict_t *ent );
int SV_ContentsMask( const edict_t *passedict );
bool SV_MoveStep (edict_t *ent, vec3_t move, bool relink);

View File

@ -82,6 +82,21 @@ void SV_UpdateEntityState( edict_t *ent )
VectorCopy( ent->progs.sv->origin, ent->priv.sv->s.old_origin );
ent->priv.sv->s.model.colormap = ent->progs.sv->colormap = client->progs.sv->colormap;
}
else if( ent->priv.sv->s.ed_type == ED_AMBIENT )
{
if( ent->progs.sv->solid == SOLID_TRIGGER )
{
vec3_t midPoint;
// NOTE: no reason to compute this shit on the client - save bandwidth
VectorAverage( ent->progs.sv->mins, ent->progs.sv->maxs, midPoint );
VectorAdd( ent->priv.sv->s.origin, midPoint, ent->priv.sv->s.origin );
}
}
else if( ent->priv.sv->s.ed_type == ED_MOVER )
{
// FIXME: send mins\maxs for sound spatialization and entity prediction ?
}
}
/*
@ -232,6 +247,17 @@ static void SV_AddEntitiesToPacket( vec3_t origin, client_frame_t *frame, sv_ent
svent = ent->priv.sv;
// quick reject by type
switch( svent->s.ed_type )
{
case ED_MOVER:
case ED_NORMAL:
case ED_AMBIENT:
case ED_BSPBRUSH:
case ED_RIGIDBODY: break;
default: if( !force ) continue;
}
// don't double add an entity through portals
if( svent->framenum == sv.net_framenum ) continue;

View File

@ -85,22 +85,20 @@ to the clients -- only the fields that differ from the
baseline will be transmitted
================
*/
void SV_CreateBaseline (void)
void SV_CreateBaseline( void )
{
edict_t *svent;
int entnum;
edict_t *svent;
int entnum;
for (entnum = 1; entnum < prog->num_edicts ; entnum++)
for( entnum = 1; entnum < prog->num_edicts ; entnum++ )
{
svent = PRVM_EDICT_NUM(entnum);
if (svent->priv.sv->free) continue;
if (!svent->progs.sv->modelindex && !svent->priv.sv->s.soundindex && !svent->progs.sv->effects)
svent = PRVM_EDICT_NUM( entnum );
if( svent->priv.sv->free ) continue;
if( !svent->progs.sv->modelindex && !svent->priv.sv->s.soundindex && !svent->progs.sv->effects )
continue;
svent->priv.sv->serialnumber = entnum;
//
// take current state as baseline
//
VectorCopy (svent->progs.sv->origin, svent->progs.sv->old_origin);
SV_UpdateEntityState( svent );
@ -108,7 +106,6 @@ void SV_CreateBaseline (void)
}
}
/*
=================
SV_CheckForSavegame
@ -214,8 +211,15 @@ void SV_SpawnServer( const char *server, const char *savename )
// create a baseline for more efficient communications
SV_CreateBaseline();
// classify edicts for quick network sorting
for( i = 0; i < prog->num_edicts; i++ )
{
edict_t *ent = PRVM_EDICT_NUM( i );
SV_ClassifyEdict( ent );
}
// set serverinfo variable
Cvar_FullSet("mapname", sv.name, CVAR_SERVERINFO | CVAR_INIT);
Cvar_FullSet( "mapname", sv.name, CVAR_SERVERINFO|CVAR_INIT );
pe->EndRegistration(); // free unused models
SV_VM_End();
}
@ -296,13 +300,12 @@ void SV_InitGame( void )
SV_VM_Begin();
for (i = 0; i < Host_MaxClients(); i++)
for( i = 0; i < Host_MaxClients(); i++ )
{
ent = PRVM_EDICT_NUM(i + 1);
ent = PRVM_EDICT_NUM( i + 1 );
ent->priv.sv->serialnumber = i + 1;
svs.clients[i].edict = ent;
Mem_Set (&svs.clients[i].lastcmd, 0, sizeof(svs.clients[i].lastcmd));
}
SV_VM_End();
}

View File

@ -565,10 +565,10 @@ void SV_BeginIncreaseEdicts( void )
edict_t *ent;
// links don't survive the transition, so unlink everything
for (i = 0, ent = prog->edicts; i < prog->max_edicts; i++, ent++)
for( i = 0, ent = prog->edicts; i < prog->max_edicts; i++, ent++ )
{
if (!ent->priv.sv->free) SV_UnlinkEdict(prog->edicts + i); //free old entity
memset(&ent->priv.sv->clusternums, 0, sizeof(ent->priv.sv->clusternums));
if( !ent->priv.sv->free ) SV_UnlinkEdict( prog->edicts + i ); // free old entity
Mem_Set( &ent->priv.sv->clusternums, 0, sizeof( ent->priv.sv->clusternums ));
}
SV_ClearWorld();
}
@ -578,10 +578,10 @@ void SV_EndIncreaseEdicts(void)
int i;
edict_t *ent;
for (i = 0, ent = prog->edicts; i < prog->max_edicts; i++, ent++)
for( i = 0, ent = prog->edicts; i < prog->max_edicts; i++, ent++ )
{
// link every entity except world
if (!ent->priv.sv->free) SV_LinkEdict(ent);
if( !ent->priv.sv->free ) SV_LinkEdict(ent);
}
}
@ -609,6 +609,7 @@ void SV_FreeEdict( edict_t *ed )
// unlink from world
SV_UnlinkEdict( ed );
ed->priv.sv->s.ed_type = ED_SPAWNED;
ed->priv.sv->freetime = sv.time;
ed->priv.sv->free = true;
@ -620,8 +621,8 @@ void SV_FreeEdict( edict_t *ed )
ed->progs.sv->solid = 0;
pe->RemoveBody( ed->priv.sv->physbody );
VectorClear(ed->progs.sv->origin);
VectorClear(ed->progs.sv->angles);
VectorClear( ed->progs.sv->origin );
VectorClear( ed->progs.sv->angles );
ed->progs.sv->nextthink = -1;
ed->priv.sv->physbody = NULL;
}
@ -1491,7 +1492,7 @@ void PF_ambientsound( void )
// check to see if samp was properly precached
ent->progs.sv->loopsound = PRVM_G_INT(OFS_PARM1);
ent->priv.sv->s.soundindex = SV_SoundIndex( samp );
if(!ent->progs.sv->modelindex ) SV_LinkEdict( ent );
if( !ent->progs.sv->modelindex ) SV_LinkEdict( ent );
}
/*
@ -2504,7 +2505,7 @@ Init the game subsystem for a new map
*/
void SV_InitServerProgs( void )
{
Msg("\n");
Msg( "\n" );
PRVM_Begin;
PRVM_InitProg( PRVM_SERVERPROG );
@ -2526,7 +2527,7 @@ void SV_InitServerProgs( void )
prog->free_edict = SV_FreeEdict;
prog->count_edicts = SV_CountEdicts;
prog->load_edict = SV_LoadEdict;
prog->restore_edict = SV_RestoreEdict;
prog->restore_edict = SV_RestoreEdict;
prog->filecrc = PROG_CRC_SERVER;
// using default builtins

View File

@ -39,6 +39,31 @@ typedef struct area_s
int type;
} area_t;
const char *ed_name[] =
{
"unknown",
"world",
"static",
"ambient",
"normal",
"brush",
"player",
"monster",
"tempent",
"beam",
"mover",
"viewmodel",
"item",
"ragdoll",
"physbody",
"trigger",
"portal",
"missile",
"decal",
"vehicle",
"error",
};
areanode_t sv_areanodes[AREA_NODES];
int sv_numareanodes;
@ -142,6 +167,71 @@ void SV_ClearWorld( void )
SV_CreateAreaNode( 0, world->mins, world->maxs );
}
/*
=================
SV_ClassifyEdict
sorting edict by type
=================
*/
void SV_ClassifyEdict( edict_t *ent )
{
sv_edict_t *sv_ent;
const char *classname;
sv_ent = ent->priv.sv;
if( sv_ent->s.ed_type != ED_SPAWNED )
return;
classname = PRVM_GetString( ent->progs.sv->classname );
if( !com.strnicmp( "worldspawn", classname, 10 ))
{
sv_ent->s.ed_type = ED_WORLDSPAWN;
return;
}
// first pass: determine type by explicit parms
if( ent->progs.sv->solid == SOLID_TRIGGER )
{
if( sv_ent->s.soundindex )
sv_ent->s.ed_type = ED_AMBIENT; // e.g. trigger_teleport
else sv_ent->s.ed_type = ED_TRIGGER; // never sending to client
}
else if( ent->progs.sv->movetype == MOVETYPE_PHYSIC )
sv_ent->s.ed_type = ED_RIGIDBODY;
else if( ent->progs.sv->solid == SOLID_BSP )
{
if((int)ent->progs.sv->flags & FL_WORLDBRUSH )
sv_ent->s.ed_type = ED_BSPBRUSH;
else if( ent->progs.sv->movetype == MOVETYPE_PUSH )
sv_ent->s.ed_type = ED_MOVER;
else if( ent->progs.sv->movetype == MOVETYPE_CONVEYOR )
sv_ent->s.ed_type = ED_MOVER;
else if( ent->progs.sv->movetype == MOVETYPE_NONE )
sv_ent->s.ed_type = ED_BSPBRUSH;
}
else if((int)ent->progs.sv->flags & FL_MONSTER )
sv_ent->s.ed_type = ED_MONSTER;
else if((int)ent->progs.sv->flags & FL_CLIENT )
sv_ent->s.ed_type = ED_CLIENT;
else if( !sv_ent->s.model.index && !sv_ent->s.aiment )
{
if( sv_ent->s.soundindex )
sv_ent->s.ed_type = ED_AMBIENT;
else sv_ent->s.ed_type = ED_STATIC; // never sending to client
}
if( sv_ent->s.ed_type == ED_SPAWNED )
{
// mark as normal
if( sv_ent->s.model.index || sv_ent->s.soundindex )
sv_ent->s.ed_type = ED_NORMAL;
}
// or leave unclassified, wait for next SV_LinkEdict...
// Msg( "%s: <%s>\n", PRVM_GetString( ent->progs.sv->classname ), ed_name[sv_ent->s.ed_type] );
}
/*
===============
SV_UnlinkEdict
@ -178,6 +268,10 @@ void SV_LinkEdict( edict_t *ent )
if( ent == prog->edicts ) return; // don't add the world
if( sv_ent->free ) return;
// trying to classify unclassified edicts
if( sv.state == ss_active && sv_ent->s.ed_type == ED_SPAWNED )
SV_ClassifyEdict( ent );
// set the size
VectorSubtract( ent->progs.sv->maxs, ent->progs.sv->mins, ent->progs.sv->size );

View File

@ -9,10 +9,10 @@
int Callback_ContactBegin( const NewtonMaterial* material, const NewtonBody* body0, const NewtonBody* body1 )
{
// save the collision bodies
cm.touch_info.m_body0 = (NewtonBody*) body0;
cm.touch_info.m_body1 = (NewtonBody*) body1;
cm.touch_info.normal_speed = 0.0f;// clear the contact normal speed
cm.touch_info.tangent_speed = 0.0f;// clear the contact sliding speed
cms.touch_info.m_body0 = (NewtonBody*) body0;
cms.touch_info.m_body1 = (NewtonBody*) body1;
cms.touch_info.normal_speed = 0.0f;// clear the contact normal speed
cms.touch_info.tangent_speed = 0.0f;// clear the contact sliding speed
// return one the tell Newton the application wants to process this contact
return 1;
@ -26,11 +26,11 @@ int Callback_ContactProcess( const NewtonMaterial* material, const NewtonContact
// get the maximum normal speed of this impact. this can be used for particles of playing collision sound
speed0 = NewtonMaterialGetContactNormalSpeed( material, contact );
if( speed0 > cm.touch_info.normal_speed )
if( speed0 > cms.touch_info.normal_speed )
{
// save the position of the contact (for 3d sound of particles effects)
cm.touch_info.normal_speed = speed0;
NewtonMaterialGetContactPositionAndNormal( material, &cm.touch_info.position[0], &normal[0] );
cms.touch_info.normal_speed = speed0;
NewtonMaterialGetContactPositionAndNormal( material, &cms.touch_info.position[0], &normal[0] );
}
// get the maximum of the two sliding contact speed
@ -40,11 +40,11 @@ int Callback_ContactProcess( const NewtonMaterial* material, const NewtonContact
if( speed1 > speed0 ) speed0 = speed1;
// Get the maximum tangent speed of this contact. this can be used for particles(sparks) of playing scratch sounds
if( speed0 > cm.touch_info.tangent_speed )
if( speed0 > cms.touch_info.tangent_speed )
{
// save the position of the contact (for 3d sound of particles effects)
cm.touch_info.tangent_speed = speed0;
NewtonMaterialGetContactPositionAndNormal( material, &cm.touch_info.position[0], &normal[0] );
cms.touch_info.tangent_speed = speed0;
NewtonMaterialGetContactPositionAndNormal( material, &cms.touch_info.position[0], &normal[0] );
}
// return one to tell Newton we want to accept this contact
@ -54,20 +54,20 @@ int Callback_ContactProcess( const NewtonMaterial* material, const NewtonContact
// this function is call after all contacts for this pairs is processed
void Callback_ContactEnd( const NewtonMaterial* material )
{
sv_edict_t *edict = (sv_edict_t *)NewtonBodyGetUserData( cm.touch_info.m_body0 );
sv_edict_t *edict = (sv_edict_t *)NewtonBodyGetUserData( cms.touch_info.m_body0 );
// if the max contact speed is larger than some minimum value. play a sound
if( cm.touch_info.normal_speed > 15.0f )
if( cms.touch_info.normal_speed > 15.0f )
{
float pitch = cm.touch_info.normal_speed - 15.0f;
float pitch = cms.touch_info.normal_speed - 15.0f;
// TODO: play impact sound here
pi.PlaySound( edict, pitch, "materials/metal/bustmetal1.wav" );
}
// if the max contact speed is larger than some minimum value. play a sound
if( cm.touch_info.normal_speed > 5.0f )
if( cms.touch_info.normal_speed > 5.0f )
{
float pitch = cm.touch_info.normal_speed - 5.0f;
float pitch = cms.touch_info.normal_speed - 5.0f;
// TODO: play scratch sound here
pi.PlaySound( edict, pitch, "materials/metal/pushmetal1.wav" );
}

View File

@ -1434,11 +1434,11 @@ void CM_CollisionDrawForEachBrush( void )
if( !ph.debug_line ) return;
for( i = 0; i < cm.numbmodels; i++ )
for( i = 0; i < cms.numbmodels; i++ )
{
for( j = 0; j < cm.bmodels[i].numbrushes; j++ )
for( j = 0; j < cms.bmodels[i].numbrushes; j++ )
{
draw = cm.brushes[cm.bmodels[i].firstbrush + j].colbrushf;
draw = cm.brushes[cms.bmodels[i].firstbrush + j].colbrushf;
if( !draw ) continue;
if( i == 0 ) color = PackRGBA( 1, 0.7f, 0, 1 ); // world
else color = PackRGBA( 1, 0.1f, 0.1f, 1 );

View File

@ -9,7 +9,7 @@ void DebugShowGeometryCollision( const NewtonBody* body, int vertexCount, const
{
int color;
if( body == cm.body ) color = PackRGBA( 1, 0.7f, 0, 1 ); // world
if( body == cms.body ) color = PackRGBA( 1, 0.7f, 0, 1 ); // world
else color = PackRGBA( 1, 0.1f, 0.1f, 1 );
ph.debug_line( color, vertexCount, faceVertec, NULL );

View File

@ -134,17 +134,7 @@ typedef struct collide_info_s
typedef struct clipmap_s
{
string name;
uint checksum; // map checksum
byte pvsrow[MAX_MAP_LEAFS/8];
byte phsrow[MAX_MAP_LEAFS/8];
byte portalopen[MAX_MAP_AREAPORTALS];
// brush, studio and sprite models
cmodel_t cmodels[MAX_MODELS];
cmodel_t bmodels[MAX_MODELS];
int numcmodels;
byte *mod_base; // start of buffer
// shared copy of map (client - server)
@ -163,30 +153,43 @@ typedef struct clipmap_s
cbrushside_t *brushsides;
byte *visbase; // vis offset
dvis_t *vis;
NewtonCollision *collision;
csurface_t *shaders;
carea_t *areas;
dareaportal_t *areaportals;
int numbrushsides;
int numtexinfo;
int numplanes;
int numbmodels;
int numnodes;
int numleafs; // allow leaf funcs to be called without a map
int numleafbrushes;
int numleafsurfaces;
int numtexinfo;
int numplanes;
int numnodes;
int numleafs; // allow leaf funcs to be called without a map
int numshaders;
int numbrushes;
int numsurfaces;
int numareas;
int numareaportals;
int numclusters;
int floodvalid;
int numareas;
matrix4x4 matrix; // world matrix
} clipmap_t;
typedef struct clipmap_static_s
{
byte pvsrow[MAX_MAP_LEAFS/8];
byte phsrow[MAX_MAP_LEAFS/8];
byte portalopen[MAX_MAP_AREAPORTALS];
// brush, studio and sprite models
cmodel_t cmodels[MAX_MODELS];
cmodel_t bmodels[MAX_MODELS];
int numcmodels;
int numbmodels;
// misc stuff
NewtonBody *body;
matrix4x4 matrix; // world matrix
NewtonCollision *collision;
NewtonJoint *upVector; // world upvector
material_info_t mat[MAX_MATERIALS];
uint num_materials; // number of parsed materials
@ -196,7 +199,8 @@ typedef struct clipmap_s
vfile_t *world_tree; // pre-calcualated collision tree (worldmodel only)
trace_t trace; // contains result of last trace
int checkcount;
} clipmap_t;
} clipmap_static_t;
typedef struct physic_s
{
@ -234,9 +238,10 @@ typedef struct leaflist_s
void (*storeleafs)( struct leaflist_s *ll, cnode_t *node );
} leaflist_t;
extern clipmap_t cm;
extern studio_t studio;
extern physic_t ph;
extern clipmap_t cm;
extern clipmap_static_t cms;
extern studio_t studio;
extern physic_t ph;
extern cvar_t *cm_noareas;
extern cvar_t *cm_debugdraw;

View File

@ -9,7 +9,7 @@ static script_t *materials = NULL;
bool CM_ParseMaterial( token_t *token )
{
uint num = cm.num_materials;
uint num = cms.num_materials;
if( num > MAX_MATERIALS - 1 )
{
@ -25,7 +25,7 @@ bool CM_ParseMaterial( token_t *token )
num = 0; // write default material first
// member material name
com.strncpy( cm.mat[num].name, token->string, MAX_STRING );
com.strncpy( cms.mat[num].name, token->string, MAX_STRING );
// setup default values
while( com.stricmp( token->string, "}" ))
@ -35,28 +35,28 @@ bool CM_ParseMaterial( token_t *token )
if( !com.stricmp( token->string, "elasticity" ))
{
Com_ReadFloat( materials, false, &cm.mat[num].elasticity );
Com_ReadFloat( materials, false, &cms.mat[num].elasticity );
}
else if( !com.stricmp( token->string, "softness" ))
{
Com_ReadFloat( materials, false, &cm.mat[num].softness );
Com_ReadFloat( materials, false, &cms.mat[num].softness );
}
else if( !com.stricmp( token->string, "friction" ))
{
Com_ReadFloat( materials, false, &cm.mat[num].friction_static );
Com_ReadFloat( materials, false, &cms.mat[num].friction_static );
if(!Com_ReadFloat( materials, false, &cm.mat[num].friction_kinetic ))
cm.mat[num].friction_kinetic = cm.mat[num].friction_static; // same as static friction
if(!Com_ReadFloat( materials, false, &cms.mat[num].friction_kinetic ))
cms.mat[num].friction_kinetic = cms.mat[num].friction_static; // same as static friction
}
}
// set default values if needed
if( cm.mat[num].softness == 0.0f ) cm.mat[num].softness = cm.mat[0].softness;
if( cm.mat[num].elasticity == 0.0f ) cm.mat[num].elasticity = cm.mat[0].elasticity;
if( cm.mat[num].friction_static == 0.0f ) cm.mat[num].friction_static = cm.mat[0].friction_static;
if( cm.mat[num].friction_kinetic == 0.0f ) cm.mat[num].friction_kinetic = cm.mat[0].friction_kinetic;
if( cms.mat[num].softness == 0.0f ) cms.mat[num].softness = cms.mat[0].softness;
if( cms.mat[num].elasticity == 0.0f ) cms.mat[num].elasticity = cms.mat[0].elasticity;
if( cms.mat[num].friction_static == 0.0f ) cms.mat[num].friction_static = cms.mat[0].friction_static;
if( cms.mat[num].friction_kinetic == 0.0f ) cms.mat[num].friction_kinetic = cms.mat[0].friction_kinetic;
cm.num_materials++;
cms.num_materials++;
// material will be parsed sucessfully
return true;
@ -75,26 +75,26 @@ void CM_InitMaterials( void )
MsgDev( D_WARN, "scripts/materials.txt not found!\n" );
return;
}
cm.num_materials = 0;
Mem_Set( cm.mat, 0, sizeof(material_info_t) * MAX_MATERIALS );
cms.num_materials = 0;
Mem_Set( cms.mat, 0, sizeof(material_info_t) * MAX_MATERIALS );
while( Com_ReadToken( materials, SC_ALLOW_NEWLINES, &token ))
CM_ParseMaterial( &token );
// assume IDs are in order and we don't need to remember them
for ( i = 1; i < cm.num_materials; i++ )
for ( i = 1; i < cms.num_materials; i++ )
NewtonMaterialCreateGroupID( gWorld );
for ( i = 0; i < cm.num_materials; i++ )
for ( i = 0; i < cms.num_materials; i++ )
{
for ( j = 0; j < cm.num_materials; j++ )
for ( j = 0; j < cms.num_materials; j++ )
{
NewtonMaterialSetDefaultCollidable( gWorld, i, j, true );
NewtonMaterialSetDefaultSoftness( gWorld, i, j, cm.mat[i].softness / 2.0f + cm.mat[j].softness / 2.0f );
NewtonMaterialSetDefaultElasticity( gWorld, i, j, cm.mat[i].elasticity / 2.0f + cm.mat[j].elasticity / 2.0f );
NewtonMaterialSetDefaultFriction( gWorld, i, j, cm.mat[i].friction_static / 2.0f + cm.mat[j].friction_static / 2.0f, cm.mat[i].friction_kinetic / 2.0f + cm.mat[j].friction_kinetic / 2.0f );
NewtonMaterialSetDefaultSoftness( gWorld, i, j, cms.mat[i].softness / 2.0f + cms.mat[j].softness / 2.0f );
NewtonMaterialSetDefaultElasticity( gWorld, i, j, cms.mat[i].elasticity / 2.0f + cms.mat[j].elasticity / 2.0f );
NewtonMaterialSetDefaultFriction( gWorld, i, j, cms.mat[i].friction_static / 2.0f + cms.mat[j].friction_static / 2.0f, cms.mat[i].friction_kinetic / 2.0f + cms.mat[j].friction_kinetic / 2.0f );
NewtonMaterialSetCollisionCallback( gWorld, i, j, NULL, Callback_ContactBegin, Callback_ContactProcess, Callback_ContactEnd );
}
}
Msg( "num materials %d\n", cm.num_materials );
Msg( "num materials %d\n", cms.num_materials );
}

View File

@ -8,6 +8,7 @@
#include "const.h"
clipmap_t cm;
clipmap_static_t cms;
studio_t studio;
cvar_t *cm_noareas;
@ -69,13 +70,13 @@ CM_FreeModel
void CM_FreeModel( cmodel_t *mod )
{
Mem_FreePool( &mod->mempool );
Mem_Set( mod, 0, sizeof(*mod));
Mem_Set( mod, 0, sizeof( *mod ));
mod = NULL;
}
int CM_NumTextures( void ) { return cm.numshaders; }
int CM_NumClusters( void ) { return cm.numclusters; }
int CM_NumInlineModels( void ) { return cm.numbmodels; }
int CM_NumInlineModels( void ) { return cms.numbmodels; }
const char *CM_EntityString( void ) { return cm.entitystring; }
const char *CM_TexName( int index ) { return cm.shaders[index].name; }
@ -98,10 +99,10 @@ void BSP_CreateMeshBuffer( int modelnum )
int flags;
// ignore world or bsplib instance
if( app_name == HOST_BSPLIB || modelnum >= cm.numbmodels )
if( app_name == HOST_BSPLIB || modelnum >= cms.numbmodels )
return;
loadmodel = &cm.bmodels[modelnum];
loadmodel = &cms.bmodels[modelnum];
if( modelnum ) loadmodel->type = mod_brush;
else loadmodel->type = mod_world; // level static geometry
loadmodel->TraceBox = CM_TraceBmodel;
@ -154,8 +155,8 @@ void BSP_LoadModels( lump_t *l )
if(count < 1) Host_Error( "Map %s without models\n", cm.name );
if(count > MAX_MODELS ) Host_Error( "Map %s has too many models\n", cm.name );
cm.numbmodels = count;
out = &cm.bmodels[0];
cms.numbmodels = count;
out = &cms.bmodels[0];
for( i = 0; i < count; i++, in++, out++ )
{
@ -693,7 +694,7 @@ BSP_LoadCollision
void BSP_LoadCollision( lump_t *l )
{
if( !l->filelen ) return;
cm.world_tree = VFS_Create( cm.mod_base + l->fileofs, l->filelen );
cms.world_tree = VFS_Create( cm.mod_base + l->fileofs, l->filelen );
}
static void BSP_RecursiveFindNumLeafs( cnode_t *node )
@ -707,8 +708,8 @@ static void BSP_RecursiveFindNumLeafs( cnode_t *node )
}
numleafs = ((cleaf_t *)node - cm.leafs) + 1;
// these never happens
if( cm.numleafs < numleafs ) cm.numleafs = numleafs;
if( cm.numleafs < numleafs ) // these never happens
Host_Error( "BSP_RecursiveFindNumLeafs: invalid leafs count %i > %i\n", numleafs, cm.numleafs );
}
static void BSP_RecursiveSetParent( cnode_t *node, cnode_t *parent )
@ -761,8 +762,8 @@ static void BSP_RecursiveSetParent( cnode_t *node, cnode_t *parent )
void BSP_BeginBuildTree( void )
{
// create tree collision
cm.collision = NewtonCreateTreeCollision( gWorld, NULL );
NewtonTreeCollisionBeginBuild( cm.collision );
cms.collision = NewtonCreateTreeCollision( gWorld, NULL );
NewtonTreeCollisionBeginBuild( cms.collision );
}
void BSP_AddCollisionFace( int facenum )
@ -793,14 +794,14 @@ void BSP_AddCollisionFace( int facenum )
CM_GetPoint( k, face[0] );
CM_GetPoint( k+j+1, face[1] );
CM_GetPoint( k+j+2, face[2] );
NewtonTreeCollisionAddFace( cm.collision, 3, (float *)face[0], sizeof(vec3_t), 1 );
NewtonTreeCollisionAddFace( cms.collision, 3, (float *)face[0], sizeof(vec3_t), 1 );
}
}
else
{
vec3_t *face = Mem_Alloc( cmappool, m_surface->numedges * sizeof( vec3_t ));
for(j = 0; j < m_surface->numedges; j++ ) CM_GetPoint( k+j, face[j] );
NewtonTreeCollisionAddFace( cm.collision, m_surface->numedges, (float *)face[0], sizeof(vec3_t), 1);
NewtonTreeCollisionAddFace( cms.collision, m_surface->numedges, (float *)face[0], sizeof(vec3_t), 1);
if( face ) Mem_Free( face ); // polygons with 0 edges ?
}
}
@ -808,7 +809,7 @@ void BSP_AddCollisionFace( int facenum )
void BSP_EndBuildTree( void )
{
if( app_name == HOST_BSPLIB ) Msg("Optimize collision tree..." );
NewtonTreeCollisionEndBuild( cm.collision, true );
NewtonTreeCollisionEndBuild( cms.collision, true );
if( app_name == HOST_BSPLIB ) Msg(" done\n");
}
@ -833,7 +834,7 @@ void CM_LoadBSP( const void *buffer )
BSP_LoadSurfaces(&header.lumps[LUMP_SURFACES]);
BSP_LoadModels(&header.lumps[LUMP_MODELS]);
BSP_LoadCollision(&header.lumps[LUMP_COLLISION]);
cm.loaded = true;
cms.loaded = true;
}
void CM_FreeBSP( void )
@ -842,9 +843,11 @@ void CM_FreeBSP( void )
cmodel_t *mod;
CM_FreeWorld();
for( i = 0, mod = &cm.cmodels[0]; i < cm.numcmodels; i++, mod++)
for( i = 0, mod = cms.cmodels; i < cms.numcmodels; i++, mod++)
{
if( mod->name ) CM_FreeModel( mod );
if( !mod->name[0] ) continue;
CM_FreeModel( mod );
}
}
@ -852,16 +855,16 @@ void CM_MakeCollisionTree( void )
{
int i, world = 0; // world index
if( !cm.loaded ) Host_Error( "CM_MakeCollisionTree: map not loaded\n" );
if( cm.collision ) return; // already generated
if( !cms.loaded ) Host_Error( "CM_MakeCollisionTree: map not loaded\n" );
if( cms.collision ) return; // already generated
if( app_name == HOST_BSPLIB ) Msg("Building collision tree...\n" );
BSP_BeginBuildTree();
// world firstface index always equal 0
if( app_name == HOST_BSPLIB )
RunThreadsOnIndividual( cm.bmodels[world].numfaces, true, BSP_AddCollisionFace );
else for( i = 0; i < cm.bmodels[world].numfaces; i++ ) BSP_AddCollisionFace( i );
RunThreadsOnIndividual( cms.bmodels[world].numfaces, true, BSP_AddCollisionFace );
else for( i = 0; i < cms.bmodels[world].numfaces; i++ ) BSP_AddCollisionFace( i );
BSP_EndBuildTree();
}
@ -869,14 +872,14 @@ void CM_MakeCollisionTree( void )
void CM_SaveCollisionTree( file_t *f, cmsave_t callback )
{
CM_MakeCollisionTree(); // create if needed
NewtonTreeCollisionSerialize( cm.collision, callback, f );
NewtonTreeCollisionSerialize( cms.collision, callback, f );
}
void CM_LoadCollisionTree( void )
{
if( !cm.world_tree ) return;
cm.collision = NewtonCreateTreeCollisionFromSerialization( gWorld, NULL, BSP_LoadTree, cm.world_tree );
VFS_Close( cm.world_tree );
if( !cms.world_tree ) return;
cms.collision = NewtonCreateTreeCollisionFromSerialization( gWorld, NULL, BSP_LoadTree, cms.world_tree );
VFS_Close( cms.world_tree );
}
void CM_LoadWorld( const void *buffer )
@ -884,13 +887,13 @@ void CM_LoadWorld( const void *buffer )
vec3_t boxP0, boxP1;
vec3_t extra = { 10.0f, 10.0f, 10.0f };
if( cm.world_tree ) CM_LoadCollisionTree();
if( cms.world_tree ) CM_LoadCollisionTree();
else CM_MakeCollisionTree(); // can be used for old maps or for product of alternative map compiler
cm.body = NewtonCreateBody( gWorld, cm.collision );
NewtonBodyGetMatrix( cm.body, &cm.matrix[0][0] ); // set the global position of this body
NewtonCollisionCalculateAABB( cm.collision, &cm.matrix[0][0], &boxP0[0], &boxP1[0] );
NewtonReleaseCollision( gWorld, cm.collision );
cms.body = NewtonCreateBody( gWorld, cms.collision );
NewtonBodyGetMatrix( cms.body, &cm.matrix[0][0] ); // set the global position of this body
NewtonCollisionCalculateAABB( cms.collision, &cm.matrix[0][0], &boxP0[0], &boxP1[0] );
NewtonReleaseCollision( gWorld, cms.collision );
VectorSubtract( boxP0, extra, boxP0 );
VectorAdd( boxP1, extra, boxP1 );
@ -906,35 +909,21 @@ void CM_FreeWorld( void )
cmodel_t *mod;
// free old stuff
if( cm.loaded ) Mem_EmptyPool( cmappool );
cm.numplanes = cm.numnodes = cm.numleafs = 0;
cm.numleafbrushes = cm.numsurfaces = cm.numbmodels = 0;
cm.floodvalid = cm.numbrushsides = cm.numtexinfo = 0;
cm.numbrushes = cm.numleafsurfaces = cm.numareas = 0;
cm.numareaportals = cm.numclusters = cm.numshaders = 0;
cm.world_tree = NULL;
cm.vis = NULL;
if( cms.loaded ) Mem_EmptyPool( cmappool );
Mem_Set( &cm, 0, sizeof( cm ));
cm.name[0] = 0;
Mem_Set( cm.matrix, 0, sizeof(matrix4x4));
// free bmodels too
for (i = 0, mod = &cm.bmodels[0]; i < cm.numbmodels; i++, mod++)
{
if(!mod->name[0]) continue;
if(mod->registration_sequence != registration_sequence)
CM_FreeModel( mod );
}
cm.numbmodels = 0;
for( i = 0, mod = cms.bmodels; i < cms.numbmodels; i++, mod++ )
CM_FreeModel( mod );
cms.numbmodels = 0;
if( cm.body )
if( cms.body )
{
// and physical body release too
NewtonDestroyBody( gWorld, cm.body );
cm.body = NULL;
cm.collision = NULL;
NewtonDestroyBody( gWorld, cms.body );
cms.body = NULL;
cms.collision = NULL;
}
cm.loaded = false;
cms.loaded = false;
}
/*
@ -956,20 +945,20 @@ cmodel_t *CM_BeginRegistration( const char *name, bool clientload, uint *checksu
// cinematic servers won't have anything at all
cm.numleafs = cm.numclusters = cm.numareas = 1;
*checksum = 0;
return &cm.bmodels[0];
return &cms.bmodels[0];
}
if(!com.strcmp( cm.name, name ) && cm.loaded )
if(!com.strcmp( cm.name, name ) && cms.loaded )
{
// singleplayer mode: serever already loading map
*checksum = cm.checksum;
if( !clientload )
{
// rebuild portals for server
Mem_Set( cm.portalopen, 0, sizeof( cm.portalopen ));
Mem_Set( cms.portalopen, 0, sizeof( cms.portalopen ));
CM_FloodAreaConnections();
}
// still have the right version
return &cm.bmodels[0];
return &cms.bmodels[0];
}
CM_FreeWorld(); // release old map
@ -1006,7 +995,7 @@ cmodel_t *CM_BeginRegistration( const char *name, bool clientload, uint *checksu
BSP_LoadVisibility(&hdr->lumps[LUMP_VISIBILITY]);
BSP_LoadModels(&hdr->lumps[LUMP_MODELS]);
BSP_LoadCollision(&hdr->lumps[LUMP_COLLISION]);
cm.loaded = true;
cms.loaded = true;
BSP_RecursiveFindNumLeafs( cm.nodes );
BSP_RecursiveSetParent( cm.nodes, NULL );
@ -1015,10 +1004,10 @@ cmodel_t *CM_BeginRegistration( const char *name, bool clientload, uint *checksu
Mem_Free( buf ); // release map buffer
com.strncpy( cm.name, name, MAX_STRING );
Mem_Set( cm.portalopen, 0, sizeof( cm.portalopen ));
Mem_Set( cms.portalopen, 0, sizeof( cms.portalopen ));
CM_FloodAreaConnections();
return &cm.bmodels[0];
return &cms.bmodels[0];
}
void CM_EndRegistration( void )
@ -1026,7 +1015,7 @@ void CM_EndRegistration( void )
cmodel_t *mod;
int i;
for( i = 0, mod = &cm.cmodels[0]; i < cm.numcmodels; i++, mod++)
for( i = 0, mod = &cms.cmodels[0]; i < cms.numcmodels; i++, mod++)
{
if(!mod->name[0]) continue;
if( mod->registration_sequence != registration_sequence )
@ -1372,18 +1361,18 @@ cmodel_t *CM_RegisterModel( const char *name )
if(name[0] == '*')
{
i = com.atoi( name + 1);
if( i < 1 || !cm.loaded || i >= cm.numbmodels)
if( i < 1 || !cms.loaded || i >= cms.numbmodels)
{
MsgDev(D_WARN, "CM_InlineModel: bad submodel number %d\n", i );
return NULL;
}
// prolonge registration
cm.bmodels[i].registration_sequence = registration_sequence;
return &cm.bmodels[i];
cms.bmodels[i].registration_sequence = registration_sequence;
return &cms.bmodels[i];
}
for( i = 0; i < cm.numcmodels; i++ )
for( i = 0; i < cms.numcmodels; i++ )
{
mod = &cm.cmodels[i];
mod = &cms.cmodels[i];
if(!mod->name[0]) continue;
if(!com.strcmp( name, mod->name ))
{
@ -1394,18 +1383,18 @@ cmodel_t *CM_RegisterModel( const char *name )
}
// find a free model slot spot
for( i = 0, mod = cm.cmodels; i < cm.numcmodels; i++, mod++)
for( i = 0, mod = cms.cmodels; i < cms.numcmodels; i++, mod++)
{
if(!mod->name[0]) break; // free spot
}
if( i == cm.numcmodels)
if( i == cms.numcmodels)
{
if( cm.numcmodels == MAX_MODELS )
if( cms.numcmodels == MAX_MODELS )
{
MsgDev( D_ERROR, "CM_LoadModel: MAX_MODELS limit exceeded\n" );
return NULL;
}
cm.numcmodels++;
cms.numcmodels++;
}
com.strncpy( mod->name, name, sizeof(mod->name));

View File

@ -230,7 +230,7 @@ void CM_ServerMove( pmove_t *pmove )
m_isAirBorne = true;
VectorSet( m_stepContact, 0.0f, -m_size[2], 0.0f );
NewtonUpVectorSetPin( cm.upVector, &vec3_up[0] );
NewtonUpVectorSetPin( cms.upVector, &vec3_up[0] );
}
void CM_ClientMove( pmove_t *pmove )
@ -298,7 +298,7 @@ physbody_t *Phys_CreatePlayer( sv_edict_t *ed, cmodel_t *mod, matrix4x3 transfor
// add and up vector constraint to help in keeping the body upright
VectorSet( upDirection, 0.0f, 1.0f, 0.0f );
cm.upVector = NewtonConstraintCreateUpVector( gWorld, &upDirection[0], body );
cms.upVector = NewtonConstraintCreateUpVector( gWorld, &upDirection[0], body );
NewtonBodySetContinuousCollisionMode( body, 1 );
return (physbody_t *)body;

View File

@ -63,17 +63,17 @@ void CM_DecompressVis( byte *in, byte *out )
byte *CM_ClusterPVS( int cluster )
{
if( cluster < 0 || cluster >= cm.numclusters || !cm.vis )
Mem_Set( cm.pvsrow, 0xFF, (cm.numclusters + 31) & ~31 );
else CM_DecompressVis( cm.visbase + cm.vis->bitofs[cluster][DVIS_PVS], cm.pvsrow );
return cm.pvsrow;
Mem_Set( cms.pvsrow, 0xFF, (cm.numclusters + 31) & ~31 );
else CM_DecompressVis( cm.visbase + cm.vis->bitofs[cluster][DVIS_PVS], cms.pvsrow );
return cms.pvsrow;
}
byte *CM_ClusterPHS( int cluster )
{
if( cluster < 0 || cluster >= cm.numclusters || !cm.vis )
Mem_Set( cm.phsrow, 0xFF, (cm.numclusters + 31) & ~31 );
else CM_DecompressVis( cm.visbase + cm.vis->bitofs[cluster][DVIS_PHS], cm.phsrow );
return cm.phsrow;
Mem_Set( cms.phsrow, 0xFF, (cm.numclusters + 31) & ~31 );
else CM_DecompressVis( cm.visbase + cm.vis->bitofs[cluster][DVIS_PHS], cms.phsrow );
return cms.phsrow;
}
/*
@ -149,7 +149,7 @@ void CM_FloodArea_r( carea_t *area, int floodnum )
for( i = 0; i < area->numareaportals; i++, p++ )
{
if( cm.portalopen[p->portalnum] )
if( cms.portalopen[p->portalnum] )
CM_FloodArea_r( &cm.areas[p->otherarea], floodnum );
}
}
@ -180,9 +180,9 @@ void CM_FloodAreaConnections( void )
void CM_SetAreaPortals ( byte *portals, size_t size )
{
if( size == sizeof( cm.portalopen ))
if( size == sizeof( cms.portalopen ))
{
Mem_Copy( cm.portalopen, portals, size );
Mem_Copy( cms.portalopen, portals, size );
CM_FloodAreaConnections();
return;
}
@ -193,8 +193,8 @@ void CM_GetAreaPortals ( byte **portals, size_t *size )
{
byte *prt = *portals;
if( prt ) Mem_Copy( prt, cm.portalopen, sizeof( cm.portalopen ));
if( size) *size = sizeof( cm.portalopen );
if( prt ) Mem_Copy( prt, cms.portalopen, sizeof( cms.portalopen ));
if( size) *size = sizeof( cms.portalopen );
}
void CM_SetAreaPortalState( int portalnum, bool open )
@ -202,7 +202,7 @@ void CM_SetAreaPortalState( int portalnum, bool open )
if( portalnum > cm.numareaportals )
Host_Error( "CM_SetAreaPortalState: areaportal > numareaportals\n" );
cm.portalopen[portalnum] = open;
cms.portalopen[portalnum] = open;
CM_FloodAreaConnections();
}
@ -270,14 +270,17 @@ bool CM_HeadnodeVisible( int nodenum, byte *visbits )
if( nodenum < 0 )
{
leafnum = -1-nodenum;
cluster = cm.leafs[leafnum].cluster;
cluster = CM_LeafCluster( leafnum );
if( cluster == -1 ) return false;
if( visbits[cluster>>3] & (1<<(cluster&7)))
return true;
return false;
}
node = &cm.nodes[nodenum];
if( nodenum < 0 || nodenum >= cm.numnodes )
Host_Error( "CM_HeadnodeVisible: bad number %i >= %i\n", nodenum, cm.numnodes );
node = cm.nodes + nodenum;
if( CM_HeadnodeVisible( node->children[0] - cm.nodes, visbits ))
return true;
return CM_HeadnodeVisible( node->children[1] - cm.nodes, visbits );

View File

@ -131,7 +131,7 @@ int CM_BoxLeafnums( const vec3_t mins, const vec3_t maxs, int *list, int listsiz
{
leaflist_t ll;
cm.checkcount++;
cms.checkcount++;
VectorCopy( mins, ll.bounds[0] );
VectorCopy( maxs, ll.bounds[1] );
ll.count = 0;

View File

@ -20,6 +20,7 @@
typedef enum
{
ED_SPAWNED = 0, // this entity requris to set own type with SV_ClassifyEdict
ED_WORLDSPAWN, // this is a worldspawn
ED_STATIC, // this is a logic without model or entity with static model
ED_AMBIENT, // this is entity emitted ambient sounds only
ED_NORMAL, // normal entity with model (and\or) sound

View File

@ -887,6 +887,45 @@ _inline void Matrix4x4_FromVectors( matrix4x4 out, const float vx[3], const floa
#endif
}
_inline void Matrix4x4_FromMatrix3x3( matrix4x4 out, const matrix3x3 in )
{
#ifdef OPENGL_STYLE
out[0][0] = in[0][0];
out[1][0] = in[1][0];
out[2][0] = in[2][0];
out[3][0] = 0.0f;
out[0][1] = in[0][1];
out[1][1] = in[1][1];
out[2][1] = in[2][1];
out[3][1] = 0.0f;
out[0][2] = in[0][2];
out[1][2] = in[1][2];
out[2][2] = in[2][2];
out[3][2] = 0.0f;
out[0][3] = 0.0f;
out[1][3] = 0.0f;
out[2][3] = 0.0f;
out[3][3] = 1.0f;
#else
out[0][0] = in[0][0];
out[0][1] = in[1][0];
out[0][2] = in[2][0];
out[0][3] = 0.0f;
out[1][0] = in[0][1];
out[1][1] = in[1][1];
out[1][2] = in[2][1];
out[1][3] = 0.0f;
out[2][0] = in[0][2];
out[2][1] = in[1][2];
out[2][2] = in[2][2];
out[2][3] = 0.0f;
out[3][0] = 0.0f;
out[3][1] = 0.0f;
out[3][2] = 0.0f;
out[3][3] = 1.0f;
#endif
}
/*
================
Matrix4x4_CreateModelview_FromAxis

View File

@ -219,6 +219,7 @@ typedef struct prvm_prog_s
void (*free_edict)(edict_t *ed);
void (*count_edicts)(void);
bool (*load_edict)(edict_t *ent); // initialize edict for first loading
void (*classify_edict)(edict_t *ent); // called after spawn for classify edict
void (*restore_edict)(edict_t *ent); // restore edict from savegame or changelevel
void (*init_cmd)(void);
void (*reset_cmd)(void);

View File

@ -42,8 +42,8 @@ typedef struct render_exp_s
size_t api_size; // must matched with sizeof(render_exp_t)
// initialize
bool (*Init)( void ); // init all render systems
void (*Shutdown)( void ); // shutdown all render systems
bool (*Init)( bool full ); // init all render systems
void (*Shutdown)( bool full ); // shutdown all render systems
void (*BeginRegistration)( const char *map );
bool (*RegisterModel)( const char *name, int cl_index ); // also build replacement index table

View File

@ -78,7 +78,7 @@ RB_DrawElements
*/
void RB_DrawElements( void )
{
ref_vindex_t *indices;
elem_t *indices;
indices = ref.indexArray;
@ -96,9 +96,11 @@ void RB_InitVertexBuffers( void )
{
int i;
ref.vertexBuffer = RB_AllocVertexBuffer( MAX_VERTEXES * sizeof(ref_varray_t), GL_STREAM_DRAW_ARB );
ref.vertexBuffer = RB_AllocVertexBuffer( MAX_VERTEXES * sizeof(vec3_t), GL_STREAM_DRAW_ARB );
ref.colorBuffer = RB_AllocVertexBuffer( MAX_VERTEXES * sizeof(vec4_t), GL_STREAM_DRAW_ARB );
ref.normalBuffer = RB_AllocVertexBuffer( MAX_VERTEXES * sizeof(vec3_t), GL_STREAM_DRAW_ARB );
for( i = 0; i < MAX_TEXTURE_UNITS; i++ )
ref.stBuffer[i] = RB_AllocVertexBuffer( MAX_VERTEXES * sizeof(vec3_t), GL_STREAM_DRAW_ARB );
ref.texCoordBuffer[i] = RB_AllocVertexBuffer( MAX_VERTEXES * sizeof(vec3_t), GL_STREAM_DRAW_ARB );
}
/*

View File

@ -125,27 +125,7 @@ BACKEND
#define MAX_VERTEXES 4096
#define MAX_ELEMENTS MAX_VERTEXES * 6
// vbo offsets
#define BUFFER_OFFSET_POINT 0 // in bytes
#define BUFFER_OFFSET_NORMAL 12
#define BUFFER_OFFSET_TANGENT 24
#define BUFFER_OFFSET_BINORMAL 36
#define BUFFER_OFFSET_STCOORD 48
#define BUFFER_OFFSET_LMCOORD 56
#define BUFFER_OFFSET_COLOR 64
typedef uint ref_vindex_t;
typedef struct ref_varray_s
{
vec3_t point;
vec3_t normal;
vec3_t tangent;
vec3_t binormal;
vec2_t stcoord;
vec2_t lmcoord;
vec4_t color;
} ref_varray_t;
typedef uint elem_t;
typedef struct ref_buffer_s
{
@ -181,12 +161,23 @@ typedef struct
int numIndex;
int numVertex;
ref_vindex_t indexArray[MAX_ELEMENTS];
ref_varray_t vertsArray[MAX_VERTEXES];
vec3_t stArray[MAX_TEXTURE_UNITS][MAX_VERTEXES];
ref_buffer_t *stBuffer[MAX_TEXTURE_UNITS];
// immediate buffers
vec3_t tangentArray[MAX_VERTEXES];
vec3_t binormalArray[MAX_VERTEXES];
vec4_t inTexCoordArray[MAX_VERTEXES];
// vbo source buffers
elem_t indexArray[MAX_ELEMENTS];
vec4_t colorArray[MAX_VERTEXES];
vec3_t vertexArray[MAX_VERTEXES];
vec3_t normalArray[MAX_VERTEXES];
vec3_t texCoordArray[MAX_TEXTURE_UNITS][MAX_VERTEXES];
ref_buffer_t *texCoordBuffer[MAX_TEXTURE_UNITS];
ref_buffer_t *vertexBuffer;
ref_buffer_t *colorBuffer;
ref_buffer_t *normalBuffer;
uint registration_sequence;
} ref_backend_t;

View File

@ -129,9 +129,9 @@ static void RB_SetVertex( float x, float y, float z )
}
// copy current vertex
ref.vertsArray[ref.numVertex].point[0] = x;
ref.vertsArray[ref.numVertex].point[1] = y;
ref.vertsArray[ref.numVertex].point[2] = z;
ref.vertexArray[ref.numVertex][0] = x;
ref.vertexArray[ref.numVertex][1] = y;
ref.vertexArray[ref.numVertex][2] = z;
ref.numVertex++;
// flush buffer if needed
@ -140,25 +140,39 @@ static void RB_SetVertex( float x, float y, float z )
static void RB_SetTexCoord( GLfloat s, GLfloat t, GLfloat ls, GLfloat lt )
{
ref.vertsArray[ref.numVertex].stcoord[0] = s;
ref.vertsArray[ref.numVertex].stcoord[1] = t;
ref.vertsArray[ref.numVertex].lmcoord[2] = ls;
ref.vertsArray[ref.numVertex].lmcoord[3] = lt;
ref.inTexCoordArray[ref.numVertex][0] = s;
ref.inTexCoordArray[ref.numVertex][1] = t;
ref.inTexCoordArray[ref.numVertex][2] = ls;
ref.inTexCoordArray[ref.numVertex][3] = lt;
}
static void RB_SetColor( GLfloat r, GLfloat g, GLfloat b, GLfloat a )
{
ref.vertsArray[ref.numVertex].color[0] = r;
ref.vertsArray[ref.numVertex].color[1] = g;
ref.vertsArray[ref.numVertex].color[2] = b;
ref.vertsArray[ref.numVertex].color[3] = a;
ref.colorArray[ref.numVertex][0] = r;
ref.colorArray[ref.numVertex][1] = g;
ref.colorArray[ref.numVertex][2] = b;
ref.colorArray[ref.numVertex][3] = a;
}
static void RB_SetNormal( GLfloat x, GLfloat y, GLfloat z )
{
ref.vertsArray[ref.numVertex].normal[0] = x;
ref.vertsArray[ref.numVertex].normal[1] = y;
ref.vertsArray[ref.numVertex].normal[2] = z;
ref.normalArray[ref.numVertex][0] = x;
ref.normalArray[ref.numVertex][1] = y;
ref.normalArray[ref.numVertex][2] = z;
}
static void RB_SetTangent( GLfloat x, GLfloat y, GLfloat z )
{
ref.tangentArray[ref.numVertex][0] = x;
ref.tangentArray[ref.numVertex][1] = y;
ref.tangentArray[ref.numVertex][2] = z;
}
static void RB_SetBinormal( GLfloat x, GLfloat y, GLfloat z )
{
ref.binormalArray[ref.numVertex][0] = x;
ref.binormalArray[ref.numVertex][1] = y;
ref.binormalArray[ref.numVertex][2] = z;
}
/*
@ -206,6 +220,16 @@ void GL_Normal3fv( const GLfloat *v )
RB_SetNormal( v[0], v[1], v[2] );
}
void GL_Tangent3fv( const GLfloat *v )
{
RB_SetTangent( v[0], v[1], v[2] );
}
void GL_Binormal3fv( const GLfloat *v )
{
RB_SetBinormal( v[0], v[1], v[2] );
}
void GL_TexCoord2f( GLfloat s, GLfloat t )
{
RB_SetTexCoord( s, t, 0.0f, 0.0f );
@ -277,9 +301,9 @@ static void RB_BuildTables( void )
}
/*
=================
RB_TableForFunc
=================
=================
RB_TableForFunc
=================
*/
static float *RB_TableForFunc( const waveFunc_t *func )
{
@ -325,10 +349,10 @@ static void RB_DeformVertexes( void )
for( j = 0; j < ref.numVertex; j++ )
{
v = ref.vertsArray[j].point;
v = ref.vertexArray[j];
t = (v[0] + v[1] + v[2]) * deformVertexes->params[0] + now;
f = table[((int)(t * TABLE_SIZE)) & TABLE_MASK] * deformVertexes->func.params[1] + deformVertexes->func.params[0];
VectorMA(ref.vertsArray[j].point, f, ref.vertsArray[j].normal, ref.vertsArray[j].point);
VectorMA( ref.vertexArray[j], f, ref.normalArray[j], ref.vertexArray[j] );
}
break;
case DEFORM_MOVE:
@ -338,7 +362,7 @@ static void RB_DeformVertexes( void )
for( j = 0; j < ref.numVertex; j++ )
{
VectorMA(ref.vertsArray[j].point, f, deformVertexes->params, ref.vertsArray[j].point);
VectorMA(ref.vertexArray[j], f, deformVertexes->params, ref.vertexArray[j]);
}
break;
case DEFORM_NORMAL:
@ -346,10 +370,10 @@ static void RB_DeformVertexes( void )
for (j = 0; j < ref.numVertex; j++)
{
f = ref.vertsArray[j].normal[2] * now;
ref.vertsArray[j].normal[0] *= (deformVertexes->params[0] * com.sin( f ));
ref.vertsArray[j].normal[1] *= (deformVertexes->params[0] * com.cos( f ));
VectorNormalizeFast( ref.vertsArray[j].normal );
f = ref.normalArray[j][2] * now;
ref.normalArray[j][0] *= (deformVertexes->params[0] * com.sin( f ));
ref.normalArray[j][1] *= (deformVertexes->params[0] * com.cos( f ));
VectorNormalizeFast( ref.normalArray[j] );
}
break;
default:
@ -378,9 +402,9 @@ static void RB_CalcVertexColors( shaderStage_t *stage )
case RGBGEN_IDENTITY:
for( i = 0; i < ref.numVertex; i++ )
{
ref.vertsArray[i].color[0] = 1.0f;
ref.vertsArray[i].color[1] = 1.0f;
ref.vertsArray[i].color[2] = 1.0f;
ref.colorArray[i][0] = 1.0f;
ref.colorArray[i][1] = 1.0f;
ref.colorArray[i][2] = 1.0f;
}
break;
case RGBGEN_IDENTITYLIGHTING:
@ -390,9 +414,9 @@ static void RB_CalcVertexColors( shaderStage_t *stage )
for( i = 0; i < ref.numVertex; i++ )
{
ref.vertsArray[i].color[0] = r;
ref.vertsArray[i].color[1] = g;
ref.vertsArray[i].color[2] = b;
ref.colorArray[i][0] = r;
ref.colorArray[i][1] = g;
ref.colorArray[i][2] = b;
}
break;
case RGBGEN_WAVE:
@ -408,9 +432,9 @@ static void RB_CalcVertexColors( shaderStage_t *stage )
for( i = 0; i < ref.numVertex; i++ )
{
ref.vertsArray[i].color[0] = r;
ref.vertsArray[i].color[1] = g;
ref.vertsArray[i].color[2] = b;
ref.colorArray[i][0] = r;
ref.colorArray[i][1] = g;
ref.colorArray[i][2] = b;
}
break;
case RGBGEN_COLORWAVE:
@ -426,9 +450,9 @@ static void RB_CalcVertexColors( shaderStage_t *stage )
for( i = 0; i < ref.numVertex; i++ )
{
ref.vertsArray[i].color[0] = r;
ref.vertsArray[i].color[1] = g;
ref.vertsArray[i].color[2] = b;
ref.colorArray[i][0] = r;
ref.colorArray[i][1] = g;
ref.colorArray[i][2] = b;
}
break;
case RGBGEN_VERTEX:
@ -436,25 +460,25 @@ static void RB_CalcVertexColors( shaderStage_t *stage )
case RGBGEN_ONEMINUSVERTEX:
for( i = 0; i < ref.numVertex; i++ )
{
ref.vertsArray[i].color[0] = 1.0f - ref.vertsArray[i].color[0];
ref.vertsArray[i].color[1] = 1.0f - ref.vertsArray[i].color[1];
ref.vertsArray[i].color[2] = 1.0f - ref.vertsArray[i].color[2];
ref.colorArray[i][0] = 1.0f - ref.colorArray[i][0];
ref.colorArray[i][1] = 1.0f - ref.colorArray[i][1];
ref.colorArray[i][2] = 1.0f - ref.colorArray[i][2];
}
break;
case RGBGEN_ENTITY:
for( i = 0; i < ref.numVertex; i++ )
{
ref.vertsArray[i].color[0] = m_pCurrentEntity->rendercolor[0];
ref.vertsArray[i].color[1] = m_pCurrentEntity->rendercolor[1];
ref.vertsArray[i].color[2] = m_pCurrentEntity->rendercolor[2];
ref.colorArray[i][0] = m_pCurrentEntity->rendercolor[0];
ref.colorArray[i][1] = m_pCurrentEntity->rendercolor[1];
ref.colorArray[i][2] = m_pCurrentEntity->rendercolor[2];
}
break;
case RGBGEN_ONEMINUSENTITY:
for( i = 0; i < ref.numVertex; i++ )
{
ref.vertsArray[i].color[0] = 1.0f - m_pCurrentEntity->rendercolor[0];
ref.vertsArray[i].color[1] = 1.0f - m_pCurrentEntity->rendercolor[1];
ref.vertsArray[i].color[2] = 1.0f - m_pCurrentEntity->rendercolor[2];
ref.colorArray[i][0] = 1.0f - m_pCurrentEntity->rendercolor[0];
ref.colorArray[i][1] = 1.0f - m_pCurrentEntity->rendercolor[1];
ref.colorArray[i][2] = 1.0f - m_pCurrentEntity->rendercolor[2];
}
break;
case RGBGEN_LIGHTINGAMBIENT:
@ -470,9 +494,9 @@ static void RB_CalcVertexColors( shaderStage_t *stage )
for( i = 0; i < ref.numVertex; i++ )
{
ref.vertsArray[i].color[0] = r;
ref.vertsArray[i].color[1] = g;
ref.vertsArray[i].color[2] = b;
ref.colorArray[i][0] = r;
ref.colorArray[i][1] = g;
ref.colorArray[i][2] = b;
}
break;
default:
@ -483,7 +507,7 @@ static void RB_CalcVertexColors( shaderStage_t *stage )
{
case ALPHAGEN_IDENTITY:
for( i = 0; i < ref.numVertex; i++ )
ref.vertsArray[i].color[3] = 1.0f;
ref.colorArray[i][3] = 1.0f;
break;
case ALPHAGEN_WAVE:
table = RB_TableForFunc(&alphaGen->func);
@ -493,7 +517,7 @@ static void RB_CalcVertexColors( shaderStage_t *stage )
a = 1.0f * f;
for( i = 0; i < ref.numVertex; i++ )
ref.vertsArray[i].color[3] = a;
ref.colorArray[i][3] = a;
break;
case ALPHAGEN_ALPHAWAVE:
table = RB_TableForFunc(&alphaGen->func);
@ -503,91 +527,91 @@ static void RB_CalcVertexColors( shaderStage_t *stage )
a = 1.0f * (alphaGen->params[0] * f);
for( i = 0; i < ref.numVertex; i++ )
ref.vertsArray[i].color[3] = a;
ref.colorArray[i][3] = a;
break;
case ALPHAGEN_VERTEX:
break;
case ALPHAGEN_ONEMINUSVERTEX:
for( i = 0; i < ref.numVertex; i++ )
ref.vertsArray[i].color[3] = 1.0f - ref.vertsArray[i].color[3];
ref.colorArray[i][3] = 1.0f - ref.colorArray[i][3];
break;
case ALPHAGEN_ENTITY:
for( i = 0; i < ref.numVertex; i++ )
ref.vertsArray[i].color[3] = m_pCurrentEntity->renderamt;
ref.colorArray[i][3] = m_pCurrentEntity->renderamt;
break;
case ALPHAGEN_ONEMINUSENTITY:
for( i = 0; i < ref.numVertex; i++ )
ref.vertsArray[i].color[3] = 1.0f - m_pCurrentEntity->renderamt;
ref.colorArray[i][3] = 1.0f - m_pCurrentEntity->renderamt;
break;
case ALPHAGEN_DOT:
if( !AxisCompare( m_pCurrentEntity->axis, axisDefault ))
VectorRotate( r_forward, m_pCurrentEntity->axis, vec );
if( !Matrix3x3_Compare( m_pCurrentEntity->matrix, matrix3x3_identity ))
Matrix3x3_Transform( m_pCurrentEntity->matrix, r_forward, vec );
else VectorCopy( r_forward, vec );
for( i = 0; i < ref.numVertex; i++ )
{
f = DotProduct(vec, ref.vertsArray[i].normal );
f = DotProduct(vec, ref.normalArray[i] );
if( f < 0 ) f = -f;
ref.vertsArray[i].color[3] = 1.0f * bound( alphaGen->params[0], f, alphaGen->params[1] );
ref.colorArray[i][3] = 1.0f * bound( alphaGen->params[0], f, alphaGen->params[1] );
}
break;
case ALPHAGEN_ONEMINUSDOT:
if( !AxisCompare( m_pCurrentEntity->axis, axisDefault ))
VectorRotate( r_forward, m_pCurrentEntity->axis, vec );
if( !Matrix3x3_Compare( m_pCurrentEntity->matrix, matrix3x3_identity ))
Matrix3x3_Transform( m_pCurrentEntity->matrix, r_forward, vec );
else VectorCopy( r_forward, vec );
for( i = 0; i < ref.numVertex; i++ )
{
f = DotProduct(vec, ref.vertsArray[i].normal );
f = DotProduct(vec, ref.normalArray[i] );
if( f < 0 ) f = -f;
ref.vertsArray[i].color[3] = 1.0f * bound( alphaGen->params[0], 1.0 - f, alphaGen->params[1]);
ref.colorArray[i][3] = 1.0f * bound( alphaGen->params[0], 1.0 - f, alphaGen->params[1]);
}
break;
case ALPHAGEN_FADE:
for( i = 0; i < ref.numVertex; i++ )
{
VectorAdd( ref.vertsArray[i].point, m_pCurrentEntity->origin, vec );
VectorAdd( ref.vertexArray[i], m_pCurrentEntity->origin, vec );
f = VectorDistance( vec, r_refdef.vieworg );
f = bound( alphaGen->params[0], f, alphaGen->params[1] ) - alphaGen->params[0];
f = f * alphaGen->params[2];
ref.vertsArray[i].color[3] = 1.0f * bound( 0.0, f, 1.0 );
ref.colorArray[i][3] = 1.0f * bound( 0.0, f, 1.0 );
}
break;
case ALPHAGEN_ONEMINUSFADE:
for( i = 0; i < ref.numVertex; i++ )
{
VectorAdd( ref.vertsArray[i].point, m_pCurrentEntity->origin, vec );
VectorAdd( ref.vertexArray[i], m_pCurrentEntity->origin, vec );
f = VectorDistance( vec, r_refdef.vieworg );
f = bound( alphaGen->params[0], f, alphaGen->params[1] ) - alphaGen->params[0];
f = f * alphaGen->params[2];
ref.vertsArray[i].color[3] = 1.0f * bound( 0.0, 1.0 - f, 1.0 );
ref.colorArray[i][3] = 1.0f * bound( 0.0, 1.0 - f, 1.0 );
}
break;
case ALPHAGEN_LIGHTINGSPECULAR:
if( !AxisCompare( m_pCurrentEntity->axis, axisDefault ))
if( !Matrix3x3_Compare( m_pCurrentEntity->matrix, matrix3x3_identity ))
{
VectorSubtract( r_origin, m_pCurrentEntity->origin, dir );
VectorRotate( dir, m_pCurrentEntity->axis, vec );
Matrix3x3_Transform( m_pCurrentEntity->matrix, dir, vec );
}
else VectorSubtract( r_origin, m_pCurrentEntity->origin, vec );
for( i = 0; i < ref.numVertex; i++ )
{
VectorSubtract( vec, ref.vertsArray[i].point, dir );
VectorSubtract( vec, ref.vertexArray[i], dir );
VectorNormalizeFast( dir );
f = DotProduct( dir, ref.vertsArray[i].normal );
f = DotProduct( dir, ref.normalArray[i] );
f = pow( f, alphaGen->params[0] );
ref.vertsArray[i].color[3] = 1.0f * bound( 0.0, f, 1.0 );
ref.colorArray[i][3] = 1.0f * bound( 0.0, f, 1.0 );
}
break;
case ALPHAGEN_CONST:
a = 1.0f * alphaGen->params[0];
for( i = 0; i < ref.numVertex; i++ )
ref.vertsArray[i].color[3] = a;
ref.colorArray[i][3] = a;
break;
default: Host_Error( "RB_CalcVertexColors: unknown alphaGen type %i in shader '%s'\n", alphaGen->type, m_pCurrentShader->name);
}
@ -616,47 +640,47 @@ static void RB_CalcTextureCoords( stageBundle_t *bundle, uint unit )
case TCGEN_BASE:
for( i = 0; i < ref.numVertex; i++ )
{
ref.stArray[unit][i][0] = ref.vertsArray[i].stcoord[0];
ref.stArray[unit][i][1] = ref.vertsArray[i].stcoord[1];
ref.texCoordArray[unit][i][0] = ref.inTexCoordArray[i][0];
ref.texCoordArray[unit][i][1] = ref.inTexCoordArray[i][1];
}
break;
case TCGEN_LIGHTMAP:
for( i = 0; i < ref.numVertex; i++ )
{
ref.stArray[unit][i][0] = ref.vertsArray[i].lmcoord[0];
ref.stArray[unit][i][1] = ref.vertsArray[i].lmcoord[1];
ref.texCoordArray[unit][i][0] = ref.inTexCoordArray[i][2];
ref.texCoordArray[unit][i][1] = ref.inTexCoordArray[i][3];
}
break;
case TCGEN_ENVIRONMENT:
if (!AxisCompare( m_pCurrentEntity->axis, axisDefault ))
if( !Matrix3x3_Compare( m_pCurrentEntity->matrix, matrix3x3_identity ))
{
VectorSubtract( r_origin, m_pCurrentEntity->origin, dir );
VectorRotate( dir, m_pCurrentEntity->axis, vec );
Matrix3x3_Transform( m_pCurrentEntity->matrix, dir, vec );
}
else VectorSubtract( r_origin, m_pCurrentEntity->origin, vec );
for( i = 0; i < ref.numVertex; i++ )
{
VectorSubtract( vec, ref.vertsArray[i].point, dir );
VectorSubtract( vec, ref.vertexArray[i], dir );
VectorNormalizeFast( dir );
f = 2.0 * DotProduct( dir, ref.vertsArray[i].normal );
ref.stArray[unit][i][0] = dir[0] - ref.vertsArray[i].normal[0] * f;
ref.stArray[unit][i][1] = dir[1] - ref.vertsArray[i].normal[1] * f;
f = 2.0 * DotProduct( dir, ref.normalArray[i] );
ref.texCoordArray[unit][i][0] = dir[0] - ref.normalArray[i][0] * f;
ref.texCoordArray[unit][i][1] = dir[1] - ref.normalArray[i][1] * f;
}
break;
case TCGEN_VECTOR:
for( i = 0; i < ref.numVertex; i++ )
{
ref.stArray[unit][i][0] = DotProduct( ref.vertsArray[i].point, &tcGen->params[0] );
ref.stArray[unit][i][1] = DotProduct( ref.vertsArray[i].point, &tcGen->params[3] );
ref.texCoordArray[unit][i][0] = DotProduct( ref.vertexArray[i], &tcGen->params[0] );
ref.texCoordArray[unit][i][1] = DotProduct( ref.vertexArray[i], &tcGen->params[3] );
}
break;
case TCGEN_WARP:
for( i = 0; i < ref.numVertex; i++ )
{
ref.stArray[unit][i][0] = ref.vertsArray[i].stcoord[0] + rb_warpSinTable[((int)((ref.vertsArray[i].stcoord[1] * 8.0 + m_fShaderTime) * (256.0/M_PI2))) & 255] * (1.0/64);
ref.stArray[unit][i][1] = ref.vertsArray[i].stcoord[1] + rb_warpSinTable[((int)((ref.vertsArray[i].stcoord[0] * 8.0 + m_fShaderTime) * (256.0/M_PI2))) & 255] * (1.0/64);
ref.texCoordArray[unit][i][0] = ref.inTexCoordArray[i][0] + rb_warpSinTable[((int)((ref.inTexCoordArray[i][1] * 8.0 + m_fShaderTime) * (256.0/M_PI2))) & 255] * (1.0/64);
ref.texCoordArray[unit][i][1] = ref.inTexCoordArray[i][1] + rb_warpSinTable[((int)((ref.inTexCoordArray[i][0] * 8.0 + m_fShaderTime) * (256.0/M_PI2))) & 255] * (1.0/64);
}
break;
case TCGEN_LIGHTVECTOR:
@ -664,25 +688,25 @@ static void RB_CalcTextureCoords( stageBundle_t *bundle, uint unit )
{
for( i = 0; i < ref.numVertex; i++ )
{
R_LightDir( ref.vertsArray[i].point, lightVector );
R_LightDir( ref.vertexArray[i], lightVector );
ref.stArray[unit][i][0] = DotProduct( lightVector, ref.vertsArray[i].tangent );
ref.stArray[unit][i][1] = DotProduct( lightVector, ref.vertsArray[i].binormal );
ref.stArray[unit][i][2] = DotProduct( lightVector, ref.vertsArray[i].normal );
ref.texCoordArray[unit][i][0] = DotProduct( lightVector, ref.tangentArray[i] );
ref.texCoordArray[unit][i][1] = DotProduct( lightVector, ref.binormalArray[i] );
ref.texCoordArray[unit][i][2] = DotProduct( lightVector, ref.normalArray[i] );
}
}
else
{
R_LightDir( m_pCurrentEntity->origin, dir );
if( !AxisCompare( m_pCurrentEntity->axis, axisDefault ))
VectorRotate( dir, m_pCurrentEntity->axis, lightVector );
if( !Matrix3x3_Compare( m_pCurrentEntity->matrix, matrix3x3_identity ))
Matrix3x3_Transform( m_pCurrentEntity->matrix, dir, lightVector );
else VectorCopy( dir, lightVector );
for( i = 0; i < ref.numVertex; i++ )
{
ref.stArray[unit][i][0] = DotProduct(lightVector, ref.vertsArray[i].tangent );
ref.stArray[unit][i][1] = DotProduct(lightVector, ref.vertsArray[i].binormal );
ref.stArray[unit][i][2] = DotProduct(lightVector, ref.vertsArray[i].normal );
ref.texCoordArray[unit][i][0] = DotProduct(lightVector, ref.tangentArray[i] );
ref.texCoordArray[unit][i][1] = DotProduct(lightVector, ref.binormalArray[i] );
ref.texCoordArray[unit][i][2] = DotProduct(lightVector, ref.normalArray[i] );
}
}
break;
@ -691,28 +715,28 @@ static void RB_CalcTextureCoords( stageBundle_t *bundle, uint unit )
{
for( i = 0; i < ref.numVertex; i++ )
{
R_LightDir( ref.vertsArray[i].point, lightVector );
R_LightDir( ref.vertexArray[i], lightVector );
VectorSubtract( r_refdef.vieworg, ref.vertsArray[i].point, eyeVector );
VectorSubtract( r_refdef.vieworg, ref.vertexArray[i], eyeVector );
VectorNormalizeFast( lightVector );
VectorNormalizeFast( eyeVector );
VectorAdd( lightVector, eyeVector, halfAngle );
ref.stArray[unit][i][0] = DotProduct( halfAngle, ref.vertsArray[i].tangent );
ref.stArray[unit][i][1] = DotProduct( halfAngle, ref.vertsArray[i].binormal );
ref.stArray[unit][i][2] = DotProduct( halfAngle, ref.vertsArray[i].normal );
ref.texCoordArray[unit][i][0] = DotProduct( halfAngle, ref.tangentArray[i] );
ref.texCoordArray[unit][i][1] = DotProduct( halfAngle, ref.binormalArray[i] );
ref.texCoordArray[unit][i][2] = DotProduct( halfAngle, ref.normalArray[i] );
}
}
else
{
R_LightDir( m_pCurrentEntity->origin, dir );
if( !AxisCompare( m_pCurrentEntity->axis, axisDefault ))
if( !Matrix3x3_Compare( m_pCurrentEntity->matrix, matrix3x3_identity ))
{
VectorRotate( dir, m_pCurrentEntity->axis, lightVector );
Matrix3x3_Transform( m_pCurrentEntity->matrix, dir, lightVector );
VectorSubtract( r_origin, m_pCurrentEntity->origin, dir );
VectorRotate( dir, m_pCurrentEntity->axis, eyeVector );
Matrix3x3_Transform( m_pCurrentEntity->matrix, dir, eyeVector );
}
else
{
@ -727,9 +751,9 @@ static void RB_CalcTextureCoords( stageBundle_t *bundle, uint unit )
for( i = 0; i < ref.numVertex; i++ )
{
ref.stArray[unit][i][0] = DotProduct(halfAngle, ref.vertsArray[i].tangent );
ref.stArray[unit][i][1] = DotProduct(halfAngle, ref.vertsArray[i].binormal );
ref.stArray[unit][i][2] = DotProduct(halfAngle, ref.vertsArray[i].normal );
ref.texCoordArray[unit][i][0] = DotProduct(halfAngle, ref.tangentArray[i] );
ref.texCoordArray[unit][i][1] = DotProduct(halfAngle, ref.binormalArray[i] );
ref.texCoordArray[unit][i][2] = DotProduct(halfAngle, ref.normalArray[i] );
}
}
break;
@ -755,15 +779,15 @@ static void RB_CalcTextureCoords( stageBundle_t *bundle, uint unit )
case TCMOD_TRANSLATE:
for( j = 0; j < ref.numVertex; j++ )
{
ref.stArray[unit][j][0] += tcMod->params[0];
ref.stArray[unit][j][1] += tcMod->params[1];
ref.texCoordArray[unit][j][0] += tcMod->params[0];
ref.texCoordArray[unit][j][1] += tcMod->params[1];
}
break;
case TCMOD_SCALE:
for( j = 0; j < ref.numVertex; j++ )
{
ref.stArray[unit][j][0] *= tcMod->params[0];
ref.stArray[unit][j][1] *= tcMod->params[1];
ref.texCoordArray[unit][j][0] *= tcMod->params[0];
ref.texCoordArray[unit][j][1] *= tcMod->params[1];
}
break;
case TCMOD_SCROLL:
@ -774,8 +798,8 @@ static void RB_CalcTextureCoords( stageBundle_t *bundle, uint unit )
for( j = 0; j < ref.numVertex; j++ )
{
ref.stArray[unit][j][0] += st[0];
ref.stArray[unit][j][1] += st[1];
ref.texCoordArray[unit][j][0] += st[0];
ref.texCoordArray[unit][j][1] += st[1];
}
break;
case TCMOD_ROTATE:
@ -785,10 +809,10 @@ static void RB_CalcTextureCoords( stageBundle_t *bundle, uint unit )
for( j = 0; j < ref.numVertex; j++ )
{
st[0] = ref.stArray[unit][j][0];
st[1] = ref.stArray[unit][j][1];
ref.stArray[unit][j][0] = c * (st[0] - 0.5) - s * (st[1] - 0.5) + 0.5;
ref.stArray[unit][j][1] = c * (st[1] - 0.5) + s * (st[0] - 0.5) + 0.5;
st[0] = ref.texCoordArray[unit][j][0];
st[1] = ref.texCoordArray[unit][j][1];
ref.texCoordArray[unit][j][0] = c * (st[0] - 0.5) - s * (st[1] - 0.5) + 0.5;
ref.texCoordArray[unit][j][1] = c * (st[1] - 0.5) + s * (st[0] - 0.5) + 0.5;
}
break;
case TCMOD_STRETCH:
@ -801,8 +825,8 @@ static void RB_CalcTextureCoords( stageBundle_t *bundle, uint unit )
for( j = 0; j < ref.numVertex; j++ )
{
ref.stArray[unit][j][0] = ref.stArray[unit][j][0] * f + t;
ref.stArray[unit][j][1] = ref.stArray[unit][j][1] * f + t;
ref.texCoordArray[unit][j][0] = ref.texCoordArray[unit][j][0] * f + t;
ref.texCoordArray[unit][j][1] = ref.texCoordArray[unit][j][1] * f + t;
}
break;
case TCMOD_TURB:
@ -811,18 +835,18 @@ static void RB_CalcTextureCoords( stageBundle_t *bundle, uint unit )
for( j = 0; j < ref.numVertex; j++ )
{
v = ref.vertsArray[j].point;
ref.stArray[unit][j][0] += (table[((int)(((v[0] + v[2]) * 1.0/128 * 0.125 + now) * TABLE_SIZE)) & TABLE_MASK] * tcMod->func.params[1] + tcMod->func.params[0]);
ref.stArray[unit][j][1] += (table[((int)(((v[1]) * 1.0/128 * 0.125 + now) * TABLE_SIZE)) & TABLE_MASK] * tcMod->func.params[1] + tcMod->func.params[0]);
v = ref.vertexArray[j];
ref.texCoordArray[unit][j][0] += (table[((int)(((v[0] + v[2]) * 1.0/128 * 0.125 + now) * TABLE_SIZE)) & TABLE_MASK] * tcMod->func.params[1] + tcMod->func.params[0]);
ref.texCoordArray[unit][j][1] += (table[((int)(((v[1]) * 1.0/128 * 0.125 + now) * TABLE_SIZE)) & TABLE_MASK] * tcMod->func.params[1] + tcMod->func.params[0]);
}
break;
case TCMOD_TRANSFORM:
for( j = 0; j < ref.numVertex; j++ )
{
st[0] = ref.stArray[unit][j][0];
st[1] = ref.stArray[unit][j][1];
ref.stArray[unit][j][0] = st[0] * tcMod->params[0] + st[1] * tcMod->params[2] + tcMod->params[4];
ref.stArray[unit][j][1] = st[1] * tcMod->params[1] + st[0] * tcMod->params[3] + tcMod->params[5];
st[0] = ref.texCoordArray[unit][j][0];
st[1] = ref.texCoordArray[unit][j][1];
ref.texCoordArray[unit][j][0] = st[0] * tcMod->params[0] + st[1] * tcMod->params[2] + tcMod->params[4];
ref.texCoordArray[unit][j][1] = st[1] * tcMod->params[1] + st[0] * tcMod->params[3] + tcMod->params[5];
}
break;
default: Host_Error( "RB_CalcTextureCoords: unknown tcMod type %i in shader '%s'\n", tcMod->type, m_pCurrentShader->name);
@ -845,16 +869,16 @@ static void RB_SetupVertexProgram( shaderStage_t *stage )
pglProgramLocalParameter4fARB( GL_VERTEX_PROGRAM_ARB, 2, r_right[0], r_right[1], r_right[2], 0 );
pglProgramLocalParameter4fARB( GL_VERTEX_PROGRAM_ARB, 3, r_up[0], r_up[1], r_up[2], 0 );
pglProgramLocalParameter4fARB( GL_VERTEX_PROGRAM_ARB, 4, m_pCurrentEntity->origin[0], m_pCurrentEntity->origin[1], m_pCurrentEntity->origin[2], 0 );
pglProgramLocalParameter4fARB( GL_VERTEX_PROGRAM_ARB, 5, m_pCurrentEntity->axis[0][0], m_pCurrentEntity->axis[0][1], m_pCurrentEntity->axis[0][2], 0 );
pglProgramLocalParameter4fARB( GL_VERTEX_PROGRAM_ARB, 6, m_pCurrentEntity->axis[1][0], m_pCurrentEntity->axis[1][1], m_pCurrentEntity->axis[1][2], 0 );
pglProgramLocalParameter4fARB( GL_VERTEX_PROGRAM_ARB, 7, m_pCurrentEntity->axis[2][0], m_pCurrentEntity->axis[2][1], m_pCurrentEntity->axis[2][2], 0 );
pglProgramLocalParameter4fARB( GL_VERTEX_PROGRAM_ARB, 5, m_pCurrentEntity->matrix[0][0], m_pCurrentEntity->matrix[0][1], m_pCurrentEntity->matrix[0][2], 0 );
pglProgramLocalParameter4fARB( GL_VERTEX_PROGRAM_ARB, 6, m_pCurrentEntity->matrix[1][0], m_pCurrentEntity->matrix[1][1], m_pCurrentEntity->matrix[1][2], 0 );
pglProgramLocalParameter4fARB( GL_VERTEX_PROGRAM_ARB, 7, m_pCurrentEntity->matrix[2][0], m_pCurrentEntity->matrix[2][1], m_pCurrentEntity->matrix[2][2], 0 );
pglProgramLocalParameter4fARB( GL_VERTEX_PROGRAM_ARB, 8, m_fShaderTime, 0, 0, 0 );
}
/*
=================
RB_SetupFragmentProgram
=================
=================
RB_SetupFragmentProgram
=================
*/
static void RB_SetupFragmentProgram( shaderStage_t *stage )
{
@ -866,9 +890,9 @@ static void RB_SetupFragmentProgram( shaderStage_t *stage )
pglProgramLocalParameter4fARB( GL_FRAGMENT_PROGRAM_ARB, 2, r_right[0], r_right[1], r_right[2], 0 );
pglProgramLocalParameter4fARB( GL_FRAGMENT_PROGRAM_ARB, 3, r_up[0], r_up[1], r_up[2], 0 );
pglProgramLocalParameter4fARB( GL_FRAGMENT_PROGRAM_ARB, 4, m_pCurrentEntity->origin[0], m_pCurrentEntity->origin[1], m_pCurrentEntity->origin[2], 0 );
pglProgramLocalParameter4fARB( GL_FRAGMENT_PROGRAM_ARB, 5, m_pCurrentEntity->axis[0][0], m_pCurrentEntity->axis[0][1], m_pCurrentEntity->axis[0][2], 0 );
pglProgramLocalParameter4fARB( GL_FRAGMENT_PROGRAM_ARB, 6, m_pCurrentEntity->axis[1][0], m_pCurrentEntity->axis[1][1], m_pCurrentEntity->axis[1][2], 0 );
pglProgramLocalParameter4fARB( GL_FRAGMENT_PROGRAM_ARB, 7, m_pCurrentEntity->axis[2][0], m_pCurrentEntity->axis[2][1], m_pCurrentEntity->axis[2][2], 0 );
pglProgramLocalParameter4fARB( GL_FRAGMENT_PROGRAM_ARB, 5, m_pCurrentEntity->matrix[0][0], m_pCurrentEntity->matrix[0][1], m_pCurrentEntity->matrix[0][2], 0 );
pglProgramLocalParameter4fARB( GL_FRAGMENT_PROGRAM_ARB, 6, m_pCurrentEntity->matrix[1][0], m_pCurrentEntity->matrix[1][1], m_pCurrentEntity->matrix[1][2], 0 );
pglProgramLocalParameter4fARB( GL_FRAGMENT_PROGRAM_ARB, 7, m_pCurrentEntity->matrix[2][0], m_pCurrentEntity->matrix[2][1], m_pCurrentEntity->matrix[2][2], 0 );
pglProgramLocalParameter4fARB( GL_FRAGMENT_PROGRAM_ARB, 8, m_fShaderTime, 0, 0, 0 );
}
@ -1069,6 +1093,14 @@ static void RB_RenderShaderARB( void )
RB_SetShaderState();
RB_DeformVertexes();
RB_UpdateVertexBuffer( ref.vertexBuffer, ref.vertexArray, ref.numVertex * sizeof( vec3_t ));
pglEnableClientState( GL_VERTEX_ARRAY );
pglVertexPointer( 3, GL_FLOAT, 0, ref.vertexBuffer->pointer );
RB_UpdateVertexBuffer( ref.normalBuffer, ref.normalArray, ref.numVertex * sizeof( vec3_t ));
pglEnableClientState( GL_NORMAL_ARRAY );
pglNormalPointer( GL_FLOAT, 0, ref.vertexBuffer->pointer );
for( i = 0; i < m_pCurrentShader->numStages; i++ )
{
stage = m_pCurrentShader->stages[i];
@ -1076,16 +1108,9 @@ static void RB_RenderShaderARB( void )
RB_SetShaderStageState( stage );
RB_CalcVertexColors( stage );
RB_UpdateVertexBuffer( ref.vertexBuffer, ref.vertsArray, ref.numVertex * sizeof(ref_varray_t));
pglEnableClientState( GL_VERTEX_ARRAY );
pglVertexPointer( 3, GL_FLOAT, sizeof(ref_varray_t), ref.vertexBuffer->pointer + BUFFER_OFFSET_POINT );
pglEnableClientState( GL_NORMAL_ARRAY );
pglNormalPointer( GL_FLOAT, sizeof(ref_varray_t), ref.vertexBuffer->pointer + BUFFER_OFFSET_NORMAL );
RB_UpdateVertexBuffer( ref.colorBuffer, ref.colorArray, ref.numVertex * sizeof( vec4_t ));
pglEnableClientState( GL_COLOR_ARRAY );
pglColorPointer( 4, GL_FLOAT, sizeof(ref_varray_t), ref.vertexBuffer->pointer + BUFFER_OFFSET_COLOR );
pglColorPointer( 4, GL_FLOAT, 0, ref.vertexBuffer->pointer );
for( j = 0; j < stage->numBundles; j++ )
{
@ -1094,9 +1119,9 @@ static void RB_RenderShaderARB( void )
RB_SetupTextureUnit( bundle, j );
RB_CalcTextureCoords( bundle, j );
RB_UpdateVertexBuffer( ref.stBuffer[j], ref.stArray[j], ref.numVertex * sizeof(vec3_t));
RB_UpdateVertexBuffer( ref.texCoordBuffer[j], ref.texCoordArray[j], ref.numVertex * sizeof( vec3_t ));
pglEnableClientState( GL_TEXTURE_COORD_ARRAY );
pglTexCoordPointer( 3, GL_FLOAT, 0, ref.stBuffer[j]->pointer );
pglTexCoordPointer( 3, GL_FLOAT, 0, ref.texCoordBuffer[j]->pointer );
}
RB_DrawElements();
@ -1125,12 +1150,13 @@ static void RB_RenderShader( void )
RB_SetShaderState();
RB_DeformVertexes();
RB_UpdateVertexBuffer( ref.vertexBuffer, ref.vertsArray, ref.numVertex * sizeof(ref_varray_t));
RB_UpdateVertexBuffer( ref.vertexBuffer, ref.vertexArray, ref.numVertex * sizeof( vec3_t ));
pglEnableClientState( GL_VERTEX_ARRAY );
pglVertexPointer( 3, GL_FLOAT, sizeof(ref_varray_t), ref.vertexBuffer->pointer + BUFFER_OFFSET_POINT );
pglVertexPointer( 3, GL_FLOAT, 0, ref.vertexBuffer->pointer );
RB_UpdateVertexBuffer( ref.normalBuffer, ref.normalArray, ref.numVertex * sizeof( vec3_t ));
pglEnableClientState( GL_NORMAL_ARRAY );
pglNormalPointer( GL_FLOAT, sizeof(ref_varray_t), ref.vertexBuffer->pointer + BUFFER_OFFSET_NORMAL );
pglNormalPointer( GL_FLOAT, 0, ref.vertexBuffer->pointer );
if( GL_Support( R_CUSTOM_VERTEX_ARRAY_EXT ))
{
@ -1149,8 +1175,9 @@ static void RB_RenderShader( void )
RB_SetShaderStageState( stage );
RB_CalcVertexColors( stage );
RB_UpdateVertexBuffer( ref.colorBuffer, ref.colorArray, ref.numVertex * sizeof( vec4_t ));
pglEnableClientState( GL_COLOR_ARRAY );
pglColorPointer( 4, GL_FLOAT, sizeof(ref_varray_t), ref.vertexBuffer->pointer + BUFFER_OFFSET_COLOR );
pglColorPointer( 4, GL_FLOAT, 0, ref.vertexBuffer->pointer );
for( j = 0; j < stage->numBundles; j++ )
{
@ -1159,8 +1186,9 @@ static void RB_RenderShader( void )
RB_SetupTextureUnit( bundle, j );
RB_CalcTextureCoords( bundle, j );
RB_UpdateVertexBuffer( ref.texCoordBuffer[j], ref.texCoordArray[j], ref.numVertex * sizeof( vec3_t ));
pglEnableClientState( GL_TEXTURE_COORD_ARRAY );
pglTexCoordPointer( 3, GL_FLOAT, 0, ref.stArray[j] );
pglTexCoordPointer( 3, GL_FLOAT, 0, ref.texCoordBuffer[j]->pointer );
}
if(GL_Support( R_CUSTOM_VERTEX_ARRAY_EXT ))
@ -1234,8 +1262,8 @@ static void RB_DrawNormals( void )
pglBegin( GL_LINES );
for( i = 0; i < ref.numVertex; i++ )
{
VectorAdd( ref.vertsArray[i].point, ref.vertsArray[i].normal, v );
pglVertex3fv( ref.vertsArray[i].point );
VectorAdd( ref.vertexArray[i], ref.normalArray[i], v );
pglVertex3fv( ref.vertexArray[i] );
pglVertex3fv( v );
}
pglEnd();
@ -1259,8 +1287,8 @@ static void RB_DrawTangentSpace( void )
pglBegin( GL_LINES );
for( i = 0; i < ref.numVertex; i++ )
{
VectorAdd( ref.vertsArray[i].point, ref.vertsArray[i].tangent, v );
pglVertex3fv( ref.vertsArray[i].point );
VectorAdd( ref.vertexArray[i], ref.tangentArray[i], v );
pglVertex3fv( ref.vertexArray[i] );
pglVertex3fv( v );
}
pglEnd();
@ -1270,8 +1298,8 @@ static void RB_DrawTangentSpace( void )
pglBegin( GL_LINES );
for( i = 0; i < ref.numVertex; i++ )
{
VectorAdd( ref.vertsArray[i].point, ref.vertsArray[i].binormal, v );
pglVertex3fv( ref.vertsArray[i].point );
VectorAdd( ref.vertexArray[i], ref.binormalArray[i], v );
pglVertex3fv( ref.vertexArray[i] );
pglVertex3fv( v );
}
pglEnd();
@ -1281,8 +1309,8 @@ static void RB_DrawTangentSpace( void )
pglBegin( GL_LINES );
for( i = 0; i < ref.numVertex; i++ )
{
VectorAdd( ref.vertsArray[i].point, ref.vertsArray[i].normal, v );
pglVertex3fv( ref.vertsArray[i].point );
VectorAdd( ref.vertexArray[i], ref.normalArray[i], v );
pglVertex3fv( ref.vertexArray[i] );
pglVertex3fv( v );
}
pglEnd();
@ -1493,7 +1521,7 @@ void RB_RenderMeshes( mesh_t *meshes, int numMeshes )
sortKey = mesh->sortKey;
// unpack sort key
shader = r_shaders[(sortKey>>18) & (MAX_SHADERS - 1)];
shader = &r_shaders[(sortKey>>18) & (MAX_SHADERS - 1)];
entity = &r_entities[(sortKey >> 8) & MAX_ENTITIES-1];
infoKey = sortKey & 255;
@ -1522,6 +1550,10 @@ void RB_RenderMeshes( mesh_t *meshes, int numMeshes )
GL_LoadMatrix( r_worldMatrix );
else if( entity->ent_type == ED_BSPBRUSH )
R_RotateForEntity( entity );
else if( entity->ent_type == ED_RIGIDBODY )
R_RotateForEntity( entity );
else if( entity->ent_type == ED_MOVER )
R_RotateForEntity( entity );
// sprites and studio models make transformation locally
m_pCurrentEntity = entity;
@ -1573,8 +1605,6 @@ RB_DrawStretchPic
*/
void RB_DrawStretchPic( float x, float y, float w, float h, float sl, float tl, float sh, float th, ref_shader_t *shader )
{
int i;
if( r_skipbackend->integer )
return;
@ -1590,44 +1620,23 @@ void RB_DrawStretchPic( float x, float y, float w, float h, float sl, float tl,
// check if the arrays will overflow
RB_CheckMeshOverflow( 6, 4 );
// draw it
for( i = 2; i < 4; i++ )
{
ref.indexArray[ref.numIndex++] = ref.numVertex + 0;
ref.indexArray[ref.numIndex++] = ref.numVertex + i-1;
ref.indexArray[ref.numIndex++] = ref.numVertex + i;
}
GL_Begin( GL_QUADS );
GL_Color4fv( gl_state.draw_color );
GL_TexCoord2f( sl, tl );
GL_Vertex2f( x, y );
ref.vertsArray[ref.numVertex+0].point[0] = x;
ref.vertsArray[ref.numVertex+0].point[1] = y;
ref.vertsArray[ref.numVertex+0].point[2] = 0;
ref.vertsArray[ref.numVertex+1].point[0] = x + w;
ref.vertsArray[ref.numVertex+1].point[1] = y;
ref.vertsArray[ref.numVertex+1].point[2] = 0;
ref.vertsArray[ref.numVertex+2].point[0] = x + w;
ref.vertsArray[ref.numVertex+2].point[1] = y + h;
ref.vertsArray[ref.numVertex+2].point[2] = 0;
ref.vertsArray[ref.numVertex+3].point[0] = x;
ref.vertsArray[ref.numVertex+3].point[1] = y + h;
ref.vertsArray[ref.numVertex+3].point[2] = 0;
GL_Color4fv( gl_state.draw_color );
GL_TexCoord2f( sh, tl );
GL_Vertex2f( x + w, y );
ref.vertsArray[ref.numVertex+0].stcoord[0] = sl;
ref.vertsArray[ref.numVertex+0].stcoord[1] = tl;
ref.vertsArray[ref.numVertex+1].stcoord[0] = sh;
ref.vertsArray[ref.numVertex+1].stcoord[1] = tl;
ref.vertsArray[ref.numVertex+2].stcoord[0] = sh;
ref.vertsArray[ref.numVertex+2].stcoord[1] = th;
ref.vertsArray[ref.numVertex+3].stcoord[0] = sl;
ref.vertsArray[ref.numVertex+3].stcoord[1] = th;
GL_Color4fv( gl_state.draw_color );
GL_TexCoord2f( sh, th );
GL_Vertex2f( x + w, y + h );
for( i = 0; i < 4; i++ )
{
ref.vertsArray[ref.numVertex].color[0] = gl_state.draw_color[0];
ref.vertsArray[ref.numVertex].color[1] = gl_state.draw_color[1];
ref.vertsArray[ref.numVertex].color[2] = gl_state.draw_color[2];
ref.vertsArray[ref.numVertex].color[3] = gl_state.draw_color[3];
ref.numVertex++;
}
GL_Color4fv( gl_state.draw_color );
GL_TexCoord2f( sl, th );
GL_Vertex2f( x, y + h );
GL_End();
}
/*

View File

@ -16,7 +16,7 @@ void R_GetPicSize( int *w, int *h, shader_t handle )
{
ref_shader_t *shader;
if( handle >= 0 && handle < MAX_SHADERS && (shader = r_shaders[handle]))
if( handle >= 0 && handle < MAX_SHADERS && (shader = &r_shaders[handle]))
{
*w = (int)shader->stages[0]->bundles[0]->textures[0]->width;
*h = (int)shader->stages[0]->bundles[0]->textures[0]->height;
@ -37,7 +37,7 @@ void R_DrawStretchPic( float x, float y, float w, float h, float sl, float tl, f
{
ref_shader_t *shader = tr.defaultShader;
if( handle >= 0 && handle < MAX_SHADERS ) shader = r_shaders[handle];
if( handle >= 0 && handle < MAX_SHADERS ) shader = &r_shaders[handle];
RB_DrawStretchPic( x, y, w, h, sl, tl, sh, th, shader );
}

View File

@ -19,7 +19,7 @@ static byte r_intensityTable[256]; // scale intensity
static byte r_gammaTable[256]; // adjust screenshot gamma
static texture_t *r_texturesHashTable[TEXTURES_HASH_SIZE];
static texture_t *r_textures[MAX_TEXTURES];
static texture_t r_textures[MAX_TEXTURES];
static int r_numTextures;
static byte *r_imagepool; // immediate buffers
static byte *r_texpool; // texture_t permanent chain
@ -589,10 +589,9 @@ void R_SetTextureParameters( void )
r_texturelodbias->modified = false;
// change all the existing mipmapped texture objects
for( i = 0; i < r_numTextures; i++ )
for( i = 0, texture = r_textures; i < r_numTextures; i++, texture++ )
{
texture = r_textures[i];
if( !texture ) continue; // free slot
if( !texture->texnum ) continue; // free slot
if( texture->filter != TF_DEFAULT )
continue;
@ -2226,7 +2225,7 @@ static void R_UploadTexture( rgbdata_t *pic, texture_t *tex )
default: dxtformat = false; break;
}
pglGenTextures( 1, &tex->texnum );
tex->texnum = (tex - r_textures) + 1;
GL_BindTexture( tex );
// uploading texture into video memory
@ -2301,12 +2300,20 @@ texture_t *R_LoadTexture( const char *name, rgbdata_t *pic, int samples, texFlag
Host_Error( "R_LoadTexture: MAX_TEXTURES limit exceeds\n" );
// find a free texture_t slot
for( i = 0; i < r_numTextures; i++ )
if( !r_textures[i] ) break;
for( i = 0, texture = r_textures; i < r_numTextures; i++, texture++ )
if( !texture->texnum ) break;
if( i == r_numTextures )
r_textures[r_numTextures++] = texture = Mem_Alloc( r_texpool, sizeof( texture_t ));
else r_textures[i] = texture = Mem_Alloc( r_texpool, sizeof( texture_t ));
{
if( r_numTextures == MAX_TEXTURES )
{
MsgDev( D_ERROR, "R_LoadTexture: gl textures is out\n" );
return r_defaultTexture;
}
r_numTextures++;
}
texture = &r_textures[i];
// fill it in
com.strncpy( texture->name, name, sizeof( texture->name ));
@ -2655,46 +2662,33 @@ static void R_CreateBuiltInTextures( void )
R_FreeImage
================
*/
static void R_FreeImage( texture_t *image )
void R_FreeImage( texture_t *image )
{
uint hash;
uint hash;
texture_t *cur;
texture_t **prev;
Com_Assert( image == NULL );
if( !image ) return;
// add to hash table
Msg( "release texture %s\n", image->name );
// remove from hash table
hash = Com_HashKey( image->name, TEXTURES_HASH_SIZE );
r_texturesHashTable[hash] = image->nextHash;
prev = &r_texturesHashTable[hash];
while( 1 )
{
cur = *prev;
if( !cur ) break;
if( cur == image )
{
*prev = cur->nextHash;
break;
}
prev = &cur->nextHash;
}
pglDeleteTextures( 1, &image->texnum );
Mem_Free( image );
}
/*
================
R_ImageFreeUnused
Any image that was not touched on this registration sequence
will be freed.
================
*/
void R_ImageFreeUnused( void )
{
texture_t *image;
int i;
for( i = 0; i < r_numTextures; i++ )
{
image = r_textures[i];
if( !image ) continue;
// used this sequence
if( image->touchFrame == registration_sequence ) continue;
if( image->flags & TF_STATIC ) continue;
R_FreeImage( image );
r_textures[i] = NULL;
}
Mem_Set( image, 0, sizeof( *image ));
}
/*
@ -2707,7 +2701,7 @@ was there. This is used to test for texture thrashing.
*/
void RB_ShowTextures( void )
{
texture_t *texture;
texture_t *image;
float x, y, w, h;
int i, j;
@ -2720,18 +2714,17 @@ void RB_ShowTextures( void )
pglFinish();
pglEnable( GL_TEXTURE_2D );
for( i = j = 0; i < r_numTextures; i++ )
for( i = j = 0, image = r_textures; i < r_numTextures; i++, image++ )
{
texture = r_textures[i];
if( !texture ) continue;
if( !image->texnum ) continue;
// FIXME: make cases for system, 2d, bsp, sprite and model textures
if( r_showtextures->integer == 1 && texture->flags & TF_STATIC )
if( r_showtextures->integer == 1 && image->flags & TF_STATIC )
continue;
if( r_showtextures->integer == 2 && !(texture->flags & TF_STATIC ))
if( r_showtextures->integer == 2 && !(image->flags & TF_STATIC ))
continue;
if( r_showtextures->integer == 3 && !(texture->flags & TF_LIGHTMAP ))
if( r_showtextures->integer == 3 && !(image->flags & TF_LIGHTMAP ))
continue;
w = r_width->integer / 10;
@ -2742,12 +2735,12 @@ void RB_ShowTextures( void )
// show in proportional size in mode 2
/*if( r_showtextures->integer == 2 )
{
w *= texture->width / 512.0f;
h *= texture->height / 512.0f;
w *= image->width / 512.0f;
h *= image->height / 512.0f;
}*/
pglColor4f( 1.0f, 1.0f, 1.0f, 1.0f );
GL_BindTexture( texture );
GL_BindTexture( image );
pglBegin( GL_QUADS );
pglTexCoord2f( 0, 0 );
pglVertex2f( x, y );
@ -2771,25 +2764,24 @@ R_TextureList_f
*/
void R_TextureList_f( void )
{
texture_t *texture;
texture_t *image;
int i, texCount, bytes = 0;
Msg( "\n" );
Msg(" -w-- -h-- -size- -fmt- type -filter -wrap-- -name--------\n" );
for( i = texCount = 0; i < r_numTextures; i++ )
for( i = texCount = 0, image = r_textures; i < r_numTextures; i++, image++ )
{
texture = r_textures[i];
if( !texture ) continue;
if( !image->texnum ) continue;
bytes += texture->size;
bytes += image->size;
texCount++;
Msg( "%4i: ", i );
Msg( "%4i %4i ", texture->width, texture->height );
Msg( "%5ik ", texture->size >> 10 );
Msg( "%4i %4i ", image->width, image->height );
Msg( "%5ik ", image->size >> 10 );
switch( texture->format )
switch( image->format )
{
case GL_COMPRESSED_RGBA_ARB:
Msg( "CRGBA " );
@ -2832,7 +2824,7 @@ void R_TextureList_f( void )
break;
}
switch( texture->target )
switch( image->target )
{
case GL_TEXTURE_2D:
Msg( " 2D " );
@ -2845,7 +2837,7 @@ void R_TextureList_f( void )
break;
}
switch( texture->filter )
switch( image->filter )
{
case TF_DEFAULT:
Msg( "default" );
@ -2861,7 +2853,7 @@ void R_TextureList_f( void )
break;
}
switch( texture->wrap )
switch( image->wrap )
{
case TW_REPEAT:
Msg( " repeat " );
@ -2879,7 +2871,7 @@ void R_TextureList_f( void )
Msg( " ???? " );
break;
}
Msg( " %s\n", texture->name );
Msg( " %s\n", image->name );
}
Msg( "---------------------------------------------------------\n" );
@ -2951,7 +2943,7 @@ R_ShutdownTextures
void R_ShutdownTextures( void )
{
int i;
texture_t *texture;
texture_t *image;
for( i = MAX_TEXTURE_UNITS - 1; i >= 0; i-- )
{
@ -2974,14 +2966,10 @@ void R_ShutdownTextures( void )
if( gl_config.texRectangle )
pglDeleteTextures( 1, &gl_state.screenTexture );
for( i = 0; i < r_numTextures; i++ )
for( i = 0, image = r_textures; i < r_numTextures; i++, image++ )
{
texture = r_textures[i];
if( !texture ) continue;
pglDeleteTextures( 1, &texture->texnum );
Mem_Free( texture );
texture = NULL;
if( !image->texnum ) continue;
pglDeleteTextures( 1, &image->texnum );
}
Mem_Set( r_texturesHashTable, 0, sizeof( r_texturesHashTable ));

View File

@ -343,10 +343,10 @@ void R_LightingAmbient( void )
{
for( i = 0; i < ref.numVertex; i++ )
{
ref.vertsArray[i].color[0] = 1.0f;
ref.vertsArray[i].color[1] = 1.0f;
ref.vertsArray[i].color[2] = 1.0f;
ref.vertsArray[i].color[3] = 1.0f;
ref.colorArray[i][0] = 1.0f;
ref.colorArray[i][1] = 1.0f;
ref.colorArray[i][2] = 1.0f;
ref.colorArray[i][3] = 1.0f;
}
return;
}
@ -358,7 +358,7 @@ void R_LightingAmbient( void )
R_RecursiveLightPoint( r_worldModel->nodes, m_pCurrentEntity->origin, end );
VectorScale( r_pointColor, r_ambientscale->value, ambientLight );
// Always have some light
// always have some light
if( m_pCurrentEntity->renderfx & RF_MINLIGHT )
{
for( i = 0; i < 3; i++ )
@ -394,10 +394,10 @@ void R_LightingAmbient( void )
for( i = 0; i < ref.numVertex; i++ )
{
ref.vertsArray[i].color[0] = ambientLight[0];
ref.vertsArray[i].color[1] = ambientLight[1];
ref.vertsArray[i].color[2] = ambientLight[2];
ref.vertsArray[i].color[3] = 1.0f;
ref.colorArray[i][0] = ambientLight[0];
ref.colorArray[i][1] = ambientLight[1];
ref.colorArray[i][2] = ambientLight[2];
ref.colorArray[i][3] = 1.0f;
}
}
@ -419,10 +419,10 @@ void R_LightingDiffuse( void )
{
for( i = 0; i < ref.numVertex; i++ )
{
ref.vertsArray[i].color[0] = 1.0f;
ref.vertsArray[i].color[1] = 1.0f;
ref.vertsArray[i].color[2] = 1.0f;
ref.vertsArray[i].color[3] = 1.0f;
ref.colorArray[i][0] = 1.0f;
ref.colorArray[i][1] = 1.0f;
ref.colorArray[i][2] = 1.0f;
ref.colorArray[i][3] = 1.0f;
}
return;
}
@ -451,12 +451,12 @@ void R_LightingDiffuse( void )
}
// Compute lighting at each vertex
VectorRotate( lightDir, m_pCurrentEntity->axis, dir );
Matrix3x3_Transform( m_pCurrentEntity->matrix, lightDir, dir );
VectorNormalizeFast( dir );
for( i = 0; i < ref.numVertex; i++ )
{
dot = DotProduct( ref.vertsArray[i].normal, dir );
dot = DotProduct( ref.normalArray[i], dir );
if( dot <= 0 )
{
VectorCopy( ambientLight, r_lightColors[i] );
@ -479,14 +479,14 @@ void R_LightingDiffuse( void )
if( !dist || dist > dl->intensity + radius )
continue;
VectorRotate( dir, m_pCurrentEntity->axis, lightDir );
Matrix3x3_Transform( m_pCurrentEntity->matrix, dir, lightDir );
intensity = dl->intensity * 8;
// compute lighting at each vertex
for( i = 0; i < ref.numVertex; i++ )
{
VectorSubtract( lightDir, ref.vertsArray[i].point, dir );
add = DotProduct( ref.vertsArray[i].normal, dir );
VectorSubtract( lightDir, ref.vertexArray[i], dir );
add = DotProduct( ref.normalArray[i], dir );
if( add <= 0 ) continue;
dot = DotProduct( dir, dir );
@ -500,10 +500,10 @@ void R_LightingDiffuse( void )
for (i = 0; i < ref.numVertex; i++)
{
ColorNormalize( r_lightColors[i], r_lightColors[i] );
ref.vertsArray[i].color[0] = r_lightColors[i][0];
ref.vertsArray[i].color[1] = r_lightColors[i][1];
ref.vertsArray[i].color[2] = r_lightColors[i][2];
ref.vertsArray[i].color[3] = 1.0f;
ref.colorArray[i][0] = r_lightColors[i][0];
ref.colorArray[i][1] = r_lightColors[i][1];
ref.colorArray[i][2] = r_lightColors[i][2];
ref.colorArray[i][3] = 1.0f;
}
}
@ -551,13 +551,12 @@ static void R_AddDynamicLights( surface_t *surf )
for( l = 0, dl = r_dlights; l < r_numDLights; l++, dl++ )
{
if(!(surf->dlightBits & (1<<l)))
continue; // not lit by this light
if(!(surf->dlightBits & (1<<l))) continue; // not lit by this light
if( !AxisCompare( m_pCurrentEntity->axis, axisDefault ))
if( !Matrix3x3_Compare( m_pCurrentEntity->matrix, matrix3x3_identity ))
{
VectorSubtract( dl->origin, m_pCurrentEntity->origin, tmp );
VectorRotate( tmp, m_pCurrentEntity->axis, origin );
Matrix3x3_Transform( m_pCurrentEntity->matrix, tmp, origin );
}
else VectorSubtract( dl->origin, m_pCurrentEntity->origin, origin );
@ -734,10 +733,11 @@ R_UploadLightmap
static void R_UploadLightmap( void )
{
string name;
texture_t *lightmap;
texture_t *lightmap = r_lightmapTextures[r_lmState.currentNum];
if( r_lmState.currentNum == MAX_LIGHTMAPS )
Host_Error( "R_UploadLightmap: MAX_LIGHTMAPS limit exceeded\n" );
if( lightmap ) R_FreeImage( lightmap ); // free old lightmap
com.snprintf( name, sizeof(name), "*lightmap%i", r_lmState.currentNum );
lightmap = R_CreateImage( va("*lightmap%d", r_lmState.currentNum ), (byte *)r_lmState.buffer, LM_SIZE, LM_SIZE, TF_LIGHTMAP, TF_LINEAR, TW_CLAMP );

View File

@ -114,7 +114,7 @@ texture_t *R_FindTexture( const char *name, const byte *buf, size_t size, texFl
texture_t *R_FindCubeMapTexture( const char *name, const byte *buf, size_t size, texFlags_t flags, texFilter_t filter, texWrap_t wrap );
void R_InitTextures( void );
void R_ShutdownTextures( void );
void R_ImageFreeUnused( void );
void R_FreeImage( texture_t *image );
/*
=======================================================================
@ -144,12 +144,13 @@ void R_ShutdownPrograms( void );
#include "r_shader.h"
extern ref_shader_t *r_shaders[MAX_SHADERS];
extern ref_shader_t r_shaders[MAX_SHADERS];
extern int r_numShaders;
void R_EvaluateRegisters( ref_shader_t *shader, float time, const float *entityParms, const float *globalParms );
shader_t R_FindShader( const char *name, int shaderType, uint surfaceParm );
ref_shader_t *R_FindShader( const char *name, int shaderType, uint surfaceParm );
void R_SetInternalMap( texture_t *mipTex ); // internal textures (skins, spriteframes, etc)
void R_ShaderFreeUnused( void );
void R_ShaderList_f( void );
void R_InitShaders( void );
void R_ShutdownShaders( void );
@ -199,7 +200,7 @@ typedef struct
{
vec3_t xyz;
vec2_t st;
vec2_t lightmap;
vec2_t lm;
vec4_t color;
} surfPolyVert_t;
@ -408,41 +409,7 @@ STUDIO MODELS
==============================================================================
*/
typedef struct
{
uint index[3];
} mstudiotriangle_t;
typedef struct
{
int index[3];
} mstudioneighbor_t;
typedef struct
{
short point[3];
byte tangent[2];
byte binormal[2];
byte normal[2];
} mstudiopoint_t;
typedef struct
{
vec2_t st;
} mstudiost_t;
typedef struct
{
mstudiotriangle_t *triangles;
mstudioneighbor_t *neighbors;
mstudiopoint_t *points;
mstudiost_t *st;
ref_shader_t *shaders;
int numTriangles;
int numVertices;
int numShaders;
} mstudiosurface_t;
#include "r_model.h"
typedef struct rmodel_s
{
@ -557,6 +524,7 @@ typedef struct ref_entity_s
vec3_t angles;
vec3_t origin; // position
matrix3x3 matrix; // rotation vectors
float framerate; // custom framerate
float animtime; // lerping animtime
@ -595,7 +563,6 @@ typedef struct ref_entity_s
ref_shader_t *shader;
float shaderTime; // subtracted from refdef time to control effect start times
float radius; // bbox approximate radius
vec3_t axis[3]; // Rotation vectors
float rotation; // what the hell ???
} ref_entity_t;
@ -668,6 +635,10 @@ void GL_Vertex3f( GLfloat x, GLfloat y, GLfloat z );
void GL_Vertex3fv( const GLfloat *v );
void GL_Normal3f( GLfloat x, GLfloat y, GLfloat z );
void GL_Normal3fv( const GLfloat *v );
void GL_Tangent3f( GLfloat x, GLfloat y, GLfloat z );
void GL_Tangent3fv( const GLfloat *v );
void GL_Binormal3f( GLfloat x, GLfloat y, GLfloat z );
void GL_Binormal3fv( const GLfloat *v );
void GL_TexCoord2f( GLfloat s, GLfloat t );
void GL_TexCoord4f( GLfloat s, GLfloat t, GLfloat ls, GLfloat lt );
void GL_TexCoord4fv( const GLfloat *v );
@ -774,7 +745,6 @@ extern gl_matrix gl_entityMatrix;
extern gl_matrix gl_textureMatrix;
extern cplane_t r_frustum[4];
extern vec3_t axisDefault[3];
extern float r_frameTime;
extern mesh_t r_solidMeshes[MAX_MESHES];
@ -845,10 +815,7 @@ rmodel_t *R_RegisterModel( const char *name );
shader_t Mod_RegisterShader( const char *name, int shaderType );
void R_SetupSky( const char *name, float rotate, const vec3_t axis );
void R_EndRegistration( void );
void R_ShaderRegisterImages( rmodel_t *mod ); // prolonge registration
ref_shader_t *R_RegisterShader( const char *name );
ref_shader_t *R_RegisterShaderSkin( const char *name );
ref_shader_t *R_RegisterShaderNoMip( const char *name );
void R_ModRegisterShaders( rmodel_t *mod ); // prolonge registration
bool VID_ScreenShot( const char *filename, bool levelshot );
bool VID_CubemapShot( const char *base, uint size, bool skyshot );
void R_DrawFill( float x, float y, float w, float h );
@ -857,13 +824,7 @@ void R_DrawStretchPic( float x, float y, float w, float h, float sl, float tl,
void R_GetPicSize( int *w, int *h, shader_t shader );
// r_utils.c (test)
void AxisClear( vec3_t axis[3] );
void AnglesToAxis ( const vec3_t angles );
void AxisCopy( const vec3_t in[3], vec3_t out[3] );
void AnglesToAxisPrivate (const vec3_t angles, vec3_t axis[3]);
bool AxisCompare( const vec3_t axis1[3], const vec3_t axis2[3] );
void VectorRotate ( const vec3_t v, const vec3_t matrix[3], vec3_t out );
void MatrixGL_MultiplyFast (const gl_matrix m1, const gl_matrix m2, gl_matrix out);
void MatrixGL_MultiplyFast (const gl_matrix m1, const gl_matrix m2, gl_matrix out); // FIXME: remove
// cvars
extern cvar_t *r_check_errors;

View File

@ -199,7 +199,7 @@ void R_RotateForEntity( ref_entity_t *e )
Matrix4x4_ConcatRotate( rotMatrix, -e->angles[2], 1, 0, 0 );
Matrix4x4_Concat( r_entityMatrix, r_worldMatrix, rotMatrix );
#else
Matrix4x4_FromVectors( rotMatrix, e->axis[0], e->axis[1], e->axis[2], vec3_origin );
Matrix4x4_FromMatrix3x3( rotMatrix, e->matrix );
Matrix4x4_SetOrigin( rotMatrix, e->origin[0], e->origin[1], e->origin[2] );
Matrix4x4_Concat( r_entityMatrix, r_worldMatrix, rotMatrix );
#endif
@ -247,37 +247,37 @@ void R_DrawBeam( void )
ref.indexArray[ref.numIndex++] = ref.numVertex + i;
}
ref.vertsArray[ref.numVertex+0].point[0] = m_pCurrentEntity->origin[0] + axis[2][0];
ref.vertsArray[ref.numVertex+0].point[1] = m_pCurrentEntity->origin[1] + axis[2][1];
ref.vertsArray[ref.numVertex+0].point[2] = m_pCurrentEntity->origin[2] + axis[2][2];
ref.vertsArray[ref.numVertex+1].point[0] = m_pCurrentEntity->prev.origin[0] + axis[2][0];
ref.vertsArray[ref.numVertex+1].point[1] = m_pCurrentEntity->prev.origin[1] + axis[2][1];
ref.vertsArray[ref.numVertex+1].point[2] = m_pCurrentEntity->prev.origin[2] + axis[2][2];
ref.vertsArray[ref.numVertex+2].point[0] = m_pCurrentEntity->prev.origin[0] - axis[2][0];
ref.vertsArray[ref.numVertex+2].point[1] = m_pCurrentEntity->prev.origin[1] - axis[2][1];
ref.vertsArray[ref.numVertex+2].point[2] = m_pCurrentEntity->prev.origin[2] - axis[2][2];
ref.vertsArray[ref.numVertex+3].point[0] = m_pCurrentEntity->origin[0] - axis[2][0];
ref.vertsArray[ref.numVertex+3].point[1] = m_pCurrentEntity->origin[1] - axis[2][1];
ref.vertsArray[ref.numVertex+3].point[2] = m_pCurrentEntity->origin[2] - axis[2][2];
ref.vertexArray[ref.numVertex+0][0] = m_pCurrentEntity->origin[0] + axis[2][0];
ref.vertexArray[ref.numVertex+0][1] = m_pCurrentEntity->origin[1] + axis[2][1];
ref.vertexArray[ref.numVertex+0][2] = m_pCurrentEntity->origin[2] + axis[2][2];
ref.vertexArray[ref.numVertex+1][0] = m_pCurrentEntity->prev.origin[0] + axis[2][0];
ref.vertexArray[ref.numVertex+1][1] = m_pCurrentEntity->prev.origin[1] + axis[2][1];
ref.vertexArray[ref.numVertex+1][2] = m_pCurrentEntity->prev.origin[2] + axis[2][2];
ref.vertexArray[ref.numVertex+2][0] = m_pCurrentEntity->prev.origin[0] - axis[2][0];
ref.vertexArray[ref.numVertex+2][1] = m_pCurrentEntity->prev.origin[1] - axis[2][1];
ref.vertexArray[ref.numVertex+2][2] = m_pCurrentEntity->prev.origin[2] - axis[2][2];
ref.vertexArray[ref.numVertex+3][0] = m_pCurrentEntity->origin[0] - axis[2][0];
ref.vertexArray[ref.numVertex+3][1] = m_pCurrentEntity->origin[1] - axis[2][1];
ref.vertexArray[ref.numVertex+3][2] = m_pCurrentEntity->origin[2] - axis[2][2];
ref.vertsArray[ref.numVertex+0].stcoord[0] = 0;
ref.vertsArray[ref.numVertex+0].stcoord[1] = 0;
ref.vertsArray[ref.numVertex+1].stcoord[0] = length;
ref.vertsArray[ref.numVertex+1].stcoord[1] = 0;
ref.vertsArray[ref.numVertex+2].stcoord[0] = length;
ref.vertsArray[ref.numVertex+2].stcoord[1] = 1;
ref.vertsArray[ref.numVertex+3].stcoord[0] = 0;
ref.vertsArray[ref.numVertex+3].stcoord[1] = 1;
ref.inTexCoordArray[ref.numVertex+0][0] = 0;
ref.inTexCoordArray[ref.numVertex+0][1] = 0;
ref.inTexCoordArray[ref.numVertex+1][0] = length;
ref.inTexCoordArray[ref.numVertex+1][1] = 0;
ref.inTexCoordArray[ref.numVertex+2][0] = length;
ref.inTexCoordArray[ref.numVertex+2][1] = 1;
ref.inTexCoordArray[ref.numVertex+3][0] = 0;
ref.inTexCoordArray[ref.numVertex+3][1] = 1;
for( i = 0; i < 4; i++ )
{
ref.vertsArray[ref.numVertex].normal[0] = axis[0][0];
ref.vertsArray[ref.numVertex].normal[1] = axis[0][1];
ref.vertsArray[ref.numVertex].normal[2] = axis[0][2];
ref.vertsArray[ref.numVertex].color[0] = m_pCurrentEntity->rendercolor[0];
ref.vertsArray[ref.numVertex].color[1] = m_pCurrentEntity->rendercolor[1];
ref.vertsArray[ref.numVertex].color[2] = m_pCurrentEntity->rendercolor[2];
ref.vertsArray[ref.numVertex].color[3] = m_pCurrentEntity->renderamt;
ref.normalArray[ref.numVertex][0] = axis[0][0];
ref.normalArray[ref.numVertex][1] = axis[0][1];
ref.normalArray[ref.numVertex][2] = axis[0][2];
ref.colorArray[ref.numVertex][0] = m_pCurrentEntity->rendercolor[0];
ref.colorArray[ref.numVertex][1] = m_pCurrentEntity->rendercolor[1];
ref.colorArray[ref.numVertex][2] = m_pCurrentEntity->rendercolor[2];
ref.colorArray[ref.numVertex][3] = m_pCurrentEntity->renderamt;
ref.numVertex++;
}
}
@ -312,10 +312,13 @@ static void R_AddEntitiesToList( void )
{
switch( entity->ent_type )
{
case ED_MOVER:
case ED_NORMAL:
case ED_CLIENT:
case ED_BSPBRUSH:
case ED_VIEWMODEL:
case ED_RIGIDBODY:
m_pCurrentEntity = entity;
model = m_pRenderModel = entity->model;
if( !model || model->type == mod_bad )
{
@ -383,9 +386,9 @@ static void R_DrawNullModels( void )
{
entity = r_nullModels[i];
VectorMA( entity->origin, 15, entity->axis[0], points[0] );
VectorMA( entity->origin, -15, entity->axis[1], points[1] );
VectorMA( entity->origin, 15, entity->axis[2], points[2] );
VectorMA( entity->origin, 15, entity->matrix[0], points[0] );
VectorMA( entity->origin, -15, entity->matrix[1], points[1] );
VectorMA( entity->origin, 15, entity->matrix[2], points[2] );
pglBegin( GL_LINES );
@ -444,18 +447,18 @@ void R_DrawParticle( void )
VectorMA( particle->origin, -particle->length, axis[1], particle->old_origin );
VectorScale( axis[2], particle->radius, axis[2] );
ref.vertsArray[ref.numVertex+0].point[0] = particle->old_origin[0] + axis[2][0];
ref.vertsArray[ref.numVertex+0].point[1] = particle->old_origin[1] + axis[2][1];
ref.vertsArray[ref.numVertex+0].point[2] = particle->old_origin[2] + axis[2][2];
ref.vertsArray[ref.numVertex+1].point[0] = particle->origin[0] + axis[2][0];
ref.vertsArray[ref.numVertex+1].point[1] = particle->origin[1] + axis[2][1];
ref.vertsArray[ref.numVertex+1].point[2] = particle->origin[2] + axis[2][2];
ref.vertsArray[ref.numVertex+2].point[0] = particle->origin[0] - axis[2][0];
ref.vertsArray[ref.numVertex+2].point[1] = particle->origin[1] - axis[2][1];
ref.vertsArray[ref.numVertex+2].point[2] = particle->origin[2] - axis[2][2];
ref.vertsArray[ref.numVertex+3].point[0] = particle->old_origin[0] - axis[2][0];
ref.vertsArray[ref.numVertex+3].point[1] = particle->old_origin[1] - axis[2][1];
ref.vertsArray[ref.numVertex+3].point[2] = particle->old_origin[2] - axis[2][2];
ref.vertexArray[ref.numVertex+0][0] = particle->old_origin[0] + axis[2][0];
ref.vertexArray[ref.numVertex+0][1] = particle->old_origin[1] + axis[2][1];
ref.vertexArray[ref.numVertex+0][2] = particle->old_origin[2] + axis[2][2];
ref.vertexArray[ref.numVertex+1][0] = particle->origin[0] + axis[2][0];
ref.vertexArray[ref.numVertex+1][1] = particle->origin[1] + axis[2][1];
ref.vertexArray[ref.numVertex+1][2] = particle->origin[2] + axis[2][2];
ref.vertexArray[ref.numVertex+2][0] = particle->origin[0] - axis[2][0];
ref.vertexArray[ref.numVertex+2][1] = particle->origin[1] - axis[2][1];
ref.vertexArray[ref.numVertex+2][2] = particle->origin[2] - axis[2][2];
ref.vertexArray[ref.numVertex+3][0] = particle->old_origin[0] - axis[2][0];
ref.vertexArray[ref.numVertex+3][1] = particle->old_origin[1] - axis[2][1];
ref.vertexArray[ref.numVertex+3][2] = particle->old_origin[2] - axis[2][2];
}
else
{
@ -482,35 +485,35 @@ void R_DrawParticle( void )
VectorScale( r_up, particle->radius, axis[2] );
}
ref.vertsArray[ref.numVertex+0].point[0] = particle->origin[0] + axis[1][0] + axis[2][0];
ref.vertsArray[ref.numVertex+0].point[1] = particle->origin[1] + axis[1][1] + axis[2][1];
ref.vertsArray[ref.numVertex+0].point[2] = particle->origin[2] + axis[1][2] + axis[2][2];
ref.vertsArray[ref.numVertex+1].point[0] = particle->origin[0] - axis[1][0] + axis[2][0];
ref.vertsArray[ref.numVertex+1].point[1] = particle->origin[1] - axis[1][1] + axis[2][1];
ref.vertsArray[ref.numVertex+1].point[2] = particle->origin[2] - axis[1][2] + axis[2][2];
ref.vertsArray[ref.numVertex+2].point[0] = particle->origin[0] - axis[1][0] - axis[2][0];
ref.vertsArray[ref.numVertex+2].point[1] = particle->origin[1] - axis[1][1] - axis[2][1];
ref.vertsArray[ref.numVertex+2].point[2] = particle->origin[2] - axis[1][2] - axis[2][2];
ref.vertsArray[ref.numVertex+3].point[0] = particle->origin[0] + axis[1][0] - axis[2][0];
ref.vertsArray[ref.numVertex+3].point[1] = particle->origin[1] + axis[1][1] - axis[2][1];
ref.vertsArray[ref.numVertex+3].point[2] = particle->origin[2] + axis[1][2] - axis[2][2];
ref.vertexArray[ref.numVertex+0][0] = particle->origin[0] + axis[1][0] + axis[2][0];
ref.vertexArray[ref.numVertex+0][1] = particle->origin[1] + axis[1][1] + axis[2][1];
ref.vertexArray[ref.numVertex+0][2] = particle->origin[2] + axis[1][2] + axis[2][2];
ref.vertexArray[ref.numVertex+1][0] = particle->origin[0] - axis[1][0] + axis[2][0];
ref.vertexArray[ref.numVertex+1][1] = particle->origin[1] - axis[1][1] + axis[2][1];
ref.vertexArray[ref.numVertex+1][2] = particle->origin[2] - axis[1][2] + axis[2][2];
ref.vertexArray[ref.numVertex+2][0] = particle->origin[0] - axis[1][0] - axis[2][0];
ref.vertexArray[ref.numVertex+2][1] = particle->origin[1] - axis[1][1] - axis[2][1];
ref.vertexArray[ref.numVertex+2][2] = particle->origin[2] - axis[1][2] - axis[2][2];
ref.vertexArray[ref.numVertex+3][0] = particle->origin[0] + axis[1][0] - axis[2][0];
ref.vertexArray[ref.numVertex+3][1] = particle->origin[1] + axis[1][1] - axis[2][1];
ref.vertexArray[ref.numVertex+3][2] = particle->origin[2] + axis[1][2] - axis[2][2];
}
ref.vertsArray[ref.numVertex+0].stcoord[0] = 0;
ref.vertsArray[ref.numVertex+0].stcoord[1] = 0;
ref.vertsArray[ref.numVertex+1].stcoord[0] = 1;
ref.vertsArray[ref.numVertex+1].stcoord[1] = 0;
ref.vertsArray[ref.numVertex+2].stcoord[0] = 1;
ref.vertsArray[ref.numVertex+2].stcoord[1] = 1;
ref.vertsArray[ref.numVertex+3].stcoord[0] = 0;
ref.vertsArray[ref.numVertex+3].stcoord[1] = 1;
ref.inTexCoordArray[ref.numVertex+0][0] = 0;
ref.inTexCoordArray[ref.numVertex+0][1] = 0;
ref.inTexCoordArray[ref.numVertex+1][0] = 1;
ref.inTexCoordArray[ref.numVertex+1][1] = 0;
ref.inTexCoordArray[ref.numVertex+2][0] = 1;
ref.inTexCoordArray[ref.numVertex+2][1] = 1;
ref.inTexCoordArray[ref.numVertex+3][0] = 0;
ref.inTexCoordArray[ref.numVertex+3][1] = 1;
for( i = 0; i < 4; i++ )
{
ref.vertsArray[ref.numVertex].normal[0] = axis[0][0];
ref.vertsArray[ref.numVertex].normal[1] = axis[0][1];
ref.vertsArray[ref.numVertex].normal[2] = axis[0][2];
Vector4Copy( particle->modulate, ref.vertsArray[ref.numVertex].color );
ref.normalArray[ref.numVertex][0] = axis[0][0];
ref.normalArray[ref.numVertex][1] = axis[0][1];
ref.normalArray[ref.numVertex][2] = axis[0][2];
Vector4Copy( particle->modulate, ref.colorArray[ref.numVertex] );
ref.numVertex++;
}
}
@ -677,15 +680,13 @@ void R_AddMeshToList( meshType_t meshType, void *mesh, ref_shader_t *shader, ref
m = &r_transMeshes[r_numTransMeshes++];
}
m->sortKey = (shader->sort<<28) | (shader->index<<18) | ((entity - r_entities)<<8) | (infoKey);
m->sortKey = (shader->sort<<28) | (shader->shadernum<<18) | ((entity - r_entities)<<8) | (infoKey);
m->meshType = meshType;
m->mesh = mesh;
}
// =====================================================================
/*
=================
R_SetFrustum
@ -697,7 +698,8 @@ static void R_SetFrustum( void )
// build the transformation matrix for the given view angles
VectorCopy( r_refdef.vieworg, r_origin );
AnglesToAxis( r_refdef.viewangles );
AngleVectorsFLU( r_refdef.viewangles, r_forward, r_right, r_up );
RotatePointAroundVector( r_frustum[0].normal, r_up, r_forward, -(90 - r_refdef.fov_x / 2));
RotatePointAroundVector( r_frustum[1].normal, r_up, r_forward, 90 - r_refdef.fov_x / 2);
@ -972,6 +974,17 @@ static bool R_AddEntityToScene( entity_state_t *s1, entity_state_t *s2, float le
refent = &r_entities[r_numEntities];
if( !s2 ) s2 = s1; // no lerping state
// filter ents
switch( s1->ed_type )
{
case ED_MOVER:
case ED_CLIENT:
case ED_NORMAL:
case ED_BSPBRUSH:
case ED_RIGIDBODY:
case ED_VIEWMODEL: break;
default: return false;
}
// copy state to render
refent->frame = s1->model.frame;
refent->index = s1->number;
@ -1019,7 +1032,7 @@ static bool R_AddEntityToScene( entity_state_t *s1, entity_state_t *s2, float le
refent->angles[i] = LerpAngle( s2->angles[i], s1->angles[i], lerpfrac );
}
AnglesToAxisPrivate( refent->angles, refent->axis );
Matrix3x3_FromAngles( refent->angles, refent->matrix );
// copy controllers
for( i = 0; i < MAXSTUDIOCONTROLLERS; i++ )
@ -1243,10 +1256,10 @@ bool R_UploadModel( const char *name, int index )
shader_t Mod_RegisterShader( const char *name, int shaderType )
{
shader_t shader = tr.defaultShader->index;
shader_t shader = tr.defaultShader->shadernum;
if( shaderType >= SHADER_SKY && shaderType <= SHADER_NOMIP )
shader = R_FindShader( name, shaderType, 0 );
shader = R_FindShader( name, shaderType, 0 )->shadernum;
else MsgDev( D_WARN, "Mod_RegisterShader: invalid shader type (%i)\n", shaderType );
if( shaderType == SHADER_SKY ) R_SetupSky( name, 0, vec3_origin );
@ -1272,18 +1285,21 @@ bool R_PrecachePic( const char *name )
R_Init
=================
*/
bool R_Init( void )
bool R_Init( bool full )
{
GL_InitBackend();
// create the window and set up the context
if(!R_Init_OpenGL())
if( full )
{
R_Free_OpenGL();
return false;
GL_InitBackend();
// create the window and set up the context
if( !R_Init_OpenGL())
{
R_Free_OpenGL();
return false;
}
GL_InitExtensions();
}
GL_InitExtensions();
RB_InitBackend();
R_InitTextures();
@ -1300,7 +1316,7 @@ bool R_Init( void )
R_Shutdown
=================
*/
void R_Shutdown( void )
void R_Shutdown( bool full )
{
R_ShutdownModels();
R_ShutdownShaders();
@ -1308,10 +1324,14 @@ void R_Shutdown( void )
R_ShutdownTextures();
RB_ShutdownBackend();
GL_ShutdownBackend();
// shut down OS specific OpenGL stuff like contexts, etc.
R_Free_OpenGL();
if( full )
{
GL_ShutdownBackend();
// shut down OS specific OpenGL stuff like contexts, etc.
R_Free_OpenGL();
}
}
/*

View File

@ -280,7 +280,7 @@ void R_LoadShaders( const byte *base, const lump_t *l )
if( !m_pLoadModel->lightData || surfaceParm & SURF_WARP )
surfaceParm |= SURF_NOLIGHTMAP;
m_pLoadModel->shaders[i] = r_shaders[R_FindShader( in->name, shaderType, surfaceParm )];
m_pLoadModel->shaders[i] = R_FindShader( in->name, shaderType, surfaceParm );
}
}
@ -519,8 +519,8 @@ static void R_SubdividePolygon( surface_t *surf, int numVerts, float *verts )
t += LM_SAMPLE_SIZE >> 1;
t /= LM_SIZE * LM_SAMPLE_SIZE;
p->vertices[i+1].lightmap[0] = s;
p->vertices[i+1].lightmap[1] = t;
p->vertices[i+1].lm[0] = s;
p->vertices[i+1].lm[1] = t;
totalLM[0] += s;
totalLM[1] += t;
@ -545,8 +545,8 @@ static void R_SubdividePolygon( surface_t *surf, int numVerts, float *verts )
p->vertices[0].st[1] = totalST[1] / numVerts;
// lightmap texture coordinates
p->vertices[0].lightmap[0] = totalLM[0] / numVerts;
p->vertices[0].lightmap[1] = totalLM[1] / numVerts;
p->vertices[0].lm[0] = totalLM[0] / numVerts;
p->vertices[0].lm[1] = totalLM[1] / numVerts;
// vertex color
p->vertices[0].color[0] = 1.0f;
@ -568,7 +568,7 @@ static void R_SubdividePolygon( surface_t *surf, int numVerts, float *verts )
R_BuildPolygon
=================
*/
static void R_BuildPolygon( surface_t *surf, int numVerts, float *verts )
static void R_BuildPolygon( surface_t *surf, int numVerts, const float *verts )
{
int i;
uint index;
@ -593,9 +593,7 @@ static void R_BuildPolygon( surface_t *surf, int numVerts, float *verts )
// create vertices
p->numVertices = numVerts;
// FIXME:
p->vertices = Mem_Alloc( m_pLoadModel->mempool, (p->numVertices * 2) * sizeof(surfPolyVert_t));
p->vertices = Mem_Alloc( m_pLoadModel->mempool, p->numVertices * sizeof( surfPolyVert_t ));
for( i = 0; i < numVerts; i++, verts += 3 )
{
@ -625,19 +623,16 @@ static void R_BuildPolygon( surface_t *surf, int numVerts, float *verts )
t += LM_SAMPLE_SIZE >> 1;
t /= LM_SIZE * LM_SAMPLE_SIZE;
p->vertices[i].lightmap[0] = s;
p->vertices[i].lightmap[1] = t;
p->vertices[i].lm[0] = s;
p->vertices[i].lm[1] = t;
// vertex color
p->vertices[i+1].color[0] = 1.0f;
p->vertices[i+1].color[1] = 1.0f;
p->vertices[i+1].color[2] = 1.0f;
p->vertices[i+1].color[3] = 1.0f;
Vector4Set( p->vertices[i].color, 1.0f, 1.0f, 1.0f, 1.0f );
if( texInfo->surfaceFlags & SURF_TRANS )
p->vertices[i+1].color[3] *= 0.33;
p->vertices[i].color[3] *= 0.33;
else if( texInfo->surfaceFlags & SURF_BLEND )
p->vertices[i+1].color[3] *= 0.66;
p->vertices[i].color[3] *= 0.66;
}
}
@ -648,8 +643,8 @@ R_BuildSurfacePolygons
*/
static void R_BuildSurfacePolygons( surface_t *surf )
{
vec3_t verts[64];
int i, e;
vec3_t verts[MAX_BUILD_SIDES];
vertex_t *v;
// convert edges back to a normal polygon
@ -1168,9 +1163,17 @@ void R_BeginRegistration( const char *mapname )
// explicitly free the old map if different
if( com.strcmp( r_models[0].name, fullname ))
{
Mod_Free( &r_models[0] );
}
else
{
// update progress bar
Cvar_SetValue( "scr_loading", 50.0f );
if( ri.UpdateScreen ) ri.UpdateScreen();
}
r_worldModel = Mod_ForName( fullname, true );
R_ShaderRegisterImages( r_worldModel );
R_ModRegisterShaders( r_worldModel );
r_viewCluster = -1;
}
@ -1186,7 +1189,7 @@ rmodel_t *R_RegisterModel( const char *name )
rmodel_t *mod;
mod = Mod_ForName( name, false );
R_ShaderRegisterImages( mod );
R_ModRegisterShaders( mod );
return mod;
}
@ -1211,7 +1214,8 @@ void R_EndRegistration( void )
if( mod->registration_sequence != registration_sequence )
Mod_Free( mod );
}
R_ImageFreeUnused();
R_ShaderFreeUnused();
}
/*
@ -1284,7 +1288,7 @@ void R_InitModels( void )
Mem_Set( r_worldEntity, 0, sizeof( ref_entity_t ));
r_worldEntity->ent_type = ED_NORMAL;
r_worldEntity->model = r_worldModel;
AxisClear( r_worldEntity->axis );
Matrix3x3_LoadIdentity( r_worldEntity->matrix );
VectorSet( r_worldEntity->rendercolor, 1.0f, 1.0f, 1.0f );
r_worldEntity->renderamt = 1.0f; // i'm hope we don't want to see semisolid world :)

44
render/r_model.h Normal file
View File

@ -0,0 +1,44 @@
//=======================================================================
// Copyright XashXT Group 2008 ©
// r_model.h - renderer model types
//=======================================================================
#ifndef R_MODEL_H
#define R_MODEL_H
typedef struct
{
uint index[3];
} mstudiotriangle_t;
typedef struct
{
int index[3];
} mstudioneighbor_t;
typedef struct
{
vec3_t point;
vec2_t st;
vec4_t color;
} mstudiopoint_t;
typedef struct mstudiosurface_s
{
struct mstudiosurface_s *next;
int numIndices;
int numVertices;
uint *indices;
mstudiopoint_t *points;
} mstudiosurface_t;
typedef struct mstudiomesh_s
{
mstudiosurface_t *surfaces;
int numSurfaces;
ref_shader_t *shader;
} mstudiomesh_t;
#endif//R_MODEL_H

View File

@ -44,7 +44,7 @@ static ref_script_t *r_shaderScriptsHash[SHADERS_HASH_SIZE];
static ref_shader_t *r_shadersHash[SHADERS_HASH_SIZE];
static table_t *r_tables[MAX_TABLES];
static int r_numTables;
ref_shader_t *r_shaders[MAX_SHADERS];
ref_shader_t r_shaders[MAX_SHADERS];
int r_numShaders = 0;
// NOTE: this table must match with same table in common\bsplib\shaders.c
@ -1523,10 +1523,8 @@ static bool R_ParseGeneralSkyParms( ref_shader_t *shader, script_t *script )
{
for( i = 0; i < 6; i++ )
{
if( shader->skyParms.farBox[i] )
shader->skyParms.farBox[i]->flags &= ~TF_STATIC; // old skybox will be removed on next loading
com.snprintf( name, sizeof( name ), "%s%s", tok.string, r_skyBoxSuffix[i] );
shader->skyParms.farBox[i] = R_FindTexture( name, NULL, 0, TF_STATIC, TF_LINEAR, TW_CLAMP );
shader->skyParms.farBox[i] = R_FindTexture( name, NULL, 0, 0, TF_LINEAR, TW_CLAMP );
if( !shader->skyParms.farBox[i] )
{
MsgDev( D_WARN, "couldn't find texture '%s' in shader '%s'\n", name, shader->name );
@ -1562,10 +1560,8 @@ static bool R_ParseGeneralSkyParms( ref_shader_t *shader, script_t *script )
{
for( i = 0; i < 6; i++ )
{
if( shader->skyParms.nearBox[i] )
shader->skyParms.nearBox[i]->flags &= ~TF_STATIC; // old skybox will be removed on next loading
com.snprintf( name, sizeof(name), "%s%s", tok.string, r_skyBoxSuffix[i] );
shader->skyParms.nearBox[i] = R_FindTexture( name, NULL, 0, TF_STATIC, TF_LINEAR, TW_CLAMP );
shader->skyParms.nearBox[i] = R_FindTexture( name, NULL, 0, 0, TF_LINEAR, TW_CLAMP );
if( !shader->skyParms.nearBox[i] )
{
MsgDev( D_WARN, "couldn't find texture '%s' in shader '%s'\n", name, shader->name );
@ -3807,10 +3803,25 @@ R_NewShader
static ref_shader_t *R_NewShader( void )
{
ref_shader_t *shader;
int i, j;
int i, j;
// find a free shader_t slot
for( i = 0, shader = r_shaders; i < r_numShaders; i++, shader++ )
if( !shader->name[0] ) break;
if( i == r_numShaders )
{
if( r_numShaders == MAX_SHADERS )
{
Host_Error( "R_LoadShader: MAX_SHADERS limit exceeded\n" );
return tr.defaultShader;
}
r_numShaders++;
}
shader = &r_parseShader;
Mem_Set( shader, 0, sizeof( ref_shader_t ));
shader->shadernum = i;
for( i = 0; i < SHADER_MAX_STAGES; i++ )
{
@ -3850,7 +3861,6 @@ static ref_shader_t *R_CreateDefaultShader( const char *name, int shaderType, ui
// fill it in
com.strncpy( shader->name, name, sizeof( shader->name ));
shader->index = r_numShaders;
shader->type = shaderType;
shader->surfaceParm = surfaceParm;
@ -3861,9 +3871,7 @@ static ref_shader_t *R_CreateDefaultShader( const char *name, int shaderType, ui
for( i = 0; i < 6; i++ )
{
if( shader->skyParms.farBox[i] )
shader->skyParms.farBox[i]->flags &= ~TF_STATIC; // old skybox will be removed on next loading
shader->skyParms.farBox[i] = R_FindTexture(va("gfx/env/%s%s", shader->name, r_skyBoxSuffix[i]), NULL, 0, TF_STATIC, TF_LINEAR, TW_CLAMP );
shader->skyParms.farBox[i] = R_FindTexture(va("gfx/env/%s%s", shader->name, r_skyBoxSuffix[i]), NULL, 0, 0, TF_LINEAR, TW_CLAMP );
if( !shader->skyParms.farBox[i] )
{
MsgDev( D_WARN, "couldn't find texture for shader '%s', using default...\n", shader->name );
@ -4064,7 +4072,6 @@ static ref_shader_t *R_CreateShader( const char *name, int shaderType, uint surf
// fill it in
com.strncpy( shader->name, name, sizeof( shader->name ));
shader->index = r_numShaders;
shader->type = shaderType;
shader->surfaceParm = surfaceParm;
shader->flags = SHADER_EXTERNAL;
@ -4102,7 +4109,6 @@ static ref_shader_t *R_CreateShader( const char *name, int shaderType, uint surf
shader = R_NewShader();
com.strncpy( shader->name, name, sizeof( shader->name ));
shader->index = r_numShaders;
shader->type = shaderType;
shader->surfaceParm = surfaceParm;
shader->flags = SHADER_EXTERNAL|SHADER_DEFAULTED;
@ -4383,7 +4389,8 @@ static void R_FinishShader( ref_shader_t *shader )
}
else
{
if((stage->blendFunc.src == GL_DST_COLOR && stage->blendFunc.dst == GL_ZERO) || (stage->blendFunc.src == GL_ZERO && stage->blendFunc.dst == GL_SRC_COLOR))
if((stage->blendFunc.src == GL_DST_COLOR && stage->blendFunc.dst == GL_ZERO)
|| (stage->blendFunc.src == GL_ZERO && stage->blendFunc.dst == GL_SRC_COLOR))
stage->bundles[0]->texEnv = GL_MODULATE;
else if(stage->blendFunc.src == GL_ONE && stage->blendFunc.dst == GL_ONE)
stage->bundles[0]->texEnv = GL_ADD;
@ -4644,67 +4651,7 @@ static void R_OptimizeShader( ref_shader_t *shader )
shader->constantExpressions = true;
}
/*
=================
R_LoadShader
=================
*/
ref_shader_t *R_LoadShader( ref_shader_t *newShader )
{
ref_shader_t *shader;
uint hashKey;
int i, j;
if( r_numShaders == MAX_SHADERS )
Host_Error( "R_LoadShader: MAX_SHADERS limit exceeded\n" );
r_shaders[r_numShaders++] = shader = Mem_Alloc( r_shaderpool, sizeof( ref_shader_t ));
// make sure the shader is valid and set all the unset parameters
R_FinishShader( newShader );
// try to merge multiple stages for multitexturing
R_OptimizeShader( newShader );
// copy the shader
Mem_Copy( shader, newShader, sizeof( ref_shader_t ));
shader->numStages = 0;
// allocate and copy the stages
for( i = 0; i < newShader->numStages; i++ )
{
if( newShader->stages[i]->ignore )
continue;
shader->stages[shader->numStages] = Mem_Alloc( r_shaderpool, sizeof( shaderStage_t ));
Mem_Copy(shader->stages[shader->numStages], newShader->stages[i], sizeof(shaderStage_t));
// allocate and copy the bundles
for( j = 0; j < shader->stages[shader->numStages]->numBundles; j++ )
{
shader->stages[shader->numStages]->bundles[j] = Mem_Alloc( r_shaderpool, sizeof( stageBundle_t ));
Mem_Copy(shader->stages[shader->numStages]->bundles[j], newShader->stages[i]->bundles[j], sizeof(stageBundle_t));
}
shader->numStages++;
}
// allocate and copy the expression ops
shader->statements = Mem_Alloc( r_shaderpool, shader->numstatements * sizeof( statement_t ));
Mem_Copy( shader->statements, newShader->statements, shader->numstatements * sizeof( statement_t ));
// Allocate and copy the expression registers
shader->expressions = Mem_Alloc( r_shaderpool, shader->numRegisters * sizeof( float ));
Mem_Copy( shader->expressions, newShader->expressions, shader->numRegisters * sizeof( float ));
// add to hash table
hashKey = Com_HashKey( shader->name, SHADERS_HASH_SIZE );
shader->nextHash = r_shadersHash[hashKey];
r_shadersHash[hashKey] = shader;
return shader;
}
static void R_ShaderTouchImages( ref_shader_t *shader )
static void R_ShaderTouchImages( ref_shader_t *shader, bool free_unused )
{
int i, j, k;
int c_total = 0;
@ -4713,9 +4660,6 @@ static void R_ShaderTouchImages( ref_shader_t *shader )
texture_t *texture;
Com_Assert( shader == NULL );
if( !shader ) return;
if( shader->type == SHADER_NOMIP || shader->type == SHADER_FONT )
return; // static textures not needs to touch
for( i = 0; i < shader->numStages; i++ )
{
@ -4723,14 +4667,20 @@ static void R_ShaderTouchImages( ref_shader_t *shader )
for( j = 0; j < stage->numBundles; j++ )
{
bundle = stage->bundles[j];
// FIXME: implement
//if( free_unused && bundle->flags & STAGEBUNDLE_VIDEOMAP )
// CIN_StopCinematic( bundle->cinematicHandle );
for( k = 0; k < bundle->numTextures; k++ )
{
// prolonge registration for all shader textures
texture = bundle->textures[k];
if( !texture || texture->touchFrame == registration_sequence )
continue;
Msg("update texture %s with texnum %i\n", texture->name, texture->texnum );
texture->touchFrame = registration_sequence;
if( !texture || !texture->name[0] ) continue;
if( free_unused && texture->touchFrame != registration_sequence )
R_FreeImage( texture );
else texture->touchFrame = registration_sequence;
c_total++; // just for debug
}
}
@ -4742,20 +4692,90 @@ static void R_ShaderTouchImages( ref_shader_t *shader )
for( i = 0; i < 6; i++ )
{
texture = shader->skyParms.farBox[i];
if( texture ) texture->touchFrame = registration_sequence;
if( texture && texture->name[0] )
{
if( free_unused && texture->touchFrame != registration_sequence )
R_FreeImage( texture );
else texture->touchFrame = registration_sequence;
}
texture = shader->skyParms.nearBox[i];
if( texture ) texture->touchFrame = registration_sequence;
if( texture && texture->texnum )
{
if( free_unused && texture->touchFrame != registration_sequence )
R_FreeImage( texture );
else texture->touchFrame = registration_sequence;
}
c_total++; // just for debug
}
}
}
/*
=================
R_LoadShader
=================
*/
ref_shader_t *R_LoadShader( ref_shader_t *newShader )
{
ref_shader_t *shader;
uint hashKey;
int i, j;
// make sure the shader is valid and set all the unset parameters
R_FinishShader( newShader );
// try to merge multiple stages for multitexturing
R_OptimizeShader( newShader );
// copy the shader
shader = &r_shaders[newShader->shadernum];
Mem_Copy( shader, newShader, sizeof( ref_shader_t ));
shader->mempool = Mem_AllocPool( shader->name );
shader->numStages = 0;
// allocate and copy the stages
for( i = 0; i < newShader->numStages; i++ )
{
if( newShader->stages[i]->ignore )
continue;
shader->stages[shader->numStages] = Mem_Alloc( shader->mempool, sizeof( shaderStage_t ));
Mem_Copy( shader->stages[shader->numStages], newShader->stages[i], sizeof( shaderStage_t ));
// allocate and copy the bundles
for( j = 0; j < shader->stages[shader->numStages]->numBundles; j++ )
{
shader->stages[shader->numStages]->bundles[j] = Mem_Alloc( shader->mempool, sizeof( stageBundle_t ));
Mem_Copy( shader->stages[shader->numStages]->bundles[j], newShader->stages[i]->bundles[j], sizeof( stageBundle_t ));
}
shader->numStages++;
}
// allocate and copy the expression ops
shader->statements = Mem_Alloc( shader->mempool, shader->numstatements * sizeof( statement_t ));
Mem_Copy( shader->statements, newShader->statements, shader->numstatements * sizeof( statement_t ));
// Allocate and copy the expression registers
shader->expressions = Mem_Alloc( shader->mempool, shader->numRegisters * sizeof( float ));
Mem_Copy( shader->expressions, newShader->expressions, shader->numRegisters * sizeof( float ));
shader->touchFrame = registration_sequence;
R_ShaderTouchImages( shader, false );
// add to hash table
hashKey = Com_HashKey( shader->name, SHADERS_HASH_SIZE );
shader->nextHash = r_shadersHash[hashKey];
r_shadersHash[hashKey] = shader;
return shader;
}
/*
=================
R_FindShader
=================
*/
shader_t R_FindShader( const char *name, int shaderType, uint surfaceParm )
ref_shader_t *R_FindShader( const char *name, int shaderType, uint surfaceParm )
{
ref_shader_t *shader;
ref_script_t *shaderScript;
@ -4774,8 +4794,9 @@ shader_t R_FindShader( const char *name, int shaderType, uint surfaceParm )
if( !com.stricmp( shader->name, name ))
{
// prolonge registration
R_ShaderTouchImages( shader );
return shader->index;
shader->touchFrame = registration_sequence;
R_ShaderTouchImages( shader, false );
return shader;
}
}
@ -4793,7 +4814,7 @@ shader_t R_FindShader( const char *name, int shaderType, uint surfaceParm )
shader = R_CreateShader( name, shaderType, surfaceParm, shaderScript );
// load it in
return R_LoadShader( shader )->index;
return R_LoadShader( shader );
}
void R_SetInternalMap( texture_t *mipTex )
@ -4895,47 +4916,74 @@ void R_EvaluateRegisters( ref_shader_t *shader, float time, const float *entityP
/*
=================
R_RegisterShader
R_ModRegisterShaders
update shader and associated textures
=================
*/
ref_shader_t *R_RegisterShader( const char *name )
void R_ModRegisterShaders( rmodel_t *mod )
{
return r_shaders[R_FindShader( name, SHADER_GENERIC, 0 )];
ref_shader_t *shader;
int i;
if( !mod || !mod->name[0] )
return;
for( i = 0; i < mod->numShaders; i++ )
{
shader = mod->shaders[i];
if( !shader || !shader->name[0] ) continue;
shader = R_FindShader( shader->name, shader->type, shader->surfaceParm );
}
}
/*
=================
R_RegisterShaderSkin
=================
*/
ref_shader_t *R_RegisterShaderSkin( const char *name )
static void R_FreeShader( ref_shader_t *shader )
{
return r_shaders[R_FindShader( name, SHADER_STUDIO, 0 )];
uint hash;
ref_shader_t *cur;
ref_shader_t **prev;
Com_Assert( shader == NULL );
// free uinque shader images only
R_ShaderTouchImages( shader, true );
// remove from hash table
hash = Com_HashKey( shader->name, SHADERS_HASH_SIZE );
prev = &r_shadersHash[hash];
while( 1 )
{
cur = *prev;
if( !cur ) break;
if( cur == shader )
{
*prev = cur->nextHash;
break;
}
prev = &cur->nextHash;
}
// free stages
Mem_FreePool( &shader->mempool );
Mem_Set( shader, 0, sizeof( *shader ));
}
/*
=================
R_RegisterShaderNoMip
=================
*/
ref_shader_t *R_RegisterShaderNoMip( const char *name )
void R_ShaderFreeUnused( void )
{
return r_shaders[R_FindShader( name, SHADER_NOMIP, 0 )];
}
ref_shader_t *shader;
int i;
/*
=================
R_ShaderRegisterImages
many many included cycles ...
=================
*/
void R_ShaderRegisterImages( rmodel_t *mod )
{
int i;
for( i = 0; mod && i < mod->numShaders; i++ )
R_ShaderTouchImages( mod->shaders[i] );
for( i = 0, shader = r_shaders; i < r_numShaders; i++, shader++ )
{
if( !shader->name[0] ) continue;
// used this sequence
if( shader->touchFrame == registration_sequence ) continue;
if( shader->flags & SHADER_STATIC ) continue;
R_FreeShader( shader );
}
}
/*
@ -4952,8 +5000,8 @@ static void R_CreateBuiltInShaders( void )
shader = R_NewShader();
com.strncpy( shader->name, "<default>", sizeof( shader->name ));
shader->index = r_numShaders;
shader->type = SHADER_TEXTURE;
shader->flags = SHADER_STATIC;
shader->surfaceParm = SURF_NOLIGHTMAP;
shader->stages[0]->bundles[0]->textures[0] = r_defaultTexture;
shader->stages[0]->bundles[0]->numTextures++;
@ -4966,9 +5014,8 @@ static void R_CreateBuiltInShaders( void )
shader = R_NewShader();
com.strncpy( shader->name, "<lightmap>", sizeof( shader->name ));
shader->index = r_numShaders;
shader->type = SHADER_TEXTURE;
shader->flags = SHADER_HASLIGHTMAP;
shader->flags = SHADER_HASLIGHTMAP|SHADER_STATIC;
shader->stages[0]->bundles[0]->texType = TEX_LIGHTMAP;
shader->stages[0]->numBundles++;
shader->numStages++;
@ -4979,9 +5026,8 @@ static void R_CreateBuiltInShaders( void )
shader = R_NewShader();
com.strncpy( shader->name, "<skybox>", sizeof( shader->name ));
shader->index = r_numShaders;
shader->type = SHADER_SKY;
shader->flags = SHADER_SKYPARMS;
shader->flags = SHADER_SKYPARMS|SHADER_STATIC;
for( i = 0; i < 6; i++ )
shader->skyParms.farBox[i] = r_skyTexture;
shader->skyParms.cloudHeight = 128.0f;
@ -4991,8 +5037,8 @@ static void R_CreateBuiltInShaders( void )
shader = R_NewShader();
com.strncpy( shader->name, "<particle>", sizeof( shader->name ));
shader->index = r_numShaders;
shader->type = SHADER_SPRITE;
shader->flags = SHADER_STATIC;
shader->surfaceParm = SURF_NOLIGHTMAP;
shader->stages[0]->bundles[0]->textures[0] = r_particleTexture;
shader->stages[0]->blendFunc.src = GL_DST_COLOR;
@ -5013,16 +5059,17 @@ R_ShaderList_f
*/
void R_ShaderList_f( void )
{
ref_shader_t *shader;
ref_shader_t *shader;
int i, j;
int passes;
int shaderCount;
Msg( "\n" );
Msg( "-----------------------------------\n" );
for( i = 0; i < r_numShaders; i++ )
for( i = shaderCount = 0, shader = r_shaders; i < r_numShaders; i++, shader++ )
{
shader = r_shaders[i];
if( !shader->shadernum ) continue;
for( passes = j = 0; j < shader->numStages; j++ )
passes += shader->stages[j]->numBundles;
@ -5060,10 +5107,11 @@ void R_ShaderList_f( void )
Msg( "%2i ", shader->sort );
Msg( ": %s%s\n", shader->name, (shader->flags & SHADER_DEFAULTED) ? " (DEFAULTED)" : "" );
shaderCount++;
}
Msg( "-----------------------------------\n" );
Msg( "%i total shaders\n", r_numShaders );
Msg( "%i total shaders\n", shaderCount );
Msg( "\n" );
}
@ -5112,26 +5160,13 @@ R_ShutdownShaders
*/
void R_ShutdownShaders( void )
{
ref_shader_t *shader;
shaderStage_t *stage;
stageBundle_t *bundle;
int i, j, k;
ref_shader_t *shader;
int i;
for( i = 0; i < r_numShaders; i++ )
for( i = 0, shader = r_shaders; i < r_numShaders; i++, shader++ )
{
shader = r_shaders[i];
for( j = 0; j < shader->numStages; j++ )
{
stage = shader->stages[j];
for( k = 0; k < stage->numBundles; k++ )
{
bundle = stage->bundles[k];
//FIXME: implement
//if( bundle->flags & STAGEBUNDLE_VIDEOMAP )
// CIN_StopCinematic( bundle->cinematicHandle );
}
}
if( !shader->shadernum ) continue; // already freed
R_FreeShader( shader );
}
Mem_FreePool( &r_shaderpool ); // free all data allocated by shaders

View File

@ -37,22 +37,26 @@
#define SHADER_MAX_TCMOD 8
// shader flags
#define SHADER_EXTERNAL 0x00000001
#define SHADER_DEFAULTED 0x00000002
#define SHADER_HASLIGHTMAP 0x00000004
#define SHADER_SURFACEPARM 0x00000008
#define SHADER_NOMIPMAPS 0x00000010
#define SHADER_NOPICMIP 0x00000020
#define SHADER_NOCOMPRESS 0x00000040
#define SHADER_NOSHADOWS 0x00000080
#define SHADER_NOFRAGMENTS 0x00000100
#define SHADER_ENTITYMERGABLE 0x00000200
#define SHADER_POLYGONOFFSET 0x00000400
#define SHADER_CULL 0x00000800
#define SHADER_SORT 0x00001000
#define SHADER_TESSSIZE 0x00002000
#define SHADER_SKYPARMS 0x00004000
#define SHADER_DEFORMVERTEXES 0x00008000
typedef enum
{
SHADER_STATIC = BIT(0), // never freed by R_ShaderFreeUnused
SHADER_EXTERNAL = BIT(1),
SHADER_DEFAULTED = BIT(2),
SHADER_HASLIGHTMAP = BIT(3),
SHADER_SURFACEPARM = BIT(4),
SHADER_NOMIPMAPS = BIT(5),
SHADER_NOPICMIP = BIT(6),
SHADER_NOCOMPRESS = BIT(7),
SHADER_NOSHADOWS = BIT(8),
SHADER_NOFRAGMENTS = BIT(9),
SHADER_ENTITYMERGABLE = BIT(10),
SHADER_POLYGONOFFSET = BIT(11),
SHADER_CULL = BIT(12),
SHADER_SORT = BIT(13),
SHADER_TESSSIZE = BIT(14),
SHADER_SKYPARMS = BIT(15),
SHADER_DEFORMVERTEXES = BIT(16),
}shaderFlags_t;
// shader stage flags
typedef enum
@ -397,10 +401,12 @@ typedef struct shaderStage_s
typedef struct ref_shader_s
{
string name;
int index;
int type;
int shadernum;
uint surfaceParm;
int conditionRegister;
int touchFrame; // 0 = free
byte *mempool; // private shader pool
uint flags;
cull_t cull;

View File

@ -475,18 +475,18 @@ void R_DrawSky( void )
for( j = 0, v = skySide->vertices; j < skySide->numVertices; j++, v++ )
{
ref.vertsArray[ref.numVertex].point[0] = v->xyz[0];
ref.vertsArray[ref.numVertex].point[1] = v->xyz[1];
ref.vertsArray[ref.numVertex].point[2] = v->xyz[2];
ref.vertsArray[ref.numVertex].normal[0] = v->normal[0];
ref.vertsArray[ref.numVertex].normal[1] = v->normal[1];
ref.vertsArray[ref.numVertex].normal[2] = v->normal[2];
ref.vertsArray[ref.numVertex].stcoord[0] = v->sphere[0];
ref.vertsArray[ref.numVertex].stcoord[1] = v->sphere[1];
ref.vertsArray[ref.numVertex].color[0] = 1.0f;
ref.vertsArray[ref.numVertex].color[1] = 1.0f;
ref.vertsArray[ref.numVertex].color[2] = 1.0f;
ref.vertsArray[ref.numVertex].color[3] = 1.0f;
ref.vertexArray[ref.numVertex][0] = v->xyz[0];
ref.vertexArray[ref.numVertex][1] = v->xyz[1];
ref.vertexArray[ref.numVertex][2] = v->xyz[2];
ref.normalArray[ref.numVertex][0] = v->normal[0];
ref.normalArray[ref.numVertex][1] = v->normal[1];
ref.normalArray[ref.numVertex][2] = v->normal[2];
ref.inTexCoordArray[ref.numVertex][0] = v->sphere[0];
ref.inTexCoordArray[ref.numVertex][1] = v->sphere[1];
ref.colorArray[ref.numVertex][0] = 1.0f;
ref.colorArray[ref.numVertex][1] = 1.0f;
ref.colorArray[ref.numVertex][2] = 1.0f;
ref.colorArray[ref.numVertex][3] = 1.0f;
ref.numVertex++;
}
}
@ -592,7 +592,7 @@ void R_SetupSky( const char *name, float rotate, const vec3_t axis )
if( !com.strlen( name )) return; // invalid name
r_worldModel->sky = Mem_Realloc( r_temppool, r_worldModel->sky, sizeof( sky_t ));
sky = r_worldModel->sky;
sky->shader = r_shaders[R_FindShader( name, SHADER_SKY, 0 )];
sky->shader = R_FindShader( name, SHADER_SKY, 0 );
sky->rotate = rotate;
if(!VectorIsNull( axis ))

View File

@ -50,10 +50,10 @@ dframetype_t *R_SpriteLoadFrame( rmodel_t *mod, void *pin, mspriteframe_t **ppfr
*ppframe = pspriteframe;
R_SetInternalMap( pspriteframe->texture );
pspriteframe->shader = R_FindShader( name, SHADER_SPRITE, surfaceParm );
pspriteframe->shader = R_FindShader( name, SHADER_SPRITE, surfaceParm )->shadernum;
frames = Mem_Realloc( mod->mempool, frames, sizeof( ref_shader_t* ) * (mod->numShaders + 1));
frames[mod->numShaders++] = r_shaders[pspriteframe->shader];
frames[mod->numShaders++] = &r_shaders[pspriteframe->shader];
return (dframetype_t *)((byte *)(pinframe + 1) + pinframe->width * pinframe->height );
}
@ -172,6 +172,7 @@ void R_SpriteLoadModel( rmodel_t *mod, const void *buffer )
MsgDev( D_LOAD, "%s, rendermode %d\n", mod->name, psprite->rendermode );
mod->registration_sequence = registration_sequence;
frames = NULL; // invalidate pointer
for( i = 0; i < numframes; i++ )
{
@ -272,7 +273,7 @@ void R_AddSpriteModelToList( ref_entity_t *entity )
// copy frame params
entity->radius = frame->radius;
entity->rotation = 0;
entity->shader = r_shaders[frame->shader];
entity->shader = &r_shaders[frame->shader];
// add it
R_AddMeshToList( MESH_SPRITE, NULL, entity->shader, entity, 0 );
@ -299,9 +300,9 @@ void R_DrawSpriteModel( void )
switch( psprite->type )
{
case SPR_ORIENTED:
VectorCopy( e->axis[0], forward );
VectorCopy( e->axis[1], right );
VectorCopy( e->axis[2], up );
VectorCopy( e->matrix[0], forward );
VectorCopy( e->matrix[1], right );
VectorCopy( e->matrix[2], up );
VectorScale( forward, 0.01, forward ); // to avoid z-fighting
VectorSubtract( e->origin, forward, e->origin );
break;
@ -317,12 +318,12 @@ void R_DrawSpriteModel( void )
VectorSet( up, 0, 0, 1 );
break;
case SPR_FWD_PARALLEL_ORIENTED:
right[0] = e->axis[1][0] * r_forward[0] + e->axis[1][1] * r_right[0] + e->axis[1][2] * r_up[0];
right[1] = e->axis[1][0] * r_forward[1] + e->axis[1][1] * r_right[1] + e->axis[1][2] * r_up[1];
right[2] = e->axis[1][0] * r_forward[2] + e->axis[1][1] * r_right[2] + e->axis[1][2] * r_up[2];
up[0] = e->axis[2][0] * r_forward[0] + e->axis[2][1] * r_right[0] + e->axis[2][2] * r_up[0];
up[1] = e->axis[2][0] * r_forward[1] + e->axis[2][1] * r_right[1] + e->axis[2][2] * r_up[1];
up[2] = e->axis[2][0] * r_forward[2] + e->axis[2][1] * r_right[2] + e->axis[2][2] * r_up[2];
right[0] = e->matrix[1][0] * r_forward[0] + e->matrix[1][1] * r_right[0] + e->matrix[1][2] * r_up[0];
right[1] = e->matrix[1][0] * r_forward[1] + e->matrix[1][1] * r_right[1] + e->matrix[1][2] * r_up[1];
right[2] = e->matrix[1][0] * r_forward[2] + e->matrix[1][1] * r_right[2] + e->matrix[1][2] * r_up[2];
up[0] = e->matrix[2][0] * r_forward[0] + e->matrix[2][1] * r_right[0] + e->matrix[2][2] * r_up[0];
up[1] = e->matrix[2][0] * r_forward[1] + e->matrix[2][1] * r_right[1] + e->matrix[2][2] * r_up[1];
up[2] = e->matrix[2][0] * r_forward[2] + e->matrix[2][1] * r_right[2] + e->matrix[2][2] * r_up[2];
break;
case SPR_FWD_PARALLEL:
default: // normal sprite

View File

@ -223,8 +223,8 @@ dstudiohdr_t *R_StudioLoadHeader( rmodel_t *mod, const uint *buffer )
for( i = 0; i < phdr->numtextures; i++ )
{
R_SetInternalMap(R_StudioLoadTexture( mod, &ptexture[i], pin ));
ptexture[i].shader = R_FindShader( ptexture[i].name, SHADER_STUDIO, surfaceParm );
mod->shaders[i] = r_shaders[ptexture[i].shader];
ptexture[i].shader = R_FindShader( ptexture[i].name, SHADER_STUDIO, surfaceParm )->shadernum;
mod->shaders[i] = &r_shaders[ptexture[i].shader];
}
}
return (dstudiohdr_t *)buffer;
@ -1424,7 +1424,7 @@ void R_StudioDrawMeshes( dstudiotexture_t * ptexture, short *pskinref, int pass
//GL_BindTexture( m_pRenderModel->textures[ptexture[pskinref[pmesh->skinref]].index].image );
// FIXME: test
//m_pCurrentShader = m_pRenderModel->shaders[ptexture[pskinref[pmesh->skinref]].shader];
m_pCurrentShader = r_shaders[ptexture[pskinref[pmesh->skinref]].shader];
m_pCurrentShader = &r_shaders[ptexture[pskinref[pmesh->skinref]].shader];
while( i = *(ptricmds++))
{
@ -1503,7 +1503,7 @@ void R_StudioDrawPoints ( void )
// hack the depth range to prevent view model from poking into walls
if( m_pCurrentEntity->renderfx & RF_DEPTHHACK) pglDepthRange( 0.0, 0.3 );
if(( m_pCurrentEntity->renderfx & RF_VIEWMODEL ) && ( r_lefthand->value == 1.0F ))
VectorNegate( m_pCurrentEntity->axis[1], m_pCurrentEntity->axis[1] );
VectorNegate( m_pCurrentEntity->matrix[1], m_pCurrentEntity->matrix[1] );
R_StudioDrawMeshes( ptexture, pskinref, m_PassNum );
// hack the depth range to prevent view model from poking into walls

View File

@ -34,6 +34,20 @@ void R_DrawSurface( void )
for( p = surf->poly; p; p = p->next )
{
#if 0
GL_Begin( GL_POLYGON );
for( i = 0, v = p->vertices; i < p->numVertices; i++, v++ )
{
GL_TexCoord4f( v->st[0], v->st[1], v->lm[0], v->lm[1] );
GL_Binormal3fv( surf->binormal );
GL_Tangent3fv( surf->tangent );
GL_Normal3fv( surf->normal );
GL_Color4fv( v->color );
GL_Vertex3fv( v->xyz );
}
GL_End();
#else
RB_CheckMeshOverflow( p->numIndices, p->numVertices );
for( i = 0; i < p->numIndices; i += 3 )
@ -45,25 +59,26 @@ void R_DrawSurface( void )
for( i = 0, v = p->vertices; i < p->numVertices; i++, v++ )
{
ref.vertsArray[ref.numVertex].point[0] = v->xyz[0];
ref.vertsArray[ref.numVertex].point[1] = v->xyz[1];
ref.vertsArray[ref.numVertex].point[2] = v->xyz[2];
ref.vertsArray[ref.numVertex].tangent[0] = surf->tangent[0];
ref.vertsArray[ref.numVertex].tangent[1] = surf->tangent[1];
ref.vertsArray[ref.numVertex].tangent[2] = surf->tangent[2];
ref.vertsArray[ref.numVertex].binormal[0] = surf->binormal[0];
ref.vertsArray[ref.numVertex].binormal[1] = surf->binormal[1];
ref.vertsArray[ref.numVertex].binormal[2] = surf->binormal[2];
ref.vertsArray[ref.numVertex].normal[0] = surf->normal[0];
ref.vertsArray[ref.numVertex].normal[1] = surf->normal[1];
ref.vertsArray[ref.numVertex].normal[2] = surf->normal[2];
ref.vertsArray[ref.numVertex].stcoord[0] = v->st[0];
ref.vertsArray[ref.numVertex].stcoord[1] = v->st[1];
ref.vertsArray[ref.numVertex].lmcoord[0] = v->lightmap[0];
ref.vertsArray[ref.numVertex].lmcoord[1] = v->lightmap[1];
Vector4Copy( v->color, ref.vertsArray[ref.numVertex].color );
ref.vertexArray[ref.numVertex][0] = v->xyz[0];
ref.vertexArray[ref.numVertex][1] = v->xyz[1];
ref.vertexArray[ref.numVertex][2] = v->xyz[2];
ref.tangentArray[ref.numVertex][0] = surf->tangent[0];
ref.tangentArray[ref.numVertex][1] = surf->tangent[1];
ref.tangentArray[ref.numVertex][2] = surf->tangent[2];
ref.binormalArray[ref.numVertex][0] = surf->binormal[0];
ref.binormalArray[ref.numVertex][1] = surf->binormal[1];
ref.binormalArray[ref.numVertex][2] = surf->binormal[2];
ref.normalArray[ref.numVertex][0] = surf->normal[0];
ref.normalArray[ref.numVertex][1] = surf->normal[1];
ref.normalArray[ref.numVertex][2] = surf->normal[2];
ref.inTexCoordArray[ref.numVertex][0] = v->st[0];
ref.inTexCoordArray[ref.numVertex][1] = v->st[1];
ref.inTexCoordArray[ref.numVertex][2] = v->lm[0];
ref.inTexCoordArray[ref.numVertex][3] = v->lm[1];
Vector4Copy( v->color, ref.colorArray[ref.numVertex] );
ref.numVertex++;
}
#endif
}
}
@ -169,7 +184,7 @@ void R_AddBrushModelToList( ref_entity_t *entity )
return;
// cull
if( !AxisCompare( entity->axis, axisDefault ))
if( !Matrix3x3_Compare( m_pCurrentEntity->matrix, matrix3x3_identity ))
{
for( i = 0; i < 3; i++ )
{
@ -181,7 +196,7 @@ void R_AddBrushModelToList( ref_entity_t *entity )
return;
VectorSubtract( r_origin, entity->origin, tmp );
VectorRotate( tmp, entity->axis, origin );
Matrix3x3_Transform( m_pCurrentEntity->matrix, tmp, origin );
}
else
{

View File

@ -6,43 +6,6 @@
#include "r_local.h"
#include "mathlib.h"
vec3_t axisDefault[3] = {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}};
/*
=================
AxisCopy
=================
*/
void AxisCopy( const vec3_t in[3], vec3_t out[3] )
{
out[0][0] = in[0][0];
out[0][1] = in[0][1];
out[0][2] = in[0][2];
out[1][0] = in[1][0];
out[1][1] = in[1][1];
out[1][2] = in[1][2];
out[2][0] = in[2][0];
out[2][1] = in[2][1];
out[2][2] = in[2][2];
}
/*
=================
AxisClear
=================
*/
void AxisClear( vec3_t axis[3] )
{
axis[0][0] = 1;
axis[0][1] = 0;
axis[0][2] = 0;
axis[1][0] = 0;
axis[1][1] = 1;
axis[1][2] = 0;
axis[2][0] = 0;
axis[2][1] = 0;
axis[2][2] = 1;
}
/*
=================
@ -75,66 +38,6 @@ void AnglesToAxis ( const vec3_t angles )
r_up[2] = cr*cp;
}
/*
=================
AnglesToAxis
=================
*/
void AnglesToAxisPrivate (const vec3_t angles, vec3_t axis[3])
{
static float sp, sy, sr, cp, cy, cr;
float angle;
angle = DEG2RAD(angles[PITCH]);
sp = sin(angle);
cp = cos(angle);
angle = DEG2RAD(angles[YAW]);
sy = sin(angle);
cy = cos(angle);
angle = DEG2RAD(angles[ROLL]);
sr = sin(angle);
cr = cos(angle);
axis[0][0] = cp*cy;
axis[0][1] = cp*sy;
axis[0][2] = -sp;
axis[1][0] = sr*sp*cy+cr*-sy;
axis[1][1] = sr*sp*sy+cr*cy;
axis[1][2] = sr*cp;
axis[2][0] = cr*sp*cy+-sr*-sy;
axis[2][1] = cr*sp*sy+-sr*cy;
axis[2][2] = cr*cp;
}
/*
=================
AxisCompare
=================
*/
bool AxisCompare( const vec3_t axis1[3], const vec3_t axis2[3] )
{
if (axis1[0][0] != axis2[0][0] || axis1[0][1] != axis2[0][1] || axis1[0][2] != axis2[0][2])
return false;
if (axis1[1][0] != axis2[1][0] || axis1[1][1] != axis2[1][1] || axis1[1][2] != axis2[1][2])
return false;
if (axis1[2][0] != axis2[2][0] || axis1[2][1] != axis2[2][1] || axis1[2][2] != axis2[2][2])
return false;
return true;
}
/*
=================
VectorRotate
=================
*/
void VectorRotate ( const vec3_t v, const vec3_t matrix[3], vec3_t out )
{
out[0] = v[0]*matrix[0][0] + v[1]*matrix[0][1] + v[2]*matrix[0][2];
out[1] = v[0]*matrix[1][0] + v[1]*matrix[1][1] + v[2]*matrix[1][2];
out[2] = v[0]*matrix[2][0] + v[1]*matrix[2][1] + v[2]*matrix[2][2];
}
/*
=================
MatrixGL_MultiplyFast

View File

@ -35,7 +35,12 @@ GLOBAL:
13. сделать case -light для bsplib OK
14. зачинить небо OK
15. наладить отрисовку энтить
16. починить PhysWorld
16. починить PhysWorld OK
17. наладить StudioModelRender
18. энумератор текстур OK
19. наладить удаление ключей из HashTable OK
20. CM_HeadnodeVisible
21. Matrix3x3_Compare crashed
операция "Полная отладка менеджера текстур"
0. анализ менеджера egl и q2e_068

View File

@ -76,7 +76,7 @@ void PRVM_MEM_IncreaseEdicts( void )
Mem_Copy(vm.prog->edictsfields, oldedictsfields, oldmaxedicts * vm.prog->edict_size);
Mem_Copy(vm.prog->edictprivate, oldedictprivate, oldmaxedicts * vm.prog->edictprivate_size);
//set e and v pointers
// set e and v pointers
for(i = 0; i < vm.prog->max_edicts; i++)
{
vm.prog->edicts[i].priv.ed = (vm_edict_t *)((byte *)vm.prog->edictprivate + i * vm.prog->edictprivate_size);
@ -1184,6 +1184,7 @@ void PRVM_ED_LoadFromFile( const char *data )
// pev = ent
PRVM_G_INT(vm.prog->pev->ofs) = PRVM_EDICT_TO_PROG(ent);
PRVM_ExecuteProgram( func - vm.prog->functions, "", __FILE__, __LINE__ );
if( vm.prog->classify_edict ) vm.prog->classify_edict( ent );
}
spawned++;

View File

@ -637,8 +637,7 @@ void S_EndRegistration( void )
{
// don't need this sound
palDeleteBuffers( 1, &sfx->bufferNum );
sfx->name[0] = '\0'; // free spot
sfx->loaded = false;
Mem_Set( sfx, 0, sizeof( sfx_t )); // free spot
}
}

View File

@ -82,8 +82,8 @@ static void S_AllocChannels( void )
for( i = 0, ch = s_channels; i < MAX_CHANNELS; i++, ch++)
{
palGenSources(1, &ch->sourceNum);
if(palGetError() != AL_NO_ERROR)
palGenSources( 1, &ch->sourceNum );
if( palGetError() != AL_NO_ERROR )
break;
al_state.num_channels++;
}
@ -129,8 +129,8 @@ static void S_StopChannel( channel_t *ch )
{
ch->sfx = NULL;
palSourceStop(ch->sourceNum);
palSourcei(ch->sourceNum, AL_BUFFER, 0);
palSourceStop( ch->sourceNum );
palSourcei( ch->sourceNum, AL_BUFFER, 0 );
}
/*
@ -142,9 +142,9 @@ static void S_PlayChannel( channel_t *ch, sfx_t *sfx )
{
ch->sfx = sfx;
palSourcei(ch->sourceNum, AL_BUFFER, sfx->bufferNum);
palSourcei(ch->sourceNum, AL_LOOPING, ch->loopsound);
palSourcei(ch->sourceNum, AL_SOURCE_RELATIVE, false);
palSourcei( ch->sourceNum, AL_BUFFER, sfx->bufferNum );
palSourcei( ch->sourceNum, AL_LOOPING, ch->loopsound );
palSourcei( ch->sourceNum, AL_SOURCE_RELATIVE, false );
palSourcei( ch->sourceNum, AL_SAMPLE_OFFSET, 0 );
if( ch->loopstart >= 0 )
@ -193,7 +193,7 @@ static void S_SpatializeChannel( channel_t *ch )
}
}
// Update min/max distance
// update min/max distance
if( ch->distanceMult )
palSourcef( ch->sourceNum, AL_REFERENCE_DISTANCE, s_minDistance->value * ch->distanceMult );
else palSourcef( ch->sourceNum, AL_REFERENCE_DISTANCE, s_maxDistance->value );
@ -439,7 +439,8 @@ void S_StartSound( const vec3_t pos, int entnum, int channel, sound_t handle, fl
if( !sfx ) return;
// Make sure the sound is loaded
if(!S_LoadSound(sfx)) return;
if( !S_LoadSound( sfx ))
return;
// Allocate a playSound
ps = S_AllocPlaySound();
@ -460,7 +461,7 @@ void S_StartSound( const vec3_t pos, int entnum, int channel, sound_t handle, fl
VectorCopy( pos, ps->position );
}
else ps->fixedPosition = false;
ps->volume = vol;
ps->attenuation = attn;
ps->beginTime = Sys_DoubleTime();
@ -485,7 +486,7 @@ bool S_StartLocalSound( const char *name )
{
sound_t sfxHandle;
if(!al_state.initialized)
if( !al_state.initialized )
return false;
sfxHandle = S_RegisterSound( name );
@ -608,12 +609,12 @@ void S_Update( int clientnum, const vec3_t position, const vec3_t velocity, cons
// update spatialization for all sounds
for( i = 0, ch = s_channels; i < al_state.num_channels; i++, ch++ )
{
if(!ch->sfx) continue; // not active
if( !ch->sfx ) continue; // not active
// check for stop
if( ch->loopsound )
{
if(ch->loopframe != al_state.framecount)
if( ch->loopframe != al_state.framecount )
{
S_StopChannel( ch );
continue;