- Fixed: Voxel rendering completely fell apart when a mirror came into view.

SVN r4216 (trunk)
This commit is contained in:
Randy Heit 2013-04-16 20:17:34 +00:00
parent a5d770b433
commit 6dc21f9a8b
2 changed files with 63 additions and 26 deletions

View file

@ -424,13 +424,18 @@ void R_DrawVisVoxel(vissprite_t *spr, int minslabz, int maxslabz, short *cliptop
{ {
R_CheckOffscreenBuffer(RenderTarget->GetWidth(), RenderTarget->GetHeight(), !!(flags & DVF_SPANSONLY)); R_CheckOffscreenBuffer(RenderTarget->GetWidth(), RenderTarget->GetHeight(), !!(flags & DVF_SPANSONLY));
} }
if (spr->bInMirror)
{
flags |= DVF_MIRRORED;
}
// Render the voxel, either directly to the screen or offscreen. // Render the voxel, either directly to the screen or offscreen.
R_DrawVoxel(spr->gx, spr->gy, spr->gz, spr->angle, spr->xscale, spr->yscale, spr->voxel, spr->Style.colormap, cliptop, clipbot, R_DrawVoxel(spr->vx, spr->vy, spr->vz, spr->vang, spr->gx, spr->gy, spr->gz, spr->angle,
spr->xscale, spr->yscale, spr->voxel, spr->Style.colormap, cliptop, clipbot,
minslabz, maxslabz, flags); minslabz, maxslabz, flags);
// Blend the voxel, if that's what we need to do. // Blend the voxel, if that's what we need to do.
if (flags != 0) if ((flags & ~DVF_MIRRORED) != 0)
{ {
for (int x = 0; x < viewwidth; ++x) for (int x = 0; x < viewwidth; ++x)
{ {
@ -760,10 +765,10 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor
vis->angle -= angle_t(ang * (4294967296.f / 360)); vis->angle -= angle_t(ang * (4294967296.f / 360));
} }
// These are irrelevant for voxels. vis->vx = viewx;
vis->texturemid = 0x1CEDBEEF; vis->vy = viewy;
vis->startfrac = 0x1CEDBEEF; vis->vz = viewz;
vis->xiscale = 0x1CEDBEEF; vis->vang = viewangle;
} }
// killough 3/27/98: save sector for special clipping later // killough 3/27/98: save sector for special clipping later
@ -787,6 +792,7 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor
vis->fakefloor = fakefloor; vis->fakefloor = fakefloor;
vis->fakeceiling = fakeceiling; vis->fakeceiling = fakeceiling;
vis->ColormapNum = 0; vis->ColormapNum = 0;
vis->bInMirror = MirrorFlags & RF_XFLIP;
if (voxel != NULL) if (voxel != NULL)
{ {
@ -1897,6 +1903,16 @@ void R_DrawSprite (vissprite_t *spr)
return; return;
} }
} }
// Add everything outside the left and right edges to the clipping array
// for R_DrawVisVoxel().
if (x1 > 0)
{
clearbufshort(cliptop, x1, viewheight);
}
if (x2 < viewwidth - 1)
{
clearbufshort(cliptop + x2 + 1, viewwidth - x2 - 1, viewheight);
}
int minvoxely = spr->gzt <= hzt ? 0 : (spr->gzt - hzt) / spr->yscale; int minvoxely = spr->gzt <= hzt ? 0 : (spr->gzt - hzt) / spr->yscale;
int maxvoxely = spr->gzb > hzb ? INT_MAX : (spr->gzt - hzb) / spr->yscale; int maxvoxely = spr->gzb > hzb ? INT_MAX : (spr->gzt - hzb) / spr->yscale;
R_DrawVisVoxel(spr, minvoxely, maxvoxely, cliptop, clipbot); R_DrawVisVoxel(spr, minvoxely, maxvoxely, cliptop, clipbot);
@ -2228,7 +2244,8 @@ void R_DrawParticle (vissprite_t *vis)
extern fixed_t baseyaspectmul; extern fixed_t baseyaspectmul;
void R_DrawVoxel(fixed_t dasprx, fixed_t daspry, fixed_t dasprz, angle_t dasprang, void R_DrawVoxel(fixed_t globalposx, fixed_t globalposy, fixed_t globalposz, angle_t viewang,
fixed_t dasprx, fixed_t daspry, fixed_t dasprz, angle_t dasprang,
fixed_t daxscale, fixed_t dayscale, FVoxel *voxobj, fixed_t daxscale, fixed_t dayscale, FVoxel *voxobj,
lighttable_t *colormap, short *daumost, short *dadmost, int minslabz, int maxslabz, int flags) lighttable_t *colormap, short *daumost, short *dadmost, int minslabz, int maxslabz, int flags)
{ {
@ -2244,12 +2261,14 @@ void R_DrawVoxel(fixed_t dasprx, fixed_t daspry, fixed_t dasprz, angle_t daspran
const int nytooclose = centerxwide * 2100, nytoofar = 32768*32768 - 1048576; const int nytooclose = centerxwide * 2100, nytoofar = 32768*32768 - 1048576;
const int xdimenscale = Scale(centerxwide, yaspectmul, 160); const int xdimenscale = Scale(centerxwide, yaspectmul, 160);
const fixed_t globalposx = viewx >> 12;
const fixed_t globalposy = -viewy >> 12;
const fixed_t globalposz = -viewz >> 8;
const double centerxwide_f = centerxwide; const double centerxwide_f = centerxwide;
const double centerxwidebig_f = centerxwide_f * 65536*65536*8; const double centerxwidebig_f = centerxwide_f * 65536*65536*8;
// Convert to Build's coordinate system.
globalposx = globalposx >> 12;
globalposy = -globalposy >> 12;
globalposz = -globalposz >> 8;
dasprx = dasprx >> 12; dasprx = dasprx >> 12;
daspry = -daspry >> 12; daspry = -daspry >> 12;
dasprz = -dasprz >> 8; dasprz = -dasprz >> 8;
@ -2259,20 +2278,19 @@ void R_DrawVoxel(fixed_t dasprx, fixed_t daspry, fixed_t dasprz, angle_t daspran
daxscale = daxscale / (0xC000 >> 6); daxscale = daxscale / (0xC000 >> 6);
dayscale = dayscale / (0xC000 >> 6); dayscale = dayscale / (0xC000 >> 6);
cosang = viewcos >> 2; cosang = finecosine[viewang >> ANGLETOFINESHIFT] >> 2;
sinang = -viewsin >> 2; sinang = -finesine[viewang >> ANGLETOFINESHIFT] >> 2;
sprcosang = finecosine[dasprang >> ANGLETOFINESHIFT] >> 2; sprcosang = finecosine[dasprang >> ANGLETOFINESHIFT] >> 2;
sprsinang = -finesine[dasprang >> ANGLETOFINESHIFT] >> 2; sprsinang = -finesine[dasprang >> ANGLETOFINESHIFT] >> 2;
R_SetupDrawSlab(colormap); R_SetupDrawSlab(colormap);
// Select mip level // Select mip level
i = abs(DMulScale8(dasprx - globalposx, viewcos, daspry - globalposy, -viewsin)); i = abs(DMulScale6(dasprx - globalposx, cosang, daspry - globalposy, sinang));
i = DivScale6(i, MIN(daxscale, dayscale)); i = DivScale6(i, MIN(daxscale, dayscale));
j = FocalLengthX >> 3; j = FocalLengthX >> 3;
for (k = 0; k < voxobj->NumMips; ++k) for (k = 0; i >= j && k < voxobj->NumMips; ++k)
{ {
if (i < j) { break; }
i >>= 1; i >>= 1;
} }
if (k >= voxobj->NumMips) k = voxobj->NumMips - 1; if (k >= voxobj->NumMips) k = voxobj->NumMips - 1;
@ -2404,6 +2422,13 @@ void R_DrawVoxel(fixed_t dasprx, fixed_t daspry, fixed_t dasprz, angle_t daspran
if (rx > viewwidth) rx = viewwidth; if (rx > viewwidth) rx = viewwidth;
if (rx <= lx) continue; if (rx <= lx) continue;
if (flags & DVF_MIRRORED)
{
int t = viewwidth - lx;
lx = viewwidth - rx;
rx = t;
}
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 *)((BYTE *)voxptr + voxptr->zleng + 3)) for (; voxptr < voxend; voxptr = (kvxslab_t *)((BYTE *)voxptr + voxptr->zleng + 3))

View file

@ -35,25 +35,36 @@ struct vissprite_t
fixed_t gx, gy, gz; // origin in world coordinates fixed_t gx, gy, gz; // origin in world coordinates
angle_t angle; angle_t angle;
fixed_t gzb, gzt; // global bottom / top for silhouette clipping fixed_t gzb, gzt; // global bottom / top for silhouette clipping
fixed_t startfrac; // horizontal position of x1
fixed_t xscale, yscale; fixed_t xscale, yscale;
fixed_t xiscale; // negative if flipped
fixed_t depth; fixed_t depth;
fixed_t idepth; // 1/z fixed_t idepth; // 1/z
fixed_t texturemid;
DWORD FillColor; DWORD FillColor;
fixed_t floorclip;
union
{
// Used by regular sprites
struct
{
FTexture *pic;
fixed_t texturemid;
fixed_t startfrac; // horizontal position of x1
fixed_t xiscale; // negative if flipped
};
// Used by voxels
struct
{
struct FVoxel *voxel;
fixed_t vx, vy, vz; // view origin
angle_t vang; // view angle
};
};
sector_t *heightsec; // killough 3/27/98: height sector for underwater/fake ceiling sector_t *heightsec; // killough 3/27/98: height sector for underwater/fake ceiling
sector_t *sector; // [RH] sector this sprite is in sector_t *sector; // [RH] sector this sprite is in
F3DFloor *fakefloor; F3DFloor *fakefloor;
F3DFloor *fakeceiling; F3DFloor *fakeceiling;
fixed_t floorclip;
union
{
FTexture *pic;
struct FVoxel *voxel;
};
BYTE bIsVoxel:1; // [RH] Use voxel instead of pic BYTE bIsVoxel:1; // [RH] Use voxel instead of pic
BYTE bSplitSprite:1; // [RH] Sprite was split by a drawseg BYTE bSplitSprite:1; // [RH] Sprite was split by a drawseg
BYTE bInMirror:1; // [RH] Sprite is "inside" a mirror
BYTE FakeFlatStat; // [RH] which side of fake/floor ceiling sprite is on BYTE FakeFlatStat; // [RH] which side of fake/floor ceiling sprite is on
BYTE ColormapNum; // Which colormap is rendered (needed for shaded drawer) BYTE ColormapNum; // Which colormap is rendered (needed for shaded drawer)
short renderflags; short renderflags;
@ -102,9 +113,10 @@ void R_DrawRemainingPlayerSprites ();
void R_CheckOffscreenBuffer(int width, int height, bool spansonly); void R_CheckOffscreenBuffer(int width, int height, bool spansonly);
enum { DVF_OFFSCREEN = 1, DVF_SPANSONLY = 2 }; enum { DVF_OFFSCREEN = 1, DVF_SPANSONLY = 2, DVF_MIRRORED = 4 };
void R_DrawVoxel(fixed_t dasprx, fixed_t daspry, fixed_t dasprz, angle_t dasprang, void R_DrawVoxel(fixed_t viewx, fixed_t viewy, fixed_t viewz, angle_t viewangle,
fixed_t dasprx, fixed_t daspry, fixed_t dasprz, angle_t dasprang,
fixed_t daxscale, fixed_t dayscale, FVoxel *voxobj, fixed_t daxscale, fixed_t dayscale, FVoxel *voxobj,
lighttable_t *colormap, short *daumost, short *dadmost, int minslabz, int maxslabz, int flags); lighttable_t *colormap, short *daumost, short *dadmost, int minslabz, int maxslabz, int flags);