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

View File

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

View File

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

View File

@ -39,7 +39,7 @@ private:
float _viewDistance = 0.0f;
float _fogRange = 0.0f;
float _seconds = 0.0f;
double _seconds = 0.0;
glm::vec3 _focusPos { 0.0f };
@ -52,7 +52,7 @@ public:
bool init() 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);

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(SRCS
WorldRenderer.h WorldRenderer.cpp
AssetVolumeCache.h AssetVolumeCache.cpp
PlayerCamera.cpp PlayerCamera.h
worldrenderer/WorldChunkMgr.h worldrenderer/WorldChunkMgr.cpp
@ -21,6 +22,11 @@ set(FILES
sky/sky_up.png
shared/water-distortion.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)
generate_shaders(${LIB} world water postprocess)

View File

@ -43,8 +43,9 @@ alignas(16) static constexpr glm::vec2 waterPlaneVecs[] = {
{ -1.0f, 1.0f}
};
WorldRenderer::WorldRenderer() :
_threadPool(1, "WorldRenderer"), _worldChunkMgr(_threadPool), _shadowMapShader(shader::ShadowmapShader::getInstance()) {
WorldRenderer::WorldRenderer(const AssetVolumeCachePtr& assetVolumeCache) :
_threadPool(1, "WorldRenderer"), _worldChunkMgr(_threadPool), _assetVolumeCache(assetVolumeCache),
_shadowMapShader(shader::ShadowmapShader::getInstance()) {
setViewDistance(800.0f);
}
@ -239,7 +240,7 @@ int WorldRenderer::renderTerrain(const glm::mat4& viewProjectionMatrix, const gl
}
_worldShader.setFocuspos(_focusPos);
_worldShader.setLightdir(_shadow.sunDirection());
_worldShader.setTime(_seconds);
_worldShader.setTime((float)_seconds);
_worldShader.setFogrange(_fogRange);
_worldShader.setClipplane(clipPlane);
_worldShader.setViewprojection(viewProjectionMatrix);
@ -314,6 +315,7 @@ int WorldRenderer::renderAll(const video::Camera& camera) {
const glm::mat4& vpmat = camera.viewProjectionMatrix();
drawCallsWorld += renderTerrain(vpmat, ignoreClipPlane);
drawCallsWorld += renderEntities(vpmat, ignoreClipPlane);
drawCallsWorld += renderPlants(vpmat, ignoreClipPlane);
drawCallsWorld += renderEntityDetails(camera);
drawCallsWorld += renderWater(camera, ignoreClipPlane);
_skybox.render(camera);
@ -324,6 +326,12 @@ int WorldRenderer::renderEntitiesToDepthMap(const video::Camera& camera) {
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) {
return _entityRenderer.renderEntities(_entityMgr.visibleEntities(), viewProjectionMatrix, clipPlane, _shadow);
}

View File

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

View File

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

View File

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