Add minimap rendering

This commit is contained in:
Benau 2022-07-25 09:41:35 +08:00
parent a2228adef1
commit 819b3ad27f
7 changed files with 113 additions and 13 deletions

View File

@ -12,6 +12,7 @@ class GEVulkanDriver;
struct GEConfig
{
bool m_disable_npot_texture;
bool m_convert_irrlicht_mesh;
};
void setVideoDriver(irr::video::IVideoDriver* driver);

View File

@ -15,9 +15,11 @@ class SPMeshLoader;
namespace GE
{
class GESPMBuffer;
class GEVulkanSceneManager;
class GESPM : public IAnimatedMesh
{
friend class GEVulkanSceneManager;
friend class ::B3DMeshLoader;
friend class ::SPMeshLoader;
private:

View File

@ -10,8 +10,11 @@ class SPMeshLoader;
namespace GE
{
class GEVulkanSceneManager;
class GESPMBuffer : public irr::scene::IMeshBuffer
{
friend class GEVulkanSceneManager;
friend class ::B3DMeshLoader;
friend class ::SPMeshLoader;
private:

View File

@ -2,6 +2,7 @@
#include "ge_spm.hpp"
#include "IMeshCache.h"
#include "ISceneManager.h"
namespace GE
@ -14,8 +15,16 @@ GEVulkanMeshSceneNode::GEVulkanMeshSceneNode(irr::scene::IMesh* mesh,
: irr::scene::CMeshSceneNode(mesh, parent, mgr, id, position, rotation,
scale)
{
m_remove_from_mesh_cache = false;
} // GEVulkanMeshSceneNode
// ----------------------------------------------------------------------------
GEVulkanMeshSceneNode::~GEVulkanMeshSceneNode()
{
if (m_remove_from_mesh_cache)
SceneManager->getMeshCache()->removeMesh(Mesh);
} // ~GEVulkanMeshSceneNode
// ----------------------------------------------------------------------------
GESPM* GEVulkanMeshSceneNode::getSPM() const
{

View File

@ -9,6 +9,8 @@ class GESPM;
class GEVulkanMeshSceneNode : public irr::scene::CMeshSceneNode
{
private:
bool m_remove_from_mesh_cache;
public:
// ------------------------------------------------------------------------
GEVulkanMeshSceneNode(irr::scene::IMesh* mesh,
@ -17,6 +19,10 @@ public:
const irr::core::vector3df& rotation = irr::core::vector3df(0, 0, 0),
const irr::core::vector3df& scale = irr::core::vector3df(1.0f, 1.0f, 1.0f));
// ------------------------------------------------------------------------
~GEVulkanMeshSceneNode();
// ------------------------------------------------------------------------
void setRemoveFromMeshCache(bool val) { m_remove_from_mesh_cache = val; }
// ------------------------------------------------------------------------
GESPM* getSPM() const;
// ------------------------------------------------------------------------
virtual void OnRegisterSceneNode();

View File

@ -2,7 +2,9 @@
#include "../source/Irrlicht/os.h"
#include "ge_main.hpp"
#include "ge_spm.hpp"
#include "ge_spm_buffer.hpp"
#include "ge_vulkan_animated_mesh_scene_node.hpp"
#include "ge_vulkan_camera_scene_node.hpp"
#include "ge_vulkan_command_loader.hpp"
@ -13,6 +15,9 @@
#include "ge_vulkan_mesh_scene_node.hpp"
#include "ge_vulkan_texture_descriptor.hpp"
#include "mini_glm.hpp"
#include <sstream>
namespace GE
{
// ----------------------------------------------------------------------------
@ -95,27 +100,80 @@ irr::scene::IMeshSceneNode* GEVulkanSceneManager::addMeshSceneNode(
if (!alsoAddIfMeshPointerZero && !mesh)
return NULL;
bool convert_irrlicht_mesh = false;
if (mesh)
{
for (unsigned i = 0; i < mesh->getMeshBufferCount(); i++)
{
irr::scene::IMeshBuffer* b = mesh->getMeshBuffer(i);
if (b->getVertexType() != irr::video::EVT_SKINNED_MESH)
{
if (!getGEConfig()->m_convert_irrlicht_mesh)
{
return irr::scene::CSceneManager::addMeshSceneNode(
mesh, parent, id, position, rotation, scale,
alsoAddIfMeshPointerZero);
}
else
{
convert_irrlicht_mesh = true;
break;
}
}
}
}
if (!parent)
parent = this;
irr::scene::IMeshSceneNode* node =
if (convert_irrlicht_mesh)
{
GESPM* spm = new GESPM();
for (unsigned i = 0; i < mesh->getMeshBufferCount(); i++)
{
std::vector<video::S3DVertexSkinnedMesh> vertices;
scene::IMeshBuffer* mb = mesh->getMeshBuffer(i);
if (!mb)
continue;
GESPMBuffer* spm_mb = new GESPMBuffer();
assert(mb->getVertexType() == video::EVT_STANDARD);
video::S3DVertex* v_ptr = (video::S3DVertex*)mb->getVertices();
for (unsigned j = 0; j < mb->getVertexCount(); j++)
{
video::S3DVertexSkinnedMesh sp;
sp.m_position = v_ptr[j].Pos;
sp.m_normal = MiniGLM::compressVector3(v_ptr[j].Normal);
sp.m_color = v_ptr[j].Color;
sp.m_all_uvs[0] = MiniGLM::toFloat16(v_ptr[j].TCoords.X);
sp.m_all_uvs[1] = MiniGLM::toFloat16(v_ptr[j].TCoords.Y);
spm_mb->m_vertices.push_back(sp);
}
uint16_t* idx_ptr = mb->getIndices();
std::vector<uint16_t> indices(idx_ptr, idx_ptr + mb->getIndexCount());
std::swap(spm_mb->m_indices, indices);
spm_mb->m_material = mb->getMaterial();
spm_mb->recalculateBoundingBox();
spm->m_buffer.push_back(spm_mb);
}
spm->finalize();
std::stringstream oss;
oss << (uint64_t)spm;
getMeshCache()->addMesh(oss.str().c_str(), spm);
mesh = spm;
}
GEVulkanMeshSceneNode* vulkan_node =
new GEVulkanMeshSceneNode(mesh, parent, this, id, position, rotation,
scale);
irr::scene::IMeshSceneNode* node = vulkan_node;
node->drop();
if (convert_irrlicht_mesh)
{
vulkan_node->setRemoveFromMeshCache(true);
mesh->drop();
}
return node;
} // addMeshSceneNode

View File

@ -100,7 +100,17 @@ void Graph::createDebugMesh()
}
#endif
#ifndef SERVER_ONLY
bool vk = (GE::getVKDriver() != NULL);
if (vk)
GE::getGEConfig()->m_convert_irrlicht_mesh = true;
#endif
m_node = irr_driver->addMesh(m_mesh, "track-debug-mesh");
#ifndef SERVER_ONLY
if (vk)
GE::getGEConfig()->m_convert_irrlicht_mesh = false;
#endif
#ifdef DEBUG
m_node->setName("track-debug-mesh");
#endif
@ -192,10 +202,11 @@ void Graph::createMesh(bool show_invisible, bool enable_transparency,
}
if (flatten)
{
vptr[0].Pos.Y = 0;
vptr[1].Pos.Y = 0;
vptr[2].Pos.Y = 0;
vptr[3].Pos.Y = 0;
// Vulkan driver needs 0.1 instead of 0
vptr[0].Pos.Y = 0.1f;
vptr[1].Pos.Y = 0.1f;
vptr[2].Pos.Y = 0.1f;
vptr[3].Pos.Y = 0.1f;
}
// Set up the indices for the triangles
@ -220,10 +231,10 @@ void Graph::createMesh(bool show_invisible, bool enable_transparency,
m_all_nodes[0]->getVertices(lap_v, lap_color);
if (flatten)
{
lap_v[0].Pos.Y = 0;
lap_v[1].Pos.Y = 0;
lap_v[2].Pos.Y = 0;
lap_v[3].Pos.Y = 0;
lap_v[0].Pos.Y = 0.1f;
lap_v[1].Pos.Y = 0.1f;
lap_v[2].Pos.Y = 0.1f;
lap_v[3].Pos.Y = 0.1f;
}
// Now scale the length (distance between vertix 0 and 3
@ -417,7 +428,7 @@ RenderTarget* Graph::makeMiniMap(const core::dimension2du &dimension,
#ifdef SERVER_ONLY
return NULL;
#else
if (GUIEngine::isNoGraphics() || GE::getVKDriver()) return NULL;
if (GUIEngine::isNoGraphics()) return NULL;
#endif
const video::SColor oldClearColor = irr_driver->getClearColor();
@ -471,7 +482,17 @@ RenderTarget* Graph::makeMiniMap(const core::dimension2du &dimension,
}
#endif
#ifndef SERVER_ONLY
bool vk = (GE::getVKDriver() != NULL);
if (vk)
GE::getGEConfig()->m_convert_irrlicht_mesh = true;
#endif
m_node = irr_driver->addMesh(m_mesh, "mini_map");
#ifndef SERVER_ONLY
if (vk)
GE::getGEConfig()->m_convert_irrlicht_mesh = false;
#endif
#ifdef DEBUG
m_node->setName("minimap-mesh");
#endif