VOXELWORLDRENDER: prepare to readd plant support

master
Martin Gerhardy 2020-09-12 19:35:58 +02:00
parent e5ca8e44c0
commit b80680fe4d
15 changed files with 159 additions and 23 deletions

View File

@ -48,11 +48,13 @@ Client::Client(const metric::MetricPtr& metric, const animation::AnimationCacheP
const video::TexturePoolPtr& texturePool, const video::TexturePoolPtr& texturePool,
const voxelrender::CachedMeshRendererPtr& meshRenderer, const voxelrender::CachedMeshRendererPtr& meshRenderer,
const video::TextureAtlasRendererPtr& textureAtlasRenderer, const video::TextureAtlasRendererPtr& textureAtlasRenderer,
const audio::SoundManagerPtr& soundManager) : const audio::SoundManagerPtr& soundManager,
Super(metric, filesystem, eventBus, timeProvider, texturePool, meshRenderer, textureAtlasRenderer), _animationCache(animationCache), const voxelworldrender::AssetVolumeCachePtr& assetVolumeCache) :
_network(network), _worldMgr(world), _clientPager(worldPager), _messageSender(messageSender), _movement(soundManager), Super(metric, filesystem, eventBus, timeProvider, texturePool, meshRenderer, textureAtlasRenderer),
_stockDataProvider(stockDataProvider), _volumeCache(volumeCache), _animationCache(animationCache), _network(network), _worldMgr(world), _clientPager(worldPager),
_meshCache(meshCache), _camera(_worldRenderer), _soundManager(soundManager) { _messageSender(messageSender), _worldRenderer(assetVolumeCache), _movement(soundManager),
_stockDataProvider(stockDataProvider), _volumeCache(volumeCache), _meshCache(meshCache),
_camera(_worldRenderer), _soundManager(soundManager) {
init(ORGANISATION, "client"); init(ORGANISATION, "client");
} }
@ -124,6 +126,7 @@ app::AppState Client::onConstruct() {
_action.construct(); _action.construct();
_camera.construct(); _camera.construct();
_meshCache->construct(); _meshCache->construct();
_assetVolumeCache->construct();
core::Var::get(cfg::ClientPort, SERVER_PORT, "Server port"); core::Var::get(cfg::ClientPort, SERVER_PORT, "Server port");
core::Var::get(cfg::ClientHost, SERVER_HOST, "Server hostname or ip"); core::Var::get(cfg::ClientHost, SERVER_HOST, "Server hostname or ip");
@ -229,6 +232,11 @@ app::AppState Client::onInit() {
return app::AppState::InitFailure; return app::AppState::InitFailure;
} }
if (!_assetVolumeCache->init()) {
Log::error("Failed to init asset volume cache");
return app::AppState::InitFailure;
}
if (!_worldMgr->init()) { if (!_worldMgr->init()) {
Log::error("Failed to initialize world manager"); Log::error("Failed to initialize world manager");
return app::AppState::InitFailure; return app::AppState::InitFailure;
@ -345,7 +353,8 @@ app::AppState Client::onCleanup() {
_action.shutdown(); _action.shutdown();
_camera.shutdown(); _camera.shutdown();
_meshCache->shutdown(); _meshCache->shutdown();
Log::info("shutting down the volume cache"); Log::info("shutting down the volume caches");
_assetVolumeCache->shutdown();
_volumeCache->shutdown(); _volumeCache->shutdown();
compute::shutdown(); compute::shutdown();
Log::info("everything was shut down"); Log::info("everything was shut down");
@ -451,8 +460,9 @@ int main(int argc, char *argv[]) {
const stock::StockDataProviderPtr& stockDataProvider = std::make_shared<stock::StockDataProvider>(); const stock::StockDataProviderPtr& stockDataProvider = std::make_shared<stock::StockDataProvider>();
const video::TexturePoolPtr& texturePool = std::make_shared<video::TexturePool>(filesystem); const video::TexturePoolPtr& texturePool = std::make_shared<video::TexturePool>(filesystem);
const audio::SoundManagerPtr& soundMgr = core::make_shared<audio::SoundManager>(filesystem); const audio::SoundManagerPtr& soundMgr = core::make_shared<audio::SoundManager>(filesystem);
const voxelworldrender::AssetVolumeCachePtr& assetVolumeCache = core::make_shared<voxelworldrender::AssetVolumeCache>(volumeCache);
Client app(metric, animationCache, stockDataProvider, network, world, pager, messageSender, Client app(metric, animationCache, stockDataProvider, network, world, pager, messageSender,
eventBus, timeProvider, filesystem, volumeCache, meshCache, texturePool, meshRenderer, textureAtlasRenderer, eventBus, timeProvider, filesystem, volumeCache, meshCache, texturePool, meshRenderer, textureAtlasRenderer,
soundMgr); soundMgr, assetVolumeCache);
return app.startMainLoop(argc, argv); return app.startMainLoop(argc, argv);
} }

View File

@ -54,6 +54,7 @@ protected:
voxelformat::MeshCachePtr _meshCache; voxelformat::MeshCachePtr _meshCache;
voxelworldrender::PlayerCamera _camera; voxelworldrender::PlayerCamera _camera;
audio::SoundManagerPtr _soundManager; audio::SoundManagerPtr _soundManager;
voxelworldrender::AssetVolumeCachePtr _assetVolumeCache;
frontend::ClientEntityId id() const; frontend::ClientEntityId id() const;
@ -78,7 +79,8 @@ public:
const video::TexturePoolPtr& texturePool, const video::TexturePoolPtr& texturePool,
const voxelrender::CachedMeshRendererPtr& meshRenderer, const voxelrender::CachedMeshRendererPtr& meshRenderer,
const video::TextureAtlasRendererPtr& textureAtlasRenderer, const video::TextureAtlasRendererPtr& textureAtlasRenderer,
const audio::SoundManagerPtr& soundManager); const audio::SoundManagerPtr& soundManager,
const voxelworldrender::AssetVolumeCachePtr& assetVolumeCache);
~Client(); ~Client();
app::AppState onConstruct() override; app::AppState onConstruct() override;

