mirror of
https://bitbucket.org/CPMADevs/cnq3
synced 2024-12-03 17:32:52 +00:00
parent
3e0f5b2760
commit
f4e8e81ab5
3 changed files with 44 additions and 15 deletions
|
@ -505,8 +505,9 @@ struct drawSurf_t {
|
|||
unsigned sort; // bit combination for fast compares
|
||||
float depth; // transparent surface's midpoint's depth
|
||||
const surfaceType_t* surface; // any of surface*_t
|
||||
int index; // transparent surface's registration order
|
||||
qhandle_t model; // MD3 model handle
|
||||
int index; // transparent surface's registration order
|
||||
float shaderSort; // transparent surface's shader sort
|
||||
};
|
||||
|
||||
extern void (*rb_surfaceTable[SF_NUM_SURFACE_TYPES])( const void* );
|
||||
|
@ -797,15 +798,11 @@ compared quickly during the qsorting process
|
|||
|
||||
the bits are allocated as follows:
|
||||
|
||||
31-31 : unused (1 bit)
|
||||
30-30 : depth fade (1 bit)
|
||||
29-29 : polygon offset (1 bit)
|
||||
29-31 : zero (3 bits)
|
||||
15-28 : sorted shader index (14 bits)
|
||||
5-14 : entity index (10 bits)
|
||||
0- 4 : fog index (5 bits)
|
||||
*/
|
||||
#define QSORT_DEPTHFADE_SHIFT 30
|
||||
#define QSORT_POLYOFF_SHIFT 29
|
||||
#define QSORT_SHADERNUM_SHIFT 15
|
||||
#define QSORT_ENTITYNUM_SHIFT 5
|
||||
#define QSORT_FOGNUM_SHIFT 0
|
||||
|
|
|
@ -1072,9 +1072,7 @@ void R_AddDrawSurf( const surfaceType_t* surface, const shader_t* shader, int fo
|
|||
// 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)
|
||||
| ((shader->dfType != DFT_NONE) << QSORT_DEPTHFADE_SHIFT)
|
||||
| (shader->polygonOffset << QSORT_POLYOFF_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;
|
||||
}
|
||||
|
@ -1088,9 +1086,7 @@ void R_AddLitSurf( const surfaceType_t* surface, const shader_t* shader, int fog
|
|||
litSurf_t* litsurf = &tr.refdef.litSurfs[index];
|
||||
|
||||
litsurf->sort = (shader->sortedIndex << QSORT_SHADERNUM_SHIFT)
|
||||
| tr.shiftedEntityNum | (fogIndex << QSORT_FOGNUM_SHIFT)
|
||||
| ((shader->dfType != DFT_NONE) << QSORT_DEPTHFADE_SHIFT)
|
||||
| (shader->polygonOffset << QSORT_POLYOFF_SHIFT);
|
||||
| tr.shiftedEntityNum | (fogIndex << QSORT_FOGNUM_SHIFT);
|
||||
litsurf->surface = surface;
|
||||
|
||||
if (!tr.light->head)
|
||||
|
@ -1210,14 +1206,17 @@ c) What we really want is true order-independent transparency (OIT).
|
|||
- Per-pixel fixed-size arrays (there are several methods).
|
||||
- Depth peeling (there are also several methods).
|
||||
*/
|
||||
static int R_CompareDrawSurfDepth( const void* aPtr, const void* bPtr )
|
||||
static int R_CompareDrawSurf( const void* aPtr, const void* bPtr )
|
||||
{
|
||||
const drawSurf_t* a = ( const drawSurf_t* )aPtr;
|
||||
const drawSurf_t* b = ( const drawSurf_t* )bPtr;
|
||||
if ( a->shaderSort < b->shaderSort )
|
||||
return -1;
|
||||
if ( a->shaderSort > b->shaderSort )
|
||||
return 1;
|
||||
|
||||
if ( a->depth > b->depth )
|
||||
return -1;
|
||||
|
||||
if ( a->depth < b->depth )
|
||||
return 1;
|
||||
|
||||
|
@ -1288,10 +1287,21 @@ static void R_SortDrawSurfs( int firstDrawSurf, int firstLitSurf )
|
|||
|
||||
drawSurfs[i].depth = R_ComputeSurfaceDepth( drawSurfs[i].surface, entityNum, drawSurfs[i].model );
|
||||
drawSurfs[i].index = i;
|
||||
drawSurfs[i].shaderSort = shader->sort;
|
||||
}
|
||||
|
||||
// sort transparent surfaces by depth
|
||||
qsort( drawSurfs + numDrawSurfs - numTranspSurfs, numTranspSurfs, sizeof(drawSurf_t), &R_CompareDrawSurfDepth );
|
||||
qsort( drawSurfs + numDrawSurfs - numTranspSurfs, numTranspSurfs, sizeof(drawSurf_t), &R_CompareDrawSurf );
|
||||
|
||||
#if defined(_DEBUG)
|
||||
float prevSort = -1.0f;
|
||||
for ( int i = 0; i < numDrawSurfs; ++i )
|
||||
{
|
||||
R_DecomposeSort( (drawSurfs + i)->sort, &entityNum, &shader, &fogNum );
|
||||
assert( shader->sort >= prevSort );
|
||||
prevSort = shader->sort;
|
||||
}
|
||||
#endif
|
||||
|
||||
// all the lit surfaces are in a single queue
|
||||
// but each light's surfaces are sorted within its subsection
|
||||
|
|
|
@ -1508,6 +1508,22 @@ static qbool ParseShader( const char** text )
|
|||
}
|
||||
|
||||
|
||||
static int R_CompareShaders( const void* aPtr, const void* bPtr )
|
||||
{
|
||||
const shader_t* const a = *(const shader_t**)aPtr;
|
||||
const shader_t* const b = *(const shader_t**)bPtr;
|
||||
if ( a->sort < b->sort )
|
||||
return -1;
|
||||
if ( a->sort > b->sort )
|
||||
return 1;
|
||||
|
||||
if ( a->polygonOffset ^ b->polygonOffset )
|
||||
return a->polygonOffset - b->polygonOffset;
|
||||
|
||||
return a->cullType - b->cullType;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Positions the most recently created shader in the tr.sortedShaders[] array
|
||||
such that the shader->sort key is sorted relative to the other shaders.
|
||||
|
@ -1530,6 +1546,12 @@ static void SortNewShader()
|
|||
|
||||
newShader->sortedIndex = i+1;
|
||||
tr.sortedShaders[i+1] = newShader;
|
||||
|
||||
// sort it more aggressively for better performance
|
||||
qsort( tr.sortedShaders, tr.numShaders, sizeof(shader_t*), &R_CompareShaders );
|
||||
for ( i = 0; i < tr.numShaders; ++i ) {
|
||||
tr.sortedShaders[i]->sortedIndex = i;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue