diff options
| author | Dan Goodliffe <dan@randomdan.homeip.net> | 2025-03-07 02:03:21 +0000 | 
|---|---|---|
| committer | Dan Goodliffe <dan@randomdan.homeip.net> | 2025-03-11 01:13:59 +0000 | 
| commit | 226a1909e727e1a85d2b88e3bdde86cff8cf4653 (patch) | |
| tree | b9443134ae950d9ee90a17f611a2143331583a12 /game | |
| parent | Add function to test if an AABB is visible in a frustum (diff) | |
| download | ilt-226a1909e727e1a85d2b88e3bdde86cff8cf4653.tar.bz2 ilt-226a1909e727e1a85d2b88e3bdde86cff8cf4653.tar.xz ilt-226a1909e727e1a85d2b88e3bdde86cff8cf4653.zip  | |
Only render terrain tiles which are visible in the frustum
Diffstat (limited to 'game')
| -rw-r--r-- | game/terrain.cpp | 17 | ||||
| -rw-r--r-- | game/terrain.h | 1 | 
2 files changed, 14 insertions, 4 deletions
diff --git a/game/terrain.cpp b/game/terrain.cpp index ee7dfa4..9202d20 100644 --- a/game/terrain.cpp +++ b/game/terrain.cpp @@ -1,4 +1,5 @@  #include "terrain.h" +#include "gfx/frustum.h"  #include <algorithm>  #include <gfx/gl/sceneShader.h>  #include <gfx/gl/shadowMapper.h> @@ -13,6 +14,7 @@  #include <vector>  static constexpr RGB OPEN_SURFACE {-1}; +static constexpr GlobalDistance TILE_SIZE = 1024 * 1024; // ~1km, power of 2, fast divide  template<>  VertexArrayObject & @@ -31,8 +33,6 @@ Terrain::SurfaceKey::operator<(const SurfaceKey & other) const  void  Terrain::generateMeshes()  { -	constexpr GlobalDistance TILE_SIZE = 1024 * 1024; // ~1km, power of 2, fast divide -  	std::ranges::transform(all_vertices(), glMappedBufferWriter<Vertex> {GL_ARRAY_BUFFER, verticesBuffer, n_vertices()},  			[this](const auto & vertex) {  				return Vertex {point(vertex), normal(vertex)}; @@ -97,13 +97,22 @@ Terrain::afterChange()  }  void -Terrain::render(const SceneShader & shader, const Frustum &) const +Terrain::render(const SceneShader & shader, const Frustum & frustum) const  {  	grass->bind(); + +	std::ranges::for_each(meshes, [ext = getExtents(), &frustum](const auto & surfaceDef) { +		const AxisAlignedBoundingBox tileAabb {{surfaceDef.first.basePosition * TILE_SIZE || ext.min.z}, +				{(surfaceDef.first.basePosition + 1) * TILE_SIZE || ext.max.z}}; +		surfaceDef.second.visible = frustum.contains(tileAabb); +	}); +  	const auto chunkBySurface = std::views::chunk_by([](const auto & itr1, const auto & itr2) {  		return itr1.first.surface == itr2.first.surface;  	}); -	for (const auto & surfaceRange : meshes | chunkBySurface) { +	for (const auto & surfaceRange : meshes | std::views::filter([](const auto & itr) { +			 return itr.second.visible; +		 }) | chunkBySurface) {  		const auto surface = surfaceRange.front().first.surface;  		shader.landmass.use(surface ? surface->colorBias : OPEN_SURFACE);  		for (const auto & sab : surfaceRange) { diff --git a/game/terrain.h b/game/terrain.h index 66887ed..40a5989 100644 --- a/game/terrain.h +++ b/game/terrain.h @@ -35,6 +35,7 @@ private:  		glVertexArray vertexArray;  		glBuffer indicesBuffer;  		GLsizei count; +		mutable bool visible;  	};  	struct SurfaceKey {  | 