View File

@ -86,7 +86,7 @@ void ClientEntityRenderer::shutdown() {
_animationSystem.shutdown(); _animationSystem.shutdown();
} }
void ClientEntityRenderer::update(const glm::vec3& focusPos, float seconds) { void ClientEntityRenderer::update(const glm::vec3& focusPos, double seconds) {
_focusPos = focusPos; _focusPos = focusPos;
_seconds = seconds; _seconds = seconds;
} }

View File

@ -39,7 +39,7 @@ private:
float _viewDistance = 0.0f; float _viewDistance = 0.0f;
float _fogRange = 0.0f; float _fogRange = 0.0f;
float _seconds = 0.0f; double _seconds = 0.0;
glm::vec3 _focusPos { 0.0f }; glm::vec3 _focusPos { 0.0f };
@ -52,7 +52,7 @@ public:
bool init() override; bool init() override;
void shutdown() override; void shutdown() override;
void update(const glm::vec3& focusPos, float seconds); void update(const glm::vec3& focusPos, double seconds);
void bindEntitiesDepthBuffer(video::TextureUnit texunit); void bindEntitiesDepthBuffer(video::TextureUnit texunit);

View File

@ -0,0 +1,51 @@
/**
* @file
*/
#include "AssetVolumeCache.h"
#include "app/App.h"
#include "core/Log.h"
#include "core/StringUtil.h"
#include "voxelformat/VolumeFormat.h"
#include "io/Filesystem.h"
#include <glm/vec3.hpp>
#include <glm/common.hpp>
namespace voxelworldrender {
AssetVolumeCache::AssetVolumeCache(const voxelformat::VolumeCachePtr& volumeCache) :
_volumeCache(volumeCache) {
}
bool AssetVolumeCache::init() {
Log::debug("Initialize the asset volume cache");
for (const char **ext = voxelformat::SUPPORTED_VOXEL_FORMATS_LOAD_LIST; *ext; ++ext) {
core::DynamicArray<io::Filesystem::DirEntry> files;
if (!io::filesystem()->list("models/plants/", files, core::string::format("*.%s", *ext))) {
Log::warn("Failed to list assets from models/plants/");
break;
}
_plantCount += (int)files.size();
}
Log::debug("Found %i plants", _plantCount);
return true;
}
void AssetVolumeCache::shutdown() {
_volumeCache = voxelformat::VolumeCachePtr();
}
voxel::RawVolume* AssetVolumeCache::loadPlant(const glm::ivec3& pos) {
if (_plantCount <= 0) {
return nullptr;
}
const int index = 1 + (glm::abs(pos.x + pos.z) % _plantCount);
char filename[64];
if (!core::string::formatBuf(filename, sizeof(filename), "models/plants/%i", index)) {
Log::error("Failed to assemble plant path");
return nullptr;
}
return _volumeCache->loadVolume(filename);
}
}

