mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-25 05:21:02 +00:00
- Fix sprites behind midtextures unrender when near voxel
This commit is contained in:
parent
6d8281c812
commit
205350e726
4 changed files with 50 additions and 34 deletions
|
@ -41,7 +41,6 @@ namespace swrenderer
|
|||
Sprites.Clear();
|
||||
StartIndices.Clear();
|
||||
SortedSprites.Clear();
|
||||
DrewAVoxel = false;
|
||||
}
|
||||
|
||||
void VisibleSpriteList::PushPortal()
|
||||
|
@ -55,17 +54,13 @@ namespace swrenderer
|
|||
StartIndices.Pop();
|
||||
}
|
||||
|
||||
void VisibleSpriteList::Push(VisibleSprite *sprite, bool isVoxel)
|
||||
void VisibleSpriteList::Push(VisibleSprite *sprite)
|
||||
{
|
||||
Sprites.Push(sprite);
|
||||
if (isVoxel)
|
||||
DrewAVoxel = true;
|
||||
}
|
||||
|
||||
void VisibleSpriteList::Sort()
|
||||
{
|
||||
bool compare2d = DrewAVoxel;
|
||||
|
||||
unsigned int first = StartIndices.Size() == 0 ? 0 : StartIndices.Last();
|
||||
unsigned int count = Sprites.Size() - first;
|
||||
|
||||
|
@ -88,25 +83,9 @@ namespace swrenderer
|
|||
SortedSprites[i] = Sprites[first + count - i - 1];
|
||||
}
|
||||
|
||||
if (compare2d)
|
||||
{
|
||||
// This is an alternate version, for when one or more voxel is in view.
|
||||
// It does a 2D distance test based on whichever one is furthest from
|
||||
// the viewpoint.
|
||||
|
||||
std::stable_sort(&SortedSprites[0], &SortedSprites[count], [](VisibleSprite *a, VisibleSprite *b) -> bool
|
||||
{
|
||||
return a->SortDist2D() < b->SortDist2D();
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
// This is the standard version, which does a simple test based on depth.
|
||||
|
||||
std::stable_sort(&SortedSprites[0], &SortedSprites[count], [](VisibleSprite *a, VisibleSprite *b) -> bool
|
||||
{
|
||||
return a->SortDist() > b->SortDist();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ namespace swrenderer
|
|||
void Clear();
|
||||
void PushPortal();
|
||||
void PopPortal();
|
||||
void Push(VisibleSprite *sprite, bool isVoxel = false);
|
||||
void Push(VisibleSprite *sprite);
|
||||
void Sort();
|
||||
|
||||
TArray<VisibleSprite *> SortedSprites;
|
||||
|
@ -19,6 +19,5 @@ namespace swrenderer
|
|||
private:
|
||||
TArray<VisibleSprite *> Sprites;
|
||||
TArray<unsigned int> StartIndices;
|
||||
bool DrewAVoxel = false;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -124,7 +124,7 @@ namespace swrenderer
|
|||
vis->yscale = (float)yscale;
|
||||
vis->x1 = renderportal->WindowLeft;
|
||||
vis->x2 = renderportal->WindowRight;
|
||||
vis->idepth = 1 / MINZ;
|
||||
vis->idepth = float(1 / tz);
|
||||
vis->floorclip = thing->Floorclip;
|
||||
|
||||
pos.Z -= thing->Floorclip;
|
||||
|
@ -189,7 +189,19 @@ namespace swrenderer
|
|||
|
||||
vis->Light.SetColormap(thread->Light->SpriteGlobVis(foggy) / MAX(tz, MINZ), spriteshade, basecolormap, fullbright, invertcolormap, fadeToBlack);
|
||||
|
||||
thread->SpriteList->Push(vis, true);
|
||||
// Fake a voxel drawing to find its extents..
|
||||
SpriteDrawerArgs drawerargs;
|
||||
drawerargs.SetLight(vis->Light.BaseColormap, 0, vis->Light.ColormapNum << FRACBITS);
|
||||
basecolormap = (FDynamicColormap*)vis->Light.BaseColormap;
|
||||
bool visible = drawerargs.SetStyle(thread->Viewport.get(), vis->RenderStyle, vis->Alpha, vis->Translation, vis->FillColor, basecolormap);
|
||||
if (!visible)
|
||||
return;
|
||||
int flags = vis->bInMirror ? (DVF_MIRRORED | DVF_FIND_X1X2) : DVF_FIND_X1X2;
|
||||
vis->DrawVoxel(thread, drawerargs, vis->pa.vpos, vis->pa.vang, vis->gpos, vis->Angle, vis->xscale, FLOAT2FIXED(vis->yscale), vis->voxel, nullptr, nullptr, 0, 0, flags);
|
||||
if (vis->x1 >= vis->x2)
|
||||
return;
|
||||
|
||||
thread->SpriteList->Push(vis);
|
||||
}
|
||||
|
||||
void RenderVoxel::Render(RenderThread *thread, short *cliptop, short *clipbottom, int minZ, int maxZ)
|
||||
|
@ -379,8 +391,13 @@ namespace swrenderer
|
|||
|
||||
bool useSlabDataBgra = !drawerargs.DrawerNeedsPalInput() && viewport->RenderTarget->IsBgra();
|
||||
|
||||
int coverageX1 = this->x2;
|
||||
int coverageX2 = this->x1;
|
||||
|
||||
const int maxoutblocks = 100;
|
||||
VoxelBlock *outblocks = thread->FrameMemory->AllocMemory<VoxelBlock>(maxoutblocks);
|
||||
VoxelBlock *outblocks = nullptr;
|
||||
if ((flags & DVF_FIND_X1X2) == 0)
|
||||
outblocks = thread->FrameMemory->AllocMemory<VoxelBlock>(maxoutblocks);
|
||||
int nextoutblock = 0;
|
||||
|
||||
for (cnt = 0; cnt < 8; cnt++)
|
||||
|
@ -470,6 +487,13 @@ namespace swrenderer
|
|||
if (rx > this->x2) rx = this->x2;
|
||||
if (rx <= lx) continue;
|
||||
|
||||
if (flags & DVF_FIND_X1X2)
|
||||
{
|
||||
coverageX1 = MIN(coverageX1, lx);
|
||||
coverageX2 = MAX(coverageX2, rx);
|
||||
continue;
|
||||
}
|
||||
|
||||
fixed_t l1 = xs_RoundToInt(centerxwidebig_f / (ny - yoff));
|
||||
fixed_t l2 = xs_RoundToInt(centerxwidebig_f / (ny + yoff));
|
||||
for (; voxptr < voxend; voxptr = (kvxslab_t *)((uint8_t *)voxptr + voxptr->zleng + 3))
|
||||
|
@ -595,7 +619,7 @@ namespace swrenderer
|
|||
|
||||
if (nextoutblock == maxoutblocks)
|
||||
{
|
||||
drawerargs.DrawVoxelBlocks(thread, outblocks, nextoutblock);
|
||||
drawerargs.DrawVoxelBlocks(thread, outblocks, maxoutblocks);
|
||||
outblocks = thread->FrameMemory->AllocMemory<VoxelBlock>(maxoutblocks);
|
||||
nextoutblock = 0;
|
||||
}
|
||||
|
@ -646,11 +670,19 @@ namespace swrenderer
|
|||
}
|
||||
}
|
||||
|
||||
if (flags & DVF_FIND_X1X2)
|
||||
{
|
||||
this->x1 = coverageX1;
|
||||
this->x2 = coverageX2;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (nextoutblock != 0)
|
||||
{
|
||||
drawerargs.DrawVoxelBlocks(thread, outblocks, nextoutblock);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
kvxslab_t *RenderVoxel::GetSlabStart(const FVoxelMipLevel &mip, int x, int y)
|
||||
{
|
||||
|
|
|
@ -73,6 +73,12 @@ namespace swrenderer
|
|||
FAngle vang = { 0.0f }; // view angle
|
||||
};
|
||||
|
||||
struct VoxelBlockEntry
|
||||
{
|
||||
VoxelBlock *block;
|
||||
VoxelBlockEntry *next;
|
||||
};
|
||||
|
||||
posang pa;
|
||||
DAngle Angle = { 0.0 };
|
||||
fixed_t xscale = 0;
|
||||
|
@ -82,7 +88,7 @@ namespace swrenderer
|
|||
uint32_t Translation = 0;
|
||||
uint32_t FillColor = 0;
|
||||
|
||||
enum { DVF_OFFSCREEN = 1, DVF_SPANSONLY = 2, DVF_MIRRORED = 4 };
|
||||
enum { DVF_OFFSCREEN = 1, DVF_SPANSONLY = 2, DVF_MIRRORED = 4, DVF_FIND_X1X2 = 8 };
|
||||
|
||||
static kvxslab_t *GetSlabStart(const FVoxelMipLevel &mip, int x, int y);
|
||||
static kvxslab_t *GetSlabEnd(const FVoxelMipLevel &mip, int x, int y);
|
||||
|
|
Loading…
Reference in a new issue