diff --git a/src/hardware/hw_batching.c b/src/hardware/hw_batching.c index 9d06f6ec624403c4fa3dde4667b94de49658d510..d15db8aa59017fa23fd566fa190b6a211d6822d3 100644 --- a/src/hardware/hw_batching.c +++ b/src/hardware/hw_batching.c @@ -78,9 +78,7 @@ void HWR_SetCurrentTexture(GLMipmap_t *texture) // render the polygon immediately. void HWR_ProcessPolygon(FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPts, FBITFIELD PolyFlags, int shader, boolean horizonSpecial) { - // draw skybox and horizon lines immediately so they don't bloat the polygon buffer. - // this is important for performance since horizon lines are order-sensitive and can't easily be batched. - if (currently_batching && !(PolyFlags & PF_NoTexture) && !horizonSpecial) + if (currently_batching) { if (!pSurf) I_Error("Got a null FSurfaceInfo in batching");// nulls should not come in the stuff that batching currently applies to @@ -117,25 +115,36 @@ void HWR_ProcessPolygon(FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPt polygonArray[polygonArraySize].polyFlags = PolyFlags; polygonArray[polygonArraySize].texture = current_texture; polygonArray[polygonArraySize].shader = shader; + polygonArray[polygonArraySize].horizonSpecial = horizonSpecial; + // default to polygonArraySize so we don't lose order on horizon lines + // (yes, it's supposed to be negative, since we're sorting in that direction) + polygonArray[polygonArraySize].hash = -polygonArraySize; polygonArraySize++; - // use FNV-1a to hash polygons for later sorting. - INT32 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) + if (!(PolyFlags & PF_NoTexture) && !horizonSpecial) { - 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); - } + // use FNV-1a to hash polygons for later sorting. + INT32 hash = 0x811c9dc5; +#define DIGEST(h, x) h ^= (x); h *= 0x01000193 + if (current_texture) + { + 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; + // remove the sign bit to ensure that skybox and horizon line comes first. + polygonArray[polygonArraySize-1].hash = (hash & INT32_MAX); + } memcpy(&unsortedVertexArray[unsortedVertexArraySize], pOutVerts, iNumPts * sizeof(FOutVector)); unsortedVertexArraySize += iNumPts; @@ -230,7 +239,10 @@ void HWR_RenderBatches(void) HWD.pfnSetShader(currentShader); } - HWD.pfnSetTexture(currentTexture); + if (currentPolyFlags & PF_NoTexture) + currentTexture = NULL; + else + HWD.pfnSetTexture(currentTexture); while (1)// note: remember handling notexture polyflag as having texture number 0 (also in comparePolygons) { @@ -302,6 +314,8 @@ void HWR_RenderBatches(void) nextTexture = polygonArray[nextIndex].texture; nextPolyFlags = polygonArray[nextIndex].polyFlags; nextSurfaceInfo = polygonArray[nextIndex].surf; + if (nextPolyFlags & PF_NoTexture) + nextTexture = 0; if (currentShader != nextShader && cv_glshaders.value && gl_shadersavailable) { changeState = true; diff --git a/src/hardware/hw_batching.h b/src/hardware/hw_batching.h index d562d963a3366771ec098946ef66397fcf52e057..df1a4c38be5ceeea84fb61fa22ad31b8a8063dea 100644 --- a/src/hardware/hw_batching.h +++ b/src/hardware/hw_batching.h @@ -24,6 +24,8 @@ typedef struct FBITFIELD polyFlags; GLMipmap_t *texture; 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; INT32 hash; } PolygonArrayEntry;