View File

@ -0,0 +1,42 @@
/**
* @file
*/
#pragma once
#include "core/IComponent.h"
#include "core/SharedPtr.h"
#include "voxelformat/VolumeCache.h"
#include "core/collection/StringMap.h"
#include <glm/fwd.hpp>
namespace voxelworldrender {
/**
* @brief This cache is for volume models that are not part of the world volumes.
* They can be used to only render them (e.g. plants) or to let the player interact
* with them (e.g. a chest entity)
* @sa voxelworld::TreeVolumeCache
*/
class AssetVolumeCache : public core::IComponent {
private:
voxelformat::VolumeCachePtr _volumeCache;
int _plantCount = 0;
public:
AssetVolumeCache(const voxelformat::VolumeCachePtr& volumeCache);
bool init() override;
void shutdown() override;
/**
* @brief Ensure that the same volume is returned for the same input parameters.
* @param[in] pos world position
* @return voxel::RawVolume or @c nullptr if no suitable plant was found.
* @note Plants are stored by index in @c models/plants/
*/
voxel::RawVolume* loadPlant(const glm::ivec3& pos);
};
typedef core::SharedPtr<AssetVolumeCache> AssetVolumeCachePtr;
}

View File

@ -1,6 +1,7 @@
set(LIB voxelworldrender) set(LIB voxelworldrender)
set(SRCS set(SRCS
WorldRenderer.h WorldRenderer.cpp WorldRenderer.h WorldRenderer.cpp
AssetVolumeCache.h AssetVolumeCache.cpp
PlayerCamera.cpp PlayerCamera.h PlayerCamera.cpp PlayerCamera.h
worldrenderer/WorldChunkMgr.h worldrenderer/WorldChunkMgr.cpp worldrenderer/WorldChunkMgr.h worldrenderer/WorldChunkMgr.cpp
@ -21,6 +22,11 @@ set(FILES
sky/sky_up.png sky/sky_up.png
shared/water-distortion.png shared/water-distortion.png
shared/water-normal.png shared/water-normal.png
voxel/models/plants/1.qb
voxel/models/plants/2.qb
voxel/models/plants/3.qb
voxel/models/plants/4.qb
) )
engine_add_module(TARGET ${LIB} SRCS ${SRCS} ${SRCS_SHADERS} FILES ${FILES} DEPENDENCIES frontend voxelrender) engine_add_module(TARGET ${LIB} SRCS ${SRCS} ${SRCS_SHADERS} FILES ${FILES} DEPENDENCIES frontend voxelrender)
generate_shaders(${LIB} world water postprocess) generate_shaders(${LIB} world water postprocess)

View File

@ -43,8 +43,9 @@ alignas(16) static constexpr glm::vec2 waterPlaneVecs[] = {
{ -1.0f, 1.0f} { -1.0f, 1.0f}
}; };
WorldRenderer::WorldRenderer() : WorldRenderer::WorldRenderer(const AssetVolumeCachePtr& assetVolumeCache) :
_threadPool(1, "WorldRenderer"), _worldChunkMgr(_threadPool), _shadowMapShader(shader::ShadowmapShader::getInstance()) { _threadPool(1, "WorldRenderer"), _worldChunkMgr(_threadPool), _assetVolumeCache(assetVolumeCache),
_shadowMapShader(shader::ShadowmapShader::getInstance()) {
setViewDistance(800.0f); setViewDistance(800.0f);
} }
@ -239,7 +240,7 @@ int WorldRenderer::renderTerrain(const glm::mat4& viewProjectionMatrix, const gl
} }
_worldShader.setFocuspos(_focusPos); _worldShader.setFocuspos(_focusPos);
_worldShader.setLightdir(_shadow.sunDirection()); _worldShader.setLightdir(_shadow.sunDirection());
_worldShader.setTime(_seconds); _worldShader.setTime((float)_seconds);
_worldShader.setFogrange(_fogRange); _worldShader.setFogrange(_fogRange);
_worldShader.setClipplane(clipPlane); _worldShader.setClipplane(clipPlane);
_worldShader.setViewprojection(viewProjectionMatrix); _worldShader.setViewprojection(viewProjectionMatrix);
@ -314,6 +315,7 @@ int WorldRenderer::renderAll(const video::Camera& camera) {
const glm::mat4& vpmat = camera.viewProjectionMatrix(); const glm::mat4& vpmat = camera.viewProjectionMatrix();
drawCallsWorld += renderTerrain(vpmat, ignoreClipPlane); drawCallsWorld += renderTerrain(vpmat, ignoreClipPlane);
drawCallsWorld += renderEntities(vpmat, ignoreClipPlane); drawCallsWorld += renderEntities(vpmat, ignoreClipPlane);
drawCallsWorld += renderPlants(vpmat, ignoreClipPlane);
drawCallsWorld += renderEntityDetails(camera); drawCallsWorld += renderEntityDetails(camera);
drawCallsWorld += renderWater(camera, ignoreClipPlane); drawCallsWorld += renderWater(camera, ignoreClipPlane);
_skybox.render(camera); _skybox.render(camera);
@ -324,6 +326,12 @@ int WorldRenderer::renderEntitiesToDepthMap(const video::Camera& camera) {
return _entityRenderer.renderEntitiesToDepthMap(_entityMgr.visibleEntities(), camera.viewProjectionMatrix()); return _entityRenderer.renderEntitiesToDepthMap(_entityMgr.visibleEntities(), camera.viewProjectionMatrix());
} }
int WorldRenderer::renderPlants(const glm::mat4& viewProjectionMatrix, const glm::vec4& clipPlane) {
// TODO: instanced volume rendering
// place plants to chunk in WorldChunkMgr and use the positions for the instanced rendering here.
return 0;
}
int WorldRenderer::renderEntities(const glm::mat4& viewProjectionMatrix, const glm::vec4& clipPlane) { int WorldRenderer::renderEntities(const glm::mat4& viewProjectionMatrix, const glm::vec4& clipPlane) {
return _entityRenderer.renderEntities(_entityMgr.visibleEntities(), viewProjectionMatrix, clipPlane, _shadow); return _entityRenderer.renderEntities(_entityMgr.visibleEntities(), viewProjectionMatrix, clipPlane, _shadow);
} }

