Files
o3de/Code/CryEngine/Cry3DEngine/CZBufferCuller.h
T

274 lines
9.1 KiB
C++

/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
// Description : Occlusion Culler using hardware generated ZBuffer
#ifndef CRYINCLUDE_CRY3DENGINE_CZBUFFERCULLER_H
#define CRYINCLUDE_CRY3DENGINE_CZBUFFERCULLER_H
#pragma once
#include <Cry_Math.h>
struct IRenderMesh;
typedef uint16 TZBZexel;
const uint64 TZB_MAXDEPTH = (1 << (sizeof(TZBZexel) * 8)) - 1;
class CZBufferCuller
: public Cry3DEngineBase
{
protected:
bool m_DebugFreez;
uint32 m_SizeX;
uint32 m_SizeY;
f32 m_fSizeX;
f32 m_fSizeY;
f32 m_fSizeZ;
TZBZexel* m_ZBuffer;
Matrix44 m_MatProj;
Matrix44 m_MatView;
Matrix44 m_MatViewProj;
Matrix44A m_MatViewProjT;
Vec3 m_Position;
int32 m_Bias;
uint32 m_RotationSafe;
uint32 m_AccurateTest;
uint32 m_Treshold;
f32 m_FixedZFar;
uint32 m_ObjectsTested;
uint32 m_ObjectsTestedAndRejected;
CCamera m_Camera;
int m_OutdoorVisible;
template<uint32 ROTATE, class T>
bool Rasterize(const T rVertices, const uint32 VCount)
{
int64 MinX = m_SizeX;
int64 MaxX = 0;
int64 MinY = m_SizeY;
int64 MaxY = 0;
int64 MinZ = TZB_MAXDEPTH;
for (uint32 a = 0; a < VCount; a++)
{
Vec4 V = rVertices[a];
const f32 InvW = 1.f / V.w;
int64 X = static_cast<int64>((V.x * InvW * 0.5f + 0.5f) * m_fSizeX + 0.5f);
int64 Y = static_cast<int64>((V.y * InvW * 0.5f + 0.5f) * m_fSizeY + 0.5f);
int64 Z = static_cast<int64>(V.z * InvW * m_fSizeZ);
if (X < MinX)
{
MinX = X;
}
else
if (X > MaxX)
{
MaxX = X;
}
if (Y < MinY)
{
MinY = Y;
}
else
if (Y > MaxY)
{
MaxY = Y;
}
if (Z < MinZ)
{
MinZ = Z;
}
}
if (MinX < 0)
{
if constexpr (ROTATE == 1)
{
return true;
}
else
{
MinX = 0;
}
}
if (MaxX > m_SizeX)
{
if constexpr (ROTATE == 1)
{
return true;
}
else
{
MaxX = m_SizeX;
}
}
if (MinY < 0)
{
if constexpr (ROTATE == 1)
{
return true;
}
else
{
MinY = 0;
}
}
if (MaxY > m_SizeY)
{
if constexpr (ROTATE == 1)
{
return true;
}
else
{
MaxY = m_SizeY;
}
}
if constexpr (ROTATE == 2)
{
if (MinX >= m_SizeX || MinY >= m_SizeY || MaxX < 0 || MaxX < 0)
{
return true;
}
}
for (int64 y = MinY; y < MaxY; y++)
{
for (int64 x = MinX; x < MaxX; x++)
{
if (static_cast<int64>(m_ZBuffer[static_cast<int32>(x) + static_cast<int32>(y) * m_SizeX]) > MinZ)
{
return true;
}
}
}
return false;
}
bool IsBoxVisible_OCCLUDER(const AABB& objBox, uint32* const __restrict pResDest = NULL);
bool IsBoxVisible_OCEAN(const AABB& objBox, uint32* const __restrict pResDest = NULL);
bool IsBoxVisible_OCCELL(const AABB& objBox, uint32* const __restrict pResDest = NULL);
bool IsBoxVisible_OCCELL_OCCLUDER(const AABB& objBox, uint32* const __restrict pResDest = NULL);
bool IsBoxVisible_OBJECT(const AABB& objBox, uint32* const __restrict pResDest = NULL);
bool IsBoxVisible_OBJECT_TO_LIGHT(const AABB& objBox, uint32* const __restrict pResDest = NULL);
bool IsBoxVisible_TERRAIN_NODE(const AABB& objBox, uint32* const __restrict pResDest = NULL);
bool IsBoxVisible_PORTAL(const AABB& objBox, uint32* const __restrict pResDest = NULL);
bool IsBoxVisible(const AABB& objBox, uint32* const __restrict pResDest = NULL);
public:
CZBufferCuller();
~CZBufferCuller(){CryModuleMemalignFree(m_ZBuffer); }
// start new frame
void BeginFrame(const SRenderingPassInfo& passInfo);
void ReloadBuffer(const uint32 BufferID);
// render into buffer
ILINE void AddRenderMesh([[maybe_unused]] IRenderMesh* pRM, [[maybe_unused]] Matrix34A* pTranRotMatrix, _smart_ptr<IMaterial> pMaterial, [[maybe_unused]] bool bOutdoorOnly, [[maybe_unused]] bool bCompletelyInFrustum, [[maybe_unused]] bool bNoCull){}
ILINE bool IsObjectVisible(const AABB& objBox, EOcclusionObjectType eOcclusionObjectType, [[maybe_unused]] float fDistance, uint32* pRetVal = NULL)
{
switch (eOcclusionObjectType)
{
case eoot_OCCLUDER:
return IsBoxVisible_OCCLUDER(objBox, pRetVal);
case eoot_OCEAN:
return IsBoxVisible_OCEAN(objBox, pRetVal);
case eoot_OCCELL:
return IsBoxVisible_OCCELL(objBox, pRetVal);
case eoot_OCCELL_OCCLUDER:
return IsBoxVisible_OCCELL_OCCLUDER(objBox, pRetVal);
case eoot_OBJECT:
return IsBoxVisible_OBJECT(objBox, pRetVal);
case eoot_OBJECT_TO_LIGHT:
return IsBoxVisible_OBJECT_TO_LIGHT(objBox, pRetVal);
case eoot_TERRAIN_NODE:
return IsBoxVisible_TERRAIN_NODE(objBox, pRetVal);
case eoot_PORTAL:
return IsBoxVisible_PORTAL(objBox, pRetVal);
}
assert(!"Undefined occluder type");
return true;
}
// draw content to the screen for debug
void DrawDebug(int32 nStep);
// return current camera
const CCamera& GetCamera() const {return m_Camera; }
void GetMemoryUsage(ICrySizer* pSizer) const;
bool IsOutdooVisible(){return m_OutdoorVisible == 1; }
int32 TrisWritten() const{return 0; }
int32 ObjectsWritten() const{return 0; }
int32 TrisTested() const{return 0; }
int32 ObjectsTested() const{return m_ObjectsTested; }
int32 ObjectsTestedAndRejected() const{return m_ObjectsTestedAndRejected; }
int32 SelRes() const{return m_SizeX; }
float FixedZFar() const{return m_FixedZFar; }
float GetZNearInMeters() const{return 0.f; }
float GetZFarInMeters() const{return 1024; }
} _ALIGN(128);
ILINE bool CZBufferCuller::IsBoxVisible_TERRAIN_NODE(const AABB& objBox, uint32* const __restrict pResDest)
{
return IsBoxVisible(objBox, pResDest);
}
ILINE bool CZBufferCuller::IsBoxVisible_OCCELL_OCCLUDER(const AABB& objBox, uint32* const __restrict pResDest)
{
return IsBoxVisible(objBox, pResDest);
}
ILINE bool CZBufferCuller::IsBoxVisible_OCCLUDER(const AABB& objBox, uint32* const __restrict pResDest)
{
return IsBoxVisible(objBox, pResDest);
}
ILINE bool CZBufferCuller::IsBoxVisible_OCEAN(const AABB& objBox, uint32* const __restrict pResDest)
{
return IsBoxVisible(objBox, pResDest);
}
ILINE bool CZBufferCuller::IsBoxVisible_OCCELL(const AABB& objBox, uint32* const __restrict pResDest)
{
if (GetCVars()->e_CoverageBufferDebugFreeze)
{
return true;
}
return IsBoxVisible(objBox, pResDest);
}
ILINE bool CZBufferCuller::IsBoxVisible_OBJECT(const AABB& objBox, uint32* const __restrict pResDest)
{
return IsBoxVisible(objBox, pResDest);
}
ILINE bool CZBufferCuller::IsBoxVisible_OBJECT_TO_LIGHT(const AABB& objBox, uint32* const __restrict pResDest)
{
return IsBoxVisible(objBox, pResDest);
}
ILINE bool CZBufferCuller::IsBoxVisible_PORTAL(const AABB& objBox, uint32* const __restrict pResDest)
{
return IsBoxVisible(objBox, pResDest);
}
#endif // CRYINCLUDE_CRY3DENGINE_CZBUFFERCULLER_H