do not replace older surfaces with newer ones but refuse to add new ones instead

surfaces added first are part of the map itself
it's better to drop e.g. some plasma cells rather than e.g. entire walls
it's also less error-prone to work with since we don't need to fix numbers on read
but only check on write in exactly 2 spots

also removed tr.shiftedEntityNum because it was unnecessary...
This commit is contained in:
myT 2022-04-10 21:45:59 +02:00
parent 1317ce54cb
commit 981f059b7b
5 changed files with 38 additions and 45 deletions

View file

@ -421,8 +421,8 @@ static void RB_RenderLitSurfList( dlight_t* dl, qbool opaque )
RB_BeginSurface( shader, fogNum ); RB_BeginSurface( shader, fogNum );
// stage index is guaranteed valid by R_AddLitSurface // stage index is guaranteed valid by R_AddLitSurface
const int stageIndex = tess.shader->lightingStages[ST_DIFFUSE]; const int stageIndex = shader->lightingStages[ST_DIFFUSE];
const shaderStage_t* const stage = tess.xstages[stageIndex]; const shaderStage_t* const stage = shader->stages[stageIndex];
backEnd.dlIntensity = (shader->contentFlags & liquidFlags) != 0 ? 0.5f : 1.0f; backEnd.dlIntensity = (shader->contentFlags & liquidFlags) != 0 ? 0.5f : 1.0f;
backEnd.dlStateBits = backEnd.dlStateBits =
(opaque || (stage->stateBits & GLS_ATEST_BITS) != 0) ? (opaque || (stage->stateBits & GLS_ATEST_BITS) != 0) ?

View file