View File

@ -7,6 +7,7 @@
#include "RenderShaders.h" #include "RenderShaders.h"
#include "AnimationShaders.h" #include "AnimationShaders.h"
#include "VoxelworldrenderShaders.h" #include "VoxelworldrenderShaders.h"
#include "voxelworldrender/AssetVolumeCache.h"
#include "worldrenderer/WorldChunkMgr.h" #include "worldrenderer/WorldChunkMgr.h"
#include "core/Color.h" #include "core/Color.h"
#include "core/GLM.h" #include "core/GLM.h"
@ -46,6 +47,7 @@ protected:
video::TexturePtr _normalTexture; video::TexturePtr _normalTexture;
render::Skybox _skybox; render::Skybox _skybox;
frontend::ClientEntityRenderer _entityRenderer; frontend::ClientEntityRenderer _entityRenderer;
AssetVolumeCachePtr _assetVolumeCache;
video::FrameBuffer _frameBuffer; video::FrameBuffer _frameBuffer;
video::FrameBuffer _reflectionBuffer; video::FrameBuffer _reflectionBuffer;
@ -92,9 +94,9 @@ protected:
int renderAll(const video::Camera& camera); int renderAll(const video::Camera& camera);
int renderTerrain(const glm::mat4& viewProjectionMatrix, const glm::vec4& clipPlane); int renderTerrain(const glm::mat4& viewProjectionMatrix, const glm::vec4& clipPlane);
int renderEntities(const glm::mat4& viewProjectionMatrix, const glm::vec4& clipPlane); int renderEntities(const glm::mat4& viewProjectionMatrix, const glm::vec4& clipPlane);
int renderPlants(const glm::mat4& viewProjectionMatrix, const glm::vec4& clipPlane);
int renderEntityDetails(const video::Camera& camera); int renderEntityDetails(const video::Camera& camera);
int renderWater(const video::Camera& camera, const glm::vec4& clipPlane); int renderWater(const video::Camera& camera, const glm::vec4& clipPlane);
/** /**
* @brief 2-pass render of the reflection and the refraction buffers * @brief 2-pass render of the reflection and the refraction buffers
*/ */
@ -104,7 +106,7 @@ protected:
*/ */
int renderPostProcessEffects(const video::Camera& camera); int renderPostProcessEffects(const video::Camera& camera);
public: public:
WorldRenderer(); WorldRenderer(const AssetVolumeCachePtr& assetVolumeCache);
~WorldRenderer(); ~WorldRenderer();
void reset(); void reset();

