- use locally stored viewpoint variables in the hardware renderer.

- move a few variables from SceneDrawer to FRenderViewpoint.

The global r_viewpoint variable is left alone now to always represent the current viewpoint to the play code.
The main reason behind this change is to reduce the amount of global variables being used by the hardware renderer's scene processing code.
This commit is contained in:
Christoph Oelckers 2018-06-19 23:16:22 +02:00
parent d2309af3d5
commit 54970b60e8
26 changed files with 221 additions and 217 deletions

View File

@ -89,7 +89,6 @@ FGLRenderer::FGLRenderer(OpenGLFrameBuffer *fb)
mCurrentPortal = nullptr;
mMirrorCount = 0;
mPlaneMirrorCount = 0;
mAngles = FRotator(0.f, 0.f, 0.f);
mVBO = nullptr;
mSkyVBO = nullptr;
mShaderManager = nullptr;
@ -326,7 +325,7 @@ sector_t *FGLRenderer::RenderView(player_t* player)
GLSceneDrawer drawer;
mShadowMap.Update();
retsec = drawer.RenderViewpoint(player->camera, NULL, r_viewpoint.FieldOfView.Degrees, ratio, fovratio, true, true);
retsec = drawer.RenderViewpoint(r_viewpoint, player->camera, NULL, r_viewpoint.FieldOfView.Degrees, ratio, fovratio, true, true);
}
All.Unclock();
return retsec;
@ -354,7 +353,8 @@ void FGLRenderer::RenderTextureView(FCanvasTexture *tex, AActor *Viewpoint, doub
bounds.height = FHardwareTexture::GetTexDimension(gltex->GetHeight());
GLSceneDrawer drawer;
drawer.RenderViewpoint(Viewpoint, &bounds, FOV, (float)width / height, (float)width / height, false, false);
FRenderViewpoint texvp;
drawer.RenderViewpoint(texvp, Viewpoint, &bounds, FOV, (float)width / height, (float)width / height, false, false);
EndOffscreen();

View File

@ -69,7 +69,6 @@ public:
GLPortal *mCurrentPortal;
int mMirrorCount;
int mPlaneMirrorCount;
float mCurrentFoV;
FShaderManager *mShaderManager;
FSamplerManager *mSamplerManager;
unsigned int mFBID;
@ -104,7 +103,7 @@ public:
FShadowMap mShadowMap;
FRotator mAngles;
//FRotator mAngles;
FFlatVertexBuffer *mVBO;
FSkyVertexBuffer *mSkyVBO;

View File

@ -63,7 +63,7 @@ void FDrawInfo::DoDrawSorted(HWDrawList *dl, SortNode * head)
if (dl->drawitems[head->itemindex].rendertype == GLDIT_FLAT)
{
z = dl->flats[dl->drawitems[head->itemindex].index]->z;
relation = z > r_viewpoint.Pos.Z ? 1 : -1;
relation = z > Viewpoint.Pos.Z ? 1 : -1;
}
@ -190,13 +190,14 @@ FDrawInfo::~FDrawInfo()
// OpenGL has no use for multiple clippers so use the same one for all DrawInfos.
static Clipper staticClipper;
FDrawInfo *FDrawInfo::StartDrawInfo(GLSceneDrawer *drawer)
FDrawInfo *FDrawInfo::StartDrawInfo(GLSceneDrawer *drawer, FRenderViewpoint &parentvp)
{
FDrawInfo *di=di_list.GetNew();
di->mDrawer = drawer;
di->mVBO = GLRenderer->mVBO;
di->mClipper = &staticClipper;
di->mClipper->SetViewpoint(r_viewpoint);
di->Viewpoint = parentvp;
di->mClipper->SetViewpoint(di->Viewpoint);
staticClipper.Clear();
di->StartScene();
return di;
@ -224,7 +225,7 @@ void FDrawInfo::StartScene()
//
//
//==========================================================================
void FDrawInfo::EndDrawInfo()
FDrawInfo *FDrawInfo::EndDrawInfo()
{
FDrawInfo * di = gl_drawinfo;
@ -233,6 +234,7 @@ void FDrawInfo::EndDrawInfo()
di_list.Release(di);
if (gl_drawinfo == nullptr)
ResetRenderDataAllocator();
return gl_drawinfo;
}
@ -342,9 +344,9 @@ void FDrawInfo::DrawFloodedPlane(wallseg * ws, float planez, sector_t * sec, boo
SetFog(lightlevel, rel, &Colormap, false);
gl_RenderState.SetMaterial(gltexture, CLAMP_NONE, 0, -1, false);
float fviewx = r_viewpoint.Pos.X;
float fviewy = r_viewpoint.Pos.Y;
float fviewz = r_viewpoint.Pos.Z;
float fviewx = Viewpoint.Pos.X;
float fviewy = Viewpoint.Pos.Y;
float fviewz = Viewpoint.Pos.Z;
gl_RenderState.SetPlaneTextureRotation(&plane, gltexture);
gl_RenderState.Apply();
@ -395,7 +397,7 @@ void FDrawInfo::FloodUpperGap(seg_t * seg)
double frontz = fakefsector->ceilingplane.ZatPoint(seg->v1);
if (fakebsector->GetTexture(sector_t::ceiling)==skyflatnum) return;
if (backz < r_viewpoint.Pos.Z) return;
if (backz < Viewpoint.Pos.Z) return;
if (seg->sidedef == seg->linedef->sidedef[0])
{
@ -448,7 +450,7 @@ void FDrawInfo::FloodLowerGap(seg_t * seg)
if (fakebsector->GetTexture(sector_t::floor) == skyflatnum) return;
if (fakebsector->GetPlaneTexZ(sector_t::floor) > r_viewpoint.Pos.Z) return;
if (fakebsector->GetPlaneTexZ(sector_t::floor) > Viewpoint.Pos.Z) return;
if (seg->sidedef == seg->linedef->sidedef[0])
{

View File

@ -106,8 +106,8 @@ struct FDrawInfo : public HWDrawInfo
void ProcessLowerMinisegs(TArray<seg_t *> &lowersegs) override;
void AddSubsectorToPortal(FSectorPortalGroup *portal, subsector_t *sub) override;
static FDrawInfo *StartDrawInfo(GLSceneDrawer *drawer);
static void EndDrawInfo();
static FDrawInfo *StartDrawInfo(GLSceneDrawer *drawer, FRenderViewpoint &parentvp);
FDrawInfo *EndDrawInfo();
gl_subsectorrendernode * GetOtherFloorPlanes(unsigned int sector)
{

View File

@ -228,7 +228,7 @@ bool GLPortal::Start(bool usestencil, bool doquery, FDrawInfo *outer_di, FDrawIn
return false;
}
}
*pDi = FDrawInfo::StartDrawInfo(drawer);
*pDi = FDrawInfo::StartDrawInfo(drawer, outer_di->Viewpoint);
}
else
{
@ -257,7 +257,7 @@ bool GLPortal::Start(bool usestencil, bool doquery, FDrawInfo *outer_di, FDrawIn
{
if (NeedDepthBuffer())
{
*pDi = FDrawInfo::StartDrawInfo(drawer);
*pDi = FDrawInfo::StartDrawInfo(drawer, outer_di->Viewpoint);
}
else
{
@ -268,8 +268,7 @@ bool GLPortal::Start(bool usestencil, bool doquery, FDrawInfo *outer_di, FDrawIn
}
// save viewpoint
savedviewpoint = r_viewpoint;
savedvisibility = r_viewpoint.camera ? r_viewpoint.camera->renderflags & RF_MAYBEINVISIBLE : ActorRenderFlags::FromInt(0);
savedvisibility = outer_di->Viewpoint.camera ? outer_di->Viewpoint.camera->renderflags & RF_MAYBEINVISIBLE : ActorRenderFlags::FromInt(0);
PrevPortal = GLRenderer->mCurrentPortal;
@ -282,8 +281,8 @@ bool GLPortal::Start(bool usestencil, bool doquery, FDrawInfo *outer_di, FDrawIn
inline void GLPortal::ClearClipper(FDrawInfo *di)
{
FRenderViewpoint &oldvp = savedviewpoint;
DAngle angleOffset = deltaangle(oldvp.Angles.Yaw, r_viewpoint.Angles.Yaw);
auto outer_di = di->next;
DAngle angleOffset = deltaangle(outer_di->Viewpoint.Angles.Yaw, di->Viewpoint.Angles.Yaw);
di->mClipper->Clear();
@ -291,8 +290,8 @@ inline void GLPortal::ClearClipper(FDrawInfo *di)
di->mClipper->SafeAddClipRange(0,0xffffffff);
for (unsigned int i = 0; i < lines.Size(); i++)
{
DAngle startAngle = (DVector2(lines[i].glseg.x2, lines[i].glseg.y2) - oldvp.Pos).Angle() + angleOffset;
DAngle endAngle = (DVector2(lines[i].glseg.x1, lines[i].glseg.y1) - oldvp.Pos).Angle() + angleOffset;
DAngle startAngle = (DVector2(lines[i].glseg.x2, lines[i].glseg.y2) - outer_di->Viewpoint.Pos).Angle() + angleOffset;
DAngle endAngle = (DVector2(lines[i].glseg.x1, lines[i].glseg.y1) - outer_di->Viewpoint.Pos).Angle() + angleOffset;
if (deltaangle(endAngle, startAngle) < 0)
{
@ -301,8 +300,8 @@ inline void GLPortal::ClearClipper(FDrawInfo *di)
}
// and finally clip it to the visible area
angle_t a1 = drawer->FrustumAngle();
if (a1 < ANGLE_180) di->mClipper->SafeAddClipRangeRealAngles(r_viewpoint.Angles.Yaw.BAMs() + a1, r_viewpoint.Angles.Yaw.BAMs() - a1);
angle_t a1 = di->FrustumAngle();
if (a1 < ANGLE_180) di->mClipper->SafeAddClipRangeRealAngles(di->Viewpoint.Angles.Yaw.BAMs() + a1, di->Viewpoint.Angles.Yaw.BAMs() - a1);
// lock the parts that have just been clipped out.
di->mClipper->SetSilhouette();
@ -313,7 +312,7 @@ inline void GLPortal::ClearClipper(FDrawInfo *di)
// End
//
//-----------------------------------------------------------------------------
void GLPortal::End(bool usestencil)
void GLPortal::End(FDrawInfo *di, bool usestencil)
{
bool needdepth = NeedDepthBuffer();
@ -323,12 +322,12 @@ void GLPortal::End(bool usestencil)
if (usestencil)
{
if (needdepth) FDrawInfo::EndDrawInfo();
if (needdepth) di = di->EndDrawInfo();
auto &vp = di->Viewpoint;
// Restore the old view
r_viewpoint = savedviewpoint;
if (r_viewpoint.camera != nullptr) r_viewpoint.camera->renderflags = (r_viewpoint.camera->renderflags & ~RF_MAYBEINVISIBLE) | savedvisibility;
drawer->SetupView(r_viewpoint.Pos.X, r_viewpoint.Pos.Y, r_viewpoint.Pos.Z, r_viewpoint.Angles.Yaw, !!(MirrorFlag & 1), !!(PlaneMirrorFlag & 1));
if (vp.camera != nullptr) vp.camera->renderflags = (vp.camera->renderflags & ~RF_MAYBEINVISIBLE) | savedvisibility;
drawer->SetupView(vp, vp.Pos.X, vp.Pos.Y, vp.Pos.Z, vp.Angles.Yaw, !!(MirrorFlag & 1), !!(PlaneMirrorFlag & 1));
{
ScopedColorMask colorMask(0, 0, 0, 0); // glColorMask(0, 0, 0, 0); // no graphics
@ -371,7 +370,7 @@ void GLPortal::End(bool usestencil)
{
if (needdepth)
{
FDrawInfo::EndDrawInfo();
di = di->EndDrawInfo();
glClear(GL_DEPTH_BUFFER_BIT);
}
else
@ -379,10 +378,11 @@ void GLPortal::End(bool usestencil)
glEnable(GL_DEPTH_TEST);
glDepthMask(true);
}
auto &vp = di->Viewpoint;
// Restore the old view
r_viewpoint = savedviewpoint;
if (r_viewpoint.camera != nullptr) r_viewpoint.camera->renderflags |= savedvisibility;
drawer->SetupView(r_viewpoint.Pos.X, r_viewpoint.Pos.Y, r_viewpoint.Pos.Z, r_viewpoint.Angles.Yaw, !!(MirrorFlag&1), !!(PlaneMirrorFlag&1));
if (vp.camera != nullptr) vp.camera->renderflags = (vp.camera->renderflags & ~RF_MAYBEINVISIBLE) | savedvisibility;
drawer->SetupView(vp, vp.Pos.X, vp.Pos.Y, vp.Pos.Z, vp.Angles.Yaw, !!(MirrorFlag & 1), !!(PlaneMirrorFlag & 1));
// This draws a valid z-buffer into the stencil's contents to ensure it
// doesn't get overwritten by the level's geometry.
@ -560,36 +560,36 @@ GLPortal * GLPortal::FindPortal(const void * src)
void GLSkyboxPortal::DrawContents(FDrawInfo *di)
{
int old_pm = PlaneMirrorMode;
int saved_extralight = r_viewpoint.extralight;
if (skyboxrecursion >= 3)
{
ClearScreen();
return;
}
auto &vp = di->Viewpoint;
skyboxrecursion++;
AActor *origin = portal->mSkybox;
portal->mFlags |= PORTSF_INSKYBOX;
r_viewpoint.extralight = 0;
vp.extralight = 0;
PlaneMirrorMode = 0;
bool oldclamp = gl_RenderState.SetDepthClamp(false);
r_viewpoint.Pos = origin->InterpolatedPosition(r_viewpoint.TicFrac);
r_viewpoint.ActorPos = origin->Pos();
r_viewpoint.Angles.Yaw += (origin->PrevAngles.Yaw + deltaangle(origin->PrevAngles.Yaw, origin->Angles.Yaw) * r_viewpoint.TicFrac);
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 (r_viewpoint.Pos.Z < floorh + 4) r_viewpoint.Pos.Z = floorh + 4;
if (r_viewpoint.Pos.Z > ceilh - 4) r_viewpoint.Pos.Z = ceilh - 4;
if (vp.Pos.Z < floorh + 4) vp.Pos.Z = floorh + 4;
if (vp.Pos.Z > ceilh - 4) vp.Pos.Z = ceilh - 4;
r_viewpoint.ViewActor = origin;
vp.ViewActor = origin;
inskybox = true;
drawer->SetupView(r_viewpoint.Pos.X, r_viewpoint.Pos.Y, r_viewpoint.Pos.Z, r_viewpoint.Angles.Yaw, !!(MirrorFlag & 1), !!(PlaneMirrorFlag & 1));
drawer->SetupView(vp, vp.Pos.X, vp.Pos.Y, vp.Pos.Z, vp.Angles.Yaw, !!(MirrorFlag & 1), !!(PlaneMirrorFlag & 1));
di->SetViewArea();
ClearClipper(di);
@ -602,7 +602,6 @@ void GLSkyboxPortal::DrawContents(FDrawInfo *di)
skyboxrecursion--;
PlaneMirrorMode = old_pm;
r_viewpoint.extralight = saved_extralight;
}
//-----------------------------------------------------------------------------
@ -688,21 +687,22 @@ void GLSectorStackPortal::SetupCoverage(FDrawInfo *di)
void GLSectorStackPortal::DrawContents(FDrawInfo *di)
{
FSectorPortalGroup *portal = origin;
auto &vp = di->Viewpoint;
r_viewpoint.Pos += origin->mDisplacement;
r_viewpoint.ActorPos += origin->mDisplacement;
r_viewpoint.ViewActor = nullptr;
vp.Pos += origin->mDisplacement;
vp.ActorPos += origin->mDisplacement;
vp.ViewActor = nullptr;
// avoid recursions!
if (origin->plane != -1) screen->instack[origin->plane]++;
drawer->SetupView(r_viewpoint.Pos.X, r_viewpoint.Pos.Y, r_viewpoint.Pos.Z, r_viewpoint.Angles.Yaw, !!(MirrorFlag&1), !!(PlaneMirrorFlag&1));
drawer->SetupView(vp, vp.Pos.X, vp.Pos.Y, vp.Pos.Z, vp.Angles.Yaw, !!(MirrorFlag&1), !!(PlaneMirrorFlag&1));
SetupCoverage(di);
ClearClipper(di);
// 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(r_viewpoint.Pos);
subsector_t *sub = R_PointInSubsector(vp.Pos);
if (!(di->ss_renderflags[sub->Index()] & SSRF_SEEN))
{
di->mClipper->SafeAddClipRange(0, ANGLE_MAX);
@ -740,18 +740,19 @@ void GLPlaneMirrorPortal::DrawContents(FDrawInfo *di)
// 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;
int old_pm = PlaneMirrorMode;
// the player is always visible in a mirror.
r_viewpoint.showviewer = true;
vp.showviewer = true;
double planez = origin->ZatPoint(r_viewpoint.Pos);
r_viewpoint.Pos.Z = 2 * planez - r_viewpoint.Pos.Z;
r_viewpoint.ViewActor = nullptr;
double planez = origin->ZatPoint(vp.Pos);
vp.Pos.Z = 2 * planez - vp.Pos.Z;
vp.ViewActor = nullptr;
PlaneMirrorMode = origin->fC() < 0 ? -1 : 1;
PlaneMirrorFlag++;
drawer->SetupView(r_viewpoint.Pos.X, r_viewpoint.Pos.Y, r_viewpoint.Pos.Z, r_viewpoint.Angles.Yaw, !!(MirrorFlag & 1), !!(PlaneMirrorFlag & 1));
drawer->SetupView(vp, vp.Pos.X, vp.Pos.Y, vp.Pos.Z, vp.Angles.Yaw, !!(MirrorFlag & 1), !!(PlaneMirrorFlag & 1));
ClearClipper(di);
di->UpdateCurrentMapSection();
@ -808,14 +809,14 @@ void GLLinePortal::PopState()
gl_RenderState.EnableClipLine(e != 0);
}
int GLLinePortal::ClipSeg(seg_t *seg)
int GLLinePortal::ClipSeg(seg_t *seg, const DVector3 &viewpos)
{
line_t *linedef = seg->linedef;
if (!linedef)
{
return PClip_Inside; // should be handled properly.
}
return P_ClipLineToPortal(linedef, line(), r_viewpoint.Pos) ? PClip_InFront : PClip_Inside;
return P_ClipLineToPortal(linedef, line(), viewpos) ? PClip_InFront : PClip_Inside;
}
int GLLinePortal::ClipSubsector(subsector_t *sub)
@ -861,35 +862,36 @@ void GLMirrorPortal::DrawContents(FDrawInfo *di)
return;
}
auto &vp = di->Viewpoint;
di->UpdateCurrentMapSection();
di->mClipPortal = this;
DAngle StartAngle = r_viewpoint.Angles.Yaw;
DVector3 StartPos = r_viewpoint.Pos;
DAngle StartAngle = vp.Angles.Yaw;
DVector3 StartPos = vp.Pos;
vertex_t *v1 = linedef->v1;
vertex_t *v2 = linedef->v2;
// the player is always visible in a mirror.
r_viewpoint.showviewer = true;
vp.showviewer = true;
// Reflect the current view behind the mirror.
if (linedef->Delta().X == 0)
{
// vertical mirror
r_viewpoint.Pos.X = 2 * v1->fX() - StartPos.X;
vp.Pos.X = 2 * v1->fX() - StartPos.X;
// Compensation for reendering inaccuracies
if (StartPos.X < v1->fX()) r_viewpoint.Pos.X -= 0.1;
else r_viewpoint.Pos.X += 0.1;
if (StartPos.X < v1->fX()) vp.Pos.X -= 0.1;
else vp.Pos.X += 0.1;
}
else if (linedef->Delta().Y == 0)
{
// horizontal mirror
r_viewpoint.Pos.Y = 2*v1->fY() - StartPos.Y;
vp.Pos.Y = 2*v1->fY() - StartPos.Y;
// Compensation for reendering inaccuracies
if (StartPos.Y<v1->fY()) r_viewpoint.Pos.Y -= 0.1;
else r_viewpoint.Pos.Y += 0.1;
if (StartPos.Y<v1->fY()) vp.Pos.Y -= 0.1;
else vp.Pos.Y += 0.1;
}
else
{
@ -906,27 +908,27 @@ void GLMirrorPortal::DrawContents(FDrawInfo *di)
// the above two cases catch len == 0
double r = ((x - x1)*dx + (y - y1)*dy) / (dx*dx + dy*dy);
r_viewpoint.Pos.X = (x1 + r * dx)*2 - x;
r_viewpoint.Pos.Y = (y1 + r * dy)*2 - y;
vp.Pos.X = (x1 + r * dx)*2 - x;
vp.Pos.Y = (y1 + r * dy)*2 - y;
// Compensation for reendering inaccuracies
FVector2 v(-dx, dy);
v.MakeUnit();
r_viewpoint.Pos.X+= v[1] * renderdepth / 2;
r_viewpoint.Pos.Y+= v[0] * renderdepth / 2;
vp.Pos.X+= v[1] * renderdepth / 2;
vp.Pos.Y+= v[0] * renderdepth / 2;
}
r_viewpoint.Angles.Yaw = linedef->Delta().Angle() * 2. - StartAngle;
vp.Angles.Yaw = linedef->Delta().Angle() * 2. - StartAngle;
r_viewpoint.ViewActor = nullptr;
vp.ViewActor = nullptr;
MirrorFlag++;
drawer->SetupView(r_viewpoint.Pos.X, r_viewpoint.Pos.Y, r_viewpoint.Pos.Z, r_viewpoint.Angles.Yaw, !!(MirrorFlag&1), !!(PlaneMirrorFlag&1));
drawer->SetupView(vp, vp.Pos.X, vp.Pos.Y, vp.Pos.Z, vp.Angles.Yaw, !!(MirrorFlag&1), !!(PlaneMirrorFlag&1));
di->mClipper->Clear();
angle_t af = drawer->FrustumAngle();
if (af<ANGLE_180) di->mClipper->SafeAddClipRangeRealAngles(r_viewpoint.Angles.Yaw.BAMs()+af, r_viewpoint.Angles.Yaw.BAMs()-af);
angle_t af = di->FrustumAngle();
if (af<ANGLE_180) di->mClipper->SafeAddClipRangeRealAngles(vp.Angles.Yaw.BAMs()+af, vp.Angles.Yaw.BAMs()-af);
di->mClipper->SafeAddClipRange(linedef->v1, linedef->v2);
@ -961,27 +963,27 @@ void GLLineToLinePortal::DrawContents(FDrawInfo *di)
ClearScreen();
return;
}
auto &vp = di->Viewpoint;
di->mClipPortal = this;
line_t *origin = glport->lines[0]->mOrigin;
P_TranslatePortalXY(origin, r_viewpoint.Pos.X, r_viewpoint.Pos.Y);
P_TranslatePortalXY(origin, r_viewpoint.ActorPos.X, r_viewpoint.ActorPos.Y);
P_TranslatePortalAngle(origin, r_viewpoint.Angles.Yaw);
P_TranslatePortalZ(origin, r_viewpoint.Pos.Z);
P_TranslatePortalXY(origin, r_viewpoint.Path[0].X, r_viewpoint.Path[0].Y);
P_TranslatePortalXY(origin, r_viewpoint.Path[1].X, r_viewpoint.Path[1].Y);
if (!r_viewpoint.showviewer && r_viewpoint.camera != nullptr && P_PointOnLineSidePrecise(r_viewpoint.Path[0], glport->lines[0]->mDestination) != P_PointOnLineSidePrecise(r_viewpoint.Path[1], glport->lines[0]->mDestination))
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 = (r_viewpoint.Path[0] - r_viewpoint.Path[1]).Length();
double distp = (vp.Path[0] - vp.Path[1]).Length();
if (distp > EQUAL_EPSILON)
{
double dist1 = (r_viewpoint.Pos - r_viewpoint.Path[0]).Length();
double dist2 = (r_viewpoint.Pos - r_viewpoint.Path[1]).Length();
double dist1 = (vp.Pos - vp.Path[0]).Length();
double dist2 = (vp.Pos - vp.Path[1]).Length();
if (dist1 + dist2 < distp + 1)
{
r_viewpoint.camera->renderflags |= RF_MAYBEINVISIBLE;
vp.camera->renderflags |= RF_MAYBEINVISIBLE;
}
}
}
@ -997,8 +999,8 @@ void GLLineToLinePortal::DrawContents(FDrawInfo *di)
di->CurrentMapSections.Set(sub->mapsection);
}
r_viewpoint.ViewActor = nullptr;
drawer->SetupView(r_viewpoint.Pos.X, r_viewpoint.Pos.Y, r_viewpoint.Pos.Z, r_viewpoint.Angles.Yaw, !!(MirrorFlag&1), !!(PlaneMirrorFlag&1));
vp.ViewActor = nullptr;
drawer->SetupView(vp, vp.Pos.X, vp.Pos.Y, vp.Pos.Z, vp.Angles.Yaw, !!(MirrorFlag&1), !!(PlaneMirrorFlag&1));
ClearClipper(di);
gl_RenderState.SetClipLine(glport->lines[0]->mDestination);
@ -1034,16 +1036,16 @@ void GLLineToLinePortal::RenderAttached(FDrawInfo *di)
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
GLHorizonPortal::GLHorizonPortal(GLHorizonInfo * pt, bool local)
GLHorizonPortal::GLHorizonPortal(GLHorizonInfo * pt, FRenderViewpoint &vp, bool local)
: GLPortal(local)
{
origin = pt;
// create the vertex data for this horizon portal.
GLSectorPlane * sp = &origin->plane;
const float vx = r_viewpoint.Pos.X;
const float vy = r_viewpoint.Pos.Y;
const float vz = r_viewpoint.Pos.Z;
const float vx = vp.Pos.X;
const float vy = vp.Pos.Y;
const float vz = vp.Pos.Z;
const float z = sp->Texheight;
const float tz = (z - vz);
@ -1106,6 +1108,7 @@ void GLHorizonPortal::DrawContents(FDrawInfo *di)
PalEntry color;
player_t * player=&players[consoleplayer];
GLSectorPlane * sp = &origin->plane;
auto &vp = di->Viewpoint;
gltexture=FMaterial::ValidateTexture(sp->texture, false, true);
if (!gltexture)
@ -1113,7 +1116,7 @@ void GLHorizonPortal::DrawContents(FDrawInfo *di)
ClearScreen();
return;
}
gl_RenderState.SetCameraPos(r_viewpoint.Pos.X, r_viewpoint.Pos.Y, r_viewpoint.Pos.Z);
gl_RenderState.SetCameraPos(vp.Pos.X, vp.Pos.Y, vp.Pos.Z);
if (gltexture && gltexture->tex->isFullbright())
@ -1171,6 +1174,7 @@ void GLHorizonPortal::DrawContents(FDrawInfo *di)
void GLEEHorizonPortal::DrawContents(FDrawInfo *di)
{
auto &vp = di->Viewpoint;
sector_t *sector = portal->mOrigin;
if (sector->GetTexture(sector_t::floor) == skyflatnum ||
sector->GetTexture(sector_t::ceiling) == skyflatnum)
@ -1189,9 +1193,9 @@ void GLEEHorizonPortal::DrawContents(FDrawInfo *di)
horz.specialcolor = 0xffffffff;
if (portal->mType == PORTS_PLANE)
{
horz.plane.Texheight = r_viewpoint.Pos.Z + fabs(horz.plane.Texheight);
horz.plane.Texheight = vp.Pos.Z + fabs(horz.plane.Texheight);
}
GLHorizonPortal ceil(&horz, true);
GLHorizonPortal ceil(&horz, di->Viewpoint, true);
ceil.DrawContents(di);
}
if (sector->GetTexture(sector_t::floor) != skyflatnum)
@ -1203,9 +1207,9 @@ void GLEEHorizonPortal::DrawContents(FDrawInfo *di)
horz.specialcolor = 0xffffffff;
if (portal->mType == PORTS_PLANE)
{
horz.plane.Texheight = r_viewpoint.Pos.Z - fabs(horz.plane.Texheight);
horz.plane.Texheight = vp.Pos.Z - fabs(horz.plane.Texheight);
}
GLHorizonPortal floor(&horz, true);
GLHorizonPortal floor(&horz, di->Viewpoint, true);
floor.DrawContents(di);
}
}

View File

@ -72,7 +72,6 @@ private:
AActor * savedviewactor;
ActorRenderFlags savedvisibility;
FRenderViewpoint savedviewpoint;
GLPortal *PrevPortal;
TArray<unsigned int> mPrimIndices;
@ -84,7 +83,7 @@ protected:
virtual ~GLPortal() { }
bool Start(bool usestencil, bool doquery, FDrawInfo *outer_di, FDrawInfo **pDi);
void End(bool usestencil);
void End(FDrawInfo *di, bool usestencil);
virtual void DrawContents(FDrawInfo *di)=0;
virtual void * GetSource() const =0; // GetSource MUST be implemented!
void ClearClipper(FDrawInfo *di);
@ -107,7 +106,7 @@ public:
if (Start(usestencil, doquery, outer_di, &di))
{
DrawContents(di);
End(usestencil);
End(di, usestencil);
}
}
@ -179,7 +178,7 @@ struct GLLinePortal : public GLPortal
return reinterpret_cast<line_t*>(pv);
}
virtual int ClipSeg(seg_t *seg);
virtual int ClipSeg(seg_t *seg, const DVector3 &viewpos);
virtual int ClipSubsector(subsector_t *sub);
virtual int ClipPoint(const DVector2 &pos);
virtual bool NeedCap() { return false; }
@ -335,7 +334,7 @@ protected:
public:
GLHorizonPortal(GLHorizonInfo * pt, bool local = false);
GLHorizonPortal(GLHorizonInfo * pt, FRenderViewpoint &vp, bool local = false);
};
struct GLEEHorizonPortal : public GLPortal

View File

@ -72,26 +72,6 @@ EXTERN_CVAR (Bool, r_deathcamera)
EXTERN_CVAR (Float, r_visibility)
EXTERN_CVAR (Bool, r_drawvoxels)
//-----------------------------------------------------------------------------
//
// R_FrustumAngle
//
//-----------------------------------------------------------------------------
angle_t GLSceneDrawer::FrustumAngle()
{
float tilt = fabs(GLRenderer->mAngles.Pitch.Degrees);
// If the pitch is larger than this you can look all around at a FOV of 90°
if (tilt > 46.0f) return 0xffffffff;
// ok, this is a gross hack that barely works...
// but at least it doesn't overestimate too much...
double floatangle = 2.0 + (45.0 + ((tilt / 1.9)))*GLRenderer->mCurrentFoV*48.0 / AspectMultiplier(r_viewwindow.WidescreenRatio) / 90.0;
angle_t a1 = DAngle(floatangle).BAMs();
if (a1 >= ANGLE_180) return 0xffffffff;
return a1;
}
//-----------------------------------------------------------------------------
//
// resets the 3D viewport
@ -140,24 +120,6 @@ void GLSceneDrawer::Set3DViewport(bool mainview)
glStencilOp(GL_KEEP,GL_KEEP,GL_REPLACE);
}
//-----------------------------------------------------------------------------
//
// Setup the camera position
//
//-----------------------------------------------------------------------------
void GLSceneDrawer::SetViewAngle(DAngle viewangle)
{
FRenderViewpoint &vp = r_viewpoint;
GLRenderer->mAngles.Yaw = float(270.0-viewangle.Degrees);
DVector2 v = vp.Angles.Yaw.ToVector();
vp.ViewVector.X = v.X;
vp.ViewVector.Y = v.Y;
vp.SetViewAngle(r_viewwindow);
}
//-----------------------------------------------------------------------------
//
// SetProjection
@ -177,15 +139,15 @@ void GLSceneDrawer::SetProjection(VSMatrix matrix)
//
//-----------------------------------------------------------------------------
void GLSceneDrawer::SetViewMatrix(float vx, float vy, float vz, bool mirror, bool planemirror)
void GLSceneDrawer::SetViewMatrix(const FRotator &angles, float vx, float vy, float vz, bool mirror, bool planemirror)
{
float mult = mirror? -1:1;
float planemult = planemirror? -level.info->pixelstretch : level.info->pixelstretch;
gl_RenderState.mViewMatrix.loadIdentity();
gl_RenderState.mViewMatrix.rotate(GLRenderer->mAngles.Roll.Degrees, 0.0f, 0.0f, 1.0f);
gl_RenderState.mViewMatrix.rotate(GLRenderer->mAngles.Pitch.Degrees, 1.0f, 0.0f, 0.0f);
gl_RenderState.mViewMatrix.rotate(GLRenderer->mAngles.Yaw.Degrees, 0.0f, mult, 0.0f);
gl_RenderState.mViewMatrix.rotate(angles.Roll.Degrees, 0.0f, 0.0f, 1.0f);
gl_RenderState.mViewMatrix.rotate(angles.Pitch.Degrees, 1.0f, 0.0f, 0.0f);
gl_RenderState.mViewMatrix.rotate(angles.Yaw.Degrees, 0.0f, mult, 0.0f);
gl_RenderState.mViewMatrix.translate(vx * mult, -vz * planemult , -vy);
gl_RenderState.mViewMatrix.scale(-mult, planemult, 1);
}
@ -197,10 +159,10 @@ void GLSceneDrawer::SetViewMatrix(float vx, float vy, float vz, bool mirror, boo
// Setup the view rotation matrix for the given viewpoint
//
//-----------------------------------------------------------------------------
void GLSceneDrawer::SetupView(float vx, float vy, float vz, DAngle va, bool mirror, bool planemirror)
void GLSceneDrawer::SetupView(FRenderViewpoint &vp, float vx, float vy, float vz, DAngle va, bool mirror, bool planemirror)
{
SetViewAngle(va);
SetViewMatrix(vx, vy, vz, mirror, planemirror);
vp.SetViewAngle(r_viewwindow);
SetViewMatrix(vp.HWAngles, vx, vy, vz, mirror, planemirror);
gl_RenderState.ApplyMatrices();
}
@ -214,8 +176,9 @@ void GLSceneDrawer::SetupView(float vx, float vy, float vz, DAngle va, bool mirr
void GLSceneDrawer::CreateScene(FDrawInfo *di)
{
angle_t a1 = FrustumAngle();
di->mClipper->SafeAddClipRangeRealAngles(r_viewpoint.Angles.Yaw.BAMs() + a1, r_viewpoint.Angles.Yaw.BAMs() - a1);
const auto &vp = di->Viewpoint;
angle_t a1 = di->FrustumAngle();
di->mClipper->SafeAddClipRangeRealAngles(vp.Angles.Yaw.BAMs() + a1, vp.Angles.Yaw.BAMs() - a1);
// reset the portal manager
GLPortal::StartFrame();
@ -230,16 +193,15 @@ void GLSceneDrawer::CreateScene(FDrawInfo *di)
GLRenderer->mLights->Begin();
// Give the DrawInfo the viewpoint in fixed point because that's what the nodes are.
di->viewx = FLOAT2FIXED(r_viewpoint.Pos.X);
di->viewy = FLOAT2FIXED(r_viewpoint.Pos.Y);
di->viewx = FLOAT2FIXED(vp.Pos.X);
di->viewy = FLOAT2FIXED(vp.Pos.Y);
validcount++; // used for processing sidedefs only once by the renderer.
di->mAngles = GLRenderer->mAngles;
di->mShadowMap = &GLRenderer->mShadowMap;
di->RenderBSPNode (level.HeadNode());
di->PreparePlayerSprites(r_viewpoint.sector, di->in_area);
di->PreparePlayerSprites(vp.sector, di->in_area);
// Process all the sprites on the current portal's back side which touch the portal.
if (GLRenderer->mCurrentPortal != NULL) GLRenderer->mCurrentPortal->RenderAttached(di);
@ -269,12 +231,13 @@ void GLSceneDrawer::CreateScene(FDrawInfo *di)
void GLSceneDrawer::RenderScene(FDrawInfo *di, int recursion)
{
const auto &vp = di->Viewpoint;
RenderAll.Clock();
glDepthMask(true);
if (!gl_no_skyclear) GLPortal::RenderFirstSkyPortal(recursion, di);
gl_RenderState.SetCameraPos(r_viewpoint.Pos.X, r_viewpoint.Pos.Y, r_viewpoint.Pos.Z);
gl_RenderState.SetCameraPos(vp.Pos.X, vp.Pos.Y, vp.Pos.Z);
gl_RenderState.EnableFog(true);
gl_RenderState.BlendFunc(GL_ONE,GL_ZERO);
@ -379,9 +342,11 @@ void GLSceneDrawer::RenderScene(FDrawInfo *di, int recursion)
void GLSceneDrawer::RenderTranslucent(FDrawInfo *di)
{
const auto &vp = di->Viewpoint;
RenderAll.Clock();
gl_RenderState.SetCameraPos(r_viewpoint.Pos.X, r_viewpoint.Pos.Y, r_viewpoint.Pos.Z);
gl_RenderState.SetCameraPos(vp.Pos.X, vp.Pos.Y, vp.Pos.Z);
// final pass: translucent stuff
gl_RenderState.AlphaFunc(GL_GEQUAL, gl_mask_sprite_threshold);
@ -414,6 +379,7 @@ void GLSceneDrawer::DrawScene(FDrawInfo *di, int drawmode)
{
static int recursion=0;
static int ssao_portals_available = 0;
const auto &vp = di->Viewpoint;
bool applySSAO = false;
if (drawmode == DM_MAINVIEW)
@ -431,11 +397,11 @@ void GLSceneDrawer::DrawScene(FDrawInfo *di, int drawmode)
ssao_portals_available--;
}
if (r_viewpoint.camera != nullptr)
if (vp.camera != nullptr)
{
ActorRenderFlags savedflags = r_viewpoint.camera->renderflags;
ActorRenderFlags savedflags = vp.camera->renderflags;
CreateScene(di);
r_viewpoint.camera->renderflags = savedflags;
vp.camera->renderflags = savedflags;
}
else
{
@ -527,7 +493,7 @@ void GLSceneDrawer::ProcessScene(FDrawInfo *di, bool toscreen)
iter_dlightf = iter_dlight = draw_dlight = draw_dlightf = 0;
GLPortal::BeginScene();
int mapsection = R_PointInSubsector(r_viewpoint.Pos)->mapsection;
int mapsection = R_PointInSubsector(di->Viewpoint.Pos)->mapsection;
di->CurrentMapSections.Set(mapsection);
GLRenderer->mCurrentPortal = nullptr;
DrawScene(di, toscreen ? DM_MAINVIEW : DM_OFFSCREEN);
@ -540,37 +506,37 @@ void GLSceneDrawer::ProcessScene(FDrawInfo *di, bool toscreen)
//
//-----------------------------------------------------------------------------
sector_t * GLSceneDrawer::RenderViewpoint (AActor * camera, IntRect * bounds, float fov, float ratio, float fovratio, bool mainview, bool toscreen)
sector_t * GLSceneDrawer::RenderViewpoint (FRenderViewpoint &mainvp, AActor * camera, IntRect * bounds, float fov, float ratio, float fovratio, bool mainview, bool toscreen)
{
sector_t * lviewsector;
GLRenderer->mSceneClearColor[0] = 0.0f;
GLRenderer->mSceneClearColor[1] = 0.0f;
GLRenderer->mSceneClearColor[2] = 0.0f;
R_SetupFrame (r_viewpoint, r_viewwindow, camera);
R_SetupFrame (mainvp, r_viewwindow, camera);
GLRenderer->mGlobVis = R_GetGlobVis(r_viewwindow, r_visibility);
// We have to scale the pitch to account for the pixel stretching, because the playsim doesn't know about this and treats it as 1:1.
double radPitch = r_viewpoint.Angles.Pitch.Normalized180().Radians();
double radPitch = mainvp.Angles.Pitch.Normalized180().Radians();
double angx = cos(radPitch);
double angy = sin(radPitch) * level.info->pixelstretch;
double alen = sqrt(angx*angx + angy*angy);
GLRenderer->mAngles.Pitch = (float)RAD2DEG(asin(angy / alen));
GLRenderer->mAngles.Roll.Degrees = r_viewpoint.Angles.Roll.Degrees;
mainvp.HWAngles.Pitch = (float)RAD2DEG(asin(angy / alen));
mainvp.HWAngles.Roll.Degrees = mainvp.Angles.Roll.Degrees;
if (camera->player && camera->player - players == consoleplayer &&
((camera->player->cheats & CF_CHASECAM) || (r_deathcamera && camera->health <= 0)) && camera == camera->player->mo)
{
r_viewpoint.ViewActor = nullptr;
mainvp.ViewActor = nullptr;
}
else
{
r_viewpoint.ViewActor = camera;
mainvp.ViewActor = camera;
}
// 'viewsector' will not survive the rendering so it cannot be used anymore below.
lviewsector = r_viewpoint.sector;
lviewsector = mainvp.sector;
// Render (potentially) multiple views for stereo 3d
float viewShift[3];
@ -583,20 +549,21 @@ sector_t * GLSceneDrawer::RenderViewpoint (AActor * camera, IntRect * bounds, fl
screen->SetViewportRects(bounds);
Set3DViewport(mainview);
GLRenderer->mDrawingScene2D = true;
GLRenderer->mCurrentFoV = fov;
FDrawInfo *di = FDrawInfo::StartDrawInfo(this);
FDrawInfo *di = FDrawInfo::StartDrawInfo(this, mainvp);
auto vp = di->Viewpoint;
di->SetViewArea();
auto cm = di->SetFullbrightFlags(mainview ? r_viewpoint.camera->player : nullptr);
auto cm = di->SetFullbrightFlags(mainview ? vp.camera->player : nullptr);
di->Viewpoint.FieldOfView = fov; // Set the real FOV for the current scene (it's not necessarily the same as the global setting in r_viewpoint)
// Stereo mode specific perspective projection
SetProjection( eye->GetProjection(fov, ratio, fovratio) );
// SetProjection(fov, ratio, fovratio); // switch to perspective mode and set up clipper
SetViewAngle(r_viewpoint.Angles.Yaw);
vp.SetViewAngle(r_viewwindow);
// Stereo mode specific viewpoint adjustment - temporarily shifts global ViewPos
eye->GetViewShift(GLRenderer->mAngles.Yaw.Degrees, viewShift);
ScopedViewShifter viewShifter(r_viewpoint.Pos, viewShift);
SetViewMatrix(r_viewpoint.Pos.X, r_viewpoint.Pos.Y, r_viewpoint.Pos.Z, false, false);
eye->GetViewShift(vp.HWAngles.Yaw.Degrees, viewShift);
ScopedViewShifter viewShifter(vp.Pos, viewShift);
SetViewMatrix(vp.HWAngles, vp.Pos.X, vp.Pos.Y, vp.Pos.Z, false, false);
gl_RenderState.ApplyMatrices();
ProcessScene(di, toscreen);
@ -617,7 +584,7 @@ sector_t * GLSceneDrawer::RenderViewpoint (AActor * camera, IntRect * bounds, fl
gl_RenderState.ApplyMatrices();
}
}
FDrawInfo::EndDrawInfo();
di->EndDrawInfo();
GLRenderer->mDrawingScene2D = false;
if (!stereo3dMode.IsMono())
GLRenderer->mBuffers->BlitToEyeTexture(eye_ix);
@ -654,7 +621,9 @@ void GLSceneDrawer::WriteSavePic (player_t *player, FileWriter *file, int width,
GLRenderer->mVBO->Reset();
GLRenderer->mLights->Clear();
sector_t *viewsector = RenderViewpoint(players[consoleplayer].camera, &bounds, r_viewpoint.FieldOfView.Degrees, 1.6f, 1.6f, true, false);
// This shouldn't overwrite the global viewpoint even for a short time.
FRenderViewpoint savevp;
sector_t *viewsector = RenderViewpoint(savevp, players[consoleplayer].camera, &bounds, r_viewpoint.FieldOfView.Degrees, 1.6f, 1.6f, true, false);
glDisable(GL_STENCIL_TEST);
gl_RenderState.SetSoftLightLevel(-1);
GLRenderer->CopyToBackbuffer(&bounds, false);

View File

@ -28,11 +28,8 @@ public:
GLPortal::drawer = this;
}
angle_t FrustumAngle();
void SetViewMatrix(float vx, float vy, float vz, bool mirror, bool planemirror);
void SetupView(float vx, float vy, float vz, DAngle va, bool mirror, bool planemirror);
void SetViewAngle(DAngle viewangle);
void SetViewMatrix(const FRotator &angles, float vx, float vy, float vz, bool mirror, bool planemirror);
void SetupView(FRenderViewpoint &vp, float vx, float vy, float vz, DAngle va, bool mirror, bool planemirror);
void SetProjection(VSMatrix matrix);
void Set3DViewport(bool mainview);
void Reset3DViewport();
@ -41,7 +38,7 @@ public:
void EndDrawScene(FDrawInfo *di, sector_t * viewsector);
void DrawEndScene2D(FDrawInfo *di, sector_t * viewsector);
sector_t *RenderViewpoint(AActor * camera, IntRect * bounds, float fov, float ratio, float fovratio, bool mainview, bool toscreen);
sector_t *RenderViewpoint(FRenderViewpoint &mainvp, AActor * camera, IntRect * bounds, float fov, float ratio, float fovratio, bool mainview, bool toscreen);
sector_t *RenderView(player_t *player);
void WriteSavePic(player_t *player, FileWriter *file, int width, int height);
};

View File

@ -212,6 +212,7 @@ static void RenderBox(FTextureID texno, FMaterial * gltex, float x_offset, bool
void GLSkyPortal::DrawContents(FDrawInfo *di)
{
bool drawBoth = false;
auto &vp = di->Viewpoint;
// We have no use for Doom lighting special handling here, so disable it for this function.
int oldlightmode = ::level.lightmode;
@ -229,7 +230,7 @@ void GLSkyPortal::DrawContents(FDrawInfo *di)
bool oldClamp = gl_RenderState.SetDepthClamp(true);
gl_MatrixStack.Push(gl_RenderState.mViewMatrix);
drawer->SetupView(0, 0, 0, r_viewpoint.Angles.Yaw, !!(MirrorFlag & 1), !!(PlaneMirrorFlag & 1));
drawer->SetupView(vp, 0, 0, 0, vp.Angles.Yaw, !!(MirrorFlag & 1), !!(PlaneMirrorFlag & 1));
gl_RenderState.SetVertexBuffer(GLRenderer->mSkyVBO);
if (origin->texture[0] && origin->texture[0]->tex->bSkybox)

View File

@ -79,7 +79,7 @@ void FDrawInfo::DrawSprite(GLSprite *sprite, int pass)
bool additivefog = false;
bool foglayer = false;
int rel = sprite->fullbright? 0 : getExtraLight();
auto &vp = r_viewpoint;
auto &vp = Viewpoint;
if (pass==GLPASS_TRANSLUCENT)
{

View File

@ -349,7 +349,7 @@ void FDrawInfo::AddPortal(GLWall *wall, int ptype)
case PORTALTYPE_HORIZON:
wall->horizon = UniqueHorizons.Get(wall->horizon);
portal = GLPortal::FindPortal(wall->horizon);
if (!portal) portal = new GLHorizonPortal(wall->horizon);
if (!portal) portal = new GLHorizonPortal(wall->horizon, Viewpoint);
portal->AddLine(wall);
break;

View File

@ -89,7 +89,7 @@ void HWDrawInfo::AddLine (seg_t *seg, bool portalclip)
if (portalclip)
{
int clipres = mClipPortal->ClipSeg(seg);
int clipres = mClipPortal->ClipSeg(seg, Viewpoint.Pos);
if (clipres == PClip_InFront) return;
}
@ -353,7 +353,7 @@ void HWDrawInfo::RenderThings(subsector_t * sub, sector_t * sector)
SetupSprite.Clock();
sector_t * sec=sub->sector;
// Handle all things in sector.
auto &vp = r_viewpoint;
const auto &vp = Viewpoint;
for (auto p = sec->touching_renderthings; p != nullptr; p = p->m_snext)
{
auto thing = p->m_thing;

View File

@ -2,6 +2,7 @@
#include <atomic>
#include "r_defs.h"
#include "r_utility.h"
struct FSectorPortalGroup;
@ -94,9 +95,10 @@ struct HWDrawInfo
int FullbrightFlags;
std::atomic<int> spriteindex;
IPortal *mClipPortal;
FRotator mAngles;
//FRotator mAngles;
IShadowMap *mShadowMap;
Clipper *mClipper;
FRenderViewpoint Viewpoint;
TArray<MissingTextureInfo> MissingUpperTextures;
TArray<MissingTextureInfo> MissingLowerTextures;
@ -186,6 +188,7 @@ public:
void PrepareTargeterSprites();
void UpdateCurrentMapSection();
angle_t FrustumAngle();
virtual void DrawWall(GLWall *wall, int pass) = 0;
virtual void DrawFlat(GLFlat *flat, int pass, bool trans) = 0;

View File

@ -688,7 +688,7 @@ SortNode * HWDrawList::DoSort(HWDrawInfo *di, SortNode * head)
//==========================================================================
void HWDrawList::Sort(HWDrawInfo *di)
{
SortZ = r_viewpoint.Pos.Z;
SortZ = di->Viewpoint.Pos.Z;
MakeSortList();
sorted = DoSort(di, SortNodes[SortNodeStart]);
}

View File

@ -394,7 +394,7 @@ sector_t * hw_FakeFlat(sector_t * sec, sector_t * dest, area_t in_area, bool bac
//-----------------------------------------------------------------------------
void HWDrawInfo::SetViewArea()
{
auto &vp = r_viewpoint;
auto &vp = Viewpoint;
// The render_sector is better suited to represent the current position in GL
vp.sector = R_PointInSubsector(vp.Pos)->render_sector;
@ -424,7 +424,7 @@ int HWDrawInfo::SetFullbrightFlags(player_t *player)
if (cplayer->extralight == INT_MIN)
{
cm = CM_FIRSTSPECIALCOLORMAP + INVERSECOLORMAP;
r_viewpoint.extralight = 0;
Viewpoint.extralight = 0;
FullbrightFlags = Fullbright;
// This does never set stealth vision.
}
@ -463,3 +463,24 @@ int HWDrawInfo::SetFullbrightFlags(player_t *player)
return CM_DEFAULT;
}
}
//-----------------------------------------------------------------------------
//
// R_FrustumAngle
//
//-----------------------------------------------------------------------------
angle_t HWDrawInfo::FrustumAngle()
{
float tilt = fabs(Viewpoint.HWAngles.Pitch.Degrees);
// If the pitch is larger than this you can look all around at a FOV of 90°
if (tilt > 46.0f) return 0xffffffff;
// ok, this is a gross hack that barely works...
// but at least it doesn't overestimate too much...
double floatangle = 2.0 + (45.0 + ((tilt / 1.9)))*Viewpoint.FieldOfView.Degrees*48.0 / AspectMultiplier(r_viewwindow.WidescreenRatio) / 90.0;
angle_t a1 = DAngle(floatangle).BAMs();
if (a1 >= ANGLE_180) return 0xffffffff;
return a1;
}

View File

@ -306,7 +306,7 @@ void GLFlat::ProcessSector(HWDrawInfo *di, sector_t * frontsector)
dynlightindex = -1;
uint8_t &srf = di->sectorrenderflags[sector->sectornum];
auto &vp = r_viewpoint;
const auto &vp = di->Viewpoint;
//
//

View File

@ -37,7 +37,7 @@ class IPortal
{
public:
virtual ~IPortal() {}
virtual int ClipSeg(seg_t *seg) { return PClip_Inside; }
virtual int ClipSeg(seg_t *seg, const DVector3 &viewpos) { return PClip_Inside; }
virtual int ClipSubsector(subsector_t *sub) { return PClip_Inside; }
virtual int ClipPoint(const DVector2 &pos) { return PClip_Inside; }
virtual line_t *ClipLine() { return nullptr; }

View File

@ -88,7 +88,7 @@ void HWDrawInfo::ClearBuffers()
void HWDrawInfo::UpdateCurrentMapSection()
{
const int mapsection = R_PointInSubsector(r_viewpoint.Pos)->mapsection;
const int mapsection = R_PointInSubsector(Viewpoint.Pos)->mapsection;
CurrentMapSections.Set(mapsection);
}
@ -484,7 +484,7 @@ void HWDrawInfo::HandleMissingTextures(area_t in_area)
HandledSubsectors.Clear();
validcount++;
if (MissingUpperTextures[i].Planez > r_viewpoint.Pos.Z)
if (MissingUpperTextures[i].Planez > Viewpoint.Pos.Z)
{
// close the hole only if all neighboring sectors are an exact height match
// Otherwise just fill in the missing textures.
@ -556,7 +556,7 @@ void HWDrawInfo::HandleMissingTextures(area_t in_area)
HandledSubsectors.Clear();
validcount++;
if (MissingLowerTextures[i].Planez < r_viewpoint.Pos.Z)
if (MissingLowerTextures[i].Planez < Viewpoint.Pos.Z)
{
// close the hole only if all neighboring sectors are an exact height match
// Otherwise just fill in the missing textures.
@ -642,7 +642,7 @@ void HWDrawInfo::DrawUnhandledMissingTextures()
// already done!
if (seg->linedef->validcount == validcount) continue; // already done
seg->linedef->validcount = validcount;
if (seg->frontsector->GetPlaneTexZ(sector_t::ceiling) < r_viewpoint.Pos.Z) continue; // out of sight
if (seg->frontsector->GetPlaneTexZ(sector_t::ceiling) < Viewpoint.Pos.Z) continue; // out of sight
// FIXME: The check for degenerate subsectors should be more precise
if (seg->PartnerSeg && (seg->PartnerSeg->Subsector->flags & SSECF_DEGENERATE)) continue;
@ -664,7 +664,7 @@ void HWDrawInfo::DrawUnhandledMissingTextures()
if (seg->linedef->validcount == validcount) continue; // already done
seg->linedef->validcount = validcount;
if (!(sectorrenderflags[seg->backsector->sectornum] & SSRF_RENDERFLOOR)) continue;
if (seg->frontsector->GetPlaneTexZ(sector_t::floor) > r_viewpoint.Pos.Z) continue; // out of sight
if (seg->frontsector->GetPlaneTexZ(sector_t::floor) > Viewpoint.Pos.Z) continue; // out of sight
if (seg->backsector->transdoor) continue;
if (seg->backsector->GetTexture(sector_t::floor) == skyflatnum) continue;
if (seg->backsector->ValidatePortal(sector_t::floor) != NULL) continue;
@ -757,7 +757,7 @@ bool HWDrawInfo::CollectSubsectorsFloor(subsector_t * sub, sector_t * anchor)
sub->render_sector->GetPlaneTexZ(sector_t::floor) != anchor->GetPlaneTexZ(sector_t::floor) ||
sub->render_sector->GetFloorLight() != anchor->GetFloorLight())
{
if (sub == viewsubsector && r_viewpoint.Pos.Z < anchor->GetPlaneTexZ(sector_t::floor)) inview = true;
if (sub == viewsubsector && Viewpoint.Pos.Z < anchor->GetPlaneTexZ(sector_t::floor)) inview = true;
HandledSubsectors.Push(sub);
}
}
@ -903,7 +903,7 @@ bool HWDrawInfo::CollectSubsectorsCeiling(subsector_t * sub, sector_t * anchor)
void HWDrawInfo::HandleHackedSubsectors()
{
viewsubsector = R_PointInSubsector(r_viewpoint.Pos);
viewsubsector = R_PointInSubsector(Viewpoint.Pos);
// Each subsector may only be processed once in this loop!
validcount++;

View File

@ -154,7 +154,7 @@ void GLWall::SkyPlane(HWDrawInfo *di, sector_t *sector, int plane, bool allowref
}
else if (allowreflect && sector->GetReflect(plane) > 0)
{
auto vpz = r_viewpoint.Pos.Z;
auto vpz = di->Viewpoint.Pos.Z;
if ((plane == sector_t::ceiling && vpz > sector->ceilingplane.fD()) ||
(plane == sector_t::floor && vpz < -sector->floorplane.fD())) return;
ptype = PORTALTYPE_PLANEMIRROR;
@ -341,7 +341,7 @@ void GLWall::SkyBottom(HWDrawInfo *di, seg_t * seg,sector_t * fs,sector_t * bs,v
else
{
// Special hack for Vrack2b
if (bs->floorplane.ZatPoint(r_viewpoint.Pos) > r_viewpoint.Pos.Z) return;
if (bs->floorplane.ZatPoint(di->Viewpoint.Pos) > di->Viewpoint.Pos.Z) return;
}
}
zbottom[0]=zbottom[1]=-32768.0f;

View File

@ -289,7 +289,7 @@ void FSkyDomeCreator::SetupMatrices(FMaterial *tex, float x_offset, float y_offs
// smaller sky textures must be tiled. We restrict it to 128 sky pixels, though
modelMatrix.translate(0.f, -1250.f, 0.f);
modelMatrix.scale(1.f, 128 / 230.f, 1.f);
yscale = 128 / texh; // intentionally left as integer.
yscale = float(128 / texh); // intentionally left as integer.
}
else if (texh < 200)
{

View File

@ -70,6 +70,7 @@ EXTERN_CVAR(Float, transsouls)
bool GLSprite::CalculateVertices(HWDrawInfo *di, FVector3 *v, DVector3 *vp)
{
const auto &HWAngles = di->Viewpoint.HWAngles;
if (actor != nullptr && (actor->renderflags & RF_SPRITETYPEMASK) == RF_FLATSPRITE)
{
Matrix3x4 mat;
@ -149,7 +150,7 @@ bool GLSprite::CalculateVertices(HWDrawInfo *di, FVector3 *v, DVector3 *vp)
float xrel = xcenter - vp->X;
float yrel = ycenter - vp->Y;
float absAngleDeg = RAD2DEG(atan2(-yrel, xrel));
float counterRotationDeg = 270. - di->mAngles.Yaw.Degrees; // counteracts existing sprite rotation
float counterRotationDeg = 270. - HWAngles.Yaw.Degrees; // counteracts existing sprite rotation
float relAngleDeg = counterRotationDeg + absAngleDeg;
mat.Rotate(0, 1, 0, relAngleDeg);
@ -157,7 +158,7 @@ bool GLSprite::CalculateVertices(HWDrawInfo *di, FVector3 *v, DVector3 *vp)
// [fgsfds] calculate yaw vectors
float yawvecX = 0, yawvecY = 0, rollDegrees = 0;
float angleRad = (270. - di->mAngles.Yaw).Radians();
float angleRad = (270. - HWAngles.Yaw).Radians();
if (actor) rollDegrees = Angles.Roll.Degrees;
if (isFlatSprite)
{
@ -181,7 +182,7 @@ bool GLSprite::CalculateVertices(HWDrawInfo *di, FVector3 *v, DVector3 *vp)
if (useOffsets) mat.Translate(xx, zz, yy);
if (drawWithXYBillboard)
{
mat.Rotate(-sin(angleRad), 0, cos(angleRad), -di->mAngles.Pitch.Degrees);
mat.Rotate(-sin(angleRad), 0, cos(angleRad), -HWAngles.Pitch.Degrees);
}
mat.Rotate(cos(angleRad), 0, sin(angleRad), rollDegrees);
if (useOffsets) mat.Translate(-xx, -zz, -yy);
@ -191,7 +192,7 @@ bool GLSprite::CalculateVertices(HWDrawInfo *di, FVector3 *v, DVector3 *vp)
// Rotate the sprite about the vector starting at the center of the sprite
// triangle strip and with direction orthogonal to where the player is looking
// in the x/y plane.
mat.Rotate(-sin(angleRad), 0, cos(angleRad), -di->mAngles.Pitch.Degrees);
mat.Rotate(-sin(angleRad), 0, cos(angleRad), -HWAngles.Pitch.Degrees);
}
mat.Translate(-xcenter, -zcenter, -ycenter); // retreat from sprite center
@ -403,7 +404,7 @@ void GLSprite::Process(HWDrawInfo *di, AActor* thing, sector_t * sector, area_t
return;
}
auto &vp = r_viewpoint;
const auto &vp = di->Viewpoint;
AActor *camera = vp.camera;
if (thing->renderflags & RF_INVISIBLE || !thing->RenderStyle.IsVisible(thing->Alpha))
@ -924,7 +925,7 @@ void GLSprite::ProcessParticle (HWDrawInfo *di, particle_t *particle, sector_t *
}
}
auto &vp = r_viewpoint;
const auto &vp = di->Viewpoint;
double timefrac = vp.TicFrac;
if (paused || bglobal.freeze || (level.flags2 & LEVEL2_FROZEN))
timefrac = 0.;
@ -982,7 +983,7 @@ void HWDrawInfo::ProcessActorsInPortal(FLinePortalSpan *glport, area_t in_area)
TMap<AActor*, bool> processcheck;
if (glport->validcount == validcount) return; // only process once per frame
glport->validcount = validcount;
auto &vp = r_viewpoint;
const auto &vp = Viewpoint;
for (auto port : glport->lines)
{
line_t *line = port->mOrigin;

View File

@ -169,7 +169,7 @@ void GLWall::PutWall(HWDrawInfo *di, bool translucent)
if (translucent)
{
flags |= GLWF_TRANSLUCENT;
ViewDistance = (r_viewpoint.Pos - (seg->linedef->v1->fPos() + seg->linedef->Delta() / 2)).XY().LengthSquared();
ViewDistance = (di->Viewpoint.Pos - (seg->linedef->v1->fPos() + seg->linedef->Delta() / 2)).XY().LengthSquared();
}
if (di->isFullbrightScene())
@ -443,7 +443,7 @@ bool GLWall::DoHorizon(HWDrawInfo *di, seg_t * seg,sector_t * fs, vertex_t * v1,
ztop[1] = ztop[0] = fs->GetPlaneTexZ(sector_t::ceiling);
zbottom[1] = zbottom[0] = fs->GetPlaneTexZ(sector_t::floor);
auto vpz = r_viewpoint.Pos.Z;
auto vpz = di->Viewpoint.Pos.Z;
if (vpz < fs->GetPlaneTexZ(sector_t::ceiling))
{
if (vpz > fs->GetPlaneTexZ(sector_t::floor))

View File

@ -427,7 +427,7 @@ void HWDrawInfo::PreparePlayerSprites(sector_t * viewsector, area_t in_area)
player_t * player = playermo->player;
const bool hudModelStep = IsHUDModelForPlayerAvailable(player);
auto &vp = r_viewpoint;
const auto &vp = Viewpoint;
AActor *camera = vp.camera;
@ -507,7 +507,7 @@ void HWDrawInfo::PrepareTargeterSprites()
{
AActor * playermo = players[consoleplayer].camera;
player_t * player = playermo->player;
AActor *camera = r_viewpoint.camera;
AActor *camera = Viewpoint.camera;
// this is the same as above
if (!player ||

View File

@ -598,7 +598,8 @@ void R_ResetViewInterpolation ()
//==========================================================================
//
// R_SetViewAngle
// R_SetViewAngle
// sets all values derived from the view angle.
//
//==========================================================================
@ -609,6 +610,12 @@ void FRenderViewpoint::SetViewAngle (const FViewWindow &viewwindow)
TanSin = viewwindow.FocalTangent * Sin;
TanCos = viewwindow.FocalTangent * Cos;
DVector2 v = Angles.Yaw.ToVector();
ViewVector.X = v.X;
ViewVector.Y = v.Y;
HWAngles.Yaw = float(270.0 - Angles.Yaw.Degrees);
}
//==========================================================================

View File

@ -21,6 +21,7 @@ struct FRenderViewpoint
DVector3 Pos; // Camera position
DVector3 ActorPos; // Camera actor's position
DRotator Angles; // Camera angles
FRotator HWAngles; // Actual rotation angles for the hardware renderer
DVector2 ViewVector; // HWR only: direction the camera is facing.
AActor *ViewActor; // either the same as camera or nullptr

View File

@ -1180,7 +1180,7 @@ struct TAngle
TAngle &operator= (double other)
{
Degrees = other;
Degrees = (decltype(Degrees))other;
return *this;
}