mirror of
https://bitbucket.org/CPMADevs/cnq3
synced 2024-12-04 01:41:26 +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
|
unsigned sort; // bit combination for fast compares
|
||||||
float depth; // transparent surface's midpoint's depth
|
float depth; // transparent surface's midpoint's depth
|
||||||
const surfaceType_t* surface; // any of surface*_t
|
const surfaceType_t* surface; // any of surface*_t
|
||||||
int index; // transparent surface's registration order
|
|
||||||
qhandle_t model; // MD3 model handle
|
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* );
|
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:
|
the bits are allocated as follows:
|
||||||
|
|
||||||
31-31 : unused (1 bit)
|
29-31 : zero (3 bits)
|
||||||
30-30 : depth fade (1 bit)
|
|
||||||
29-29 : polygon offset (1 bit)
|
|
||||||
15-28 : sorted shader index (14 bits)
|
15-28 : sorted shader index (14 bits)
|
||||||
5-14 : entity index (10 bits)
|
5-14 : entity index (10 bits)
|
||||||
0- 4 : fog index (5 bits)
|
0- 4 : fog index (5 bits)
|
||||||
*/
|
*/
|
||||||
#define QSORT_DEPTHFADE_SHIFT 30
|
|
||||||
#define QSORT_POLYOFF_SHIFT 29
|
|
||||||
#define QSORT_SHADERNUM_SHIFT 15
|
#define QSORT_SHADERNUM_SHIFT 15
|
||||||
#define QSORT_ENTITYNUM_SHIFT 5
|
#define QSORT_ENTITYNUM_SHIFT 5
|
||||||
#define QSORT_FOGNUM_SHIFT 0
|
#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
|
// the sort data is packed into a single 32 bit value so it can be
|
||||||
// compared quickly during the qsorting process
|
// compared quickly during the qsorting process
|
||||||
tr.refdef.drawSurfs[index].sort = (shader->sortedIndex << QSORT_SHADERNUM_SHIFT)
|
tr.refdef.drawSurfs[index].sort = (shader->sortedIndex << QSORT_SHADERNUM_SHIFT)
|
||||||
| tr.shiftedEntityNum | (fogIndex << QSORT_FOGNUM_SHIFT)
|
| tr.shiftedEntityNum | (fogIndex << QSORT_FOGNUM_SHIFT);
|
||||||
| ((shader->dfType != DFT_NONE) << QSORT_DEPTHFADE_SHIFT)
|
|
||||||
| (shader->polygonOffset << QSORT_POLYOFF_SHIFT);
|
|
||||||
tr.refdef.drawSurfs[index].surface = surface;
|
tr.refdef.drawSurfs[index].surface = surface;
|
||||||
tr.refdef.drawSurfs[index].model = tr.currentModel != NULL ? tr.currentModel->index : 0;
|
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_t* litsurf = &tr.refdef.litSurfs[index];
|
||||||
|
|
||||||
litsurf->sort = (shader->sortedIndex << QSORT_SHADERNUM_SHIFT)
|
litsurf->sort = (shader->sortedIndex << QSORT_SHADERNUM_SHIFT)
|
||||||
| tr.shiftedEntityNum | (fogIndex << QSORT_FOGNUM_SHIFT)
|
| tr.shiftedEntityNum | (fogIndex << QSORT_FOGNUM_SHIFT);
|
||||||
| ((shader->dfType != DFT_NONE) << QSORT_DEPTHFADE_SHIFT)
|
|
||||||
| (shader->polygonOffset << QSORT_POLYOFF_SHIFT);
|
|
||||||
litsurf->surface = surface;
|
litsurf->surface = surface;
|
||||||
|
|
||||||
if (!tr.light->head)
|
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).
|
- Per-pixel fixed-size arrays (there are several methods).
|
||||||
- Depth peeling (there are also 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* a = ( const drawSurf_t* )aPtr;
|
||||||
const drawSurf_t* b = ( const drawSurf_t* )bPtr;
|
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 )
|
if ( a->depth > b->depth )
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if ( a->depth < b->depth )
|
if ( a->depth < b->depth )
|
||||||
return 1;
|
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].depth = R_ComputeSurfaceDepth( drawSurfs[i].surface, entityNum, drawSurfs[i].model );
|
||||||
drawSurfs[i].index = i;
|
drawSurfs[i].index = i;
|
||||||
|
drawSurfs[i].shaderSort = shader->sort;
|
||||||
}
|
}
|
||||||
|
|
||||||
// sort transparent surfaces by depth
|
// 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
|
// 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
|
||||||
|
|
|
@ -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
|
Positions the most recently created shader in the tr.sortedShaders[] array
|
||||||
such that the shader->sort key is sorted relative to the other shaders.
|
such that the shader->sort key is sorted relative to the other shaders.
|
||||||
|
@ -1530,6 +1546,12 @@ static void SortNewShader()
|
||||||
|
|
||||||
newShader->sortedIndex = i+1;
|
newShader->sortedIndex = i+1;
|
||||||
tr.sortedShaders[i+1] = newShader;
|
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