/* * 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. #ifndef CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_RENDELEMENTS_FLARESOFTOCCLUSIONQUERY_H #define CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_RENDELEMENTS_FLARESOFTOCCLUSIONQUERY_H #pragma once #include "IFlares.h" #include "Cry_Vector2.h" #include "Timeline.h" class CTexture; class CShader; class RootOpticsElement; class CSoftOcclusionVisiblityFader { public: CSoftOcclusionVisiblityFader() : m_fTargetVisibility(-1.0f) , m_fVisibilityFactor(1.0f) { } float UpdateVisibility(const float newTargetVisibility, const float duration); TimelineFloat m_TimeLine; float m_fTargetVisibility; float m_fVisibilityFactor; }; class CFlareSoftOcclusionQuery : public ISoftOcclusionQuery { public: static const int s_nIDColMax = 32; static const int s_nIDRowMax = 32; static const int s_nIDMax = s_nIDColMax * s_nIDRowMax; static const int s_nGatherEachSectorWidth = 8; static const int s_nGatherEachSectorHeight = 8; static const int s_nGatherTextureWidth = s_nGatherEachSectorWidth * s_nIDColMax; static const int s_nGatherTextureHeight = s_nGatherEachSectorHeight * s_nIDRowMax; static const float s_fSectorWidth; static const float s_fSectorHeight; private: static int s_idCount; static char s_idHashTable[s_nIDMax]; static unsigned char s_paletteRawCache[s_nIDMax * 4]; static int s_ringReadIdx; static int s_ringWriteIdx; static int s_ringSize; private: static int GenID(); static void ReleaseID(int id); public: CFlareSoftOcclusionQuery(const uint8 numFaders = 0) : m_fOccPlaneWidth(0.02f) , m_fOccPlaneHeight(0.02f) , m_PosToBeChecked(0, 0, 0) , m_fOccResultCache(1) , m_numVisibilityFaders(numFaders) , m_pVisbilityFaders(NULL) , m_refCount(1) { InitGlobalResources(); m_nID = GenID(); if (m_numVisibilityFaders > 0) { m_pVisbilityFaders = new CSoftOcclusionVisiblityFader[m_numVisibilityFaders]; } } ~CFlareSoftOcclusionQuery() { CRY_ASSERT(m_refCount == 0); ReleaseID(m_nID); m_numVisibilityFaders = 0; SAFE_DELETE_ARRAY(m_pVisbilityFaders); } // Manage multi-thread references virtual void AddRef() { CryInterlockedIncrement(&m_refCount); } virtual void Release() { if (CryInterlockedDecrement(&m_refCount) <= 0) { delete this; } } static void InitGlobalResources(); static void BatchReadResults(); static void ReadbackSoftOcclQuery(); static CTexture* GetOcclusionTex(); void GetDomainInTexture(float& out_x0, float& out_y0, float& out_x1, float& out_y1); void GetSectorSize(float& width, float& height); struct SOcclusionSectorInfo { float x0, y0, x1, y1; float u0, v0, u1, v1; float lineardepth; }; void GetOcclusionSectorInfo(SOcclusionSectorInfo& out_occlusionSector); void UpdateCachedResults(); int GetID() { return m_nID; } float GetVisibility() const { return m_fOccResultCache; } float GetOccResult() const { return m_fOccResultCache; } float GetDirResult() const { return m_fDirResultCache; } const Vec2& GetDirVecResult() const {return m_DirVecResultCache; } bool IsVisible() const { return m_fOccResultCache > 0; } void SetPosToBeChecked(const Vec3& vPos) { m_PosToBeChecked = vPos; } CSoftOcclusionVisiblityFader* GetVisibilityFader(const uint8 index) const { return (m_pVisbilityFaders && index < m_numVisibilityFaders) ? &m_pVisbilityFaders[index] : NULL; } void SetOccPlaneSizeRatio(const Vec2& vRatio) { m_fOccPlaneWidth = vRatio.x; m_fOccPlaneHeight = vRatio.y; } float GetOccPlaneWidth() const { return m_fOccPlaneWidth; } float GetOccPlaneHeight() const { return m_fOccPlaneHeight; } CTexture* GetGatherTexture() const; static bool ComputeProjPos(const Vec3& vWorldPos, const Matrix44A& viewMat, const Matrix44A& projMat, Vec3& outProjPos); static float ComputeLinearDepth(const Vec3& worldPos, const Matrix44A& cameraMat, float nearDist, float farDist); private: uint8 m_numVisibilityFaders; CSoftOcclusionVisiblityFader* m_pVisbilityFaders; int m_nID; float m_fOccResultCache; float m_fDirResultCache; Vec2 m_DirVecResultCache; Vec3 m_PosToBeChecked; float m_fOccPlaneWidth; float m_fOccPlaneHeight; volatile int m_refCount; }; class CSoftOcclusionManager { public: CSoftOcclusionManager() { m_nPos = 0; m_IndexBufferOffset = 0; m_IndexBufferCount = 0; m_bSuccessGenerateIB = false; } void AddSoftOcclusionQuery(CFlareSoftOcclusionQuery* pQuery, const Vec3& vPos); bool Begin(); void End(); int GetSize() { return m_nPos; } CFlareSoftOcclusionQuery* GetSoftOcclusionQuery(int nIndex) const; void GatherOcclusions(); void ComputeVisibility(); void ClearResources(); private: bool GenerateIndexBuffer(); bool m_bSuccessGenerateIB; uint32 m_IndexBufferOffset; uint32 m_IndexBufferCount; int m_nPos; _smart_ptr m_SoftOcclusionQueries[CFlareSoftOcclusionQuery::s_nIDMax]; }; #endif // CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_RENDELEMENTS_FLARESOFTOCCLUSIONQUERY_H