mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-13 07:57:58 +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();
|
Sprites.Clear();
|
||||||
StartIndices.Clear();
|
StartIndices.Clear();
|
||||||
SortedSprites.Clear();
|
SortedSprites.Clear();
|
||||||
DrewAVoxel = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void VisibleSpriteList::PushPortal()
|
void VisibleSpriteList::PushPortal()
|
||||||
|
@ -55,17 +54,13 @@ namespace swrenderer
|
||||||
StartIndices.Pop();
|
StartIndices.Pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void VisibleSpriteList::Push(VisibleSprite *sprite, bool isVoxel)
|
void VisibleSpriteList::Push(VisibleSprite *sprite)
|
||||||
{
|
{
|
||||||
Sprites.Push(sprite);
|
Sprites.Push(sprite);
|
||||||
if (isVoxel)
|
|
||||||
DrewAVoxel = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void VisibleSpriteList::Sort()
|
void VisibleSpriteList::Sort()
|
||||||
{
|
{
|
||||||
bool compare2d = DrewAVoxel;
|
|
||||||
|
|
||||||
unsigned int first = StartIndices.Size() == 0 ? 0 : StartIndices.Last();
|
unsigned int first = StartIndices.Size() == 0 ? 0 : StartIndices.Last();
|
||||||
unsigned int count = Sprites.Size() - first;
|
unsigned int count = Sprites.Size() - first;
|
||||||
|
|
||||||
|
@ -88,25 +83,9 @@ namespace swrenderer
|
||||||
SortedSprites[i] = Sprites[first + count - i - 1];
|
SortedSprites[i] = Sprites[first + count - i - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (compare2d)
|
std::stable_sort(&SortedSprites[0], &SortedSprites[count], [](VisibleSprite *a, VisibleSprite *b) -> bool
|
||||||
{
|
{
|
||||||
// This is an alternate version, for when one or more voxel is in view.
|
return a->SortDist() > b->SortDist();
|
||||||
// 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 Clear();
|
||||||
void PushPortal();
|
void PushPortal();
|
||||||
void PopPortal();
|
void PopPortal();
|
||||||
void Push(VisibleSprite *sprite, bool isVoxel = false);
|
void Push(VisibleSprite *sprite);
|
||||||
void Sort();
|
void Sort();
|
||||||
|
|
||||||
TArray<VisibleSprite *> SortedSprites;
|
TArray<VisibleSprite *> SortedSprites;
|
||||||
|
@ -19,6 +19,5 @@ namespace swrenderer
|
||||||
private:
|
private:
|
||||||
TArray<VisibleSprite *> Sprites;
|
TArray<VisibleSprite *> Sprites;
|
||||||
TArray<unsigned int> StartIndices;
|
TArray<unsigned int> StartIndices;
|
||||||
bool DrewAVoxel = false;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -124,7 +124,7 @@ namespace swrenderer
|
||||||
vis->yscale = (float)yscale;
|
vis->yscale = (float)yscale;
|
||||||
vis->x1 = renderportal->WindowLeft;
|
vis->x1 = renderportal->WindowLeft;
|
||||||
vis->x2 = renderportal->WindowRight;
|
vis->x2 = renderportal->WindowRight;
|
||||||
vis->idepth = 1 / MINZ;
|
vis->idepth = float(1 / tz);
|
||||||
vis->floorclip = thing->Floorclip;
|
vis->floorclip = thing->Floorclip;
|
||||||
|
|
||||||
pos.Z -= 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);
|
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)
|
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();
|
bool useSlabDataBgra = !drawerargs.DrawerNeedsPalInput() && viewport->RenderTarget->IsBgra();
|
||||||
|
|
||||||
|
int coverageX1 = this->x2;
|
||||||
|
int coverageX2 = this->x1;
|
||||||
|
|
||||||
const int maxoutblocks = 100;
|
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;
|
int nextoutblock = 0;
|
||||||
|
|
||||||
for (cnt = 0; cnt < 8; cnt++)
|
for (cnt = 0; cnt < 8; cnt++)
|
||||||
|
@ -470,6 +487,13 @@ namespace swrenderer
|
||||||
if (rx > this->x2) rx = this->x2;
|
if (rx > this->x2) rx = this->x2;
|
||||||
if (rx <= lx) continue;
|
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 l1 = xs_RoundToInt(centerxwidebig_f / (ny - yoff));
|
||||||
fixed_t l2 = 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))
|
for (; voxptr < voxend; voxptr = (kvxslab_t *)((uint8_t *)voxptr + voxptr->zleng + 3))
|
||||||
|
@ -595,7 +619,7 @@ namespace swrenderer
|
||||||
|
|
||||||
if (nextoutblock == maxoutblocks)
|
if (nextoutblock == maxoutblocks)
|
||||||
{
|
{
|
||||||
drawerargs.DrawVoxelBlocks(thread, outblocks, nextoutblock);
|
drawerargs.DrawVoxelBlocks(thread, outblocks, maxoutblocks);
|
||||||
outblocks = thread->FrameMemory->AllocMemory<VoxelBlock>(maxoutblocks);
|
outblocks = thread->FrameMemory->AllocMemory<VoxelBlock>(maxoutblocks);
|
||||||
nextoutblock = 0;
|
nextoutblock = 0;
|
||||||
}
|
}
|
||||||
|
@ -646,9 +670,17 @@ namespace swrenderer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nextoutblock != 0)
|
if (flags & DVF_FIND_X1X2)
|
||||||
{
|
{
|
||||||
drawerargs.DrawVoxelBlocks(thread, outblocks, nextoutblock);
|
this->x1 = coverageX1;
|
||||||
|
this->x2 = coverageX2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (nextoutblock != 0)
|
||||||
|
{
|
||||||
|
drawerargs.DrawVoxelBlocks(thread, outblocks, nextoutblock);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -73,6 +73,12 @@ namespace swrenderer
|
||||||
FAngle vang = { 0.0f }; // view angle
|
FAngle vang = { 0.0f }; // view angle
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct VoxelBlockEntry
|
||||||
|
{
|
||||||
|
VoxelBlock *block;
|
||||||
|
VoxelBlockEntry *next;
|
||||||
|
};
|
||||||
|
|
||||||
posang pa;
|
posang pa;
|
||||||
DAngle Angle = { 0.0 };
|
DAngle Angle = { 0.0 };
|
||||||
fixed_t xscale = 0;
|
fixed_t xscale = 0;
|
||||||
|
@ -82,7 +88,7 @@ namespace swrenderer
|
||||||
uint32_t Translation = 0;
|
uint32_t Translation = 0;
|
||||||
uint32_t FillColor = 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 *GetSlabStart(const FVoxelMipLevel &mip, int x, int y);
|
||||||
static kvxslab_t *GetSlabEnd(const FVoxelMipLevel &mip, int x, int y);
|
static kvxslab_t *GetSlabEnd(const FVoxelMipLevel &mip, int x, int y);
|
||||||
|
|
Loading…
Reference in a new issue