Exemple #1
0
void FSoftwareRenderer::ErrorCleanup ()
{
	fakeActive = 0;
	fake3D = 0;
	while (CurrentSkybox)
	{
		R_3D_DeleteHeights();
		R_3D_LeaveSkybox();
	}
	R_3D_ResetClip();
	R_3D_DeleteHeights();
}
Exemple #2
0
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;
	ptrdiff_t savedlastopening = lastopening;
	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
		R_CheckDrawSegs ();
		ds_p->CurrentPortalUniq = CurrentPortalUniq;
		ds_p->siz1 = INT_MAX;
		ds_p->siz2 = INT_MAX;
		ds_p->sz1 = 0;
		ds_p->sz2 = 0;
		ds_p->x1 = pl->left;
		ds_p->x2 = pl->right;
		ds_p->silhouette = SIL_BOTH;
		ds_p->sprbottomclip = R_NewOpening (pl->right - pl->left);
		ds_p->sprtopclip = R_NewOpening (pl->right - pl->left);
		ds_p->maskedtexturecol = ds_p->swall = -1;
		ds_p->bFogBoundary = false;
		ds_p->curline = NULL;
		ds_p->fake = 0;
		memcpy (openings + ds_p->sprbottomclip, floorclip + pl->left, (pl->right - pl->left)*sizeof(short));
		memcpy (openings + ds_p->sprtopclip, ceilingclip + pl->left, (pl->right - pl->left)*sizeof(short));

		firstvissprite = vissprite_p;
		firstdrawseg = ds_p++;
		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;

	lastopening = savedlastopening;

	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;
}