mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-11 15:21:51 +00:00
Move r_portal into a class
This commit is contained in:
parent
c2d01522f0
commit
e806b9424c
16 changed files with 179 additions and 144 deletions
|
@ -78,7 +78,9 @@ namespace swrenderer
|
|||
if (WallC.Init(pt1, pt2, 32.0 / (1 << 12)))
|
||||
return;
|
||||
|
||||
if (WallC.sx1 >= WindowRight || WallC.sx2 <= WindowLeft)
|
||||
RenderPortal *renderportal = RenderPortal::Instance();
|
||||
|
||||
if (WallC.sx1 >= renderportal->WindowRight || WallC.sx2 <= renderportal->WindowLeft)
|
||||
return;
|
||||
|
||||
if (line->linedef == NULL)
|
||||
|
@ -92,7 +94,7 @@ namespace swrenderer
|
|||
|
||||
// reject lines that aren't seen from the portal (if any)
|
||||
// [ZZ] 10.01.2016: lines inside a skybox shouldn't be clipped, although this imposes some limitations on portals in skyboxes.
|
||||
if (!CurrentPortalInSkybox && CurrentPortal && P_ClipLineToPortal(line->linedef, CurrentPortal->dst, ViewPos))
|
||||
if (!renderportal->CurrentPortalInSkybox && renderportal->CurrentPortal && P_ClipLineToPortal(line->linedef, renderportal->CurrentPortal->dst, ViewPos))
|
||||
return;
|
||||
|
||||
vertex_t *v1, *v2;
|
||||
|
@ -162,12 +164,12 @@ namespace swrenderer
|
|||
if (rw_frontcz1 > rw_backcz1 || rw_frontcz2 > rw_backcz2)
|
||||
{
|
||||
rw_havehigh = true;
|
||||
R_CreateWallSegmentYSloped(wallupper, backsector->ceilingplane, &WallC, curline, MirrorFlags & RF_XFLIP);
|
||||
R_CreateWallSegmentYSloped(wallupper, backsector->ceilingplane, &WallC, curline, renderportal->MirrorFlags & RF_XFLIP);
|
||||
}
|
||||
if (rw_frontfz1 < rw_backfz1 || rw_frontfz2 < rw_backfz2)
|
||||
{
|
||||
rw_havelow = true;
|
||||
R_CreateWallSegmentYSloped(walllower, backsector->floorplane, &WallC, curline, MirrorFlags & RF_XFLIP);
|
||||
R_CreateWallSegmentYSloped(walllower, backsector->floorplane, &WallC, curline, renderportal->MirrorFlags & RF_XFLIP);
|
||||
}
|
||||
|
||||
// Portal
|
||||
|
@ -268,8 +270,8 @@ namespace swrenderer
|
|||
}
|
||||
else
|
||||
{
|
||||
rw_ceilstat = R_CreateWallSegmentYSloped(walltop, frontsector->ceilingplane, &WallC, curline, MirrorFlags & RF_XFLIP);
|
||||
rw_floorstat = R_CreateWallSegmentYSloped(wallbottom, frontsector->floorplane, &WallC, curline, MirrorFlags & RF_XFLIP);
|
||||
rw_ceilstat = R_CreateWallSegmentYSloped(walltop, frontsector->ceilingplane, &WallC, curline, renderportal->MirrorFlags & RF_XFLIP);
|
||||
rw_floorstat = R_CreateWallSegmentYSloped(wallbottom, frontsector->floorplane, &WallC, curline, renderportal->MirrorFlags & RF_XFLIP);
|
||||
|
||||
// [RH] treat off-screen walls as solid
|
||||
#if 0 // Maybe later...
|
||||
|
@ -339,8 +341,10 @@ namespace swrenderer
|
|||
|
||||
rw_offset = FLOAT2FIXED(sidedef->GetTextureXOffset(side_t::mid));
|
||||
rw_light = rw_lightleft + rw_lightstep * (start - WallC.sx1);
|
||||
|
||||
RenderPortal *renderportal = RenderPortal::Instance();
|
||||
|
||||
draw_segment->CurrentPortalUniq = CurrentPortalUniq;
|
||||
draw_segment->CurrentPortalUniq = renderportal->CurrentPortalUniq;
|
||||
draw_segment->sx1 = WallC.sx1;
|
||||
draw_segment->sx2 = WallC.sx2;
|
||||
draw_segment->sz1 = WallC.sz1;
|
||||
|
@ -715,7 +719,8 @@ namespace swrenderer
|
|||
// wall but nothing to draw for it.
|
||||
// Recalculate walltop so that the wall is clipped by the back sector's
|
||||
// ceiling instead of the front sector's ceiling.
|
||||
R_CreateWallSegmentYSloped(walltop, backsector->ceilingplane, &WallC, curline, MirrorFlags & RF_XFLIP);
|
||||
RenderPortal *renderportal = RenderPortal::Instance();
|
||||
R_CreateWallSegmentYSloped(walltop, backsector->ceilingplane, &WallC, curline, renderportal->MirrorFlags & RF_XFLIP);
|
||||
}
|
||||
// Putting sky ceilings on the front and back of a line alters the way unpegged
|
||||
// positioning works.
|
||||
|
@ -1166,8 +1171,10 @@ namespace swrenderer
|
|||
|
||||
tleft.Y = float(pt1.X * ViewTanCos + pt1.Y * ViewTanSin);
|
||||
tright.Y = float(pt2.X * ViewTanCos + pt2.Y * ViewTanSin);
|
||||
|
||||
RenderPortal *renderportal = RenderPortal::Instance();
|
||||
|
||||
if (MirrorFlags & RF_XFLIP)
|
||||
if (renderportal->MirrorFlags & RF_XFLIP)
|
||||
{
|
||||
float t = -tleft.X;
|
||||
tleft.X = -tright.X;
|
||||
|
@ -1222,8 +1229,10 @@ namespace swrenderer
|
|||
{
|
||||
const FVector2 *left = &wallc->tleft;
|
||||
const FVector2 *right = &wallc->tright;
|
||||
|
||||
RenderPortal *renderportal = RenderPortal::Instance();
|
||||
|
||||
if (MirrorFlags & RF_XFLIP)
|
||||
if (renderportal->MirrorFlags & RF_XFLIP)
|
||||
{
|
||||
swapvalues(left, right);
|
||||
}
|
||||
|
@ -1241,8 +1250,10 @@ namespace swrenderer
|
|||
double fullx2 = right.X * ViewSin - right.Y * ViewCos;
|
||||
double fully1 = left.X * ViewTanCos + left.Y * ViewTanSin;
|
||||
double fully2 = right.X * ViewTanCos + right.Y * ViewTanSin;
|
||||
|
||||
RenderPortal *renderportal = RenderPortal::Instance();
|
||||
|
||||
if (MirrorFlags & RF_XFLIP)
|
||||
if (renderportal->MirrorFlags & RF_XFLIP)
|
||||
{
|
||||
fullx1 = -fullx1;
|
||||
fullx2 = -fullx2;
|
||||
|
|
|
@ -442,11 +442,13 @@ namespace swrenderer
|
|||
|
||||
assert(WallC.sx1 <= x1);
|
||||
assert(WallC.sx2 >= x2);
|
||||
|
||||
RenderPortal *renderportal = RenderPortal::Instance();
|
||||
|
||||
// kg3D - fake floors instead of zdoom light list
|
||||
for (unsigned int i = 0; i < frontsector->e->XFloor.lightlist.Size(); i++)
|
||||
{
|
||||
int j = R_CreateWallSegmentYSloped(most3, frontsector->e->XFloor.lightlist[i].plane, &WallC, curline, MirrorFlags & RF_XFLIP);
|
||||
int j = R_CreateWallSegmentYSloped(most3, frontsector->e->XFloor.lightlist[i].plane, &WallC, curline, renderportal->MirrorFlags & RF_XFLIP);
|
||||
if (j != 3)
|
||||
{
|
||||
for (int j = x1; j < x2; ++j)
|
||||
|
|
|
@ -93,7 +93,8 @@ namespace swrenderer
|
|||
ystep = -sin(planeang) / FocalLengthX;
|
||||
|
||||
// [RH] flip for mirrors
|
||||
if (MirrorFlags & RF_XFLIP)
|
||||
RenderPortal *renderportal = RenderPortal::Instance();
|
||||
if (renderportal->MirrorFlags & RF_XFLIP)
|
||||
{
|
||||
xstep = -xstep;
|
||||
ystep = -ystep;
|
||||
|
|
|
@ -314,6 +314,8 @@ namespace swrenderer
|
|||
void R_DrawSkyColumnStripe(int start_x, int y1, int y2, int columns, double scale, double texturemid, double yrepeat)
|
||||
{
|
||||
using namespace drawerargs;
|
||||
|
||||
RenderPortal *renderportal = RenderPortal::Instance();
|
||||
|
||||
uint32_t height = frontskytex->GetHeight();
|
||||
|
||||
|
@ -327,7 +329,7 @@ namespace swrenderer
|
|||
uint32_t uv_step = (uint32_t)(v_step * 0x01000000);
|
||||
|
||||
int x = start_x + i;
|
||||
if (MirrorFlags & RF_XFLIP)
|
||||
if (renderportal->MirrorFlags & RF_XFLIP)
|
||||
x = (viewwidth - x);
|
||||
|
||||
uint32_t ang, angle1, angle2;
|
||||
|
@ -431,8 +433,10 @@ namespace swrenderer
|
|||
{
|
||||
swall[x] = swal;
|
||||
}
|
||||
|
||||
RenderPortal *renderportal = RenderPortal::Instance();
|
||||
|
||||
if (MirrorFlags & RF_XFLIP)
|
||||
if (renderportal->MirrorFlags & RF_XFLIP)
|
||||
{
|
||||
for (x = pl->left; x < pl->right; ++x)
|
||||
{
|
||||
|
|
|
@ -143,7 +143,8 @@ namespace swrenderer
|
|||
plane_su *= 4294967296.f;
|
||||
plane_sv *= 4294967296.f;
|
||||
|
||||
if (MirrorFlags & RF_XFLIP)
|
||||
RenderPortal *renderportal = RenderPortal::Instance();
|
||||
if (renderportal->MirrorFlags & RF_XFLIP)
|
||||
{
|
||||
plane_su[0] = -plane_su[0];
|
||||
plane_sv[0] = -plane_sv[0];
|
||||
|
|
|
@ -250,6 +250,8 @@ namespace swrenderer
|
|||
|
||||
// New visplane algorithm uses hash table -- killough
|
||||
hash = isskybox ? MAXVISPLANES : visplane_hash(picnum.GetIndex(), lightlevel, height);
|
||||
|
||||
RenderPortal *renderportal = RenderPortal::Instance();
|
||||
|
||||
for (check = visplanes[hash]; check; check = check->next) // killough
|
||||
{
|
||||
|
@ -260,9 +262,9 @@ namespace swrenderer
|
|||
if (portal->mType != PORTS_SKYVIEWPOINT)
|
||||
{ // This skybox is really a stacked sector, so we need to
|
||||
// check even more.
|
||||
if (check->extralight == stacked_extralight &&
|
||||
check->visibility == stacked_visibility &&
|
||||
check->viewpos == stacked_viewpos &&
|
||||
if (check->extralight == renderportal->stacked_extralight &&
|
||||
check->visibility == renderportal->stacked_visibility &&
|
||||
check->viewpos == renderportal->stacked_viewpos &&
|
||||
(
|
||||
// headache inducing logic... :(
|
||||
(portal->mType != PORTS_STACKEDSECTORTHING) ||
|
||||
|
@ -277,7 +279,7 @@ namespace swrenderer
|
|||
*xform == check->xform
|
||||
)
|
||||
) &&
|
||||
check->viewangle == stacked_angle
|
||||
check->viewangle == renderportal->stacked_angle
|
||||
)
|
||||
)
|
||||
)
|
||||
|
@ -298,8 +300,8 @@ namespace swrenderer
|
|||
basecolormap == check->colormap && // [RH] Add more checks
|
||||
*xform == check->xform &&
|
||||
sky == check->sky &&
|
||||
CurrentPortalUniq == check->CurrentPortalUniq &&
|
||||
MirrorFlags == check->MirrorFlags &&
|
||||
renderportal->CurrentPortalUniq == check->CurrentPortalUniq &&
|
||||
renderportal->MirrorFlags == check->MirrorFlags &&
|
||||
Clip3DFloors::Instance()->CurrentSkybox == check->CurrentSkybox &&
|
||||
ViewPos == check->viewpos
|
||||
)
|
||||
|
@ -319,14 +321,14 @@ namespace swrenderer
|
|||
check->portal = portal;
|
||||
check->left = viewwidth; // Was SCREENWIDTH -- killough 11/98
|
||||
check->right = 0;
|
||||
check->extralight = stacked_extralight;
|
||||
check->visibility = stacked_visibility;
|
||||
check->viewpos = stacked_viewpos;
|
||||
check->viewangle = stacked_angle;
|
||||
check->extralight = renderportal->stacked_extralight;
|
||||
check->visibility = renderportal->stacked_visibility;
|
||||
check->viewpos = renderportal->stacked_viewpos;
|
||||
check->viewangle = renderportal->stacked_angle;
|
||||
check->Alpha = alpha;
|
||||
check->Additive = additive;
|
||||
check->CurrentPortalUniq = CurrentPortalUniq;
|
||||
check->MirrorFlags = MirrorFlags;
|
||||
check->CurrentPortalUniq = renderportal->CurrentPortalUniq;
|
||||
check->MirrorFlags = renderportal->MirrorFlags;
|
||||
check->CurrentSkybox = Clip3DFloors::Instance()->CurrentSkybox;
|
||||
|
||||
fillshort(check->top, viewwidth, 0x7fff);
|
||||
|
@ -421,13 +423,15 @@ namespace swrenderer
|
|||
int vpcount = 0;
|
||||
|
||||
drawerargs::ds_color = 3;
|
||||
|
||||
RenderPortal *renderportal = RenderPortal::Instance();
|
||||
|
||||
for (i = 0; i < MAXVISPLANES; i++)
|
||||
{
|
||||
for (pl = visplanes[i]; pl; pl = pl->next)
|
||||
{
|
||||
// kg3D - draw only correct planes
|
||||
if (pl->CurrentPortalUniq != CurrentPortalUniq || pl->CurrentSkybox != Clip3DFloors::Instance()->CurrentSkybox)
|
||||
if (pl->CurrentPortalUniq != renderportal->CurrentPortalUniq || pl->CurrentSkybox != Clip3DFloors::Instance()->CurrentSkybox)
|
||||
continue;
|
||||
// kg3D - draw only real planes now
|
||||
if (pl->sky >= 0) {
|
||||
|
@ -448,19 +452,21 @@ namespace swrenderer
|
|||
|
||||
DVector3 oViewPos = ViewPos;
|
||||
DAngle oViewAngle = ViewAngle;
|
||||
|
||||
RenderPortal *renderportal = RenderPortal::Instance();
|
||||
|
||||
for (i = 0; i < MAXVISPLANES; i++)
|
||||
{
|
||||
for (pl = visplanes[i]; pl; pl = pl->next)
|
||||
{
|
||||
if (pl->CurrentSkybox != Clip3DFloors::Instance()->CurrentSkybox || pl->CurrentPortalUniq != CurrentPortalUniq)
|
||||
if (pl->CurrentSkybox != Clip3DFloors::Instance()->CurrentSkybox || pl->CurrentPortalUniq != renderportal->CurrentPortalUniq)
|
||||
continue;
|
||||
|
||||
if (pl->sky < 0 && pl->height.Zat0() == height)
|
||||
{
|
||||
ViewPos = pl->viewpos;
|
||||
ViewAngle = pl->viewangle;
|
||||
MirrorFlags = pl->MirrorFlags;
|
||||
renderportal->MirrorFlags = pl->MirrorFlags;
|
||||
|
||||
R_DrawSinglePlane(pl, pl->sky & 0x7FFFFFFF, pl->Additive, true);
|
||||
}
|
||||
|
|
|
@ -394,20 +394,6 @@ static void R_ShutdownRenderer()
|
|||
R_FreeDrawSegs();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// R_CopyStackedViewParameters
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void R_CopyStackedViewParameters()
|
||||
{
|
||||
stacked_viewpos = ViewPos;
|
||||
stacked_angle = ViewAngle;
|
||||
stacked_extralight = extralight;
|
||||
stacked_visibility = R_GetVisibility();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// R_SetupColormap
|
||||
|
@ -555,11 +541,7 @@ void R_RenderActorView (AActor *actor, bool dontmaplines)
|
|||
colfunc = basecolfunc;
|
||||
spanfunc = &SWPixelFormatDrawers::DrawSpan;
|
||||
|
||||
WindowLeft = 0;
|
||||
WindowRight = viewwidth;
|
||||
MirrorFlags = 0;
|
||||
CurrentPortal = NULL;
|
||||
CurrentPortalUniq = 0;
|
||||
RenderPortal::Instance()->SetMainPortal();
|
||||
|
||||
r_dontmaplines = dontmaplines;
|
||||
|
||||
|
@ -589,10 +571,10 @@ void R_RenderActorView (AActor *actor, bool dontmaplines)
|
|||
{
|
||||
PlaneCycles.Clock();
|
||||
R_DrawPlanes();
|
||||
R_DrawPortals();
|
||||
RenderPortal::Instance()->RenderPlanePortals();
|
||||
PlaneCycles.Unclock();
|
||||
|
||||
R_DrawWallPortals();
|
||||
RenderPortal::Instance()->RenderLinePortals();
|
||||
|
||||
NetUpdate ();
|
||||
|
||||
|
|
|
@ -134,8 +134,6 @@ void R_MultiresInit (void);
|
|||
|
||||
|
||||
|
||||
extern void R_CopyStackedViewParameters();
|
||||
|
||||
extern double globaluclip, globaldclip;
|
||||
|
||||
}
|
||||
|
|
|
@ -38,9 +38,10 @@
|
|||
#include "v_palette.h"
|
||||
#include "v_video.h"
|
||||
#include "m_png.h"
|
||||
#include "scene/r_bsp.h"
|
||||
#include "r_swrenderer.h"
|
||||
#include "scene/r_bsp.h"
|
||||
#include "scene/r_3dfloors.h"
|
||||
#include "scene/r_portal.h"
|
||||
#include "textures/textures.h"
|
||||
#include "r_data/voxels.h"
|
||||
#include "drawers/r_draw_rgba.h"
|
||||
|
@ -395,7 +396,7 @@ void FSoftwareRenderer::SetupFrame(player_t *player)
|
|||
|
||||
void FSoftwareRenderer::CopyStackedViewParameters()
|
||||
{
|
||||
R_CopyStackedViewParameters();
|
||||
RenderPortal::Instance()->CopyStackedViewParameters();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
|
@ -333,7 +333,7 @@ namespace swrenderer
|
|||
ry1 = x1 * ViewTanCos + y1 * ViewTanSin;
|
||||
ry2 = x2 * ViewTanCos + y2 * ViewTanSin;
|
||||
|
||||
if (MirrorFlags & RF_XFLIP)
|
||||
if (RenderPortal::Instance()->MirrorFlags & RF_XFLIP)
|
||||
{
|
||||
double t = -rx1;
|
||||
rx1 = -rx2;
|
||||
|
|
|
@ -62,31 +62,12 @@ CVAR(Bool, r_skyboxes, true, 0)
|
|||
|
||||
namespace swrenderer
|
||||
{
|
||||
int WindowLeft, WindowRight;
|
||||
uint16_t MirrorFlags;
|
||||
|
||||
PortalDrawseg *CurrentPortal = nullptr;
|
||||
int CurrentPortalUniq = 0;
|
||||
bool CurrentPortalInSkybox = false;
|
||||
|
||||
// These are copies of the main parameters used when drawing stacked sectors.
|
||||
// When you change the main parameters, you should copy them here too *unless*
|
||||
// you are changing them to draw a stacked sector. Otherwise, stacked sectors
|
||||
// won't draw in skyboxes properly.
|
||||
int stacked_extralight;
|
||||
double stacked_visibility;
|
||||
DVector3 stacked_viewpos;
|
||||
DAngle stacked_angle;
|
||||
|
||||
namespace
|
||||
RenderPortal *RenderPortal::Instance()
|
||||
{
|
||||
int numskyboxes; // For ADD_STAT(skyboxes)
|
||||
static RenderPortal renderportal;
|
||||
return &renderportal;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// R_DrawPortals
|
||||
//
|
||||
// Draws any recorded sky boxes and then frees them.
|
||||
//
|
||||
// The process:
|
||||
|
@ -102,16 +83,8 @@ namespace swrenderer
|
|||
// 8. Repeat for any other sky boxes.
|
||||
// 9. Put the camera back where it was to begin with.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void R_DrawPortals()
|
||||
void RenderPortal::RenderPlanePortals()
|
||||
{
|
||||
static TArray<size_t> interestingStack;
|
||||
static TArray<ptrdiff_t> drawsegStack;
|
||||
static TArray<ptrdiff_t> visspriteStack;
|
||||
static TArray<DVector3> viewposStack;
|
||||
static TArray<visplane_t *> visplaneStack;
|
||||
|
||||
numskyboxes = 0;
|
||||
|
||||
if (visplanes[MAXVISPLANES] == nullptr)
|
||||
|
@ -164,7 +137,7 @@ namespace swrenderer
|
|||
ViewPos = sky->InterpolatedPosition(r_TicFracF);
|
||||
ViewAngle = savedangle + (sky->PrevAngles.Yaw + deltaangle(sky->PrevAngles.Yaw, sky->Angles.Yaw) * r_TicFracF);
|
||||
|
||||
R_CopyStackedViewParameters();
|
||||
CopyStackedViewParameters();
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -311,21 +284,21 @@ namespace swrenderer
|
|||
freehead = &(*freehead)->next;
|
||||
}
|
||||
|
||||
void R_DrawWallPortals()
|
||||
void RenderPortal::RenderLinePortals()
|
||||
{
|
||||
// [RH] Walk through mirrors
|
||||
// [ZZ] Merged with portals
|
||||
size_t lastportal = WallPortals.Size();
|
||||
for (unsigned int i = 0; i < lastportal; i++)
|
||||
{
|
||||
R_EnterPortal(&WallPortals[i], 0);
|
||||
RenderLinePortal(&WallPortals[i], 0);
|
||||
}
|
||||
|
||||
CurrentPortal = nullptr;
|
||||
CurrentPortalUniq = 0;
|
||||
}
|
||||
|
||||
void R_EnterPortal(PortalDrawseg* pds, int depth)
|
||||
void RenderPortal::RenderLinePortal(PortalDrawseg* pds, int depth)
|
||||
{
|
||||
// [ZZ] check depth. fill portal with black if it's exceeding the visual recursion limit, and continue like nothing happened.
|
||||
if (depth >= r_portal_recursions)
|
||||
|
@ -364,7 +337,7 @@ namespace swrenderer
|
|||
}
|
||||
|
||||
if (r_highlight_portals)
|
||||
R_HighlightPortal(pds);
|
||||
RenderLinePortalHighlight(pds);
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -441,7 +414,7 @@ namespace swrenderer
|
|||
ViewTanSin = FocalTangent * ViewSin;
|
||||
ViewTanCos = FocalTangent * ViewCos;
|
||||
|
||||
R_CopyStackedViewParameters();
|
||||
CopyStackedViewParameters();
|
||||
|
||||
validcount++;
|
||||
PortalDrawseg* prevpds = CurrentPortal;
|
||||
|
@ -478,7 +451,7 @@ namespace swrenderer
|
|||
|
||||
PlaneCycles.Clock();
|
||||
R_DrawPlanes();
|
||||
R_DrawPortals();
|
||||
RenderPlanePortals();
|
||||
PlaneCycles.Unclock();
|
||||
|
||||
double vzp = ViewPos.Z;
|
||||
|
@ -488,7 +461,7 @@ namespace swrenderer
|
|||
unsigned int portalsAtEnd = WallPortals.Size();
|
||||
for (; portalsAtStart < portalsAtEnd; portalsAtStart++)
|
||||
{
|
||||
R_EnterPortal(&WallPortals[portalsAtStart], depth + 1);
|
||||
RenderLinePortal(&WallPortals[portalsAtStart], depth + 1);
|
||||
}
|
||||
int prevuniq2 = CurrentPortalUniq;
|
||||
CurrentPortalUniq = prevuniq;
|
||||
|
@ -506,7 +479,7 @@ namespace swrenderer
|
|||
|
||||
// draw a red line around a portal if it's being highlighted
|
||||
if (r_highlight_portals)
|
||||
R_HighlightPortal(pds);
|
||||
RenderLinePortalHighlight(pds);
|
||||
|
||||
CurrentPortal = prevpds;
|
||||
MirrorFlags = prevmf;
|
||||
|
@ -516,7 +489,7 @@ namespace swrenderer
|
|||
ViewPath[1] = savedpath[1];
|
||||
}
|
||||
|
||||
void R_HighlightPortal(PortalDrawseg* pds)
|
||||
void RenderPortal::RenderLinePortalHighlight(PortalDrawseg* pds)
|
||||
{
|
||||
// [ZZ] NO OVERFLOW CHECKS HERE
|
||||
// I believe it won't break. if it does, blame me. :(
|
||||
|
@ -555,11 +528,28 @@ namespace swrenderer
|
|||
else *(pixels + Ybottom * RenderTarget->GetPitch() + x) = color;
|
||||
}
|
||||
}
|
||||
|
||||
void RenderPortal::CopyStackedViewParameters()
|
||||
{
|
||||
stacked_viewpos = ViewPos;
|
||||
stacked_angle = ViewAngle;
|
||||
stacked_extralight = extralight;
|
||||
stacked_visibility = R_GetVisibility();
|
||||
}
|
||||
|
||||
void RenderPortal::SetMainPortal()
|
||||
{
|
||||
WindowLeft = 0;
|
||||
WindowRight = viewwidth;
|
||||
MirrorFlags = 0;
|
||||
CurrentPortal = nullptr;
|
||||
CurrentPortalUniq = 0;
|
||||
}
|
||||
}
|
||||
|
||||
ADD_STAT(skyboxes)
|
||||
{
|
||||
FString out;
|
||||
out.Format("%d skybox planes", swrenderer::numskyboxes);
|
||||
out.Format("%d skybox planes", swrenderer::RenderPortal::Instance()->numskyboxes);
|
||||
return out;
|
||||
}
|
||||
|
|
|
@ -17,20 +17,46 @@
|
|||
|
||||
namespace swrenderer
|
||||
{
|
||||
extern int WindowLeft, WindowRight;
|
||||
extern uint16_t MirrorFlags;
|
||||
struct visplane_t;
|
||||
|
||||
extern PortalDrawseg* CurrentPortal;
|
||||
extern int CurrentPortalUniq;
|
||||
extern bool CurrentPortalInSkybox;
|
||||
class RenderPortal
|
||||
{
|
||||
public:
|
||||
static RenderPortal *Instance();
|
||||
|
||||
void SetMainPortal();
|
||||
void CopyStackedViewParameters();
|
||||
|
||||
void RenderPlanePortals();
|
||||
void RenderLinePortals();
|
||||
|
||||
int WindowLeft = 0;
|
||||
int WindowRight = 0;
|
||||
uint16_t MirrorFlags = 0;
|
||||
|
||||
extern int stacked_extralight;
|
||||
extern double stacked_visibility;
|
||||
extern DVector3 stacked_viewpos;
|
||||
extern DAngle stacked_angle;
|
||||
PortalDrawseg* CurrentPortal = nullptr;
|
||||
int CurrentPortalUniq = 0;
|
||||
bool CurrentPortalInSkybox = false;
|
||||
|
||||
void R_DrawPortals();
|
||||
void R_DrawWallPortals();
|
||||
void R_EnterPortal(PortalDrawseg* pds, int depth);
|
||||
void R_HighlightPortal(PortalDrawseg* pds);
|
||||
// These are copies of the main parameters used when drawing stacked sectors.
|
||||
// When you change the main parameters, you should copy them here too *unless*
|
||||
// you are changing them to draw a stacked sector. Otherwise, stacked sectors
|
||||
// won't draw in skyboxes properly.
|
||||
int stacked_extralight = 0;
|
||||
double stacked_visibility = 0.0;
|
||||
DVector3 stacked_viewpos;
|
||||
DAngle stacked_angle;
|
||||
|
||||
int numskyboxes = 0; // For ADD_STAT(skyboxes)
|
||||
|
||||
private:
|
||||
void RenderLinePortal(PortalDrawseg* pds, int depth);
|
||||
void RenderLinePortalHighlight(PortalDrawseg* pds);
|
||||
|
||||
TArray<size_t> interestingStack;
|
||||
TArray<ptrdiff_t> drawsegStack;
|
||||
TArray<ptrdiff_t> visspriteStack;
|
||||
TArray<DVector3> viewposStack;
|
||||
TArray<visplane_t *> visplaneStack;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -427,14 +427,16 @@ static inline void R_CollectPortals()
|
|||
|
||||
bool R_ClipSpriteColumnWithPortals(vissprite_t* spr)
|
||||
{
|
||||
RenderPortal *renderportal = RenderPortal::Instance();
|
||||
|
||||
// [ZZ] 10.01.2016: don't clip sprites from the root of a skybox.
|
||||
if (CurrentPortalInSkybox)
|
||||
if (renderportal->CurrentPortalInSkybox)
|
||||
return false;
|
||||
|
||||
for (drawseg_t *seg : portaldrawsegs)
|
||||
{
|
||||
// ignore segs from other portals
|
||||
if (seg->CurrentPortalUniq != CurrentPortalUniq)
|
||||
if (seg->CurrentPortalUniq != renderportal->CurrentPortalUniq)
|
||||
continue;
|
||||
|
||||
// (all checks that are already done in R_CollectPortals have been removed for performance reasons.)
|
||||
|
@ -636,10 +638,12 @@ void R_ProjectSprite (AActor *thing, WaterFakeSide fakeside, F3DFloor *fakefloor
|
|||
{
|
||||
return;
|
||||
}
|
||||
|
||||
RenderPortal *renderportal = RenderPortal::Instance();
|
||||
|
||||
// [ZZ] Or less definitely not visible (hue)
|
||||
// [ZZ] 10.01.2016: don't try to clip stuff inside a skybox against the current portal.
|
||||
if (!CurrentPortalInSkybox && CurrentPortal && !!P_PointOnLineSidePrecise(thing->Pos(), CurrentPortal->dst))
|
||||
if (!renderportal->CurrentPortalInSkybox && renderportal->CurrentPortal && !!P_PointOnLineSidePrecise(thing->Pos(), renderportal->CurrentPortal->dst))
|
||||
return;
|
||||
|
||||
// [RH] Interpolate the sprite's position to make it look smooth
|
||||
|
@ -776,7 +780,7 @@ void R_ProjectSprite (AActor *thing, WaterFakeSide fakeside, F3DFloor *fakefloor
|
|||
tx = tr_x * ViewSin - tr_y * ViewCos;
|
||||
|
||||
// [RH] Flip for mirrors
|
||||
if (MirrorFlags & RF_XFLIP)
|
||||
if (renderportal->MirrorFlags & RF_XFLIP)
|
||||
{
|
||||
tx = -tx;
|
||||
}
|
||||
|
@ -847,7 +851,7 @@ void R_ProjectSprite (AActor *thing, WaterFakeSide fakeside, F3DFloor *fakefloor
|
|||
}
|
||||
|
||||
// [RH] Flip for mirrors
|
||||
renderflags ^= MirrorFlags & RF_XFLIP;
|
||||
renderflags ^= renderportal->MirrorFlags & RF_XFLIP;
|
||||
|
||||
// calculate edges of the shape
|
||||
const double thingxscalemul = spriteScale.X / tex->Scale.X;
|
||||
|
@ -857,14 +861,14 @@ void R_ProjectSprite (AActor *thing, WaterFakeSide fakeside, F3DFloor *fakefloor
|
|||
x1 = centerx + xs_RoundToInt(dtx1);
|
||||
|
||||
// off the right side?
|
||||
if (x1 >= WindowRight)
|
||||
if (x1 >= renderportal->WindowRight)
|
||||
return;
|
||||
|
||||
tx += tex->GetWidth() * thingxscalemul;
|
||||
x2 = centerx + xs_RoundToInt(tx * xscale);
|
||||
|
||||
// off the left side or too small?
|
||||
if ((x2 < WindowLeft || x2 <= x1))
|
||||
if ((x2 < renderportal->WindowLeft || x2 <= x1))
|
||||
return;
|
||||
|
||||
xscale = spriteScale.X * xscale / tex->Scale.X;
|
||||
|
@ -875,14 +879,14 @@ void R_ProjectSprite (AActor *thing, WaterFakeSide fakeside, F3DFloor *fakefloor
|
|||
// store information in a vissprite
|
||||
vis = R_NewVisSprite();
|
||||
|
||||
vis->CurrentPortalUniq = CurrentPortalUniq;
|
||||
vis->CurrentPortalUniq = renderportal->CurrentPortalUniq;
|
||||
vis->xscale = FLOAT2FIXED(xscale);
|
||||
vis->yscale = float(InvZtoScale * yscale / tz);
|
||||
vis->idepth = float(1 / tz);
|
||||
vis->floorclip = thing->Floorclip / yscale;
|
||||
vis->texturemid = tex->TopOffset - (ViewPos.Z - pos.Z + thing->Floorclip) / yscale;
|
||||
vis->x1 = x1 < WindowLeft ? WindowLeft : x1;
|
||||
vis->x2 = x2 > WindowRight ? WindowRight : x2;
|
||||
vis->x1 = x1 < renderportal->WindowLeft ? renderportal->WindowLeft : x1;
|
||||
vis->x2 = x2 > renderportal->WindowRight ? renderportal->WindowRight : x2;
|
||||
vis->Angle = thing->Angles.Yaw;
|
||||
|
||||
if (renderflags & RF_XFLIP)
|
||||
|
@ -902,11 +906,11 @@ void R_ProjectSprite (AActor *thing, WaterFakeSide fakeside, F3DFloor *fakefloor
|
|||
{
|
||||
vis = R_NewVisSprite();
|
||||
|
||||
vis->CurrentPortalUniq = CurrentPortalUniq;
|
||||
vis->CurrentPortalUniq = renderportal->CurrentPortalUniq;
|
||||
vis->xscale = FLOAT2FIXED(xscale);
|
||||
vis->yscale = (float)yscale;
|
||||
vis->x1 = WindowLeft;
|
||||
vis->x2 = WindowRight;
|
||||
vis->x1 = renderportal->WindowLeft;
|
||||
vis->x2 = renderportal->WindowRight;
|
||||
vis->idepth = 1 / MINZ;
|
||||
vis->floorclip = thing->Floorclip;
|
||||
|
||||
|
@ -946,7 +950,7 @@ void R_ProjectSprite (AActor *thing, WaterFakeSide fakeside, F3DFloor *fakefloor
|
|||
vis->fakefloor = fakefloor;
|
||||
vis->fakeceiling = fakeceiling;
|
||||
vis->Style.ColormapNum = 0;
|
||||
vis->bInMirror = MirrorFlags & RF_XFLIP;
|
||||
vis->bInMirror = renderportal->MirrorFlags & RF_XFLIP;
|
||||
vis->bSplitSprite = false;
|
||||
|
||||
if (voxel != NULL)
|
||||
|
@ -1604,15 +1608,20 @@ void R_DrawSprite (vissprite_t *spr)
|
|||
neardepth = ds->sz2, fardepth = ds->sz1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Check if sprite is in front of draw seg:
|
||||
if ((!spr->bWallSprite && neardepth > spr->depth) || ((spr->bWallSprite || fardepth > spr->depth) &&
|
||||
(spr->gpos.Y - ds->curline->v1->fY()) * (ds->curline->v2->fX() - ds->curline->v1->fX()) -
|
||||
(spr->gpos.X - ds->curline->v1->fX()) * (ds->curline->v2->fY() - ds->curline->v1->fY()) <= 0))
|
||||
{
|
||||
RenderPortal *renderportal = RenderPortal::Instance();
|
||||
|
||||
// seg is behind sprite, so draw the mid texture if it has one
|
||||
if (ds->CurrentPortalUniq == CurrentPortalUniq && // [ZZ] instead, portal uniq check is made here
|
||||
if (ds->CurrentPortalUniq == renderportal->CurrentPortalUniq && // [ZZ] instead, portal uniq check is made here
|
||||
(ds->maskedtexturecol != -1 || ds->bFogBoundary))
|
||||
R_RenderMaskedSegRange (ds, r1, r2);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -1711,13 +1720,11 @@ void R_DrawMaskedSingle (bool renew)
|
|||
drawseg_t *ds;
|
||||
int i;
|
||||
|
||||
#if 0
|
||||
R_SplitVisSprites ();
|
||||
#endif
|
||||
RenderPortal *renderportal = RenderPortal::Instance();
|
||||
|
||||
for (i = vsprcount; i > 0; i--)
|
||||
{
|
||||
if (spritesorter[i-1]->CurrentPortalUniq != CurrentPortalUniq)
|
||||
if (spritesorter[i-1]->CurrentPortalUniq != renderportal->CurrentPortalUniq)
|
||||
continue; // probably another time
|
||||
R_DrawSprite (spritesorter[i-1]);
|
||||
}
|
||||
|
@ -1737,7 +1744,7 @@ void R_DrawMaskedSingle (bool renew)
|
|||
for (ds = ds_p; ds-- > firstdrawseg; ) // new -- killough
|
||||
{
|
||||
// [ZZ] the same as above
|
||||
if (ds->CurrentPortalUniq != CurrentPortalUniq)
|
||||
if (ds->CurrentPortalUniq != renderportal->CurrentPortalUniq)
|
||||
continue;
|
||||
// kg3D - no fake segs
|
||||
if (ds->fake) continue;
|
||||
|
|
|
@ -109,13 +109,15 @@ namespace swrenderer
|
|||
{
|
||||
short most[MAXWIDTH];
|
||||
|
||||
R_CreateWallSegmentYSloped(most, curline->frontsector->ceilingplane, &WallC, curline, MirrorFlags & RF_XFLIP);
|
||||
RenderPortal *renderportal = RenderPortal::Instance();
|
||||
|
||||
R_CreateWallSegmentYSloped(most, curline->frontsector->ceilingplane, &WallC, curline, renderportal->MirrorFlags & RF_XFLIP);
|
||||
for (int i = x1; i < x2; ++i)
|
||||
{
|
||||
if (wallupper[i] < most[i])
|
||||
wallupper[i] = most[i];
|
||||
}
|
||||
R_CreateWallSegmentYSloped(most, curline->frontsector->floorplane, &WallC, curline, MirrorFlags & RF_XFLIP);
|
||||
R_CreateWallSegmentYSloped(most, curline->frontsector->floorplane, &WallC, curline, renderportal->MirrorFlags & RF_XFLIP);
|
||||
for (int i = x1; i < x2; ++i)
|
||||
{
|
||||
if (walllower[i] > most[i])
|
||||
|
|
|
@ -66,9 +66,11 @@ namespace swrenderer
|
|||
vissprite_t* vis;
|
||||
sector_t* heightsec = NULL;
|
||||
FSWColormap* map;
|
||||
|
||||
RenderPortal *renderportal = RenderPortal::Instance();
|
||||
|
||||
// [ZZ] Particle not visible through the portal plane
|
||||
if (CurrentPortal && !!P_PointOnLineSide(particle->Pos, CurrentPortal->dst))
|
||||
if (renderportal->CurrentPortal && !!P_PointOnLineSide(particle->Pos, renderportal->CurrentPortal->dst))
|
||||
return;
|
||||
|
||||
// transform the origin point
|
||||
|
@ -84,7 +86,7 @@ namespace swrenderer
|
|||
tx = tr_x * ViewSin - tr_y * ViewCos;
|
||||
|
||||
// Flip for mirrors
|
||||
if (MirrorFlags & RF_XFLIP)
|
||||
if (renderportal->MirrorFlags & RF_XFLIP)
|
||||
{
|
||||
tx = viewwidth - tx - 1;
|
||||
}
|
||||
|
@ -99,8 +101,8 @@ namespace swrenderer
|
|||
// calculate edges of the shape
|
||||
double psize = particle->size / 8.0;
|
||||
|
||||
x1 = MAX<int>(WindowLeft, centerx + xs_RoundToInt((tx - psize) * xscale));
|
||||
x2 = MIN<int>(WindowRight, centerx + xs_RoundToInt((tx + psize) * xscale));
|
||||
x1 = MAX<int>(renderportal->WindowLeft, centerx + xs_RoundToInt((tx - psize) * xscale));
|
||||
x2 = MIN<int>(renderportal->WindowRight, centerx + xs_RoundToInt((tx + psize) * xscale));
|
||||
|
||||
if (x1 >= x2)
|
||||
return;
|
||||
|
@ -175,7 +177,7 @@ namespace swrenderer
|
|||
|
||||
// store information in a vissprite
|
||||
vis = R_NewVisSprite();
|
||||
vis->CurrentPortalUniq = CurrentPortalUniq;
|
||||
vis->CurrentPortalUniq = renderportal->CurrentPortalUniq;
|
||||
vis->heightsec = heightsec;
|
||||
vis->xscale = FLOAT2FIXED(xscale);
|
||||
vis->yscale = (float)xscale;
|
||||
|
|
|
@ -86,8 +86,10 @@ namespace swrenderer
|
|||
// Is it off-screen?
|
||||
if (wallc.Init(left, right, TOO_CLOSE_Z))
|
||||
return;
|
||||
|
||||
RenderPortal *renderportal = RenderPortal::Instance();
|
||||
|
||||
if (wallc.sx1 >= WindowRight || wallc.sx2 <= WindowLeft)
|
||||
if (wallc.sx1 >= renderportal->WindowRight || wallc.sx2 <= renderportal->WindowLeft)
|
||||
return;
|
||||
|
||||
// Sprite sorting should probably treat these as walls, not sprites,
|
||||
|
@ -100,9 +102,9 @@ namespace swrenderer
|
|||
gzb = pos.Z + scale.Y * scaled_bo;
|
||||
|
||||
vis = R_NewVisSprite();
|
||||
vis->CurrentPortalUniq = CurrentPortalUniq;
|
||||
vis->x1 = wallc.sx1 < WindowLeft ? WindowLeft : wallc.sx1;
|
||||
vis->x2 = wallc.sx2 >= WindowRight ? WindowRight : wallc.sx2;
|
||||
vis->CurrentPortalUniq = renderportal->CurrentPortalUniq;
|
||||
vis->x1 = wallc.sx1 < renderportal->WindowLeft ? renderportal->WindowLeft : wallc.sx1;
|
||||
vis->x2 = wallc.sx2 >= renderportal->WindowRight ? renderportal->WindowRight : wallc.sx2;
|
||||
vis->yscale = (float)scale.Y;
|
||||
vis->idepth = float(1 / tz);
|
||||
vis->depth = (float)tz;
|
||||
|
@ -122,7 +124,7 @@ namespace swrenderer
|
|||
vis->Style.Alpha = float(thing->Alpha);
|
||||
vis->fakefloor = NULL;
|
||||
vis->fakeceiling = NULL;
|
||||
vis->bInMirror = MirrorFlags & RF_XFLIP;
|
||||
vis->bInMirror = renderportal->MirrorFlags & RF_XFLIP;
|
||||
vis->pic = pic;
|
||||
vis->bIsVoxel = false;
|
||||
vis->bWallSprite = true;
|
||||
|
|
Loading…
Reference in a new issue