- 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; mCurrentPortal = nullptr;
mMirrorCount = 0; mMirrorCount = 0;
mPlaneMirrorCount = 0; mPlaneMirrorCount = 0;
mAngles = FRotator(0.f, 0.f, 0.f);
mVBO = nullptr; mVBO = nullptr;
mSkyVBO = nullptr; mSkyVBO = nullptr;
mShaderManager = nullptr; mShaderManager = nullptr;
@ -326,7 +325,7 @@ sector_t *FGLRenderer::RenderView(player_t* player)
GLSceneDrawer drawer; GLSceneDrawer drawer;
mShadowMap.Update(); 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(); All.Unclock();
return retsec; return retsec;
@ -354,7 +353,8 @@ void FGLRenderer::RenderTextureView(FCanvasTexture *tex, AActor *Viewpoint, doub
bounds.height = FHardwareTexture::GetTexDimension(gltex->GetHeight()); bounds.height = FHardwareTexture::GetTexDimension(gltex->GetHeight());
GLSceneDrawer drawer; 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(); EndOffscreen();

View file

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

View file

@ -63,7 +63,7 @@ void FDrawInfo::DoDrawSorted(HWDrawList *dl, SortNode * head)
if (dl->drawitems[head->itemindex].rendertype == GLDIT_FLAT) if (dl->drawitems[head->itemindex].rendertype == GLDIT_FLAT)
{ {
z = dl->flats[dl->drawitems[head->itemindex].index]->z; 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. // OpenGL has no use for multiple clippers so use the same one for all DrawInfos.
static Clipper staticClipper; static Clipper staticClipper;
FDrawInfo *FDrawInfo::StartDrawInfo(GLSceneDrawer *drawer) FDrawInfo *FDrawInfo::StartDrawInfo(GLSceneDrawer *drawer, FRenderViewpoint &parentvp)
{ {
FDrawInfo *di=di_list.GetNew(); FDrawInfo *di=di_list.GetNew();
di->mDrawer = drawer; di->mDrawer = drawer;
di->mVBO = GLRenderer->mVBO; di->mVBO = GLRenderer->mVBO;
di->mClipper = &staticClipper; di->mClipper = &staticClipper;
di->mClipper->SetViewpoint(r_viewpoint); di->Viewpoint = parentvp;
di->mClipper->SetViewpoint(di->Viewpoint);
staticClipper.Clear(); staticClipper.Clear();
di->StartScene(); di->StartScene();
return di; return di;
@ -224,7 +225,7 @@ void FDrawInfo::StartScene()
// //
// //
//========================================================================== //==========================================================================
void FDrawInfo::EndDrawInfo() FDrawInfo *FDrawInfo::EndDrawInfo()
{ {
FDrawInfo * di = gl_drawinfo; FDrawInfo * di = gl_drawinfo;
@ -233,6 +234,7 @@ void FDrawInfo::EndDrawInfo()
di_list.Release(di); di_list.Release(di);
if (gl_drawinfo == nullptr) if (gl_drawinfo == nullptr)
ResetRenderDataAllocator(); ResetRenderDataAllocator();
return gl_drawinfo;
} }
@ -342,9 +344,9 @@ void FDrawInfo::DrawFloodedPlane(wallseg * ws, float planez, sector_t * sec, boo
SetFog(lightlevel, rel, &Colormap, false); SetFog(lightlevel, rel, &Colormap, false);
gl_RenderState.SetMaterial(gltexture, CLAMP_NONE, 0, -1, false); gl_RenderState.SetMaterial(gltexture, CLAMP_NONE, 0, -1, false);
float fviewx = r_viewpoint.Pos.X; float fviewx = Viewpoint.Pos.X;
float fviewy = r_viewpoint.Pos.Y; float fviewy = Viewpoint.Pos.Y;
float fviewz = r_viewpoint.Pos.Z; float fviewz = Viewpoint.Pos.Z;
gl_RenderState.SetPlaneTextureRotation(&plane, gltexture); gl_RenderState.SetPlaneTextureRotation(&plane, gltexture);
gl_RenderState.Apply(); gl_RenderState.Apply();
@ -395,7 +397,7 @@ void FDrawInfo::FloodUpperGap(seg_t * seg)
double frontz = fakefsector->ceilingplane.ZatPoint(seg->v1); double frontz = fakefsector->ceilingplane.ZatPoint(seg->v1);
if (fakebsector->GetTexture(sector_t::ceiling)==skyflatnum) return; 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]) 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->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]) 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 ProcessLowerMinisegs(TArray<seg_t *> &lowersegs) override;
void AddSubsectorToPortal(FSectorPortalGroup *portal, subsector_t *sub) override; void AddSubsectorToPortal(FSectorPortalGroup *portal, subsector_t *sub) override;
static FDrawInfo *StartDrawInfo(GLSceneDrawer *drawer); static FDrawInfo *StartDrawInfo(GLSceneDrawer *drawer, FRenderViewpoint &parentvp);
static void EndDrawInfo(); FDrawInfo *EndDrawInfo();
gl_subsectorrendernode * GetOtherFloorPlanes(unsigned int sector) 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; return false;
} }
} }
*pDi = FDrawInfo::StartDrawInfo(drawer); *pDi = FDrawInfo::StartDrawInfo(drawer, outer_di->Viewpoint);
} }
else else
{ {
@ -257,7 +257,7 @@ bool GLPortal::Start(bool usestencil, bool doquery, FDrawInfo *outer_di, FDrawIn
{ {
if (NeedDepthBuffer()) if (NeedDepthBuffer())
{ {
*pDi = FDrawInfo::StartDrawInfo(drawer); *pDi = FDrawInfo::StartDrawInfo(drawer, outer_di->Viewpoint);
} }
else else
{ {
@ -268,8 +268,7 @@ bool GLPortal::Start(bool usestencil, bool doquery, FDrawInfo *outer_di, FDrawIn
} }
// save viewpoint // save viewpoint
savedviewpoint = r_viewpoint; savedvisibility = outer_di->Viewpoint.camera ? outer_di->Viewpoint.camera->renderflags & RF_MAYBEINVISIBLE : ActorRenderFlags::FromInt(0);
savedvisibility = r_viewpoint.camera ? r_viewpoint.camera->renderflags & RF_MAYBEINVISIBLE : ActorRenderFlags::FromInt(0);
PrevPortal = GLRenderer->mCurrentPortal; PrevPortal = GLRenderer->mCurrentPortal;
@ -282,8 +281,8 @@ bool GLPortal::Start(bool usestencil, bool doquery, FDrawInfo *outer_di, FDrawIn
inline void GLPortal::ClearClipper(FDrawInfo *di) inline void GLPortal::ClearClipper(FDrawInfo *di)
{ {
FRenderViewpoint &oldvp = savedviewpoint; auto outer_di = di->next;
DAngle angleOffset = deltaangle(oldvp.Angles.Yaw, r_viewpoint.Angles.Yaw); DAngle angleOffset = deltaangle(outer_di->Viewpoint.Angles.Yaw, di->Viewpoint.Angles.Yaw);
di->mClipper->Clear(); di->mClipper->Clear();
@ -291,8 +290,8 @@ inline void GLPortal::ClearClipper(FDrawInfo *di)
di->mClipper->SafeAddClipRange(0,0xffffffff); di->mClipper->SafeAddClipRange(0,0xffffffff);
for (unsigned int i = 0; i < lines.Size(); i++) 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 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) - oldvp.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) if (deltaangle(endAngle, startAngle) < 0)
{ {
@ -301,8 +300,8 @@ inline void GLPortal::ClearClipper(FDrawInfo *di)
} }
// and finally clip it to the visible area // and finally clip it to the visible area
angle_t a1 = drawer->FrustumAngle(); angle_t a1 = di->FrustumAngle();
if (a1 < ANGLE_180) di->mClipper->SafeAddClipRangeRealAngles(r_viewpoint.Angles.Yaw.BAMs() + a1, r_viewpoint.Angles.Yaw.BAMs() - a1); 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. // lock the parts that have just been clipped out.
di->mClipper->SetSilhouette(); di->mClipper->SetSilhouette();
@ -313,7 +312,7 @@ inline void GLPortal::ClearClipper(FDrawInfo *di)
// End // End
// //
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void GLPortal::End(bool usestencil) void GLPortal::End(FDrawInfo *di, bool usestencil)
{ {
bool needdepth = NeedDepthBuffer(); bool needdepth = NeedDepthBuffer();
@ -323,12 +322,12 @@ void GLPortal::End(bool usestencil)
if (usestencil) if (usestencil)
{ {
if (needdepth) FDrawInfo::EndDrawInfo(); if (needdepth) di = di->EndDrawInfo();
auto &vp = di->Viewpoint;
// Restore the old view // Restore the old view
r_viewpoint = savedviewpoint; if (vp.camera != nullptr) vp.camera->renderflags = (vp.camera->renderflags & ~RF_MAYBEINVISIBLE) | savedvisibility;
if (r_viewpoint.camera != nullptr) r_viewpoint.camera->renderflags = (r_viewpoint.camera->renderflags & ~RF_MAYBEINVISIBLE) | savedvisibility; drawer->SetupView(vp, vp.Pos.X, vp.Pos.Y, vp.Pos.Z, vp.Angles.Yaw, !!(MirrorFlag & 1), !!(PlaneMirrorFlag & 1));
drawer->SetupView(r_viewpoint.Pos.X, r_viewpoint.Pos.Y, r_viewpoint.Pos.Z, r_viewpoint.Angles.Yaw, !!(MirrorFlag & 1), !!(PlaneMirrorFlag & 1));
{ {
ScopedColorMask colorMask(0, 0, 0, 0); // glColorMask(0, 0, 0, 0); // no graphics ScopedColorMask colorMask(0, 0, 0, 0); // glColorMask(0, 0, 0, 0); // no graphics
@ -371,7 +370,7 @@ void GLPortal::End(bool usestencil)
{ {
if (needdepth) if (needdepth)
{ {
FDrawInfo::EndDrawInfo(); di = di->EndDrawInfo();
glClear(GL_DEPTH_BUFFER_BIT); glClear(GL_DEPTH_BUFFER_BIT);
} }
else else
@ -379,10 +378,11 @@ void GLPortal::End(bool usestencil)
glEnable(GL_DEPTH_TEST); glEnable(GL_DEPTH_TEST);
glDepthMask(true); glDepthMask(true);
} }
auto &vp = di->Viewpoint;
// Restore the old view // Restore the old view
r_viewpoint = savedviewpoint; if (vp.camera != nullptr) vp.camera->renderflags = (vp.camera->renderflags & ~RF_MAYBEINVISIBLE) | savedvisibility;
if (r_viewpoint.camera != nullptr) r_viewpoint.camera->renderflags |= savedvisibility; drawer->SetupView(vp, vp.Pos.X, vp.Pos.Y, vp.Pos.Z, vp.Angles.Yaw, !!(MirrorFlag & 1), !!(PlaneMirrorFlag & 1));
drawer->SetupView(r_viewpoint.Pos.X, r_viewpoint.Pos.Y, r_viewpoint.Pos.Z, r_viewpoint.Angles.Yaw, !!(MirrorFlag&1), !!(PlaneMirrorFlag&1));
// This draws a valid z-buffer into the stencil's contents to ensure it // This draws a valid z-buffer into the stencil's contents to ensure it
// doesn't get overwritten by the level's geometry. // doesn't get overwritten by the level's geometry.
@ -560,36 +560,36 @@ GLPortal * GLPortal::FindPortal(const void * src)
void GLSkyboxPortal::DrawContents(FDrawInfo *di) void GLSkyboxPortal::DrawContents(FDrawInfo *di)
{ {
int old_pm = PlaneMirrorMode; int old_pm = PlaneMirrorMode;
int saved_extralight = r_viewpoint.extralight;
if (skyboxrecursion >= 3) if (skyboxrecursion >= 3)
{ {
ClearScreen(); ClearScreen();
return; return;
} }
auto &vp = di->Viewpoint;
skyboxrecursion++; skyboxrecursion++;
AActor *origin = portal->mSkybox; AActor *origin = portal->mSkybox;
portal->mFlags |= PORTSF_INSKYBOX; portal->mFlags |= PORTSF_INSKYBOX;
r_viewpoint.extralight = 0; vp.extralight = 0;
PlaneMirrorMode = 0; PlaneMirrorMode = 0;
bool oldclamp = gl_RenderState.SetDepthClamp(false); bool oldclamp = gl_RenderState.SetDepthClamp(false);
r_viewpoint.Pos = origin->InterpolatedPosition(r_viewpoint.TicFrac); vp.Pos = origin->InterpolatedPosition(vp.TicFrac);
r_viewpoint.ActorPos = origin->Pos(); vp.ActorPos = origin->Pos();
r_viewpoint.Angles.Yaw += (origin->PrevAngles.Yaw + deltaangle(origin->PrevAngles.Yaw, origin->Angles.Yaw) * r_viewpoint.TicFrac); 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 // Don't let the viewpoint be too close to a floor or ceiling
double floorh = origin->Sector->floorplane.ZatPoint(origin->Pos()); double floorh = origin->Sector->floorplane.ZatPoint(origin->Pos());
double ceilh = origin->Sector->ceilingplane.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 (vp.Pos.Z < floorh + 4) vp.Pos.Z = floorh + 4;
if (r_viewpoint.Pos.Z > ceilh - 4) r_viewpoint.Pos.Z = ceilh - 4; if (vp.Pos.Z > ceilh - 4) vp.Pos.Z = ceilh - 4;
r_viewpoint.ViewActor = origin; vp.ViewActor = origin;
inskybox = true; 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(); di->SetViewArea();
ClearClipper(di); ClearClipper(di);
@ -602,7 +602,6 @@ void GLSkyboxPortal::DrawContents(FDrawInfo *di)
skyboxrecursion--; skyboxrecursion--;
PlaneMirrorMode = old_pm; PlaneMirrorMode = old_pm;
r_viewpoint.extralight = saved_extralight;
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -688,21 +687,22 @@ void GLSectorStackPortal::SetupCoverage(FDrawInfo *di)
void GLSectorStackPortal::DrawContents(FDrawInfo *di) void GLSectorStackPortal::DrawContents(FDrawInfo *di)
{ {
FSectorPortalGroup *portal = origin; FSectorPortalGroup *portal = origin;
auto &vp = di->Viewpoint;
r_viewpoint.Pos += origin->mDisplacement; vp.Pos += origin->mDisplacement;
r_viewpoint.ActorPos += origin->mDisplacement; vp.ActorPos += origin->mDisplacement;
r_viewpoint.ViewActor = nullptr; vp.ViewActor = nullptr;
// avoid recursions! // avoid recursions!
if (origin->plane != -1) screen->instack[origin->plane]++; 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); SetupCoverage(di);
ClearClipper(di); ClearClipper(di);
// If the viewpoint is not within the portal, we need to invalidate the entire clip area. // 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. // 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)) if (!(di->ss_renderflags[sub->Index()] & SSRF_SEEN))
{ {
di->mClipper->SafeAddClipRange(0, ANGLE_MAX); 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. // 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]); std::swap(screen->instack[sector_t::floor], screen->instack[sector_t::ceiling]);
auto &vp = di->Viewpoint;
int old_pm = PlaneMirrorMode; int old_pm = PlaneMirrorMode;
// the player is always visible in a mirror. // the player is always visible in a mirror.
r_viewpoint.showviewer = true; vp.showviewer = true;
double planez = origin->ZatPoint(r_viewpoint.Pos); double planez = origin->ZatPoint(vp.Pos);
r_viewpoint.Pos.Z = 2 * planez - r_viewpoint.Pos.Z; vp.Pos.Z = 2 * planez - vp.Pos.Z;
r_viewpoint.ViewActor = nullptr; vp.ViewActor = nullptr;
PlaneMirrorMode = origin->fC() < 0 ? -1 : 1; PlaneMirrorMode = origin->fC() < 0 ? -1 : 1;
PlaneMirrorFlag++; 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); ClearClipper(di);
di->UpdateCurrentMapSection(); di->UpdateCurrentMapSection();
@ -808,14 +809,14 @@ void GLLinePortal::PopState()
gl_RenderState.EnableClipLine(e != 0); 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; line_t *linedef = seg->linedef;
if (!linedef) if (!linedef)
{ {
return PClip_Inside; // should be handled properly. 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) int GLLinePortal::ClipSubsector(subsector_t *sub)
@ -861,35 +862,36 @@ void GLMirrorPortal::DrawContents(FDrawInfo *di)
return; return;
} }
auto &vp = di->Viewpoint;
di->UpdateCurrentMapSection(); di->UpdateCurrentMapSection();
di->mClipPortal = this; di->mClipPortal = this;
DAngle StartAngle = r_viewpoint.Angles.Yaw; DAngle StartAngle = vp.Angles.Yaw;
DVector3 StartPos = r_viewpoint.Pos; DVector3 StartPos = vp.Pos;
vertex_t *v1 = linedef->v1; vertex_t *v1 = linedef->v1;
vertex_t *v2 = linedef->v2; vertex_t *v2 = linedef->v2;
// the player is always visible in a mirror. // the player is always visible in a mirror.
r_viewpoint.showviewer = true; vp.showviewer = true;
// Reflect the current view behind the mirror. // Reflect the current view behind the mirror.
if (linedef->Delta().X == 0) if (linedef->Delta().X == 0)
{ {
// vertical mirror // vertical mirror
r_viewpoint.Pos.X = 2 * v1->fX() - StartPos.X; vp.Pos.X = 2 * v1->fX() - StartPos.X;
// Compensation for reendering inaccuracies // Compensation for reendering inaccuracies
if (StartPos.X < v1->fX()) r_viewpoint.Pos.X -= 0.1; if (StartPos.X < v1->fX()) vp.Pos.X -= 0.1;
else r_viewpoint.Pos.X += 0.1; else vp.Pos.X += 0.1;
} }
else if (linedef->Delta().Y == 0) else if (linedef->Delta().Y == 0)
{ {
// horizontal mirror // horizontal mirror
r_viewpoint.Pos.Y = 2*v1->fY() - StartPos.Y; vp.Pos.Y = 2*v1->fY() - StartPos.Y;
// Compensation for reendering inaccuracies // Compensation for reendering inaccuracies
if (StartPos.Y<v1->fY()) r_viewpoint.Pos.Y -= 0.1; if (StartPos.Y<v1->fY()) vp.Pos.Y -= 0.1;
else r_viewpoint.Pos.Y += 0.1; else vp.Pos.Y += 0.1;
} }
else else
{ {
@ -906,27 +908,27 @@ void GLMirrorPortal::DrawContents(FDrawInfo *di)
// the above two cases catch len == 0 // the above two cases catch len == 0
double r = ((x - x1)*dx + (y - y1)*dy) / (dx*dx + dy*dy); double r = ((x - x1)*dx + (y - y1)*dy) / (dx*dx + dy*dy);
r_viewpoint.Pos.X = (x1 + r * dx)*2 - x; vp.Pos.X = (x1 + r * dx)*2 - x;
r_viewpoint.Pos.Y = (y1 + r * dy)*2 - y; vp.Pos.Y = (y1 + r * dy)*2 - y;
// Compensation for reendering inaccuracies // Compensation for reendering inaccuracies
FVector2 v(-dx, dy); FVector2 v(-dx, dy);
v.MakeUnit(); v.MakeUnit();
r_viewpoint.Pos.X+= v[1] * renderdepth / 2; vp.Pos.X+= v[1] * renderdepth / 2;
r_viewpoint.Pos.Y+= v[0] * 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++; 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(); di->mClipper->Clear();
angle_t af = drawer->FrustumAngle(); angle_t af = di->FrustumAngle();
if (af<ANGLE_180) di->mClipper->SafeAddClipRangeRealAngles(r_viewpoint.Angles.Yaw.BAMs()+af, r_viewpoint.Angles.Yaw.BAMs()-af); if (af<ANGLE_180) di->mClipper->SafeAddClipRangeRealAngles(vp.Angles.Yaw.BAMs()+af, vp.Angles.Yaw.BAMs()-af);
di->mClipper->SafeAddClipRange(linedef->v1, linedef->v2); di->mClipper->SafeAddClipRange(linedef->v1, linedef->v2);
@ -961,27 +963,27 @@ void GLLineToLinePortal::DrawContents(FDrawInfo *di)
ClearScreen(); ClearScreen();
return; return;
} }
auto &vp = di->Viewpoint;
di->mClipPortal = this; di->mClipPortal = this;
line_t *origin = glport->lines[0]->mOrigin; line_t *origin = glport->lines[0]->mOrigin;
P_TranslatePortalXY(origin, r_viewpoint.Pos.X, r_viewpoint.Pos.Y); P_TranslatePortalXY(origin, vp.Pos.X, vp.Pos.Y);
P_TranslatePortalXY(origin, r_viewpoint.ActorPos.X, r_viewpoint.ActorPos.Y); P_TranslatePortalXY(origin, vp.ActorPos.X, vp.ActorPos.Y);
P_TranslatePortalAngle(origin, r_viewpoint.Angles.Yaw); P_TranslatePortalAngle(origin, vp.Angles.Yaw);
P_TranslatePortalZ(origin, r_viewpoint.Pos.Z); P_TranslatePortalZ(origin, vp.Pos.Z);
P_TranslatePortalXY(origin, r_viewpoint.Path[0].X, r_viewpoint.Path[0].Y); P_TranslatePortalXY(origin, vp.Path[0].X, vp.Path[0].Y);
P_TranslatePortalXY(origin, r_viewpoint.Path[1].X, r_viewpoint.Path[1].Y); P_TranslatePortalXY(origin, vp.Path[1].X, vp.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)) 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) if (distp > EQUAL_EPSILON)
{ {
double dist1 = (r_viewpoint.Pos - r_viewpoint.Path[0]).Length(); double dist1 = (vp.Pos - vp.Path[0]).Length();
double dist2 = (r_viewpoint.Pos - r_viewpoint.Path[1]).Length(); double dist2 = (vp.Pos - vp.Path[1]).Length();
if (dist1 + dist2 < distp + 1) 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); di->CurrentMapSections.Set(sub->mapsection);
} }
r_viewpoint.ViewActor = nullptr; vp.ViewActor = nullptr;
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); ClearClipper(di);
gl_RenderState.SetClipLine(glport->lines[0]->mDestination); 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) : GLPortal(local)
{ {
origin = pt; origin = pt;
// create the vertex data for this horizon portal. // create the vertex data for this horizon portal.
GLSectorPlane * sp = &origin->plane; GLSectorPlane * sp = &origin->plane;
const float vx = r_viewpoint.Pos.X; const float vx = vp.Pos.X;
const float vy = r_viewpoint.Pos.Y; const float vy = vp.Pos.Y;
const float vz = r_viewpoint.Pos.Z; const float vz = vp.Pos.Z;
const float z = sp->Texheight; const float z = sp->Texheight;
const float tz = (z - vz); const float tz = (z - vz);
@ -1106,6 +1108,7 @@ void GLHorizonPortal::DrawContents(FDrawInfo *di)
PalEntry color; PalEntry color;
player_t * player=&players[consoleplayer]; player_t * player=&players[consoleplayer];
GLSectorPlane * sp = &origin->plane; GLSectorPlane * sp = &origin->plane;
auto &vp = di->Viewpoint;
gltexture=FMaterial::ValidateTexture(sp->texture, false, true); gltexture=FMaterial::ValidateTexture(sp->texture, false, true);
if (!gltexture) if (!gltexture)
@ -1113,7 +1116,7 @@ void GLHorizonPortal::DrawContents(FDrawInfo *di)
ClearScreen(); ClearScreen();
return; 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()) if (gltexture && gltexture->tex->isFullbright())
@ -1171,6 +1174,7 @@ void GLHorizonPortal::DrawContents(FDrawInfo *di)
void GLEEHorizonPortal::DrawContents(FDrawInfo *di) void GLEEHorizonPortal::DrawContents(FDrawInfo *di)
{ {
auto &vp = di->Viewpoint;
sector_t *sector = portal->mOrigin; sector_t *sector = portal->mOrigin;
if (sector->GetTexture(sector_t::floor) == skyflatnum || if (sector->GetTexture(sector_t::floor) == skyflatnum ||
sector->GetTexture(sector_t::ceiling) == skyflatnum) sector->GetTexture(sector_t::ceiling) == skyflatnum)
@ -1189,9 +1193,9 @@ void GLEEHorizonPortal::DrawContents(FDrawInfo *di)
horz.specialcolor = 0xffffffff; horz.specialcolor = 0xffffffff;
if (portal->mType == PORTS_PLANE) 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); ceil.DrawContents(di);
} }
if (sector->GetTexture(sector_t::floor) != skyflatnum) if (sector->GetTexture(sector_t::floor) != skyflatnum)
@ -1203,9 +1207,9 @@ void GLEEHorizonPortal::DrawContents(FDrawInfo *di)
horz.specialcolor = 0xffffffff; horz.specialcolor = 0xffffffff;
if (portal->mType == PORTS_PLANE) 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); floor.DrawContents(di);
} }
} }

View file

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

View file

@ -72,26 +72,6 @@ EXTERN_CVAR (Bool, r_deathcamera)
EXTERN_CVAR (Float, r_visibility) EXTERN_CVAR (Float, r_visibility)
EXTERN_CVAR (Bool, r_drawvoxels) 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 // resets the 3D viewport
@ -140,24 +120,6 @@ void GLSceneDrawer::Set3DViewport(bool mainview)
glStencilOp(GL_KEEP,GL_KEEP,GL_REPLACE); 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 // 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 mult = mirror? -1:1;
float planemult = planemirror? -level.info->pixelstretch : level.info->pixelstretch; float planemult = planemirror? -level.info->pixelstretch : level.info->pixelstretch;
gl_RenderState.mViewMatrix.loadIdentity(); gl_RenderState.mViewMatrix.loadIdentity();
gl_RenderState.mViewMatrix.rotate(GLRenderer->mAngles.Roll.Degrees, 0.0f, 0.0f, 1.0f); gl_RenderState.mViewMatrix.rotate(angles.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(angles.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.Yaw.Degrees, 0.0f, mult, 0.0f);
gl_RenderState.mViewMatrix.translate(vx * mult, -vz * planemult , -vy); gl_RenderState.mViewMatrix.translate(vx * mult, -vz * planemult , -vy);
gl_RenderState.mViewMatrix.scale(-mult, planemult, 1); 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 // 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); vp.SetViewAngle(r_viewwindow);
SetViewMatrix(vx, vy, vz, mirror, planemirror); SetViewMatrix(vp.HWAngles, vx, vy, vz, mirror, planemirror);
gl_RenderState.ApplyMatrices(); 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) void GLSceneDrawer::CreateScene(FDrawInfo *di)
{ {
angle_t a1 = FrustumAngle(); const auto &vp = di->Viewpoint;
di->mClipper->SafeAddClipRangeRealAngles(r_viewpoint.Angles.Yaw.BAMs() + a1, r_viewpoint.Angles.Yaw.BAMs() - a1); angle_t a1 = di->FrustumAngle();
di->mClipper->SafeAddClipRangeRealAngles(vp.Angles.Yaw.BAMs() + a1, vp.Angles.Yaw.BAMs() - a1);
// reset the portal manager // reset the portal manager
GLPortal::StartFrame(); GLPortal::StartFrame();
@ -230,16 +193,15 @@ void GLSceneDrawer::CreateScene(FDrawInfo *di)
GLRenderer->mLights->Begin(); GLRenderer->mLights->Begin();
// Give the DrawInfo the viewpoint in fixed point because that's what the nodes are. // Give the DrawInfo the viewpoint in fixed point because that's what the nodes are.
di->viewx = FLOAT2FIXED(r_viewpoint.Pos.X); di->viewx = FLOAT2FIXED(vp.Pos.X);
di->viewy = FLOAT2FIXED(r_viewpoint.Pos.Y); di->viewy = FLOAT2FIXED(vp.Pos.Y);
validcount++; // used for processing sidedefs only once by the renderer. validcount++; // used for processing sidedefs only once by the renderer.
di->mAngles = GLRenderer->mAngles;
di->mShadowMap = &GLRenderer->mShadowMap; di->mShadowMap = &GLRenderer->mShadowMap;
di->RenderBSPNode (level.HeadNode()); 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. // Process all the sprites on the current portal's back side which touch the portal.
if (GLRenderer->mCurrentPortal != NULL) GLRenderer->mCurrentPortal->RenderAttached(di); if (GLRenderer->mCurrentPortal != NULL) GLRenderer->mCurrentPortal->RenderAttached(di);
@ -269,12 +231,13 @@ void GLSceneDrawer::CreateScene(FDrawInfo *di)
void GLSceneDrawer::RenderScene(FDrawInfo *di, int recursion) void GLSceneDrawer::RenderScene(FDrawInfo *di, int recursion)
{ {
const auto &vp = di->Viewpoint;
RenderAll.Clock(); RenderAll.Clock();
glDepthMask(true); glDepthMask(true);
if (!gl_no_skyclear) GLPortal::RenderFirstSkyPortal(recursion, di); 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.EnableFog(true);
gl_RenderState.BlendFunc(GL_ONE,GL_ZERO); gl_RenderState.BlendFunc(GL_ONE,GL_ZERO);
@ -379,9 +342,11 @@ void GLSceneDrawer::RenderScene(FDrawInfo *di, int recursion)
void GLSceneDrawer::RenderTranslucent(FDrawInfo *di) void GLSceneDrawer::RenderTranslucent(FDrawInfo *di)
{ {
const auto &vp = di->Viewpoint;
RenderAll.Clock(); 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 // final pass: translucent stuff
gl_RenderState.AlphaFunc(GL_GEQUAL, gl_mask_sprite_threshold); 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 recursion=0;
static int ssao_portals_available = 0; static int ssao_portals_available = 0;
const auto &vp = di->Viewpoint;
bool applySSAO = false; bool applySSAO = false;
if (drawmode == DM_MAINVIEW) if (drawmode == DM_MAINVIEW)
@ -431,11 +397,11 @@ void GLSceneDrawer::DrawScene(FDrawInfo *di, int drawmode)
ssao_portals_available--; 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); CreateScene(di);
r_viewpoint.camera->renderflags = savedflags; vp.camera->renderflags = savedflags;
} }
else else
{ {
@ -527,7 +493,7 @@ void GLSceneDrawer::ProcessScene(FDrawInfo *di, bool toscreen)
iter_dlightf = iter_dlight = draw_dlight = draw_dlightf = 0; iter_dlightf = iter_dlight = draw_dlight = draw_dlightf = 0;
GLPortal::BeginScene(); GLPortal::BeginScene();
int mapsection = R_PointInSubsector(r_viewpoint.Pos)->mapsection; int mapsection = R_PointInSubsector(di->Viewpoint.Pos)->mapsection;
di->CurrentMapSections.Set(mapsection); di->CurrentMapSections.Set(mapsection);
GLRenderer->mCurrentPortal = nullptr; GLRenderer->mCurrentPortal = nullptr;
DrawScene(di, toscreen ? DM_MAINVIEW : DM_OFFSCREEN); 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; sector_t * lviewsector;
GLRenderer->mSceneClearColor[0] = 0.0f; GLRenderer->mSceneClearColor[0] = 0.0f;
GLRenderer->mSceneClearColor[1] = 0.0f; GLRenderer->mSceneClearColor[1] = 0.0f;
GLRenderer->mSceneClearColor[2] = 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); 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. // 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 angx = cos(radPitch);
double angy = sin(radPitch) * level.info->pixelstretch; double angy = sin(radPitch) * level.info->pixelstretch;
double alen = sqrt(angx*angx + angy*angy); double alen = sqrt(angx*angx + angy*angy);
GLRenderer->mAngles.Pitch = (float)RAD2DEG(asin(angy / alen)); mainvp.HWAngles.Pitch = (float)RAD2DEG(asin(angy / alen));
GLRenderer->mAngles.Roll.Degrees = r_viewpoint.Angles.Roll.Degrees; mainvp.HWAngles.Roll.Degrees = mainvp.Angles.Roll.Degrees;
if (camera->player && camera->player - players == consoleplayer && if (camera->player && camera->player - players == consoleplayer &&
((camera->player->cheats & CF_CHASECAM) || (r_deathcamera && camera->health <= 0)) && camera == camera->player->mo) ((camera->player->cheats & CF_CHASECAM) || (r_deathcamera && camera->health <= 0)) && camera == camera->player->mo)
{ {
r_viewpoint.ViewActor = nullptr; mainvp.ViewActor = nullptr;
} }
else else
{ {
r_viewpoint.ViewActor = camera; mainvp.ViewActor = camera;
} }
// 'viewsector' will not survive the rendering so it cannot be used anymore below. // '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 // Render (potentially) multiple views for stereo 3d
float viewShift[3]; float viewShift[3];
@ -583,20 +549,21 @@ sector_t * GLSceneDrawer::RenderViewpoint (AActor * camera, IntRect * bounds, fl
screen->SetViewportRects(bounds); screen->SetViewportRects(bounds);
Set3DViewport(mainview); Set3DViewport(mainview);
GLRenderer->mDrawingScene2D = true; GLRenderer->mDrawingScene2D = true;
GLRenderer->mCurrentFoV = fov;
FDrawInfo *di = FDrawInfo::StartDrawInfo(this); FDrawInfo *di = FDrawInfo::StartDrawInfo(this, mainvp);
auto vp = di->Viewpoint;
di->SetViewArea(); 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 // Stereo mode specific perspective projection
SetProjection( eye->GetProjection(fov, ratio, fovratio) ); SetProjection( eye->GetProjection(fov, ratio, fovratio) );
// SetProjection(fov, ratio, fovratio); // switch to perspective mode and set up clipper // 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 // Stereo mode specific viewpoint adjustment - temporarily shifts global ViewPos
eye->GetViewShift(GLRenderer->mAngles.Yaw.Degrees, viewShift); eye->GetViewShift(vp.HWAngles.Yaw.Degrees, viewShift);
ScopedViewShifter viewShifter(r_viewpoint.Pos, viewShift); ScopedViewShifter viewShifter(vp.Pos, viewShift);
SetViewMatrix(r_viewpoint.Pos.X, r_viewpoint.Pos.Y, r_viewpoint.Pos.Z, false, false); SetViewMatrix(vp.HWAngles, vp.Pos.X, vp.Pos.Y, vp.Pos.Z, false, false);
gl_RenderState.ApplyMatrices(); gl_RenderState.ApplyMatrices();
ProcessScene(di, toscreen); ProcessScene(di, toscreen);
@ -617,7 +584,7 @@ sector_t * GLSceneDrawer::RenderViewpoint (AActor * camera, IntRect * bounds, fl
gl_RenderState.ApplyMatrices(); gl_RenderState.ApplyMatrices();
} }
} }
FDrawInfo::EndDrawInfo(); di->EndDrawInfo();
GLRenderer->mDrawingScene2D = false; GLRenderer->mDrawingScene2D = false;
if (!stereo3dMode.IsMono()) if (!stereo3dMode.IsMono())
GLRenderer->mBuffers->BlitToEyeTexture(eye_ix); GLRenderer->mBuffers->BlitToEyeTexture(eye_ix);
@ -654,7 +621,9 @@ void GLSceneDrawer::WriteSavePic (player_t *player, FileWriter *file, int width,
GLRenderer->mVBO->Reset(); GLRenderer->mVBO->Reset();
GLRenderer->mLights->Clear(); 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); glDisable(GL_STENCIL_TEST);
gl_RenderState.SetSoftLightLevel(-1); gl_RenderState.SetSoftLightLevel(-1);
GLRenderer->CopyToBackbuffer(&bounds, false); GLRenderer->CopyToBackbuffer(&bounds, false);

View file

@ -28,11 +28,8 @@ public:
GLPortal::drawer = this; GLPortal::drawer = this;
} }
angle_t FrustumAngle(); 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 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 SetProjection(VSMatrix matrix); void SetProjection(VSMatrix matrix);
void Set3DViewport(bool mainview); void Set3DViewport(bool mainview);
void Reset3DViewport(); void Reset3DViewport();
@ -41,7 +38,7 @@ public:
void EndDrawScene(FDrawInfo *di, sector_t * viewsector); void EndDrawScene(FDrawInfo *di, sector_t * viewsector);
void DrawEndScene2D(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); sector_t *RenderView(player_t *player);
void WriteSavePic(player_t *player, FileWriter *file, int width, int height); 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) void GLSkyPortal::DrawContents(FDrawInfo *di)
{ {
bool drawBoth = false; bool drawBoth = false;
auto &vp = di->Viewpoint;
// We have no use for Doom lighting special handling here, so disable it for this function. // We have no use for Doom lighting special handling here, so disable it for this function.
int oldlightmode = ::level.lightmode; int oldlightmode = ::level.lightmode;
@ -229,7 +230,7 @@ void GLSkyPortal::DrawContents(FDrawInfo *di)
bool oldClamp = gl_RenderState.SetDepthClamp(true); bool oldClamp = gl_RenderState.SetDepthClamp(true);
gl_MatrixStack.Push(gl_RenderState.mViewMatrix); 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); gl_RenderState.SetVertexBuffer(GLRenderer->mSkyVBO);
if (origin->texture[0] && origin->texture[0]->tex->bSkybox) 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 additivefog = false;
bool foglayer = false; bool foglayer = false;
int rel = sprite->fullbright? 0 : getExtraLight(); int rel = sprite->fullbright? 0 : getExtraLight();
auto &vp = r_viewpoint; auto &vp = Viewpoint;
if (pass==GLPASS_TRANSLUCENT) if (pass==GLPASS_TRANSLUCENT)
{ {

View file

@ -349,7 +349,7 @@ void FDrawInfo::AddPortal(GLWall *wall, int ptype)
case PORTALTYPE_HORIZON: case PORTALTYPE_HORIZON:
wall->horizon = UniqueHorizons.Get(wall->horizon); wall->horizon = UniqueHorizons.Get(wall->horizon);
portal = GLPortal::FindPortal(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); portal->AddLine(wall);
break; break;

View file

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

View file

@ -2,6 +2,7 @@
#include <atomic> #include <atomic>
#include "r_defs.h" #include "r_defs.h"
#include "r_utility.h"
struct FSectorPortalGroup; struct FSectorPortalGroup;
@ -94,9 +95,10 @@ struct HWDrawInfo
int FullbrightFlags; int FullbrightFlags;
std::atomic<int> spriteindex; std::atomic<int> spriteindex;
IPortal *mClipPortal; IPortal *mClipPortal;
FRotator mAngles; //FRotator mAngles;
IShadowMap *mShadowMap; IShadowMap *mShadowMap;
Clipper *mClipper; Clipper *mClipper;
FRenderViewpoint Viewpoint;
TArray<MissingTextureInfo> MissingUpperTextures; TArray<MissingTextureInfo> MissingUpperTextures;
TArray<MissingTextureInfo> MissingLowerTextures; TArray<MissingTextureInfo> MissingLowerTextures;
@ -186,6 +188,7 @@ public:
void PrepareTargeterSprites(); void PrepareTargeterSprites();
void UpdateCurrentMapSection(); void UpdateCurrentMapSection();
angle_t FrustumAngle();
virtual void DrawWall(GLWall *wall, int pass) = 0; virtual void DrawWall(GLWall *wall, int pass) = 0;
virtual void DrawFlat(GLFlat *flat, int pass, bool trans) = 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) void HWDrawList::Sort(HWDrawInfo *di)
{ {
SortZ = r_viewpoint.Pos.Z; SortZ = di->Viewpoint.Pos.Z;
MakeSortList(); MakeSortList();
sorted = DoSort(di, SortNodes[SortNodeStart]); 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() void HWDrawInfo::SetViewArea()
{ {
auto &vp = r_viewpoint; auto &vp = Viewpoint;
// The render_sector is better suited to represent the current position in GL // The render_sector is better suited to represent the current position in GL
vp.sector = R_PointInSubsector(vp.Pos)->render_sector; vp.sector = R_PointInSubsector(vp.Pos)->render_sector;
@ -424,7 +424,7 @@ int HWDrawInfo::SetFullbrightFlags(player_t *player)
if (cplayer->extralight == INT_MIN) if (cplayer->extralight == INT_MIN)
{ {
cm = CM_FIRSTSPECIALCOLORMAP + INVERSECOLORMAP; cm = CM_FIRSTSPECIALCOLORMAP + INVERSECOLORMAP;
r_viewpoint.extralight = 0; Viewpoint.extralight = 0;
FullbrightFlags = Fullbright; FullbrightFlags = Fullbright;
// This does never set stealth vision. // This does never set stealth vision.
} }
@ -463,3 +463,24 @@ int HWDrawInfo::SetFullbrightFlags(player_t *player)
return CM_DEFAULT; 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; dynlightindex = -1;
uint8_t &srf = di->sectorrenderflags[sector->sectornum]; 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: public:
virtual ~IPortal() {} 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 ClipSubsector(subsector_t *sub) { return PClip_Inside; }
virtual int ClipPoint(const DVector2 &pos) { return PClip_Inside; } virtual int ClipPoint(const DVector2 &pos) { return PClip_Inside; }
virtual line_t *ClipLine() { return nullptr; } virtual line_t *ClipLine() { return nullptr; }

View file

@ -88,7 +88,7 @@ void HWDrawInfo::ClearBuffers()
void HWDrawInfo::UpdateCurrentMapSection() void HWDrawInfo::UpdateCurrentMapSection()
{ {
const int mapsection = R_PointInSubsector(r_viewpoint.Pos)->mapsection; const int mapsection = R_PointInSubsector(Viewpoint.Pos)->mapsection;
CurrentMapSections.Set(mapsection); CurrentMapSections.Set(mapsection);
} }
@ -484,7 +484,7 @@ void HWDrawInfo::HandleMissingTextures(area_t in_area)
HandledSubsectors.Clear(); HandledSubsectors.Clear();
validcount++; 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 // close the hole only if all neighboring sectors are an exact height match
// Otherwise just fill in the missing textures. // Otherwise just fill in the missing textures.
@ -556,7 +556,7 @@ void HWDrawInfo::HandleMissingTextures(area_t in_area)
HandledSubsectors.Clear(); HandledSubsectors.Clear();
validcount++; 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 // close the hole only if all neighboring sectors are an exact height match
// Otherwise just fill in the missing textures. // Otherwise just fill in the missing textures.
@ -642,7 +642,7 @@ void HWDrawInfo::DrawUnhandledMissingTextures()
// already done! // already done!
if (seg->linedef->validcount == validcount) continue; // already done if (seg->linedef->validcount == validcount) continue; // already done
seg->linedef->validcount = validcount; 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 // FIXME: The check for degenerate subsectors should be more precise
if (seg->PartnerSeg && (seg->PartnerSeg->Subsector->flags & SSECF_DEGENERATE)) continue; 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 if (seg->linedef->validcount == validcount) continue; // already done
seg->linedef->validcount = validcount; seg->linedef->validcount = validcount;
if (!(sectorrenderflags[seg->backsector->sectornum] & SSRF_RENDERFLOOR)) continue; 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->transdoor) continue;
if (seg->backsector->GetTexture(sector_t::floor) == skyflatnum) continue; if (seg->backsector->GetTexture(sector_t::floor) == skyflatnum) continue;
if (seg->backsector->ValidatePortal(sector_t::floor) != NULL) 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->GetPlaneTexZ(sector_t::floor) != anchor->GetPlaneTexZ(sector_t::floor) ||
sub->render_sector->GetFloorLight() != anchor->GetFloorLight()) 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); HandledSubsectors.Push(sub);
} }
} }
@ -903,7 +903,7 @@ bool HWDrawInfo::CollectSubsectorsCeiling(subsector_t * sub, sector_t * anchor)
void HWDrawInfo::HandleHackedSubsectors() void HWDrawInfo::HandleHackedSubsectors()
{ {
viewsubsector = R_PointInSubsector(r_viewpoint.Pos); viewsubsector = R_PointInSubsector(Viewpoint.Pos);
// Each subsector may only be processed once in this loop! // Each subsector may only be processed once in this loop!
validcount++; 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) 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()) || if ((plane == sector_t::ceiling && vpz > sector->ceilingplane.fD()) ||
(plane == sector_t::floor && vpz < -sector->floorplane.fD())) return; (plane == sector_t::floor && vpz < -sector->floorplane.fD())) return;
ptype = PORTALTYPE_PLANEMIRROR; ptype = PORTALTYPE_PLANEMIRROR;
@ -341,7 +341,7 @@ void GLWall::SkyBottom(HWDrawInfo *di, seg_t * seg,sector_t * fs,sector_t * bs,v
else else
{ {
// Special hack for Vrack2b // 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; 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 // smaller sky textures must be tiled. We restrict it to 128 sky pixels, though
modelMatrix.translate(0.f, -1250.f, 0.f); modelMatrix.translate(0.f, -1250.f, 0.f);
modelMatrix.scale(1.f, 128 / 230.f, 1.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) else if (texh < 200)
{ {

View file

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

View file

@ -169,7 +169,7 @@ void GLWall::PutWall(HWDrawInfo *di, bool translucent)
if (translucent) if (translucent)
{ {
flags |= GLWF_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()) 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); ztop[1] = ztop[0] = fs->GetPlaneTexZ(sector_t::ceiling);
zbottom[1] = zbottom[0] = fs->GetPlaneTexZ(sector_t::floor); 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::ceiling))
{ {
if (vpz > fs->GetPlaneTexZ(sector_t::floor)) 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; player_t * player = playermo->player;
const bool hudModelStep = IsHUDModelForPlayerAvailable(player); const bool hudModelStep = IsHUDModelForPlayerAvailable(player);
auto &vp = r_viewpoint; const auto &vp = Viewpoint;
AActor *camera = vp.camera; AActor *camera = vp.camera;
@ -507,7 +507,7 @@ void HWDrawInfo::PrepareTargeterSprites()
{ {
AActor * playermo = players[consoleplayer].camera; AActor * playermo = players[consoleplayer].camera;
player_t * player = playermo->player; player_t * player = playermo->player;
AActor *camera = r_viewpoint.camera; AActor *camera = Viewpoint.camera;
// this is the same as above // this is the same as above
if (!player || 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; TanSin = viewwindow.FocalTangent * Sin;
TanCos = viewwindow.FocalTangent * Cos; 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 Pos; // Camera position
DVector3 ActorPos; // Camera actor's position DVector3 ActorPos; // Camera actor's position
DRotator Angles; // Camera angles DRotator Angles; // Camera angles
FRotator HWAngles; // Actual rotation angles for the hardware renderer
DVector2 ViewVector; // HWR only: direction the camera is facing. DVector2 ViewVector; // HWR only: direction the camera is facing.
AActor *ViewActor; // either the same as camera or nullptr AActor *ViewActor; // either the same as camera or nullptr

View file

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