Move portal drawing to r_portal
This commit is contained in:
parent
60c0dcc3c7
commit
41d0e7c663
10 changed files with 569 additions and 503 deletions
|
|
@ -73,7 +73,6 @@
|
|||
|
||||
CVAR(Bool, r_linearsky, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG);
|
||||
CVAR(Bool, tilt, false, 0);
|
||||
CVAR(Bool, r_skyboxes, true, 0)
|
||||
|
||||
EXTERN_CVAR(Int, r_skymode)
|
||||
|
||||
|
|
@ -90,16 +89,10 @@ static void R_DrawSkyStriped (visplane_t *pl);
|
|||
planefunction_t floorfunc;
|
||||
planefunction_t ceilingfunc;
|
||||
|
||||
// Here comes the obnoxious "visplane".
|
||||
#define MAXVISPLANES 128 /* must be a power of 2 */
|
||||
|
||||
// Avoid infinite recursion with stacked sectors by limiting them.
|
||||
#define MAX_SKYBOX_PLANES 1000
|
||||
|
||||
// [RH] Allocate one extra for sky box planes.
|
||||
static visplane_t *visplanes[MAXVISPLANES+1]; // killough
|
||||
static visplane_t *freetail; // killough
|
||||
static visplane_t **freehead = &freetail; // killough
|
||||
visplane_t *visplanes[MAXVISPLANES+1];
|
||||
visplane_t *freetail;
|
||||
visplane_t **freehead = &freetail;
|
||||
|
||||
visplane_t *floorplane;
|
||||
visplane_t *ceilingplane;
|
||||
|
|
@ -1300,241 +1293,6 @@ void R_DrawSinglePlane (visplane_t *pl, fixed_t alpha, bool additive, bool maske
|
|||
NetUpdate ();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// R_DrawPortals
|
||||
//
|
||||
// Draws any recorded sky boxes and then frees them.
|
||||
//
|
||||
// The process:
|
||||
// 1. Move the camera to coincide with the SkyViewpoint.
|
||||
// 2. Clear out the old planes. (They have already been drawn.)
|
||||
// 3. Clear a window out of the ClipSegs just large enough for the plane.
|
||||
// 4. Pretend the existing vissprites and drawsegs aren't there.
|
||||
// 5. Create a drawseg at 0 distance to clip sprites to the visplane. It
|
||||
// doesn't need to be associated with a line in the map, since there
|
||||
// will never be any sprites in front of it.
|
||||
// 6. Render the BSP, then planes, then masked stuff.
|
||||
// 7. Restore the previous vissprites and drawsegs.
|
||||
// 8. Repeat for any other sky boxes.
|
||||
// 9. Put the camera back where it was to begin with.
|
||||
//
|
||||
//==========================================================================
|
||||
static int numskyboxes;
|
||||
|
||||
void R_DrawPortals ()
|
||||
{
|
||||
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] == NULL)
|
||||
return;
|
||||
|
||||
R_3D_EnterSkybox();
|
||||
CurrentPortalInSkybox = true;
|
||||
|
||||
int savedextralight = extralight;
|
||||
DVector3 savedpos = ViewPos;
|
||||
DAngle savedangle = ViewAngle;
|
||||
ptrdiff_t savedvissprite_p = vissprite_p - vissprites;
|
||||
ptrdiff_t savedds_p = ds_p - drawsegs;
|
||||
size_t savedinteresting = FirstInterestingDrawseg;
|
||||
double savedvisibility = R_GetVisibility();
|
||||
AActor *savedcamera = camera;
|
||||
sector_t *savedsector = viewsector;
|
||||
|
||||
int i;
|
||||
visplane_t *pl;
|
||||
|
||||
for (pl = visplanes[MAXVISPLANES]; pl != NULL; pl = visplanes[MAXVISPLANES])
|
||||
{
|
||||
// Pop the visplane off the list now so that if this skybox adds more
|
||||
// skyboxes to the list, they will be drawn instead of skipped (because
|
||||
// new skyboxes go to the beginning of the list instead of the end).
|
||||
visplanes[MAXVISPLANES] = pl->next;
|
||||
pl->next = NULL;
|
||||
|
||||
if (pl->right < pl->left || !r_skyboxes || numskyboxes == MAX_SKYBOX_PLANES || pl->portal == NULL)
|
||||
{
|
||||
R_DrawSinglePlane (pl, OPAQUE, false, false);
|
||||
*freehead = pl;
|
||||
freehead = &pl->next;
|
||||
continue;
|
||||
}
|
||||
|
||||
numskyboxes++;
|
||||
|
||||
FSectorPortal *port = pl->portal;
|
||||
switch (port->mType)
|
||||
{
|
||||
case PORTS_SKYVIEWPOINT:
|
||||
{
|
||||
// Don't let gun flashes brighten the sky box
|
||||
ASkyViewpoint *sky = barrier_cast<ASkyViewpoint*>(port->mSkybox);
|
||||
extralight = 0;
|
||||
R_SetVisibility(sky->args[0] * 0.25f);
|
||||
|
||||
ViewPos = sky->InterpolatedPosition(r_TicFracF);
|
||||
ViewAngle = savedangle + (sky->PrevAngles.Yaw + deltaangle(sky->PrevAngles.Yaw, sky->Angles.Yaw) * r_TicFracF);
|
||||
|
||||
R_CopyStackedViewParameters();
|
||||
break;
|
||||
}
|
||||
|
||||
case PORTS_STACKEDSECTORTHING:
|
||||
case PORTS_PORTAL:
|
||||
case PORTS_LINKEDPORTAL:
|
||||
extralight = pl->extralight;
|
||||
R_SetVisibility (pl->visibility);
|
||||
ViewPos.X = pl->viewpos.X + port->mDisplacement.X;
|
||||
ViewPos.Y = pl->viewpos.Y + port->mDisplacement.Y;
|
||||
ViewPos.Z = pl->viewpos.Z;
|
||||
ViewAngle = pl->viewangle;
|
||||
break;
|
||||
|
||||
case PORTS_HORIZON:
|
||||
case PORTS_PLANE:
|
||||
// not implemented yet
|
||||
|
||||
default:
|
||||
R_DrawSinglePlane(pl, OPAQUE, false, false);
|
||||
*freehead = pl;
|
||||
freehead = &pl->next;
|
||||
numskyboxes--;
|
||||
continue;
|
||||
}
|
||||
|
||||
port->mFlags |= PORTSF_INSKYBOX;
|
||||
if (port->mPartner > 0) sectorPortals[port->mPartner].mFlags |= PORTSF_INSKYBOX;
|
||||
camera = NULL;
|
||||
viewsector = port->mDestination;
|
||||
assert(viewsector != NULL);
|
||||
R_SetViewAngle ();
|
||||
validcount++; // Make sure we see all sprites
|
||||
|
||||
R_ClearPlanes (false);
|
||||
R_ClearClipSegs (pl->left, pl->right);
|
||||
WindowLeft = pl->left;
|
||||
WindowRight = pl->right;
|
||||
|
||||
for (i = pl->left; i < pl->right; i++)
|
||||
{
|
||||
if (pl->top[i] == 0x7fff)
|
||||
{
|
||||
ceilingclip[i] = viewheight;
|
||||
floorclip[i] = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
ceilingclip[i] = pl->top[i];
|
||||
floorclip[i] = pl->bottom[i];
|
||||
}
|
||||
}
|
||||
|
||||
// Create a drawseg to clip sprites to the sky plane
|
||||
drawseg_t *draw_segment = R_AddDrawSegment();
|
||||
draw_segment->CurrentPortalUniq = CurrentPortalUniq;
|
||||
draw_segment->siz1 = INT_MAX;
|
||||
draw_segment->siz2 = INT_MAX;
|
||||
draw_segment->sz1 = 0;
|
||||
draw_segment->sz2 = 0;
|
||||
draw_segment->x1 = pl->left;
|
||||
draw_segment->x2 = pl->right;
|
||||
draw_segment->silhouette = SIL_BOTH;
|
||||
draw_segment->sprbottomclip = R_NewOpening (pl->right - pl->left);
|
||||
draw_segment->sprtopclip = R_NewOpening (pl->right - pl->left);
|
||||
draw_segment->maskedtexturecol = ds_p->swall = -1;
|
||||
draw_segment->bFogBoundary = false;
|
||||
draw_segment->curline = NULL;
|
||||
draw_segment->fake = 0;
|
||||
memcpy (openings + draw_segment->sprbottomclip, floorclip + pl->left, (pl->right - pl->left)*sizeof(short));
|
||||
memcpy (openings + draw_segment->sprtopclip, ceilingclip + pl->left, (pl->right - pl->left)*sizeof(short));
|
||||
|
||||
firstvissprite = vissprite_p;
|
||||
firstdrawseg = draw_segment;
|
||||
FirstInterestingDrawseg = InterestingDrawsegs.Size();
|
||||
|
||||
interestingStack.Push (FirstInterestingDrawseg);
|
||||
ptrdiff_t diffnum = firstdrawseg - drawsegs;
|
||||
drawsegStack.Push (diffnum);
|
||||
diffnum = firstvissprite - vissprites;
|
||||
visspriteStack.Push (diffnum);
|
||||
viewposStack.Push(ViewPos);
|
||||
visplaneStack.Push (pl);
|
||||
|
||||
InSubsector = NULL;
|
||||
R_RenderBSPNode (nodes + numnodes - 1);
|
||||
R_3D_ResetClip(); // reset clips (floor/ceiling)
|
||||
R_DrawPlanes ();
|
||||
|
||||
port->mFlags &= ~PORTSF_INSKYBOX;
|
||||
if (port->mPartner > 0) sectorPortals[port->mPartner].mFlags &= ~PORTSF_INSKYBOX;
|
||||
}
|
||||
|
||||
// Draw all the masked textures in a second pass, in the reverse order they
|
||||
// were added. This must be done separately from the previous step for the
|
||||
// sake of nested skyboxes.
|
||||
while (interestingStack.Pop (FirstInterestingDrawseg))
|
||||
{
|
||||
ptrdiff_t pd = 0;
|
||||
|
||||
drawsegStack.Pop (pd);
|
||||
firstdrawseg = drawsegs + pd;
|
||||
visspriteStack.Pop (pd);
|
||||
firstvissprite = vissprites + pd;
|
||||
|
||||
// Masked textures and planes need the view coordinates restored for proper positioning.
|
||||
viewposStack.Pop(ViewPos);
|
||||
|
||||
R_DrawMasked ();
|
||||
|
||||
ds_p = firstdrawseg;
|
||||
vissprite_p = firstvissprite;
|
||||
|
||||
visplaneStack.Pop (pl);
|
||||
if (pl->Alpha > 0 && pl->picnum != skyflatnum)
|
||||
{
|
||||
R_DrawSinglePlane (pl, pl->Alpha, pl->Additive, true);
|
||||
}
|
||||
*freehead = pl;
|
||||
freehead = &pl->next;
|
||||
}
|
||||
firstvissprite = vissprites;
|
||||
vissprite_p = vissprites + savedvissprite_p;
|
||||
firstdrawseg = drawsegs;
|
||||
ds_p = drawsegs + savedds_p;
|
||||
InterestingDrawsegs.Resize ((unsigned int)FirstInterestingDrawseg);
|
||||
FirstInterestingDrawseg = savedinteresting;
|
||||
|
||||
camera = savedcamera;
|
||||
viewsector = savedsector;
|
||||
ViewPos = savedpos;
|
||||
R_SetVisibility(savedvisibility);
|
||||
extralight = savedextralight;
|
||||
ViewAngle = savedangle;
|
||||
R_SetViewAngle ();
|
||||
|
||||
CurrentPortalInSkybox = false;
|
||||
R_3D_LeaveSkybox();
|
||||
|
||||
if(fakeActive) return;
|
||||
|
||||
for (*freehead = visplanes[MAXVISPLANES], visplanes[MAXVISPLANES] = NULL; *freehead; )
|
||||
freehead = &(*freehead)->next;
|
||||
}
|
||||
|
||||
ADD_STAT(skyboxes)
|
||||
{
|
||||
FString out;
|
||||
out.Format ("%d skybox planes", numskyboxes);
|
||||
return out;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// R_DrawSkyPlane
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue