Add the camera frustum culling to the normal hwrenderer as well

This commit is contained in:
Magnus Norddahl 2025-08-01 09:34:13 +02:00
commit a66e584be0
3 changed files with 51 additions and 45 deletions

View file

@ -371,7 +371,7 @@ void HWDrawInfo::AddLine (seg_t *seg, bool portalclip, FRenderState& state)
backsector = hw_FakeFlat(drawctx, seg->backsector, in_area, true);
if (hw_CheckClip(seg->sidedef, currentsector, backsector))
if (hw_CheckClip(seg->sidedef, currentsector, backsector, &ClipFrustum))
{
if(!Viewpoint.IsAllowedOoB() && !(seg->sidedef->Flags & WALLF_DITHERTRANS_MID))
clipper.SafeAddClipRange(startAngle, endAngle);
@ -1048,6 +1048,10 @@ void HWDrawInfo::RenderBSP(void *node, bool drawpsprites, FRenderState& state)
viewy = FLOAT2FIXED(Viewpoint.OffPos.Y);
}
VSMatrix m = VPUniforms.mProjectionMatrix;
m.multMatrix(VPUniforms.mViewMatrix);
ClipFrustum.Set(m, Viewpoint.Pos);
validcount++; // used for processing sidedefs only once by the renderer.
multithread = gl_multithread;

View file

@ -96,6 +96,50 @@ enum DrawListType
GLDL_TYPES,
};
struct CameraFrustum
{
void Set(const VSMatrix& worldToProjection, const DVector3& viewpoint);
bool IsSphereVisible(const DVector3& point, double radius) const
{
for (int i = 0; i < 6; i++)
{
if ((Planes[i].XYZ() | point) < -radius)
return false;
}
return true;
}
bool IsAABBVisible(const DVector3& aabbMin, const DVector3& aabbMax) const
{
DVector3 aabbCenter = (aabbMin + aabbMax) * 0.5;
DVector3 aabbExtents = (aabbMax - aabbMin) * 0.5;
for (int i = 0; i < 6; i++)
{
double distance = Planes[i] | DVector4(aabbCenter, 1.0);
double radius = AbsPlaneNormals[i] | aabbExtents;
bool outside = distance < -radius;
//bool inside = distance > radius;
//bool intersect = distance > -radius && distance < radius;
if (outside)
return false;
}
return true;
}
private:
static DVector4 LeftFrustum(const VSMatrix& matrix);
static DVector4 RightFrustum(const VSMatrix& matrix);
static DVector4 TopFrustum(const VSMatrix& matrix);
static DVector4 BottomFrustum(const VSMatrix& matrix);
static DVector4 NearFrustum(const VSMatrix& matrix);
static DVector4 FarFrustum(const VSMatrix& matrix);
static DVector4 Normalize(DVector4 v);
DVector3 AbsPlaneNormals[6];
DVector4 Planes[6];
};
struct HWDrawInfo
{
struct wallseg
@ -149,6 +193,7 @@ struct HWDrawInfo
Clipper *mClipper;
Clipper *vClipper; // Vertical clipper
Clipper *rClipper; // Radar clipper
CameraFrustum ClipFrustum;
FRenderViewpoint Viewpoint;
HWViewpointUniforms VPUniforms; // per-viewpoint uniform state
VSMatrix ProjectionMatrix2;

View file

@ -4,6 +4,7 @@
#include "r_utility.h"
#include "hw_fakeflat.h"
#include "hw_drawcontext.h"
#include "hw_drawinfo.h"
#include <thread>
#include <mutex>
#include <condition_variable>
@ -13,50 +14,6 @@ class Clipper;
class HWPortal;
struct HWDrawInfo;
struct CameraFrustum
{
void Set(const VSMatrix& worldToProjection, const DVector3& viewpoint);
bool IsSphereVisible(const DVector3& point, double radius) const
{
for (int i = 0; i < 6; i++)
{
if ((Planes[i].XYZ() | point) < -radius)
return false;
}
return true;
}
bool IsAABBVisible(const DVector3& aabbMin, const DVector3& aabbMax) const
{
DVector3 aabbCenter = (aabbMin + aabbMax) * 0.5;
DVector3 aabbExtents = (aabbMax - aabbMin) * 0.5;
for (int i = 0; i < 6; i++)
{
double distance = Planes[i] | DVector4(aabbCenter, 1.0);
double radius = AbsPlaneNormals[i] | aabbExtents;
bool outside = distance < -radius;
//bool inside = distance > radius;
//bool intersect = distance > -radius && distance < radius;
if (outside)
return false;
}
return true;
}
private:
static DVector4 LeftFrustum(const VSMatrix& matrix);
static DVector4 RightFrustum(const VSMatrix& matrix);
static DVector4 TopFrustum(const VSMatrix& matrix);
static DVector4 BottomFrustum(const VSMatrix& matrix);
static DVector4 NearFrustum(const VSMatrix& matrix);
static DVector4 FarFrustum(const VSMatrix& matrix);
static DVector4 Normalize(DVector4 v);
DVector3 AbsPlaneNormals[6];
DVector4 Planes[6];
};
class HWVisibleSet
{
public: