mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2024-11-11 23:32:02 +00:00
- separate draw lists for walls and flats. This makes the sorting much more efficient because draw types no longer need to be checked in the compare function. This is a lot more important than having perfect texture order.
This commit is contained in:
parent
a903cbe12e
commit
49ec7beb8f
5 changed files with 87 additions and 59 deletions
|
@ -644,7 +644,6 @@ SortNode * GLDrawList::DoSort(SortNode * head)
|
||||||
case GLDIT_SPRITE:
|
case GLDIT_SPRITE:
|
||||||
SortSpriteIntoPlane(head,node);
|
SortSpriteIntoPlane(head,node);
|
||||||
break;
|
break;
|
||||||
case GLDIT_POLY: break;
|
|
||||||
}
|
}
|
||||||
node=next;
|
node=next;
|
||||||
}
|
}
|
||||||
|
@ -670,7 +669,7 @@ SortNode * GLDrawList::DoSort(SortNode * head)
|
||||||
case GLDIT_SPRITE:
|
case GLDIT_SPRITE:
|
||||||
SortSpriteIntoWall(head,node);
|
SortSpriteIntoWall(head,node);
|
||||||
break;
|
break;
|
||||||
case GLDIT_POLY: break;
|
|
||||||
case GLDIT_FLAT: break;
|
case GLDIT_FLAT: break;
|
||||||
}
|
}
|
||||||
node=next;
|
node=next;
|
||||||
|
@ -722,7 +721,6 @@ void GLDrawList::DoDraw(int pass, int i, bool trans)
|
||||||
RenderSprite.Unclock();
|
RenderSprite.Unclock();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case GLDIT_POLY: break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -783,6 +781,36 @@ void GLDrawList::Draw(int pass)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
void GLDrawList::DrawWalls(int pass)
|
||||||
|
{
|
||||||
|
RenderWall.Clock();
|
||||||
|
for(unsigned i=0;i<drawitems.Size();i++)
|
||||||
|
{
|
||||||
|
walls[drawitems[i].index].Draw(pass);
|
||||||
|
}
|
||||||
|
RenderWall.Unclock();
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
void GLDrawList::DrawFlats(int pass)
|
||||||
|
{
|
||||||
|
RenderFlat.Clock();
|
||||||
|
for(unsigned i=0;i<drawitems.Size();i++)
|
||||||
|
{
|
||||||
|
flats[drawitems[i].index].Draw(pass, false);
|
||||||
|
}
|
||||||
|
RenderFlat.Unclock();
|
||||||
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// Sorting the drawitems first by texture and then by light level.
|
// Sorting the drawitems first by texture and then by light level.
|
||||||
|
@ -790,56 +818,45 @@ void GLDrawList::Draw(int pass)
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
static GLDrawList * sortinfo;
|
static GLDrawList * sortinfo;
|
||||||
|
|
||||||
static int __cdecl dicmp (const void *a, const void *b)
|
static int __cdecl diwcmp (const void *a, const void *b)
|
||||||
{
|
{
|
||||||
const GLDrawItem * di[2];
|
const GLDrawItem * di1 = (const GLDrawItem *)a;
|
||||||
FMaterial * tx[2];
|
GLWall * w1=&sortinfo->walls[di1->index];
|
||||||
int clamp[2];
|
|
||||||
//colormap_t cm[2];
|
|
||||||
di[0]=(const GLDrawItem *)a;
|
|
||||||
di[1]=(const GLDrawItem *)b;
|
|
||||||
|
|
||||||
for(int i=0;i<2;i++)
|
const GLDrawItem * di2 = (const GLDrawItem *)b;
|
||||||
{
|
GLWall * w2=&sortinfo->walls[di2->index];
|
||||||
switch(di[i]->rendertype)
|
|
||||||
{
|
|
||||||
case GLDIT_FLAT:
|
|
||||||
{
|
|
||||||
GLFlat * f=&sortinfo->flats[di[i]->index];
|
|
||||||
tx[i]=f->gltexture;
|
|
||||||
clamp[i] = 0;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GLDIT_WALL:
|
if (w1->gltexture != w2->gltexture) return w1->gltexture - w2->gltexture;
|
||||||
{
|
return ((w1->flags & 3) - (w2->flags & 3));
|
||||||
GLWall * w=&sortinfo->walls[di[i]->index];
|
}
|
||||||
tx[i]=w->gltexture;
|
|
||||||
clamp[i] = w->flags & 3;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GLDIT_SPRITE:
|
static int __cdecl difcmp (const void *a, const void *b)
|
||||||
{
|
{
|
||||||
GLSprite * s=&sortinfo->sprites[di[i]->index];
|
const GLDrawItem * di1 = (const GLDrawItem *)a;
|
||||||
tx[i]=s->gltexture;
|
GLFlat * w1=&sortinfo->flats[di1->index];
|
||||||
clamp[i] = 3;
|
|
||||||
}
|
const GLDrawItem * di2 = (const GLDrawItem *)b;
|
||||||
break;
|
GLFlat* w2=&sortinfo->flats[di2->index];
|
||||||
case GLDIT_POLY: break;
|
|
||||||
}
|
return w1->gltexture - w2->gltexture;
|
||||||
}
|
|
||||||
if (tx[0]!=tx[1]) return tx[0]-tx[1];
|
|
||||||
return clamp[0]-clamp[1]; // clamping forces different textures.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void GLDrawList::Sort()
|
void GLDrawList::SortWalls()
|
||||||
{
|
{
|
||||||
if (drawitems.Size()!=0 && gl_sort_textures)
|
if (drawitems.Size()!=0 && gl_sort_textures)
|
||||||
{
|
{
|
||||||
sortinfo=this;
|
sortinfo=this;
|
||||||
qsort(&drawitems[0], drawitems.Size(), sizeof(drawitems[0]), dicmp);
|
qsort(&drawitems[0], drawitems.Size(), sizeof(drawitems[0]), diwcmp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GLDrawList::SortFlats()
|
||||||
|
{
|
||||||
|
if (drawitems.Size()!=0 && gl_sort_textures)
|
||||||
|
{
|
||||||
|
sortinfo=this;
|
||||||
|
qsort(&drawitems[0], drawitems.Size(), sizeof(drawitems[0]), difcmp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,9 +13,11 @@ enum GLDrawItemType
|
||||||
|
|
||||||
enum DrawListType
|
enum DrawListType
|
||||||
{
|
{
|
||||||
GLDL_PLAIN,
|
GLDL_PLAINWALLS,
|
||||||
GLDL_MASKED,
|
GLDL_PLAINFLATS,
|
||||||
GLDL_MASKEDOFS,
|
GLDL_MASKEDWALLS,
|
||||||
|
GLDL_MASKEDFLATS,
|
||||||
|
GLDL_MASKEDWALLSOFS,
|
||||||
GLDL_MODELS,
|
GLDL_MODELS,
|
||||||
|
|
||||||
GLDL_TRANSLUCENT,
|
GLDL_TRANSLUCENT,
|
||||||
|
@ -106,7 +108,8 @@ public:
|
||||||
void AddFlat(GLFlat * flat);
|
void AddFlat(GLFlat * flat);
|
||||||
void AddSprite(GLSprite * sprite);
|
void AddSprite(GLSprite * sprite);
|
||||||
void Reset();
|
void Reset();
|
||||||
void Sort();
|
void SortWalls();
|
||||||
|
void SortFlats();
|
||||||
|
|
||||||
|
|
||||||
void MakeSortList();
|
void MakeSortList();
|
||||||
|
@ -125,6 +128,8 @@ public:
|
||||||
void DoDrawSorted(SortNode * node);
|
void DoDrawSorted(SortNode * node);
|
||||||
void DrawSorted();
|
void DrawSorted();
|
||||||
void Draw(int pass);
|
void Draw(int pass);
|
||||||
|
void DrawWalls(int pass);
|
||||||
|
void DrawFlats(int pass);
|
||||||
|
|
||||||
GLDrawList * next;
|
GLDrawList * next;
|
||||||
} ;
|
} ;
|
||||||
|
|
|
@ -402,7 +402,7 @@ inline void GLFlat::PutFlat(bool fog)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
bool masked = gltexture->isMasked() && ((renderflags&SSRF_RENDER3DPLANES) || stack);
|
bool masked = gltexture->isMasked() && ((renderflags&SSRF_RENDER3DPLANES) || stack);
|
||||||
list = masked ? GLDL_MASKED : GLDL_PLAIN;
|
list = masked ? GLDL_MASKEDFLATS : GLDL_PLAINFLATS;
|
||||||
}
|
}
|
||||||
gl_drawinfo->drawlists[list].AddFlat (this);
|
gl_drawinfo->drawlists[list].AddFlat (this);
|
||||||
}
|
}
|
||||||
|
|
|
@ -340,18 +340,22 @@ void FGLRenderer::RenderScene(int recursion)
|
||||||
gl_RenderState.EnableFog(true);
|
gl_RenderState.EnableFog(true);
|
||||||
gl_RenderState.BlendFunc(GL_ONE,GL_ZERO);
|
gl_RenderState.BlendFunc(GL_ONE,GL_ZERO);
|
||||||
|
|
||||||
gl_drawinfo->drawlists[GLDL_PLAIN].Sort();
|
gl_drawinfo->drawlists[GLDL_PLAINWALLS].SortWalls();
|
||||||
gl_drawinfo->drawlists[GLDL_MASKED].Sort();
|
gl_drawinfo->drawlists[GLDL_PLAINFLATS].SortFlats();
|
||||||
gl_drawinfo->drawlists[GLDL_MASKEDOFS].Sort();
|
gl_drawinfo->drawlists[GLDL_MASKEDWALLS].SortWalls();
|
||||||
|
gl_drawinfo->drawlists[GLDL_MASKEDFLATS].SortFlats();
|
||||||
|
gl_drawinfo->drawlists[GLDL_MASKEDWALLSOFS].SortWalls();
|
||||||
|
|
||||||
// if we don't have a persistently mapped buffer, we have to process all the dynamic lights up front,
|
// if we don't have a persistently mapped buffer, we have to process all the dynamic lights up front,
|
||||||
// so that we don't have to do repeated map/unmap calls on the buffer.
|
// so that we don't have to do repeated map/unmap calls on the buffer.
|
||||||
if (mLightCount > 0 && gl_fixedcolormap == CM_DEFAULT && gl_lights && !(gl.flags & RFL_BUFFER_STORAGE))
|
if (mLightCount > 0 && gl_fixedcolormap == CM_DEFAULT && gl_lights && !(gl.flags & RFL_BUFFER_STORAGE))
|
||||||
{
|
{
|
||||||
GLRenderer->mLights->Begin();
|
GLRenderer->mLights->Begin();
|
||||||
gl_drawinfo->drawlists[GLDL_PLAIN].Draw(GLPASS_LIGHTSONLY);
|
gl_drawinfo->drawlists[GLDL_PLAINWALLS].Draw(GLPASS_LIGHTSONLY);
|
||||||
gl_drawinfo->drawlists[GLDL_MASKED].Draw(GLPASS_LIGHTSONLY);
|
gl_drawinfo->drawlists[GLDL_PLAINFLATS].Draw(GLPASS_LIGHTSONLY);
|
||||||
gl_drawinfo->drawlists[GLDL_MASKEDOFS].Draw(GLPASS_LIGHTSONLY);
|
gl_drawinfo->drawlists[GLDL_MASKEDWALLS].Draw(GLPASS_LIGHTSONLY);
|
||||||
|
gl_drawinfo->drawlists[GLDL_MASKEDFLATS].Draw(GLPASS_LIGHTSONLY);
|
||||||
|
gl_drawinfo->drawlists[GLDL_MASKEDWALLSOFS].Draw(GLPASS_LIGHTSONLY);
|
||||||
gl_drawinfo->drawlists[GLDL_TRANSLUCENTBORDER].Draw(GLPASS_LIGHTSONLY);
|
gl_drawinfo->drawlists[GLDL_TRANSLUCENTBORDER].Draw(GLPASS_LIGHTSONLY);
|
||||||
gl_drawinfo->drawlists[GLDL_TRANSLUCENT].Draw(GLPASS_LIGHTSONLY);
|
gl_drawinfo->drawlists[GLDL_TRANSLUCENT].Draw(GLPASS_LIGHTSONLY);
|
||||||
GLRenderer->mLights->Finish();
|
GLRenderer->mLights->Finish();
|
||||||
|
@ -375,7 +379,8 @@ void FGLRenderer::RenderScene(int recursion)
|
||||||
|
|
||||||
gl_RenderState.EnableTexture(gl_texture);
|
gl_RenderState.EnableTexture(gl_texture);
|
||||||
gl_RenderState.EnableBrightmap(true);
|
gl_RenderState.EnableBrightmap(true);
|
||||||
gl_drawinfo->drawlists[GLDL_PLAIN].Draw(pass);
|
gl_drawinfo->drawlists[GLDL_PLAINWALLS].Draw(pass);
|
||||||
|
gl_drawinfo->drawlists[GLDL_PLAINFLATS].Draw(pass);
|
||||||
|
|
||||||
|
|
||||||
// Part 2: masked geometry. This is set up so that only pixels with alpha>gl_mask_threshold will show
|
// Part 2: masked geometry. This is set up so that only pixels with alpha>gl_mask_threshold will show
|
||||||
|
@ -385,14 +390,15 @@ void FGLRenderer::RenderScene(int recursion)
|
||||||
gl_RenderState.SetTextureMode(TM_MASK);
|
gl_RenderState.SetTextureMode(TM_MASK);
|
||||||
}
|
}
|
||||||
gl_RenderState.AlphaFunc(GL_GEQUAL, gl_mask_threshold);
|
gl_RenderState.AlphaFunc(GL_GEQUAL, gl_mask_threshold);
|
||||||
gl_drawinfo->drawlists[GLDL_MASKED].Draw(pass);
|
gl_drawinfo->drawlists[GLDL_MASKEDWALLS].Draw(pass);
|
||||||
|
gl_drawinfo->drawlists[GLDL_MASKEDFLATS].Draw(pass);
|
||||||
|
|
||||||
// Part 3: masked geometry with polygon offset. This list is empty most of the time so only waste time on it when in use.
|
// Part 3: masked geometry with polygon offset. This list is empty most of the time so only waste time on it when in use.
|
||||||
if (gl_drawinfo->drawlists[GLDL_MASKEDOFS].Size() > 0)
|
if (gl_drawinfo->drawlists[GLDL_MASKEDWALLSOFS].Size() > 0)
|
||||||
{
|
{
|
||||||
glEnable(GL_POLYGON_OFFSET_FILL);
|
glEnable(GL_POLYGON_OFFSET_FILL);
|
||||||
glPolygonOffset(-1.0f, -128.0f);
|
glPolygonOffset(-1.0f, -128.0f);
|
||||||
gl_drawinfo->drawlists[GLDL_MASKEDOFS].Draw(pass);
|
gl_drawinfo->drawlists[GLDL_MASKEDWALLSOFS].Draw(pass);
|
||||||
glDisable(GL_POLYGON_OFFSET_FILL);
|
glDisable(GL_POLYGON_OFFSET_FILL);
|
||||||
glPolygonOffset(0, 0);
|
glPolygonOffset(0, 0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -151,11 +151,11 @@ void GLWall::PutWall(bool translucent)
|
||||||
|
|
||||||
if ((flags&GLWF_SKYHACK && type == RENDERWALL_M2S))
|
if ((flags&GLWF_SKYHACK && type == RENDERWALL_M2S))
|
||||||
{
|
{
|
||||||
list = GLDL_MASKEDOFS;
|
list = GLDL_MASKEDWALLSOFS;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
list = masked ? GLDL_MASKED : GLDL_PLAIN;
|
list = masked ? GLDL_MASKEDWALLS : GLDL_PLAINWALLS;
|
||||||
}
|
}
|
||||||
gl_drawinfo->drawlists[list].AddWall(this);
|
gl_drawinfo->drawlists[list].AddWall(this);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue