summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Goodliffe <dan@randomdan.homeip.net>2023-04-23 21:31:41 +0100
committerDan Goodliffe <dan@randomdan.homeip.net>2023-04-23 21:31:41 +0100
commit687afb09ada73fb4aee932242a3b7ee492e63cb0 (patch)
treee8c654edf5b0927238c89d8c861afe9bed995c8c
parentAdd BufferedLocation (diff)
downloadilt-687afb09ada73fb4aee932242a3b7ee492e63cb0.tar.bz2
ilt-687afb09ada73fb4aee932242a3b7ee492e63cb0.tar.xz
ilt-687afb09ada73fb4aee932242a3b7ee492e63cb0.zip
Handle rendering of RailVehicles through RailVehicleClass instancing
Trains no longer need rendering as their parts are all RVC assets and that just works now. This commit creates some irritating duplication in RVC wrt body/2 bogies all of which are stored separately, but function in exactly the same way. This breaks RV shadows as we have no instancing shadow shaders yet.
-rw-r--r--game/vehicles/railVehicle.cpp29
-rw-r--r--game/vehicles/railVehicle.h12
-rw-r--r--game/vehicles/railVehicleClass.cpp44
-rw-r--r--game/vehicles/railVehicleClass.h15
-rw-r--r--game/vehicles/train.cpp11
-rw-r--r--game/vehicles/train.h3
-rw-r--r--game/vehicles/vehicle.h2
-rw-r--r--test/test-assetFactory.cpp2
-rw-r--r--test/test-render.cpp14
9 files changed, 60 insertions, 72 deletions
diff --git a/game/vehicles/railVehicle.cpp b/game/vehicles/railVehicle.cpp
index 77907be..b77b93c 100644
--- a/game/vehicles/railVehicle.cpp
+++ b/game/vehicles/railVehicle.cpp
@@ -11,22 +11,14 @@
#include <memory>
#include <ray.hpp>
-RailVehicle::RailVehicle(RailVehicleClassPtr rvc) : rvClass {std::move(rvc)}
+RailVehicle::RailVehicle(RailVehicleClassPtr rvc) :
+ rvClass {std::move(rvc)}, location {rvClass->instancesBody}, bogies {
+ rvClass->instancesBogies.front(),
+ rvClass->instancesBogies.back(),
+ }
{
- bogies.front().pos.y = rvClass->wheelBase / 2.F;
- bogies.back().pos.y = -bogies.front().pos.y;
-}
-
-void
-RailVehicle::render(const SceneShader & shader) const
-{
- rvClass->render(shader, location, bogies);
-}
-
-void
-RailVehicle::shadows(const ShadowMapper & shadowMapper) const
-{
- rvClass->shadows(shadowMapper, location, bogies);
+ bogies.front().setPosition({0, rvClass->wheelBase / 2.F, 0});
+ bogies.back().setPosition({0, -bogies.front().position().y, 0});
}
void
@@ -35,9 +27,8 @@ RailVehicle::move(const Train * t, float & trailBy)
const auto overhang {(rvClass->length - rvClass->wheelBase) / 2};
const auto & b1Pos = bogies[0] = t->getBogiePosition(t->linkDist, trailBy += overhang);
const auto & b2Pos = bogies[1] = t->getBogiePosition(t->linkDist, trailBy += rvClass->wheelBase);
- const auto diff = glm::normalize(b2Pos.pos - b1Pos.pos);
- location.pos = (b1Pos.pos + b2Pos.pos) / 2.F;
- location.rot = {vector_pitch(diff), vector_yaw(diff), 0};
+ const auto diff = glm::normalize(b2Pos.position() - b1Pos.position());
+ location.setLocation((b1Pos.position() + b2Pos.position()) / 2.F, {vector_pitch(diff), vector_yaw(diff), 0});
trailBy += 0.6F + overhang;
}
@@ -47,7 +38,7 @@ RailVehicle::intersectRay(const Ray & ray, glm::vec2 * baryPos, float * distance
constexpr const auto X = 1.35F;
const auto Y = this->rvClass->length / 2.F;
constexpr const auto Z = 3.9F;
- const auto moveBy = glm::translate(location.pos) * rotate_ypr(location.rot);
+ const auto moveBy = location.getTransform();
const std::array<glm::vec3, 8> cornerVertices {{
moveBy * glm::vec4 {-X, Y, 0, 1}, // LFB
moveBy * glm::vec4 {X, Y, 0, 1}, // RFB
diff --git a/game/vehicles/railVehicle.h b/game/vehicles/railVehicle.h
index bbf4df9..247bf66 100644
--- a/game/vehicles/railVehicle.h
+++ b/game/vehicles/railVehicle.h
@@ -1,11 +1,10 @@
#pragma once
-#include "gfx/renderable.h"
+#include "gfx/gl/bufferedLocation.h"
#include "railVehicleClass.h"
#include <array>
#include <game/selectable.h>
#include <glm/glm.hpp>
-#include <location.hpp>
#include <memory>
#include <utility>
@@ -14,19 +13,16 @@ class ShadowMapper;
class Ray;
class Train;
-class RailVehicle : public Renderable, Selectable {
+class RailVehicle : Selectable {
public:
explicit RailVehicle(RailVehicleClassPtr rvc);
void move(const Train *, float & trailBy);
- void render(const SceneShader & shader) const override;
- void shadows(const ShadowMapper & shadowMapper) const override;
[[nodiscard]] bool intersectRay(const Ray &, glm::vec2 *, float *) const override;
- Location location;
-
RailVehicleClassPtr rvClass;
- std::array<Location, 2> bogies;
+ BufferedLocation location;
+ std::array<BufferedLocation, 2> bogies;
};
using RailVehiclePtr = std::unique_ptr<RailVehicle>;
diff --git a/game/vehicles/railVehicleClass.cpp b/game/vehicles/railVehicleClass.cpp
index b7a3b1e..3e62bf1 100644
--- a/game/vehicles/railVehicleClass.cpp
+++ b/game/vehicles/railVehicleClass.cpp
@@ -1,6 +1,7 @@
#include "railVehicleClass.h"
#include "gfx/gl/sceneShader.h"
#include "gfx/gl/shadowMapper.h"
+#include "gfx/gl/vertexArrayObject.hpp"
#include "gfx/models/mesh.h"
#include "gfx/models/texture.h"
#include <algorithm>
@@ -33,30 +34,37 @@ void
RailVehicleClass::postLoad()
{
texture = getTexture();
+ bodyMesh->configureVAO(instanceVAO).addAttribs<glm::mat4>(instancesBody.bufferName(), 1);
+ bogies.front()
+ ->configureVAO(instancesBogiesVAO.front())
+ .addAttribs<glm::mat4>(instancesBogies.front().bufferName(), 1);
+ bogies.back()
+ ->configureVAO(instancesBogiesVAO.back())
+ .addAttribs<glm::mat4>(instancesBogies.back().bufferName(), 1);
}
void
-RailVehicleClass::render(
- const SceneShader & shader, const Location & location, const std::array<Location, 2> & bl) const
+RailVehicleClass::render(const SceneShader & shader) const
{
- shader.basic.use(location);
- if (texture) {
- texture->bind();
- }
- bodyMesh->Draw();
- for (auto b = 0U; b < bogies.size(); ++b) {
- shader.basic.setModel(bl[b]);
- bogies[b]->Draw();
+ if (const auto count = instancesBody.count()) {
+ if (texture) {
+ texture->bind();
+ }
+ shader.basicInst.use();
+ glBindVertexArray(instanceVAO);
+ glDrawElementsInstanced(
+ bodyMesh->type(), bodyMesh->count(), GL_UNSIGNED_INT, nullptr, static_cast<GLsizei>(count));
+ glBindVertexArray(instancesBogiesVAO.front());
+ glDrawElementsInstanced(bogies.front()->type(), bogies.front()->count(), GL_UNSIGNED_INT, nullptr,
+ static_cast<GLsizei>(instancesBogies.front().count()));
+ glBindVertexArray(instancesBogiesVAO.back());
+ glDrawElementsInstanced(bogies.back()->type(), bogies.back()->count(), GL_UNSIGNED_INT, nullptr,
+ static_cast<GLsizei>(instancesBogies.back().count()));
+ glBindVertexArray(0);
}
}
+
void
-RailVehicleClass::shadows(
- const ShadowMapper & shadowMapper, const Location & location, const std::array<Location, 2> & bl) const
+RailVehicleClass::shadows(const ShadowMapper &) const
{
- shadowMapper.dynamicPoint.use(location);
- bodyMesh->Draw();
- for (auto b = 0U; b < bogies.size(); ++b) {
- shadowMapper.dynamicPoint.setModel(bl[b]);
- bogies[b]->Draw();
- }
}
diff --git a/game/vehicles/railVehicleClass.h b/game/vehicles/railVehicleClass.h
index 1a52e2b..2fda8f7 100644
--- a/game/vehicles/railVehicleClass.h
+++ b/game/vehicles/railVehicleClass.h
@@ -1,7 +1,9 @@
#pragma once
#include "assetFactory/asset.h"
+#include "gfx/gl/instanceVertices.h"
#include "gfx/models/mesh.h"
+#include "gfx/renderable.h"
#include <array>
#include <memory>
#include <string>
@@ -11,10 +13,10 @@ class ShadowMapper;
class Texture;
class Location;
-class RailVehicleClass : public Asset {
+class RailVehicleClass : public Renderable, public Asset {
public:
- void render(const SceneShader &, const Location &, const std::array<Location, 2> &) const;
- void shadows(const ShadowMapper &, const Location &, const std::array<Location, 2> &) const;
+ void render(const SceneShader & shader) const override;
+ void shadows(const ShadowMapper & shadowMapper) const override;
std::array<Mesh::Ptr, 2> bogies;
Mesh::Ptr bodyMesh;
@@ -23,9 +25,16 @@ public:
float length;
float maxSpeed;
+ mutable InstanceVertices<glm::mat4> instancesBody;
+ mutable std::array<InstanceVertices<glm::mat4>, 2> instancesBogies;
+
protected:
friend Persistence::SelectionPtrBase<std::shared_ptr<RailVehicleClass>>;
bool persist(Persistence::PersistenceStore & store) override;
void postLoad() override;
+
+private:
+ glVertexArray instanceVAO;
+ std::array<glVertexArray, 2> instancesBogiesVAO;
};
using RailVehicleClassPtr = std::shared_ptr<RailVehicleClass>;
diff --git a/game/vehicles/train.cpp b/game/vehicles/train.cpp
index 0332c04..fdfc3e1 100644
--- a/game/vehicles/train.cpp
+++ b/game/vehicles/train.cpp
@@ -11,17 +11,6 @@
class Ray;
-void
-Train::render(const SceneShader & shader) const
-{
- apply(&Renderable::render, shader);
-}
-void
-Train::shadows(const ShadowMapper & shadowMapper) const
-{
- apply(&Renderable::shadows, shadowMapper);
-}
-
Location
Train::getBogiePosition(float linkDist, float dist) const
{
diff --git a/game/vehicles/train.h b/game/vehicles/train.h
index 91f7ddb..15e2f6e 100644
--- a/game/vehicles/train.h
+++ b/game/vehicles/train.h
@@ -27,9 +27,6 @@ public:
return objects.front()->location;
}
- void render(const SceneShader & shader) const override;
- void shadows(const ShadowMapper & shadowMapper) const override;
-
[[nodiscard]] bool intersectRay(const Ray &, glm::vec2 *, float *) const override;
void tick(TickDuration elapsed) override;
diff --git a/game/vehicles/vehicle.h b/game/vehicles/vehicle.h
index 3fa3092..369bd7a 100644
--- a/game/vehicles/vehicle.h
+++ b/game/vehicles/vehicle.h
@@ -12,7 +12,7 @@
class Location;
-class Vehicle : public WorldObject, public Renderable, public Selectable {
+class Vehicle : public WorldObject, public Selectable {
public:
explicit Vehicle(const Link::Ptr & link, float linkDist = 0);
float linkDist; // distance along current link
diff --git a/test/test-assetFactory.cpp b/test/test-assetFactory.cpp
index 82a1825..c0edd66 100644
--- a/test/test-assetFactory.cpp
+++ b/test/test-assetFactory.cpp
@@ -93,7 +93,7 @@ BOOST_AUTO_TEST_CASE(brush47xml, *boost::unit_test::timeout(5))
BOOST_REQUIRE(brush47rvc->bogies.back());
auto railVehicle = std::make_shared<RailVehicle>(brush47rvc);
- objects.objects.push_back(railVehicle);
+ objects.objects.push_back(brush47rvc);
render();
}
diff --git a/test/test-render.cpp b/test/test-render.cpp
index 1643068..0fbeb2b 100644
--- a/test/test-render.cpp
+++ b/test/test-render.cpp
@@ -22,6 +22,8 @@
class TestScene : public SceneProvider {
std::shared_ptr<RailVehicle> train1, train2;
+ const RailVehicleClassPtr brush47rvc = std::dynamic_pointer_cast<RailVehicleClass>(
+ AssetFactory::loadXML(RESDIR "/brush47.xml")->assets.at("brush-47"));
Terrain terrain {[]() {
auto gd = std::make_shared<GeoData>(GeoData::Limits {{0, 0}, {100, 100}});
@@ -32,19 +34,16 @@ class TestScene : public SceneProvider {
public:
TestScene()
{
- const auto assetFactory = AssetFactory::loadXML(RESDIR "/brush47.xml");
- const auto brush47rvc = std::dynamic_pointer_cast<RailVehicleClass>(assetFactory->assets.at("brush-47"));
train1 = std::make_shared<RailVehicle>(brush47rvc);
- train1->location.pos = {52, 50, 2};
+ train1->location.setPosition({52, 50, 2});
train2 = std::make_shared<RailVehicle>(brush47rvc);
- train2->location.pos = {52, 30, 2};
+ train2->location.setPosition({52, 30, 2});
}
void
content(const SceneShader & shader) const override
{
terrain.render(shader);
- train1->render(shader);
- train2->render(shader);
+ brush47rvc->render(shader);
}
void
lights(const SceneShader &) const override
@@ -54,8 +53,7 @@ public:
shadows(const ShadowMapper & shadowMapper) const override
{
terrain.shadows(shadowMapper);
- train1->shadows(shadowMapper);
- train2->shadows(shadowMapper);
+ brush47rvc->shadows(shadowMapper);
}
};