mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2025-02-21 03:11:03 +00:00
Optimize polygon sorting on batch renderer
This commit is contained in:
parent
35b6b21562
commit
636b3ab954
2 changed files with 25 additions and 82 deletions
|
@ -116,8 +116,30 @@ void HWR_ProcessPolygon(FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPt
|
|||
polygonArray[polygonArraySize].texture = current_texture;
|
||||
polygonArray[polygonArraySize].shader = shader;
|
||||
polygonArray[polygonArraySize].horizonSpecial = horizonSpecial;
|
||||
polygonArray[polygonArraySize].hash = 0;
|
||||
polygonArraySize++;
|
||||
|
||||
if (!(PolyFlags & PF_NoTexture) && !horizonSpecial)
|
||||
{
|
||||
// use FNV-1a to hash polygons for later sorting.
|
||||
int32_t hash = 0x811c9dc5;
|
||||
#define DIGEST(h, x) h ^= (x); h *= 0x01000193
|
||||
DIGEST(hash, current_texture->downloaded);
|
||||
DIGEST(hash, PolyFlags);
|
||||
DIGEST(hash, pSurf->PolyColor.rgba);
|
||||
if (cv_glshaders.value && gl_shadersavailable)
|
||||
{
|
||||
DIGEST(hash, shader);
|
||||
DIGEST(hash, pSurf->TintColor.rgba);
|
||||
DIGEST(hash, pSurf->FadeColor.rgba);
|
||||
DIGEST(hash, pSurf->LightInfo.light_level);
|
||||
DIGEST(hash, pSurf->LightInfo.fade_start);
|
||||
DIGEST(hash, pSurf->LightInfo.fade_end);
|
||||
}
|
||||
#undef DIGEST
|
||||
polygonArray[polygonArraySize-1].hash = hash;
|
||||
}
|
||||
|
||||
memcpy(&unsortedVertexArray[unsortedVertexArraySize], pOutVerts, iNumPts * sizeof(FOutVector));
|
||||
unsortedVertexArraySize += iNumPts;
|
||||
}
|
||||
|
@ -135,84 +157,7 @@ static int comparePolygons(const void *p1, const void *p2)
|
|||
unsigned int index2 = *(const unsigned int*)p2;
|
||||
PolygonArrayEntry* poly1 = &polygonArray[index1];
|
||||
PolygonArrayEntry* poly2 = &polygonArray[index2];
|
||||
int diff;
|
||||
INT64 diff64;
|
||||
UINT32 downloaded1 = 0;
|
||||
UINT32 downloaded2 = 0;
|
||||
|
||||
int shader1 = poly1->shader;
|
||||
int shader2 = poly2->shader;
|
||||
// make skywalls and horizon lines first in order
|
||||
if (poly1->polyFlags & PF_NoTexture || poly1->horizonSpecial)
|
||||
shader1 = -1;
|
||||
if (poly2->polyFlags & PF_NoTexture || poly2->horizonSpecial)
|
||||
shader2 = -1;
|
||||
diff = shader1 - shader2;
|
||||
if (diff != 0) return diff;
|
||||
|
||||
// skywalls and horizon lines must retain their order for horizon lines to work
|
||||
if (shader1 == -1 && shader2 == -1)
|
||||
return index1 - index2;
|
||||
|
||||
if (poly1->texture)
|
||||
downloaded1 = poly1->texture->downloaded; // there should be a opengl texture name here, usable for comparisons
|
||||
if (poly2->texture)
|
||||
downloaded2 = poly2->texture->downloaded;
|
||||
diff64 = downloaded1 - downloaded2;
|
||||
if (diff64 != 0) return diff64;
|
||||
|
||||
diff = poly1->polyFlags - poly2->polyFlags;
|
||||
if (diff != 0) return diff;
|
||||
|
||||
diff64 = poly1->surf.PolyColor.rgba - poly2->surf.PolyColor.rgba;
|
||||
if (diff64 < 0) return -1; else if (diff64 > 0) return 1;
|
||||
diff64 = poly1->surf.TintColor.rgba - poly2->surf.TintColor.rgba;
|
||||
if (diff64 < 0) return -1; else if (diff64 > 0) return 1;
|
||||
diff64 = poly1->surf.FadeColor.rgba - poly2->surf.FadeColor.rgba;
|
||||
if (diff64 < 0) return -1; else if (diff64 > 0) return 1;
|
||||
|
||||
diff = poly1->surf.LightInfo.light_level - poly2->surf.LightInfo.light_level;
|
||||
if (diff != 0) return diff;
|
||||
diff = poly1->surf.LightInfo.fade_start - poly2->surf.LightInfo.fade_start;
|
||||
if (diff != 0) return diff;
|
||||
diff = poly1->surf.LightInfo.fade_end - poly2->surf.LightInfo.fade_end;
|
||||
return diff;
|
||||
}
|
||||
|
||||
static int comparePolygonsNoShaders(const void *p1, const void *p2)
|
||||
{
|
||||
unsigned int index1 = *(const unsigned int*)p1;
|
||||
unsigned int index2 = *(const unsigned int*)p2;
|
||||
PolygonArrayEntry* poly1 = &polygonArray[index1];
|
||||
PolygonArrayEntry* poly2 = &polygonArray[index2];
|
||||
int diff;
|
||||
INT64 diff64;
|
||||
|
||||
GLMipmap_t *texture1 = poly1->texture;
|
||||
GLMipmap_t *texture2 = poly2->texture;
|
||||
UINT32 downloaded1 = 0;
|
||||
UINT32 downloaded2 = 0;
|
||||
if (poly1->polyFlags & PF_NoTexture || poly1->horizonSpecial)
|
||||
texture1 = NULL;
|
||||
if (poly2->polyFlags & PF_NoTexture || poly2->horizonSpecial)
|
||||
texture2 = NULL;
|
||||
if (texture1)
|
||||
downloaded1 = texture1->downloaded; // there should be a opengl texture name here, usable for comparisons
|
||||
if (texture2)
|
||||
downloaded2 = texture2->downloaded;
|
||||
// skywalls and horizon lines must retain their order for horizon lines to work
|
||||
if (!texture1 && !texture2)
|
||||
return index1 - index2;
|
||||
diff64 = downloaded1 - downloaded2;
|
||||
if (diff64 != 0) return diff64;
|
||||
|
||||
diff = poly1->polyFlags - poly2->polyFlags;
|
||||
if (diff != 0) return diff;
|
||||
|
||||
diff64 = poly1->surf.PolyColor.rgba - poly2->surf.PolyColor.rgba;
|
||||
if (diff64 < 0) return -1; else if (diff64 > 0) return 1;
|
||||
|
||||
return 0;
|
||||
return poly1->hash - poly2->hash;
|
||||
}
|
||||
|
||||
// This function organizes the geometry collected by HWR_ProcessPolygon calls into batches and uses
|
||||
|
@ -263,10 +208,7 @@ void HWR_RenderBatches(void)
|
|||
|
||||
// sort polygons
|
||||
PS_START_TIMING(ps_hw_batchsorttime);
|
||||
if (cv_glshaders.value && gl_shadersavailable)
|
||||
qsort(polygonIndexArray, polygonArraySize, sizeof(unsigned int), comparePolygons);
|
||||
else
|
||||
qsort(polygonIndexArray, polygonArraySize, sizeof(unsigned int), comparePolygonsNoShaders);
|
||||
qsort(polygonIndexArray, polygonArraySize, sizeof(unsigned int), comparePolygons);
|
||||
PS_STOP_TIMING(ps_hw_batchsorttime);
|
||||
// sort order
|
||||
// 1. shader
|
||||
|
|
|
@ -26,6 +26,7 @@ typedef struct
|
|||
int shader;
|
||||
// this tells batching that the plane belongs to a horizon line and must be drawn in correct order with the skywalls
|
||||
boolean horizonSpecial;
|
||||
uint32_t hash;
|
||||
} PolygonArrayEntry;
|
||||
|
||||
void HWR_StartBatching(void);
|
||||
|
|
Loading…
Reference in a new issue