Add billboard text rendering in vulkan

This commit is contained in:
Benau 2022-09-12 10:56:39 +08:00
parent 7cc238e101
commit 48730d1db4
2 changed files with 116 additions and 36 deletions

View File

@ -23,6 +23,10 @@
#include "graphics/irr_driver.hpp"
#include "graphics/graphics_restrictions.hpp"
#include <ge_spm.hpp>
#include <ge_spm_buffer.hpp>
#include <sstream>
// ----------------------------------------------------------------------------
STKTextBillboard::STKTextBillboard(const video::SColor& color_top,
const video::SColor& color_bottom,
@ -50,6 +54,7 @@ STKTextBillboard::STKTextBillboard(const video::SColor& color_top,
m_color_bottom.setBlue(srgb255ToLinear(m_color_bottom.getBlue()));
}
static_assert(sizeof(GLTB) == 20, "Wrong compiler padding");
m_ge_node = NULL;
} // STKTextBillboard
// ----------------------------------------------------------------------------
@ -83,7 +88,13 @@ void STKTextBillboard::updateAbsolutePosition()
core::matrix4 m;
m.setScale(RelativeScale);
AbsoluteTransformation *= m;
if (CVS->isGLSL())
if (m_ge_node)
{
m_ge_node->setPosition(AbsoluteTransformation.getTranslation());
m_ge_node->setRotation(AbsoluteTransformation.getRotationDegrees());
m_ge_node->setScale(AbsoluteTransformation.getScale());
}
else if (CVS->isGLSL())
{
m_instanced_data =
SP::SPInstancedData(AbsoluteTransformation, 0, 0, 0, 0);
@ -265,6 +276,7 @@ void STKTextBillboard::init(const core::stringw& text, FontWithFace* face)
// ----------------------------------------------------------------------------
void STKTextBillboard::initLegacy(const core::stringw& text, FontWithFace* face)
{
removeGENode();
m_face = face;
m_text = text;
m_chars = new std::vector<STKTextBillboardChar>();
@ -366,6 +378,50 @@ void STKTextBillboard::initLegacy(const core::stringw& text, FontWithFace* face)
irr_tbs[(*m_chars)[i].m_texture].push_back(triangle);
}
if (SceneManager->getVideoDriver()->getDriverType() == video::EDT_VULKAN)
{
GE::GESPM* spm = new GE::GESPM();
for (auto& p : irr_tbs)
{
GE::GESPMBuffer* spm_mb = new GE::GESPMBuffer();
spm_mb->getMaterial().setTexture(0, p.first);
spm_mb->getMaterial().MaterialType =
video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
spm_mb->getMaterial().Lighting = false;
for (auto& q : p.second)
{
for (irr::video::S3DVertex& v : q)
{
video::S3DVertexSkinnedMesh sp;
sp.m_position = v.Pos;
sp.m_normal = MiniGLM::compressVector3(v.Normal);
sp.m_color = v.Color;
sp.m_all_uvs[0] = MiniGLM::toFloat16(v.TCoords.X);
sp.m_all_uvs[1] = MiniGLM::toFloat16(v.TCoords.Y);
spm_mb->getVerticesVector().push_back(sp);
}
}
for (unsigned i = 0; i < p.second.size(); i++)
{
spm_mb->getIndicesVector().push_back(4 * i + 2);
spm_mb->getIndicesVector().push_back(4 * i + 1);
spm_mb->getIndicesVector().push_back(4 * i + 0);
spm_mb->getIndicesVector().push_back(4 * i + 3);
spm_mb->getIndicesVector().push_back(4 * i + 2);
spm_mb->getIndicesVector().push_back(4 * i + 0);
}
spm_mb->recalculateBoundingBox();
spm->addMeshBuffer(spm_mb);
}
spm->finalize();
std::stringstream oss;
oss << (uint64_t)spm;
SceneManager->getMeshCache()->addMesh(oss.str().c_str(), spm);
spm->drop();
m_ge_node = SceneManager->addMeshSceneNode(spm);
}
else
{
for (auto& p : irr_tbs)
{
scene::SMeshBuffer* buffer = new scene::SMeshBuffer();
@ -406,10 +462,10 @@ void STKTextBillboard::initLegacy(const core::stringw& text, FontWithFace* face)
}
m_bbox.MinEdge = min.toIrrVector();
m_bbox.MaxEdge = max.toIrrVector();
}
delete m_chars;
updateAbsolutePosition();
} // initLegacy
// ----------------------------------------------------------------------------
@ -470,5 +526,16 @@ void STKTextBillboard::updateAllTextBillboards()
irr_driver->getSceneManager()->getRootSceneNode()->getChildren());
} // updateAllTextBillboards
// ----------------------------------------------------------------------------
void STKTextBillboard::removeGENode()
{
if (m_ge_node)
{
SceneManager->getMeshCache()->removeMesh(m_ge_node->getMesh());
m_ge_node->remove();
m_ge_node = NULL;
}
} // removeGENode
#endif // !SERVER_ONLY

View File

@ -31,6 +31,14 @@
using namespace irr;
using namespace scene;
namespace irr
{
namespace scene
{
class IMeshSceneNode;
}
}
class STKTextBillboard : public ISceneNode, public NoCopy,
FontWithFace::FontCharCollector
{
@ -87,8 +95,12 @@ private:
core::stringw m_text;
IMeshSceneNode* m_ge_node;
// ------------------------------------------------------------------------
float getDefaultScale(FontWithFace* face);
// ------------------------------------------------------------------------
void removeGENode();
public:
// ------------------------------------------------------------------------
STKTextBillboard(const video::SColor& color_top,
@ -99,6 +111,7 @@ public:
// ------------------------------------------------------------------------
~STKTextBillboard()
{
removeGENode();
clearBuffer();
}
// ------------------------------------------------------------------------