Skip to content

Commit

Permalink
Frustrum culling for tilemap (#8935)
Browse files Browse the repository at this point in the history
* Frustrum culling for tilemap.
  • Loading branch information
ekharkunov committed Jun 3, 2024
1 parent cb0d7b8 commit 985b43d
Showing 1 changed file with 43 additions and 4 deletions.
47 changes: 43 additions & 4 deletions engine/gamesys/src/gamesys/components/comp_tilegrid.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include <gameobject/gameobject.h>
#include <gameobject/gameobject_ddf.h>
#include <dmsdk/dlib/vmath.h>
#include <dmsdk/dlib/intersection.h>

#include "../gamesys_private.h"
#include "../gamesys.h"
Expand All @@ -55,9 +56,9 @@ namespace dmGameSystem
// where the the box spans TILEGRID_REGION_SIZE tiles in each direction
struct TileGridRegion
{
uint8_t m_Dirty:1;
uint8_t m_Occupied:1;
uint8_t :6;
uint8_t m_Dirty : 1;
uint8_t m_Occupied : 1;
uint8_t : 6;
};

struct TileGridLayer
Expand Down Expand Up @@ -631,6 +632,44 @@ namespace dmGameSystem
return where;
}

static void RenderListFrustumCulling(dmRender::RenderListVisibilityParams const &params)
{
DM_PROFILE("TileGridFrustrumCulling");
TileGridWorld* tilegrid_world = (TileGridWorld*)params.m_UserData;
const dmIntersection::Frustum frustum = *params.m_Frustum;
uint32_t num_entries = params.m_NumEntries;
for (uint32_t i = 0; i < num_entries; ++i)
{
dmRender::RenderListEntry* entry = &params.m_Entries[i];
uint32_t index, layer, region_x, region_y;
//entry->m_UserData - encoded region info
DecodeGridAndLayer(entry->m_UserData, index, layer, region_x, region_y);
TileGridComponent* component = tilegrid_world->m_Components[index];

TileGridResource* resource = component->m_Resource;
TextureSetResource* texture_set = GetTextureSet(component);
int32_t tile_width = (int32_t)texture_set->m_TextureSet->m_TileWidth;
int32_t tile_height = (int32_t)texture_set->m_TextureSet->m_TileHeight;

int32_t column_count = (int32_t)resource->m_ColumnCount;
int32_t row_count = (int32_t)resource->m_RowCount;
int32_t min_x = resource->m_MinCellX + region_x * TILEGRID_REGION_SIZE;
int32_t min_y = resource->m_MinCellY + region_y * TILEGRID_REGION_SIZE;

int32_t region_max_x = min_x + TILEGRID_REGION_SIZE;
int32_t tilemap_max_x = resource->m_MinCellX + column_count;
int32_t region_max_y = min_y + TILEGRID_REGION_SIZE;
int32_t tilemap_max_y = resource->m_MinCellY + row_count;
int32_t max_x = dmMath::Min(region_max_x, tilemap_max_x);
int32_t max_y = dmMath::Min(region_max_y, tilemap_max_y);

dmVMath::Vector3 min_corner = dmVMath::Vector3((float)(min_x * tile_width), (float)(min_y * tile_height), 0.f);
dmVMath::Vector3 max_corner = dmVMath::Vector3((float)(max_x * tile_width), (float)(max_y * tile_height), 0.f);
bool intersect = dmIntersection::TestFrustumOBB(frustum, component->m_World, min_corner, max_corner);
entry->m_Visibility = intersect ? dmRender::VISIBILITY_FULL : dmRender::VISIBILITY_NONE;
}
}

static void RenderBatch(TileGridWorld* world, dmRender::HRenderContext render_context, dmRender::RenderListEntry *buf, uint32_t* begin, uint32_t* end)
{
DM_PROFILE("TileGridRenderBatch");
Expand Down Expand Up @@ -779,7 +818,7 @@ namespace dmGameSystem

dmRender::HRenderContext render_context = context->m_RenderContext;
dmRender::RenderListEntry* render_list = dmRender::RenderListAlloc(render_context, num_render_entries);
dmRender::HRenderListDispatch dispatch = dmRender::RenderListMakeDispatch(render_context, &RenderListDispatch, world);
dmRender::HRenderListDispatch dispatch = dmRender::RenderListMakeDispatch(render_context, &RenderListDispatch, &RenderListFrustumCulling, world);
dmRender::RenderListEntry* write_ptr = render_list;

for (uint32_t i = 0; i < n; ++i)
Expand Down

0 comments on commit 985b43d

Please sign in to comment.