View File

@ -23,6 +23,7 @@
#include "attrib/Attributes.h" #include "attrib/Attributes.h"
#include "attrib/ContainerProvider.h" #include "attrib/ContainerProvider.h"
#include "audio/SoundManager.h" #include "audio/SoundManager.h"
#include "voxelworldrender/AssetVolumeCache.h"
#include <SDL.h> #include <SDL.h>
#define GLM_ENABLE_EXPERIMENTAL #define GLM_ENABLE_EXPERIMENTAL
#include <glm/gtx/string_cast.hpp> #include <glm/gtx/string_cast.hpp>
@ -35,11 +36,13 @@ MapView::MapView(const metric::MetricPtr& metric, const animation::AnimationCach
const voxelworld::WorldPagerPtr& worldPager, const voxelworld::WorldPagerPtr& worldPager,
const voxelformat::VolumeCachePtr& volumeCache, const voxelformat::VolumeCachePtr& volumeCache,
const voxelformat::MeshCachePtr& meshCache, const voxelformat::MeshCachePtr& meshCache,
const audio::SoundManagerPtr& soundManager) : const audio::SoundManagerPtr& soundManager,
const voxelworldrender::AssetVolumeCachePtr& assetVolumeCache) :
Super(metric, filesystem, eventBus, timeProvider), Super(metric, filesystem, eventBus, timeProvider),
_animationCache(animationCache), _worldMgr(worldMgr), _worldPager(worldPager), _movement(soundManager), _animationCache(animationCache), _worldRenderer(assetVolumeCache), _worldMgr(worldMgr),
_stockDataProvider(stockDataProvider), _volumeCache(volumeCache), _meshCache(meshCache), _worldPager(worldPager), _movement(soundManager), _stockDataProvider(stockDataProvider),
_camera(_worldRenderer), _soundManager(soundManager) { _volumeCache(volumeCache), _meshCache(meshCache), _camera(_worldRenderer),
_soundManager(soundManager), _assetVolumeCache(assetVolumeCache) {
init(ORGANISATION, "mapview"); init(ORGANISATION, "mapview");
} }
@ -51,6 +54,8 @@ app::AppState MapView::onConstruct() {
_rotationSpeed = core::Var::getSafe(cfg::ClientMouseRotationSpeed); _rotationSpeed = core::Var::getSafe(cfg::ClientMouseRotationSpeed);
_assetVolumeCache->construct();
_movement.construct(); _movement.construct();
_action.construct(); _action.construct();
_camera.construct(); _camera.construct();
@ -107,6 +112,11 @@ app::AppState MapView::onInit() {
return app::AppState::InitFailure; return app::AppState::InitFailure;
} }
if (!_assetVolumeCache->init()) {
Log::error("Failed to init asset volume cache");
return app::AppState::InitFailure;
}
if (!_movement.init()) { if (!_movement.init()) {
Log::error("Failed to init movement"); Log::error("Failed to init movement");
return app::AppState::InitFailure; return app::AppState::InitFailure;
@ -192,7 +202,7 @@ bool MapView::changeEntityType(const glm::vec3& pos, const network::EntityType e
attrib::Attributes attributes; attrib::Attributes attributes;
attributes.add(attribContainer); attributes.add(attribContainer);
attributes.update(0l); attributes.update(0l);
const float speed = attributes.max(attrib::Type::SPEED); const double speed = attributes.max(attrib::Type::SPEED);
_entity->attrib().setCurrent(attrib::Type::SPEED, speed); _entity->attrib().setCurrent(attrib::Type::SPEED, speed);
_worldRenderer.entityMgr().removeEntity(_entity->id()); _worldRenderer.entityMgr().removeEntity(_entity->id());
if (!_worldRenderer.entityMgr().addEntity(_entity)) { if (!_worldRenderer.entityMgr().addEntity(_entity)) {
@ -421,6 +431,7 @@ app::AppState MapView::onCleanup() {
_stockDataProvider->shutdown(); _stockDataProvider->shutdown();
_animationCache->shutdown(); _animationCache->shutdown();
_worldRenderer.shutdown(); _worldRenderer.shutdown();
_assetVolumeCache->shutdown();
_volumeCache->shutdown(); _volumeCache->shutdown();
_depthBufferRenderer.shutdown(); _depthBufferRenderer.shutdown();
_axis.shutdown(); _axis.shutdown();
@ -462,7 +473,8 @@ int main(int argc, char *argv[]) {
const metric::MetricPtr& metric = std::make_shared<metric::Metric>(); const metric::MetricPtr& metric = std::make_shared<metric::Metric>();
const stock::StockDataProviderPtr& stockDataProvider = std::make_shared<stock::StockDataProvider>(); const stock::StockDataProviderPtr& stockDataProvider = std::make_shared<stock::StockDataProvider>();
const audio::SoundManagerPtr& soundMgr = core::make_shared<audio::SoundManager>(filesystem); const audio::SoundManagerPtr& soundMgr = core::make_shared<audio::SoundManager>(filesystem);
const voxelworldrender::AssetVolumeCachePtr& assetVolumeCache = core::make_shared<voxelworldrender::AssetVolumeCache>(volumeCache);
MapView app(metric, animationCache, stockDataProvider, filesystem, eventBus, timeProvider, MapView app(metric, animationCache, stockDataProvider, filesystem, eventBus, timeProvider,
worldMgr, worldPager, volumeCache, meshCache, soundMgr); worldMgr, worldPager, volumeCache, meshCache, soundMgr, assetVolumeCache);
return app.startMainLoop(argc, argv); return app.startMainLoop(argc, argv);
} }

View File

@ -6,6 +6,7 @@
#include "ui/imgui/IMGUIApp.h" #include "ui/imgui/IMGUIApp.h"
#include "RenderShaders.h" #include "RenderShaders.h"
#include "voxelworldrender/AssetVolumeCache.h"
#include "voxelworldrender/WorldRenderer.h" #include "voxelworldrender/WorldRenderer.h"
#include "voxelworldrender/PlayerCamera.h" #include "voxelworldrender/PlayerCamera.h"
#include "frontend/ClientEntity.h" #include "frontend/ClientEntity.h"
@ -48,6 +49,7 @@ protected:
testcore::DepthBufferRenderer _depthBufferRenderer; testcore::DepthBufferRenderer _depthBufferRenderer;
voxelworld::CachedFloorResolver _floorResolver; voxelworld::CachedFloorResolver _floorResolver;
audio::SoundManagerPtr _soundManager; audio::SoundManagerPtr _soundManager;
voxelworldrender::AssetVolumeCachePtr _assetVolumeCache;
bool _lineModeRendering = false; bool _lineModeRendering = false;
bool _freelook = false; bool _freelook = false;
@ -80,7 +82,8 @@ public:
const voxelworld::WorldPagerPtr& worldPager, const voxelworld::WorldPagerPtr& worldPager,
const voxelformat::VolumeCachePtr& volumeCache, const voxelformat::VolumeCachePtr& volumeCache,
const voxelformat::MeshCachePtr& meshCache, const voxelformat::MeshCachePtr& meshCache,
const audio::SoundManagerPtr& soundManager); const audio::SoundManagerPtr& soundManager,
const voxelworldrender::AssetVolumeCachePtr& assetVolumeCache);
~MapView(); ~MapView();
app::AppState onConstruct() override; app::AppState onConstruct() override;