From 981f059b7b7ee537d44fed4cf64ebaa5bd1abcec Mon Sep 17 00:00:00 2001 From: myT Date: Sun, 10 Apr 2022 21:45:59 +0200 Subject: [PATCH] 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... --- code/renderer/tr_backend.cpp | 4 +- code/renderer/tr_local.h | 3 +- code/renderer/tr_main.cpp | 74 +++++++++++++++++------------------- code/renderer/tr_scene.cpp | 1 - code/renderer/tr_world.cpp | 1 - 5 files changed, 38 insertions(+), 45 deletions(-) diff --git a/code/renderer/tr_backend.cpp b/code/renderer/tr_backend.cpp index e5b0b69..720263a 100644 --- a/code/renderer/tr_backend.cpp +++ b/code/renderer/tr_backend.cpp @@ -421,8 +421,8 @@ static void RB_RenderLitSurfList( dlight_t* dl, qbool opaque ) RB_BeginSurface( shader, fogNum ); // stage index is guaranteed valid by R_AddLitSurface - const int stageIndex = tess.shader->lightingStages[ST_DIFFUSE]; - const shaderStage_t* const stage = tess.xstages[stageIndex]; + const int stageIndex = shader->lightingStages[ST_DIFFUSE]; + const shaderStage_t* const stage = shader->stages[stageIndex]; backEnd.dlIntensity = (shader->contentFlags & liquidFlags) != 0 ? 0.5f : 1.0f; backEnd.dlStateBits = (opaque || (stage->stateBits & GLS_ATEST_BITS) != 0) ? diff --git a/code/renderer/tr_local.h b/code/renderer/tr_local.h index 2a58e1a..7a9dbdb 100644 --- a/code/renderer/tr_local.h +++ b/code/renderer/tr_local.h @@ -790,7 +790,6 @@ extern refimport_t ri; #define MAX_SKINS 1024 #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 @@ -887,7 +886,6 @@ typedef struct { trRefEntity_t *currentEntity; trRefEntity_t worldEntity; // point currentEntity at this when rendering world int currentEntityNum; - int shiftedEntityNum; // currentEntityNum << QSORT_ENTITYNUM_SHIFT const model_t* currentModel; 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_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 ); diff --git a/code/renderer/tr_main.cpp b/code/renderer/tr_main.cpp index 7b4fb27..8b2a841 100644 --- a/code/renderer/tr_main.cpp +++ b/code/renderer/tr_main.cpp @@ -1067,38 +1067,46 @@ static void R_SortLitsurfs( dlight_t* dl ) 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 - const int index = tr.refdef.numDrawSurfs++ & DRAWSURF_MASK; - // the sort data is packed into a single 32 bit value so it can be - // compared quickly during the qsorting process - tr.refdef.drawSurfs[index].sort = (shader->sortedIndex << QSORT_SHADERNUM_SHIFT) - | tr.shiftedEntityNum | (fogIndex << QSORT_FOGNUM_SHIFT); - tr.refdef.drawSurfs[index].surface = surface; - tr.refdef.drawSurfs[index].model = tr.currentModel != NULL ? tr.currentModel->index : 0; + if (tr.refdef.numDrawSurfs >= MAX_DRAWSURFS) + return; + + drawSurf_t* const drawSurf = &tr.refdef.drawSurfs[tr.refdef.numDrawSurfs++]; + drawSurf->sort = R_ComposeSort( tr.currentEntityNum, shader, fogIndex ); + drawSurf->surface = surface; + drawSurf->model = tr.currentModel != NULL ? tr.currentModel->index : 0; } 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]++; - int index = tr.refdef.numLitSurfs++ & DRAWSURF_MASK; - litSurf_t* litsurf = &tr.refdef.litSurfs[index]; - - litsurf->sort = (shader->sortedIndex << QSORT_SHADERNUM_SHIFT) - | tr.shiftedEntityNum | (fogIndex << QSORT_FOGNUM_SHIFT); - litsurf->surface = surface; + litSurf_t* const litSurf = &tr.refdef.litSurfs[tr.refdef.numLitSurfs++]; + litSurf->sort = R_ComposeSort( tr.currentEntityNum, shader, fogIndex ); + litSurf->surface = surface; if (!tr.light->head) - tr.light->head = litsurf; + tr.light->head = litSurf; 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; } +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 ) { *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 ) { - int numDrawSurfs = tr.refdef.numDrawSurfs - firstDrawSurf; - drawSurf_t* drawSurfs = tr.refdef.drawSurfs + firstDrawSurf; - - const shader_t* shader; - int fogNum; - int entityNum; - int i; + const int numDrawSurfs = tr.refdef.numDrawSurfs - firstDrawSurf; + drawSurf_t* const drawSurfs = tr.refdef.drawSurfs + firstDrawSurf; // it is possible for some views to not have any surfaces if ( numDrawSurfs < 1 ) { @@ -1241,19 +1244,15 @@ static void R_SortDrawSurfs( int firstDrawSurf, int firstLitSurf ) 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 R_RadixSort( drawSurfs, numDrawSurfs ); + const shader_t* shader; + int fogNum, entityNum; + // check for any pass through drawing, // 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 ); 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 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 ); 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 // 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]; if (dl->head) { R_SortLitsurfs( dl ); @@ -1331,9 +1330,6 @@ static void R_AddEntitySurfaces() for (tr.currentEntityNum = 0; tr.currentEntityNum < tr.refdef.num_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 -- // 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.frameCount = tr.frameCount; - int firstDrawSurf = tr.refdef.numDrawSurfs; - int firstLitSurf = tr.refdef.numLitSurfs; + const int firstDrawSurf = tr.refdef.numDrawSurfs; + const int firstLitSurf = tr.refdef.numLitSurfs; // set viewParms.world re_cameraMatrixTime = Sys_Milliseconds(); diff --git a/code/renderer/tr_scene.cpp b/code/renderer/tr_scene.cpp index d6b4c24..da96c81 100644 --- a/code/renderer/tr_scene.cpp +++ b/code/renderer/tr_scene.cpp @@ -80,7 +80,6 @@ DISCRETE POLYS void R_AddPolygonSurfaces() { tr.currentEntityNum = ENTITYNUM_WORLD; - tr.shiftedEntityNum = tr.currentEntityNum << QSORT_ENTITYNUM_SHIFT; const srfPoly_t* poly = tr.refdef.polys; for (int i = 0; i < tr.refdef.numPolys; ++i, ++poly) { diff --git a/code/renderer/tr_world.cpp b/code/renderer/tr_world.cpp index d743fb1..d09f824 100644 --- a/code/renderer/tr_world.cpp +++ b/code/renderer/tr_world.cpp @@ -577,7 +577,6 @@ void R_AddWorldSurfaces() } tr.currentEntityNum = ENTITYNUM_WORLD; - tr.shiftedEntityNum = tr.currentEntityNum << QSORT_ENTITYNUM_SHIFT; // determine which leaves are in the PVS / areamask R_MarkLeaves();