VOXELWORLDRENDER: prepare to readd plant support
parent
e5ca8e44c0
commit
b80680fe4d
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
|
||||
}
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue