Example #1
0
bool HWPlaneMirrorPortal::Setup(HWDrawInfo *di, FRenderState &rstate, Clipper *clipper)
{
	auto state = mState;
	if (state->renderdepth > r_mirror_recursions)
	{
		return false;
	}
	// A plane mirror needs to flip the portal exclusion logic because inside the mirror, up is down and down is up.
	std::swap(screen->instack[sector_t::floor], screen->instack[sector_t::ceiling]);

	auto &vp = di->Viewpoint;
	old_pm = state->PlaneMirrorMode;

	// the player is always visible in a mirror.
	vp.showviewer = true;

	double planez = origin->ZatPoint(vp.Pos);
	vp.Pos.Z = 2 * planez - vp.Pos.Z;
	vp.ViewActor = nullptr;
	state->PlaneMirrorMode = origin->fC() < 0 ? -1 : 1;

	state->PlaneMirrorFlag++;
	di->SetClipHeight(planez, state->PlaneMirrorMode < 0 ? -1.f : 1.f);
	di->SetupView(rstate, vp.Pos.X, vp.Pos.Y, vp.Pos.Z, !!(state->MirrorFlag & 1), !!(state->PlaneMirrorFlag & 1));
	ClearClipper(di, clipper);

	di->UpdateCurrentMapSection();
	return true;
}
Example #2
0
void GLPlaneMirrorPortal::DrawContents()
{
	if (renderdepth>r_mirror_recursions) 
	{
		ClearScreen();
		return;
	}

	int old_pm=PlaneMirrorMode;

	fixed_t planez = origin->ZatPoint(viewx, viewy);
	viewz = 2*planez - viewz;
	GLRenderer->mViewActor = NULL;
	PlaneMirrorMode = ksgn(origin->c);

	validcount++;

	PlaneMirrorFlag++;
	GLRenderer->SetupView(viewx, viewy, viewz, viewangle, !!(MirrorFlag&1), !!(PlaneMirrorFlag&1));
	ClearClipper();

	glEnable(GL_CLIP_PLANE0+renderdepth);
	// This only works properly for non-sloped planes so don't bother with the math.
	//double d[4]={origin->a/65536., origin->c/65536., origin->b/65536., FIXED2FLOAT(origin->d)};
	double d[4]={0, static_cast<double>(PlaneMirrorMode), 0, FIXED2FLOAT(origin->d)};
	glClipPlane(GL_CLIP_PLANE0+renderdepth, d);

	GLRenderer->DrawScene();
	glDisable(GL_CLIP_PLANE0+renderdepth);
	PlaneMirrorFlag--;
	PlaneMirrorMode=old_pm;
}
Example #3
0
void GLPlaneMirrorPortal::DrawContents()
{
	if (renderdepth>r_mirror_recursions) 
	{
		ClearScreen();
		return;
	}

	int old_pm=PlaneMirrorMode;

	double planez = origin->ZatPoint(ViewPos);
	ViewPos.Z = 2 * planez - ViewPos.Z;
	GLRenderer->mViewActor = NULL;
	PlaneMirrorMode = origin->fC() < 0 ? -1 : 1;
	
	PlaneMirrorFlag++;
	GLRenderer->SetupView(ViewPos.X, ViewPos.Y, ViewPos.Z, ViewAngle, !!(MirrorFlag&1), !!(PlaneMirrorFlag&1));
	ClearClipper();

	gl_RenderState.SetClipHeight(planez, PlaneMirrorMode < 0? -1.f : 1.f);
	GLRenderer->DrawScene(DM_PORTAL);
	gl_RenderState.SetClipHeight(0.f, 0.f);
	PlaneMirrorFlag--;
	PlaneMirrorMode=old_pm;
}
Example #4
0
//-----------------------------------------------------------------------------
//
// GLSectorStackPortal::DrawContents
//
//-----------------------------------------------------------------------------
bool HWSectorStackPortal::Setup(HWDrawInfo *di, FRenderState &rstate, Clipper *clipper)
{
	auto state = mState;
	FSectorPortalGroup *portal = origin;
	auto &vp = di->Viewpoint;

	vp.Pos += origin->mDisplacement;
	vp.ActorPos += origin->mDisplacement;
	vp.ViewActor = nullptr;

	// avoid recursions!
	if (origin->plane != -1) screen->instack[origin->plane]++;

	di->SetupView(rstate, vp.Pos.X, vp.Pos.Y, vp.Pos.Z, !!(state->MirrorFlag & 1), !!(state->PlaneMirrorFlag & 1));
	SetupCoverage(di);
	ClearClipper(di, clipper);

	// If the viewpoint is not within the portal, we need to invalidate the entire clip area.
	// The portal will re-validate the necessary parts when its subsectors get traversed.
	subsector_t *sub = di->Level->PointInRenderSubsector(vp.Pos);
	if (!(di->ss_renderflags[sub->Index()] & SSRF_SEEN))
	{
		clipper->SafeAddClipRange(0, ANGLE_MAX);
		clipper->SetBlocked(true);
	}
	return true;
}
Example #5
0
//-----------------------------------------------------------------------------
//
// GLSectorStackPortal::DrawContents
//
//-----------------------------------------------------------------------------
void GLSectorStackPortal::DrawContents()
{
	FPortal *portal = origin;

	ViewPos += origin->mDisplacement;
	GLRenderer->mViewActor = NULL;

	// avoid recursions!
	if (origin->plane != -1) instack[origin->plane]++;

	GLRenderer->SetupView(ViewPos.X, ViewPos.Y, ViewPos.Z, ViewAngle, !!(MirrorFlag&1), !!(PlaneMirrorFlag&1));
	SaveMapSection();
	SetupCoverage();
	ClearClipper();
	
	// If the viewpoint is not within the portal, we need to invalidate the entire clip area.
	// The portal will re-validate the necessary parts when its subsectors get traversed.
	subsector_t *sub = R_PointInSubsector(ViewPos);
	if (!(gl_drawinfo->ss_renderflags[sub - ::subsectors] & SSRF_SEEN))
	{
		clipper.SafeAddClipRange(0, ANGLE_MAX);
		clipper.SetBlocked(true);
	}

	GLRenderer->DrawScene(DM_PORTAL);
	RestoreMapSection();

	if (origin->plane != -1) instack[origin->plane]--;
}
Example #6
0
//-----------------------------------------------------------------------------
//
//
//
//-----------------------------------------------------------------------------
void GLLineToLinePortal::DrawContents()
{
	// TODO: Handle recursion more intelligently
	if (renderdepth>r_mirror_recursions) 
	{
		ClearScreen();
		return;
	}

	GLRenderer->mClipPortal = this;

	line_t *origin = glport->lines[0]->mOrigin;
	P_TranslatePortalXY(origin, ViewPos.X, ViewPos.Y);
	P_TranslatePortalAngle(origin, ViewAngle);
	P_TranslatePortalZ(origin, ViewPos.Z);
	P_TranslatePortalXY(origin, ViewPath[0].X, ViewPath[0].Y);
	P_TranslatePortalXY(origin, ViewPath[1].X, ViewPath[1].Y);
	if (!r_showviewer && camera != nullptr && P_PointOnLineSidePrecise(ViewPath[0], glport->lines[0]->mDestination) != P_PointOnLineSidePrecise(ViewPath[1], glport->lines[0]->mDestination))
	{
		double distp = (ViewPath[0] - ViewPath[1]).Length();
		if (distp > EQUAL_EPSILON)
		{
			double dist1 = (ViewPos - ViewPath[0]).Length();
			double dist2 = (ViewPos - ViewPath[1]).Length();

			if (dist1 + dist2 < distp + 1)
			{
				camera->renderflags |= RF_INVISIBLE;
			}
		}
	}


	SaveMapSection();

	for (unsigned i = 0; i < lines.Size(); i++)
	{
		line_t *line = lines[i].seg->linedef->getPortalDestination();
		subsector_t *sub;
		if (line->sidedef[0]->Flags & WALLF_POLYOBJ) 
			sub = R_PointInSubsector(line->v1->fixX(), line->v1->fixY());
		else sub = line->frontsector->subsectors[0];
		int mapsection = sub->mapsection;
		currentmapsection[mapsection >> 3] |= 1 << (mapsection & 7);
	}

	GLRenderer->mViewActor = nullptr;
	GLRenderer->SetupView(ViewPos.X, ViewPos.Y, ViewPos.Z, ViewAngle, !!(MirrorFlag&1), !!(PlaneMirrorFlag&1));

	ClearClipper();
	gl_RenderState.SetClipLine(glport->lines[0]->mDestination);
	gl_RenderState.EnableClipLine(true);
	GLRenderer->DrawScene(DM_PORTAL);
	gl_RenderState.EnableClipLine(false);
	RestoreMapSection();
}
Example #7
0
void GLSkyboxPortal::DrawContents()
{
	int old_pm=PlaneMirrorMode;
	int saved_extralight = extralight;

	if (skyboxrecursion>=3)
	{
		ClearScreen();
		return;
	}

	skyboxrecursion++;
	origin->flags|=MF_JUSTHIT;
	extralight = 0;

	PlaneMirrorMode=0;

	glDisable(GL_DEPTH_CLAMP_NV);

	viewx = origin->PrevX + FixedMul(r_TicFrac, origin->x - origin->PrevX);
	viewy = origin->PrevY + FixedMul(r_TicFrac, origin->y - origin->PrevY);
	viewz = origin->PrevZ + FixedMul(r_TicFrac, origin->z - origin->PrevZ);
	viewangle += origin->PrevAngle + FixedMul(r_TicFrac, origin->angle - origin->PrevAngle);

	// Don't let the viewpoint be too close to a floor or ceiling!
	fixed_t floorh = origin->Sector->floorplane.ZatPoint(origin->x, origin->y);
	fixed_t ceilh = origin->Sector->ceilingplane.ZatPoint(origin->x, origin->y);
	if (viewz<floorh+4*FRACUNIT) viewz=floorh+4*FRACUNIT;
	if (viewz>ceilh-4*FRACUNIT) viewz=ceilh-4*FRACUNIT;


	GLRenderer->mViewActor = origin;

	validcount++;
	inskybox=true;
	GLRenderer->SetupView(viewx, viewy, viewz, viewangle, !!(MirrorFlag&1), !!(PlaneMirrorFlag&1));
	GLRenderer->SetViewArea();
	ClearClipper();

	int mapsection = R_PointInSubsector(viewx, viewy)->mapsection;

	SaveMapSection();
	currentmapsection[mapsection>>3] |= 1 << (mapsection & 7);

	GLRenderer->DrawScene();
	origin->flags&=~MF_JUSTHIT;
	inskybox=false;
	glEnable(GL_DEPTH_CLAMP_NV);
	skyboxrecursion--;

	PlaneMirrorMode=old_pm;
	extralight = saved_extralight;

	RestoreMapSection();
}
Example #8
0
//-----------------------------------------------------------------------------
//
//
//
//-----------------------------------------------------------------------------
bool HWLineToLinePortal::Setup(HWDrawInfo *di, FRenderState &rstate, Clipper *clipper)
{
	// TODO: Handle recursion more intelligently
	auto &state = mState;
	if (state->renderdepth>r_mirror_recursions)
	{
		return false;
	}
	auto &vp = di->Viewpoint;
	di->mClipPortal = this;

	line_t *origin = glport->lines[0]->mOrigin;
	P_TranslatePortalXY(origin, vp.Pos.X, vp.Pos.Y);
	P_TranslatePortalXY(origin, vp.ActorPos.X, vp.ActorPos.Y);
	P_TranslatePortalAngle(origin, vp.Angles.Yaw);
	P_TranslatePortalZ(origin, vp.Pos.Z);
	P_TranslatePortalXY(origin, vp.Path[0].X, vp.Path[0].Y);
	P_TranslatePortalXY(origin, vp.Path[1].X, vp.Path[1].Y);
	if (!vp.showviewer && vp.camera != nullptr && P_PointOnLineSidePrecise(vp.Path[0], glport->lines[0]->mDestination) != P_PointOnLineSidePrecise(vp.Path[1], glport->lines[0]->mDestination))
	{
		double distp = (vp.Path[0] - vp.Path[1]).Length();
		if (distp > EQUAL_EPSILON)
		{
			double dist1 = (vp.Pos - vp.Path[0]).Length();
			double dist2 = (vp.Pos - vp.Path[1]).Length();

			if (dist1 + dist2 < distp + 1)
			{
				vp.camera->renderflags |= RF_MAYBEINVISIBLE;
			}
		}
	}


	for (unsigned i = 0; i < lines.Size(); i++)
	{
		line_t *line = lines[i].seg->linedef->getPortalDestination();
		subsector_t *sub;
		if (line->sidedef[0]->Flags & WALLF_POLYOBJ)
			sub = di->Level->PointInRenderSubsector(line->v1->fixX(), line->v1->fixY());
		else sub = line->frontsector->subsectors[0];
		di->CurrentMapSections.Set(sub->mapsection);
	}

	vp.ViewActor = nullptr;
	di->SetClipLine(glport->lines[0]->mDestination);
	di->SetupView(rstate, vp.Pos.X, vp.Pos.Y, vp.Pos.Z, !!(state->MirrorFlag & 1), !!(state->PlaneMirrorFlag & 1));

	ClearClipper(di, clipper);
	return true;
}
Example #9
0
void GLSkyboxPortal::DrawContents()
{
	int old_pm = PlaneMirrorMode;
	int saved_extralight = extralight;

	if (skyboxrecursion >= 3)
	{
		ClearScreen();
		return;
	}

	skyboxrecursion++;
	AActor *origin = portal->mSkybox;
	portal->mFlags |= PORTSF_INSKYBOX;
	extralight = 0;

	PlaneMirrorMode = 0;

	bool oldclamp = gl_RenderState.SetDepthClamp(false);
	ViewPos = origin->InterpolatedPosition(r_TicFracF);
	ViewAngle += (origin->PrevAngles.Yaw + deltaangle(origin->PrevAngles.Yaw, origin->Angles.Yaw) * r_TicFracF);

	// Don't let the viewpoint be too close to a floor or ceiling
	double floorh = origin->Sector->floorplane.ZatPoint(origin->Pos());
	double ceilh = origin->Sector->ceilingplane.ZatPoint(origin->Pos());
	if (ViewPos.Z < floorh + 4) ViewPos.Z = floorh + 4;
	if (ViewPos.Z > ceilh - 4) ViewPos.Z = ceilh - 4;

	GLRenderer->mViewActor = origin;

	inskybox = true;
	GLRenderer->SetupView(ViewPos.X, ViewPos.Y, ViewPos.Z, ViewAngle, !!(MirrorFlag & 1), !!(PlaneMirrorFlag & 1));
	GLRenderer->SetViewArea();
	ClearClipper();

	int mapsection = R_PointInSubsector(ViewPos)->mapsection;

	SaveMapSection();
	currentmapsection[mapsection >> 3] |= 1 << (mapsection & 7);

	GLRenderer->DrawScene(DM_PORTAL);
	portal->mFlags &= ~PORTSF_INSKYBOX;
	inskybox = false;
	gl_RenderState.SetDepthClamp(oldclamp);
	skyboxrecursion--;

	PlaneMirrorMode = old_pm;
	extralight = saved_extralight;

	RestoreMapSection();
}
Example #10
0
bool HWSkyboxPortal::Setup(HWDrawInfo *di, FRenderState &rstate, Clipper *clipper)
{
	auto state = mState;
	old_pm = state->PlaneMirrorMode;

	if (mState->skyboxrecursion >= 3)
	{
		return false;
	}
	auto &vp = di->Viewpoint;

	state->skyboxrecursion++;
	state->PlaneMirrorMode = 0;
	state->inskybox = true;

	AActor *origin = portal->mSkybox;
	portal->mFlags |= PORTSF_INSKYBOX;
	vp.extralight = 0;

	oldclamp = rstate.SetDepthClamp(false);
	vp.Pos = origin->InterpolatedPosition(vp.TicFrac);
	vp.ActorPos = origin->Pos();
	vp.Angles.Yaw += (origin->PrevAngles.Yaw + deltaangle(origin->PrevAngles.Yaw, origin->Angles.Yaw) * vp.TicFrac);

	// Don't let the viewpoint be too close to a floor or ceiling
	double floorh = origin->Sector->floorplane.ZatPoint(origin->Pos());
	double ceilh = origin->Sector->ceilingplane.ZatPoint(origin->Pos());
	if (vp.Pos.Z < floorh + 4) vp.Pos.Z = floorh + 4;
	if (vp.Pos.Z > ceilh - 4) vp.Pos.Z = ceilh - 4;

	vp.ViewActor = origin;

	di->SetupView(rstate, vp.Pos.X, vp.Pos.Y, vp.Pos.Z, !!(state->MirrorFlag & 1), !!(state->PlaneMirrorFlag & 1));
	di->SetViewArea();
	ClearClipper(di, clipper);
	di->UpdateCurrentMapSection();
	return true;
}
Example #11
0
//-----------------------------------------------------------------------------
//
// GLSectorStackPortal::DrawContents
//
//-----------------------------------------------------------------------------
void GLSectorStackPortal::DrawContents()
{
	FPortal *portal = origin;

	viewx += origin->xDisplacement;
	viewy += origin->yDisplacement;
	GLRenderer->mViewActor = NULL;
	GLRenderer->mCurrentPortal = this;


	validcount++;

	// avoid recursions!
	if (origin->plane != -1) instack[origin->plane]++;

	GLRenderer->SetupView(viewx, viewy, viewz, viewangle, !!(MirrorFlag&1), !!(PlaneMirrorFlag&1));
	SaveMapSection();
	SetupCoverage();
	ClearClipper();
	GLRenderer->DrawScene();
	RestoreMapSection();

	if (origin->plane != -1) instack[origin->plane]--;
}