summaryrefslogtreecommitdiff
path: root/game/scenary/foliage.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'game/scenary/foliage.cpp')
-rw-r--r--game/scenary/foliage.cpp25
1 files changed, 22 insertions, 3 deletions
diff --git a/game/scenary/foliage.cpp b/game/scenary/foliage.cpp
index cefee9f..680d902 100644
--- a/game/scenary/foliage.cpp
+++ b/game/scenary/foliage.cpp
@@ -1,11 +1,24 @@
#include "foliage.h"
#include "gfx/frustum.h"
+#include "gfx/gl/billboardPainter.h"
#include "gfx/gl/sceneShader.h"
#include "gfx/gl/shadowMapper.h"
+#include "gfx/gl/shadowStenciller.h"
#include "gfx/gl/vertexArrayObject.h"
#include <location.h>
static_assert(std::is_constructible_v<Foliage>);
+constexpr float OBJECT_BILLBOARD_DIVISOR = 64;
+constexpr float ASSUMED_VIEWPORT = 1440;
+constexpr float OVER_SAMPLE_MULTIPLIER = 4; // Use mesh until billboard 1/4 of rendered size
+
+namespace {
+ GLsizei
+ billboardTextureSizeForObject(RelativeDistance objectSize)
+ {
+ return static_cast<GLsizei>(std::pow(2, std::ceil(std::log2(objectSize / OBJECT_BILLBOARD_DIVISOR))));
+ }
+}
std::any
Foliage::createAt(const Location & position) const
@@ -29,6 +42,12 @@ Foliage::postLoad()
instances.bufferName(), 1);
VertexArrayObject {instancePointVAO}.addAttribs<LocationVertex, &LocationVertex::position, &LocationVertex::yaw>(
instances.bufferName());
+
+ const auto & size = bodyMesh->getDimensions().size;
+ billboardSize = billboardTextureSizeForObject(size);
+ shadowStencil = ShadowStenciller::createStencilTexture(billboardSize, billboardSize);
+ billboard = BillboardPainter::createBillBoardTextures(billboardSize, billboardSize);
+ useMeshClipDist = (ASSUMED_VIEWPORT * OVER_SAMPLE_MULTIPLIER * size) / static_cast<RelativeDistance>(billboardSize);
}
void
@@ -51,13 +70,13 @@ void
Foliage::preFrame(const Frustum & frustum, const Frustum & lighting)
{
if (instances.size() > 0) {
- const auto dims = bodyMesh->getDimensions();
+ const auto & dims = bodyMesh->getDimensions();
instancePartitions = instances.partition(
[&frustum, &dims](const auto & location) {
return frustum.contains(location.position + dims.centre, dims.size);
},
- [&frustum](const auto & location) {
- return distance(frustum.getPosition(), location.position) < 140'000.F;
+ [&frustum, this](const auto & location) {
+ return distance(frustum.getPosition(), location.position) < useMeshClipDist;
},
[&lighting, &dims](const auto & location) {
return lighting.contains(location.position + dims.centre, dims.size);