Files
GTASource/game/renderer/renderListGroup.cpp
expvintl 419f2e4752 init
2025-02-23 17:40:52 +08:00

144 lines
5.4 KiB
C++

// Title : RenderListGroup.h
// Authors : John Whyte, Alessandro Piva
// Started : 31/07/2006
//////////////
// Includes //
//////////////
#include "renderListGroup.h"
#include "fwrenderer/renderlistgroup.h"
#include "renderer/Shadows/ParaboloidShadows.h"
#include "renderer/PostScan.h"
#include "scene/Entity.h"
#define MAX_NUM_DEFERRED_ENTITY_LISTS (MAX_PARABOLOID_SHADOW_RENDERPHASES + 1 + 1 + 1 + 1) //1 for GBUF, 1 for cascaded shadows, 1 for draw scene alpha, 1 for mirror reflections, and rest from MAX_PARABOLOID_SHADOW_RENDERPHASES
#define MAX_NUM_DEFERRED_ENTITIES_PER_LIST (600)
struct DeferredEntityData
{
fwEntity* m_pEntity;
u32 m_subPhaseVisFlags;
float m_sortVal;
u16 m_flags;
};
struct DeferredListToProcess
{
int m_List;
fwRenderPassId m_renderPassId;
atArray<DeferredEntityData> m_entities;
};
static atArray<DeferredListToProcess> m_DeferredLists;
static int m_DeferredListsCount = 0;
void CGtaRenderListGroup::Init(unsigned initMode)
{
gRenderListGroup.Init(initMode, MAX_NUM_RENDER_PHASES, RPTYPE_NUM_RENDER_PHASE_TYPES, RPASS_NUM_RENDER_PASSES);
gRenderListGroup.SetRenderPhaseTypeInfo(RPTYPE_SHADOW, 9); // 1 for cascade shadows + 8 for local shadows
gRenderListGroup.SetRenderPhaseTypeInfo(RPTYPE_REFLECTION, 3); // 1 paraboloid + 1 water + 1 mirror
gRenderListGroup.SetRenderPhaseTypeInfo(RPTYPE_MAIN, 3);
gRenderListGroup.SetRenderPhaseTypeInfo(RPTYPE_STREAMING, 5); // 1 hd sphere + 1 lod sphere + 1 interior sphere + 2 stream vols
gRenderListGroup.SetRenderPhaseTypeInfo(RPTYPE_HEIGHTMAP, 1);
gRenderListGroup.SetRenderPhaseTypeInfo(RPTYPE_DEBUG, 1);
fwRenderListDesc::SetSortType(RPASS_VISIBLE, fwRenderListDesc::SORT_ASCENDING_PEDS_BIASED); // B*644704 Make peds in vehilces render after the vehicle
fwRenderListDesc::SetSortType(RPASS_LOD, fwRenderListDesc::SORT_ASCENDING);
fwRenderListDesc::SetSortType(RPASS_CUTOUT, fwRenderListDesc::SORT_DESCENDING);
fwRenderListDesc::SetSortType(RPASS_DECAL, fwRenderListDesc::SORT_ASCENDING);
fwRenderListDesc::SetSortType(RPASS_FADING, fwRenderListDesc::SORT_DESCENDING);
fwRenderListDesc::SetSortType(RPASS_ALPHA, fwRenderListDesc::SORT_DESCENDING);
fwRenderListDesc::SetSortType(RPASS_WATER, fwRenderListDesc::SORT_DESCENDING);
fwRenderListDesc::SetSortType(RPASS_TREE, fwRenderListDesc::SORT_ASCENDING);
m_DeferredLists.Reserve(MAX_NUM_DEFERRED_ENTITY_LISTS);
for(int i=0; i<MAX_NUM_DEFERRED_ENTITY_LISTS; i++)
{
DeferredListToProcess& deferredList = m_DeferredLists.Append();
deferredList.m_entities.Reserve(MAX_NUM_DEFERRED_ENTITIES_PER_LIST);
}
}
void CGtaRenderListGroup::DeferredAddEntity(int list, fwEntity* pEntity, u32 subphaseVisFlags, float sortVal, fwRenderPassId id, u16 flags)
{
DeferredEntityData data;
data.m_pEntity = pEntity;
data.m_subPhaseVisFlags = subphaseVisFlags;
data.m_sortVal = sortVal;
data.m_flags = flags;
int listCount = m_DeferredListsCount;
for(int i = 0; i < listCount; i++)
{
if(m_DeferredLists[i].m_List == list && m_DeferredLists[i].m_renderPassId == id)
{
Assertf(m_DeferredLists[i].m_entities.GetCount() < MAX_NUM_DEFERRED_ENTITIES_PER_LIST, "Reached Max amount of deferred entities in a list. Please increase MAX_NUM_DEFERRED_ENTITIES_PER_LIST = %d currently", MAX_NUM_DEFERRED_ENTITIES_PER_LIST);
if(m_DeferredLists[i].m_entities.GetCount() < MAX_NUM_DEFERRED_ENTITIES_PER_LIST)
{
m_DeferredLists[i].m_entities.Append() = data;
}
return;
}
}
Assertf(m_DeferredListsCount < MAX_NUM_DEFERRED_ENTITY_LISTS, "Reached Max amount of deferred entity list. Please increase MAX_NUM_DEFERRED_ENTITY_LISTS = %d currently", MAX_NUM_DEFERRED_ENTITY_LISTS);
if(m_DeferredListsCount < MAX_NUM_DEFERRED_ENTITY_LISTS)
{
DeferredListToProcess& newList = m_DeferredLists[m_DeferredListsCount++];
newList.m_List = list;
newList.m_renderPassId = id;
newList.m_entities.ResetCount();
newList.m_entities.Append() = data;
}
}
void CGtaRenderListGroup::ProcessDeferredAdditions()
{
int iListCount = m_DeferredListsCount;
if(!iListCount)
{
return;
}
#if SORT_RENDERLISTS_ON_SPU
// We sometimes decide to add entities to the render list after we've already kicked off the sort render list job.
// If we hit this point, we know that we have entities to add. We will wait for the render list sort to complete
// (if we don't, we risk the possibility of re-allocating the array as we add them and invalidating the addresses
// already passed to the sort job)
gPostScan.WaitForPostScanHelper();
gRenderListGroup.WaitForSortEntityListJob();
#endif //SORT_RENDERLISTS_ON_SPU
// Now that we know the sort is done, we can add these entities to the render lists
// and re-sort the lists that have been modified
for(int iList = 0; iList < iListCount; iList++)
{
fwRenderListDesc& listDesc = gRenderListGroup.GetRenderListForPhase(m_DeferredLists[iList].m_List);
fwRenderPassId renderPassId = m_DeferredLists[iList].m_renderPassId;
int iEntityCount = m_DeferredLists[iList].m_entities.GetCount();
for(int iEntity = 0; iEntity < iEntityCount; iEntity++)
{
DeferredEntityData &data = m_DeferredLists[iList].m_entities[iEntity];
listDesc.AddEntity(data.m_pEntity, data.m_subPhaseVisFlags, data.m_sortVal, renderPassId, data.m_flags);
}
listDesc.SortList(renderPassId);
}
gRenderListGroup.StartSortEntityListJob();
for(int i=0; i<m_DeferredListsCount; i++)
{
m_DeferredLists[i].m_List = -1;
m_DeferredLists[i].m_renderPassId = -1;
m_DeferredLists[i].m_entities.ResetCount();
}
m_DeferredListsCount = 0;
}