@ -790,7 +790,6 @@ extern refimport_t ri;
#define MAX_SKINS 1024 #define MAX_SKINS 1024
#define MAX_DRAWSURFS 0x10000 #define MAX_DRAWSURFS 0x10000
#define DRAWSURF_MASK (MAX_DRAWSURFS-1)
/* /*
the drawsurf sort data is packed into a single 32 bit value so it can be the drawsurf sort data is packed into a single 32 bit value so it can be
@ -887,7 +886,6 @@ typedef struct {
trRefEntity_t *currentEntity; trRefEntity_t *currentEntity;
trRefEntity_t worldEntity; // point currentEntity at this when rendering world trRefEntity_t worldEntity; // point currentEntity at this when rendering world
int currentEntityNum; int currentEntityNum;
int shiftedEntityNum; // currentEntityNum << QSORT_ENTITYNUM_SHIFT
const model_t* currentModel; const model_t* currentModel;
viewParms_t viewParms; viewParms_t viewParms;
@ -1074,6 +1072,7 @@ void R_AddPolygonSurfaces();
void R_AddDrawSurf( const surfaceType_t* surface, const shader_t* shader, int fogIndex ); void R_AddDrawSurf( const surfaceType_t* surface, const shader_t* shader, int fogIndex );
void R_AddLitSurf( const surfaceType_t* surface, const shader_t* shader, int fogIndex ); void R_AddLitSurf( const surfaceType_t* surface, const shader_t* shader, int fogIndex );
unsigned int R_ComposeSort( int entityNum, const shader_t *shader, int fogNum );
void R_DecomposeSort( unsigned sort, int *entityNum, const shader_t **shader, int *fogNum ); void R_DecomposeSort( unsigned sort, int *entityNum, const shader_t **shader, int *fogNum );

View file

@ -1067,38 +1067,46 @@ static void R_SortLitsurfs( dlight_t* dl )
void R_AddDrawSurf( const surfaceType_t* surface, const shader_t* shader, int fogIndex ) void R_AddDrawSurf( const surfaceType_t* surface, const shader_t* shader, int fogIndex )
{ {
// instead of checking for overflow, we just mask the index so it wraps around if (tr.refdef.numDrawSurfs >= MAX_DRAWSURFS)
const int index = tr.refdef.numDrawSurfs++ & DRAWSURF_MASK; return;
// the sort data is packed into a single 32 bit value so it can be
// compared quickly during the qsorting process drawSurf_t* const drawSurf = &tr.refdef.drawSurfs[tr.refdef.numDrawSurfs++];
tr.refdef.drawSurfs[index].sort = (shader->sortedIndex << QSORT_SHADERNUM_SHIFT) drawSurf->sort = R_ComposeSort( tr.currentEntityNum, shader, fogIndex );
| tr.shiftedEntityNum | (fogIndex << QSORT_FOGNUM_SHIFT); drawSurf->surface = surface;
tr.refdef.drawSurfs[index].surface = surface; drawSurf->model = tr.currentModel != NULL ? tr.currentModel->index : 0;
tr.refdef.drawSurfs[index].model = tr.currentModel != NULL ? tr.currentModel->index : 0;
} }
void R_AddLitSurf( const surfaceType_t* surface, const shader_t* shader, int fogIndex ) void R_AddLitSurf( const surfaceType_t* surface, const shader_t* shader, int fogIndex )
{ {
if (tr.refdef.numLitSurfs >= MAX_DRAWSURFS)
return;
tr.pc[RF_LIT_SURFS]++; tr.pc[RF_LIT_SURFS]++;
int index = tr.refdef.numLitSurfs++ & DRAWSURF_MASK; litSurf_t* const litSurf = &tr.refdef.litSurfs[tr.refdef.numLitSurfs++];
litSurf_t* litsurf = &tr.refdef.litSurfs[index]; litSurf->sort = R_ComposeSort( tr.currentEntityNum, shader, fogIndex );
litSurf->surface = surface;
litsurf->sort = (shader->sortedIndex << QSORT_SHADERNUM_SHIFT)
| tr.shiftedEntityNum | (fogIndex << QSORT_FOGNUM_SHIFT);
litsurf->surface = surface;
if (!tr.light->head) if (!tr.light->head)
tr.light->head = litsurf; tr.light->head = litSurf;
if (tr.light->tail) if (tr.light->tail)
tr.light->tail->next = litsurf; tr.light->tail->next = litSurf;
tr.light->tail = litsurf; tr.light->tail = litSurf;
tr.light->tail->next = 0; tr.light->tail->next = 0;
} }
unsigned int R_ComposeSort( int entityNum, const shader_t *shader, int fogNum )
{
return
(entityNum << QSORT_ENTITYNUM_SHIFT) |
(shader->sortedIndex << QSORT_SHADERNUM_SHIFT) |
(fogNum << QSORT_FOGNUM_SHIFT);
}
void R_DecomposeSort( unsigned sort, int *entityNum, const shader_t **shader, int *fogNum ) void R_DecomposeSort( unsigned sort, int *entityNum, const shader_t **shader, int *fogNum )
{ {
*fogNum = ( sort >> QSORT_FOGNUM_SHIFT ) & 31; *fogNum = ( sort >> QSORT_FOGNUM_SHIFT ) & 31;
@ -1226,13 +1234,8 @@ static int R_CompareDrawSurf( const void* aPtr, const void* bPtr )
static void R_SortDrawSurfs( int firstDrawSurf, int firstLitSurf ) static void R_SortDrawSurfs( int firstDrawSurf, int firstLitSurf )
{ {
int numDrawSurfs = tr.refdef.numDrawSurfs - firstDrawSurf; const int numDrawSurfs = tr.refdef.numDrawSurfs - firstDrawSurf;
drawSurf_t* drawSurfs = tr.refdef.drawSurfs + firstDrawSurf; drawSurf_t* const drawSurfs = tr.refdef.drawSurfs + firstDrawSurf;
const shader_t* shader;
int fogNum;
int entityNum;
int i;
// it is possible for some views to not have any surfaces // it is possible for some views to not have any surfaces
if ( numDrawSurfs < 1 ) { if ( numDrawSurfs < 1 ) {
@ -1241,19 +1244,15 @@ static void R_SortDrawSurfs( int firstDrawSurf, int firstLitSurf )
return; return;
} }
// if we overflowed MAX_DRAWSURFS, the drawsurfs
// wrapped around in the buffer and we will be missing
// the first surfaces, not the last ones
if ( numDrawSurfs > MAX_DRAWSURFS ) {
numDrawSurfs = MAX_DRAWSURFS;
}
// sort the drawsurfs by sort type, then shader, then entity, etc // sort the drawsurfs by sort type, then shader, then entity, etc
R_RadixSort( drawSurfs, numDrawSurfs ); R_RadixSort( drawSurfs, numDrawSurfs );
const shader_t* shader;
int fogNum, entityNum;
// check for any pass through drawing, // check for any pass through drawing,
// which may cause another view to be rendered first // which may cause another view to be rendered first
for ( i = 0 ; i < numDrawSurfs ; i++ ) { for ( int i = 0 ; i < numDrawSurfs ; i++ ) {
R_DecomposeSort( (drawSurfs+i)->sort, &entityNum, &shader, &fogNum ); R_DecomposeSort( (drawSurfs+i)->sort, &entityNum, &shader, &fogNum );
if ( shader->sort > SS_PORTAL ) { if ( shader->sort > SS_PORTAL ) {
@ -1277,7 +1276,7 @@ static void R_SortDrawSurfs( int firstDrawSurf, int firstLitSurf )
// compute the average camera depth of all transparent surfaces // compute the average camera depth of all transparent surfaces
int numTranspSurfs = 0; int numTranspSurfs = 0;
for ( i = numDrawSurfs - 1; i >= 0; --i ) { for ( int i = numDrawSurfs - 1; i >= 0; --i ) {
R_DecomposeSort( (drawSurfs+i)->sort, &entityNum, &shader, &fogNum ); R_DecomposeSort( (drawSurfs+i)->sort, &entityNum, &shader, &fogNum );
if ( shader->sort <= SS_OPAQUE ) { if ( shader->sort <= SS_OPAQUE ) {
@ -1305,7 +1304,7 @@ static void R_SortDrawSurfs( int firstDrawSurf, int firstLitSurf )
// all the lit surfaces are in a single queue // all the lit surfaces are in a single queue
// but each light's surfaces are sorted within its subsection // but each light's surfaces are sorted within its subsection
for ( i = 0; i < tr.refdef.num_dlights; ++i ) { for ( int i = 0; i < tr.refdef.num_dlights; ++i ) {
dlight_t* dl = &tr.refdef.dlights[i]; dlight_t* dl = &tr.refdef.dlights[i];
if (dl->head) { if (dl->head) {
R_SortLitsurfs( dl ); R_SortLitsurfs( dl );
@ -1331,9 +1330,6 @@ static void R_AddEntitySurfaces()
for (tr.currentEntityNum = 0; tr.currentEntityNum < tr.refdef.num_entities; ++tr.currentEntityNum) { for (tr.currentEntityNum = 0; tr.currentEntityNum < tr.refdef.num_entities; ++tr.currentEntityNum) {
ent = tr.currentEntity = &tr.refdef.entities[tr.currentEntityNum]; ent = tr.currentEntity = &tr.refdef.entities[tr.currentEntityNum];
// preshift the value we are going to OR into the drawsurf sort
tr.shiftedEntityNum = tr.currentEntityNum << QSORT_ENTITYNUM_SHIFT;
// //
// the weapon model must be handled special -- // the weapon model must be handled special --
// we don't want the hacked weapon position showing in mirrors, // we don't want the hacked weapon position showing in mirrors,
@ -1424,8 +1420,8 @@ void R_RenderView( const viewParms_t* parms )
tr.viewParms.frameSceneNum = tr.frameSceneNum; tr.viewParms.frameSceneNum = tr.frameSceneNum;
tr.viewParms.frameCount = tr.frameCount; tr.viewParms.frameCount = tr.frameCount;
int firstDrawSurf = tr.refdef.numDrawSurfs; const int firstDrawSurf = tr.refdef.numDrawSurfs;
int firstLitSurf = tr.refdef.numLitSurfs; const int firstLitSurf = tr.refdef.numLitSurfs;
// set viewParms.world // set viewParms.world
re_cameraMatrixTime = Sys_Milliseconds(); re_cameraMatrixTime = Sys_Milliseconds();

View file

@ -80,7 +80,6 @@ DISCRETE POLYS
void R_AddPolygonSurfaces() void R_AddPolygonSurfaces()
{ {
tr.currentEntityNum = ENTITYNUM_WORLD; tr.currentEntityNum = ENTITYNUM_WORLD;
tr.shiftedEntityNum = tr.currentEntityNum << QSORT_ENTITYNUM_SHIFT;
const srfPoly_t* poly = tr.refdef.polys; const srfPoly_t* poly = tr.refdef.polys;
for (int i = 0; i < tr.refdef.numPolys; ++i, ++poly) { for (int i = 0; i < tr.refdef.numPolys; ++i, ++poly) {

View file

@ -577,7 +577,6 @@ void R_AddWorldSurfaces()
} }
tr.currentEntityNum = ENTITYNUM_WORLD; tr.currentEntityNum = ENTITYNUM_WORLD;
tr.shiftedEntityNum = tr.currentEntityNum << QSORT_ENTITYNUM_SHIFT;
// determine which leaves are in the PVS / areamask // determine which leaves are in the PVS / areamask
R_MarkLeaves(); R_MarkLeaves();