Use STKTextBillboard for legacy pipeline for correct glyph metrics
This commit is contained in:
parent
a906e607df
commit
874895ba11
@ -333,11 +333,6 @@ void CBillboardTextSceneNode::OnRegisterSceneNode()
|
||||
//! render
|
||||
void CBillboardTextSceneNode::render()
|
||||
{
|
||||
// FIXME: Billboard text is broken with GLES 2.0.
|
||||
#ifdef _IRR_COMPILE_WITH_OGLES2_
|
||||
return;
|
||||
#endif
|
||||
|
||||
if ( !Mesh )
|
||||
return;
|
||||
|
||||
|
@ -35,14 +35,14 @@ STKTextBillboard::STKTextBillboard(const video::SColor& color_top,
|
||||
{
|
||||
using namespace SP;
|
||||
m_color_top = color_top;
|
||||
if (CVS->isDeferredEnabled())
|
||||
if (CVS->isDeferredEnabled() && CVS->isGLSL())
|
||||
{
|
||||
m_color_top.setRed(srgb255ToLinear(m_color_top.getRed()));
|
||||
m_color_top.setGreen(srgb255ToLinear(m_color_top.getGreen()));
|
||||
m_color_top.setBlue(srgb255ToLinear(m_color_top.getBlue()));
|
||||
}
|
||||
m_color_bottom = color_bottom;
|
||||
if (CVS->isDeferredEnabled())
|
||||
if (CVS->isDeferredEnabled() && CVS->isGLSL())
|
||||
{
|
||||
video::SColorf tmp(m_color_bottom);
|
||||
m_color_bottom.setRed(srgb255ToLinear(m_color_bottom.getRed()));
|
||||
@ -77,8 +77,11 @@ void STKTextBillboard::updateAbsolutePosition()
|
||||
core::matrix4 m;
|
||||
m.setScale(RelativeScale);
|
||||
AbsoluteTransformation *= m;
|
||||
m_instanced_data = SP::SPInstancedData(AbsoluteTransformation, 0, 0, 0, 0);
|
||||
|
||||
if (CVS->isGLSL())
|
||||
{
|
||||
m_instanced_data =
|
||||
SP::SPInstancedData(AbsoluteTransformation, 0, 0, 0, 0);
|
||||
}
|
||||
} // updateAbsolutePosition
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -251,6 +254,173 @@ void STKTextBillboard::init(core::stringw text, FontWithFace* face)
|
||||
updateAbsolutePosition();
|
||||
} // init
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void STKTextBillboard::initLegacy(core::stringw text, FontWithFace* face)
|
||||
{
|
||||
m_chars = new std::vector<STKTextBillboardChar>();
|
||||
core::dimension2du size = face->getDimension(text.c_str());
|
||||
face->render(text, core::rect<s32>(0, 0, size.Width, size.Height),
|
||||
video::SColor(255,255,255,255), false, false, NULL, NULL, this);
|
||||
|
||||
const float scale = 0.02f;
|
||||
float max_x = 0;
|
||||
float min_y = 0;
|
||||
float max_y = 0;
|
||||
for (unsigned int i = 0; i < m_chars->size(); i++)
|
||||
{
|
||||
float char_x = (*m_chars)[i].m_dest_rect.LowerRightCorner.X;
|
||||
if (char_x > max_x)
|
||||
{
|
||||
max_x = char_x;
|
||||
}
|
||||
|
||||
float char_min_y = (*m_chars)[i].m_dest_rect.UpperLeftCorner.Y;
|
||||
float char_max_y = (*m_chars)[i].m_dest_rect.LowerRightCorner.Y;
|
||||
if (char_min_y < min_y)
|
||||
{
|
||||
min_y = char_min_y;
|
||||
}
|
||||
if (char_max_y > min_y)
|
||||
{
|
||||
max_y = char_max_y;
|
||||
}
|
||||
}
|
||||
float scaled_center_x = (max_x / 2.0f) * scale;
|
||||
float scaled_y = (max_y / 2.0f) * scale;
|
||||
|
||||
std::unordered_map<video::ITexture*,
|
||||
std::vector<std::array<irr::video::S3DVertex, 4> > > irr_tbs;
|
||||
for (unsigned int i = 0; i < m_chars->size(); i++)
|
||||
{
|
||||
core::vector3df char_pos((*m_chars)[i].m_dest_rect.UpperLeftCorner.X,
|
||||
(*m_chars)[i].m_dest_rect.UpperLeftCorner.Y, 0);
|
||||
char_pos *= scale;
|
||||
|
||||
core::vector3df char_pos2((*m_chars)[i].m_dest_rect.LowerRightCorner.X,
|
||||
(*m_chars)[i].m_dest_rect.LowerRightCorner.Y, 0);
|
||||
char_pos2 *= scale;
|
||||
|
||||
float tex_width = (float)(*m_chars)[i].m_texture->getSize().Width;
|
||||
float tex_height = (float)(*m_chars)[i].m_texture->getSize().Height;
|
||||
std::array<irr::video::S3DVertex, 4> triangle =
|
||||
{{
|
||||
{
|
||||
core::vector3df
|
||||
(char_pos.X - scaled_center_x, char_pos.Y - scaled_y, 0),
|
||||
core::vector3df(0.0f, 1.0f, 0.0f),
|
||||
m_color_bottom,
|
||||
core::vector2df
|
||||
((*m_chars)
|
||||
[i].m_source_rect.UpperLeftCorner.X / tex_width,
|
||||
(*m_chars)
|
||||
[i].m_source_rect.LowerRightCorner.Y / tex_height)
|
||||
},
|
||||
|
||||
{
|
||||
core::vector3df
|
||||
(char_pos2.X - scaled_center_x, char_pos.Y - scaled_y, 0),
|
||||
core::vector3df(0.0f, 1.0f, 0.0f),
|
||||
m_color_bottom,
|
||||
core::vector2df
|
||||
((*m_chars)
|
||||
[i].m_source_rect.LowerRightCorner.X / tex_width,
|
||||
(*m_chars)
|
||||
[i].m_source_rect.LowerRightCorner.Y / tex_height)
|
||||
},
|
||||
|
||||
{
|
||||
core::vector3df
|
||||
(char_pos2.X - scaled_center_x, char_pos2.Y - scaled_y, 0),
|
||||
core::vector3df(0.0f, 1.0f, 0.0f),
|
||||
|
||||
m_color_top,
|
||||
core::vector2df
|
||||
((*m_chars)
|
||||
[i].m_source_rect.LowerRightCorner.X / tex_width,
|
||||
(*m_chars)
|
||||
[i].m_source_rect.UpperLeftCorner.Y / tex_height)
|
||||
},
|
||||
|
||||
{
|
||||
core::vector3df
|
||||
(char_pos.X - scaled_center_x, char_pos2.Y - scaled_y, 0),
|
||||
core::vector3df(0.0f, 1.0f, 0.0f),
|
||||
m_color_top,
|
||||
core::vector2df
|
||||
((*m_chars)
|
||||
[i].m_source_rect.UpperLeftCorner.X / tex_width,
|
||||
(*m_chars)
|
||||
[i].m_source_rect.UpperLeftCorner.Y / tex_height)
|
||||
}
|
||||
}};
|
||||
irr_tbs[(*m_chars)[i].m_texture].push_back(triangle);
|
||||
}
|
||||
|
||||
for (auto& p : irr_tbs)
|
||||
{
|
||||
scene::SMeshBuffer* buffer = new scene::SMeshBuffer();
|
||||
buffer->getMaterial().setTexture(0, p.first);
|
||||
buffer->getMaterial().MaterialType =
|
||||
video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
|
||||
buffer->getMaterial().Lighting = false;
|
||||
|
||||
std::vector<uint16_t> indices;
|
||||
for (unsigned i = 0; i < p.second.size(); i++)
|
||||
{
|
||||
indices.push_back(4 * i + 2);
|
||||
indices.push_back(4 * i + 1);
|
||||
indices.push_back(4 * i + 0);
|
||||
indices.push_back(4 * i + 3);
|
||||
indices.push_back(4 * i + 2);
|
||||
indices.push_back(4 * i + 0);
|
||||
}
|
||||
buffer->append(p.second.data(), p.second.size() * 4,
|
||||
indices.data(), indices.size());
|
||||
buffer->recalculateBoundingBox();
|
||||
m_gl_mb[p.first] = buffer;
|
||||
}
|
||||
|
||||
Vec3 min = Vec3( 999999.9f);
|
||||
Vec3 max = Vec3(-999999.9f);
|
||||
for (auto& p : irr_tbs)
|
||||
{
|
||||
for (auto& q : p.second)
|
||||
{
|
||||
for (auto& r : q)
|
||||
{
|
||||
Vec3 c(r.Pos.X, r.Pos.Y, r.Pos.Z);
|
||||
min.min(c);
|
||||
max.max(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
m_bbox.MinEdge = min.toIrrVector();
|
||||
m_bbox.MaxEdge = max.toIrrVector();
|
||||
|
||||
delete m_chars;
|
||||
updateAbsolutePosition();
|
||||
|
||||
} // initLegacy
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void STKTextBillboard::render()
|
||||
{
|
||||
video::IVideoDriver* driver = SceneManager->getVideoDriver();
|
||||
driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
|
||||
for (auto& p : m_gl_mb)
|
||||
{
|
||||
driver->setMaterial(p.second->getMaterial());
|
||||
driver->drawMeshBuffer(p.second);
|
||||
}
|
||||
} // render
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void STKTextBillboard::OnRegisterSceneNode()
|
||||
{
|
||||
SceneManager->registerNodeForRendering(this, ESNRP_TRANSPARENT);
|
||||
ISceneNode::OnRegisterSceneNode();
|
||||
} // OnRegisterSceneNode
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void STKTextBillboard::collectChar(video::ITexture* texture,
|
||||
const core::rect<float>& dest_rect,
|
||||
|
@ -79,6 +79,8 @@ private:
|
||||
std::unordered_map<video::ITexture*, std::pair<GLuint, GLuint> >
|
||||
m_vao_vbos;
|
||||
|
||||
std::unordered_map<video::ITexture*, IMeshBuffer*> m_gl_mb;
|
||||
|
||||
core::aabbox3df m_bbox;
|
||||
|
||||
public:
|
||||
@ -102,6 +104,11 @@ public:
|
||||
glDeleteBuffers(1, &p.second.second);
|
||||
}
|
||||
m_vao_vbos.clear();
|
||||
for (auto& p : m_gl_mb)
|
||||
{
|
||||
p.second->drop();
|
||||
}
|
||||
m_gl_mb.clear();
|
||||
#endif
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
@ -112,12 +119,16 @@ public:
|
||||
// ------------------------------------------------------------------------
|
||||
virtual void updateAbsolutePosition();
|
||||
// ------------------------------------------------------------------------
|
||||
virtual void render() {}
|
||||
virtual void OnRegisterSceneNode();
|
||||
// ------------------------------------------------------------------------
|
||||
virtual void render();
|
||||
// ------------------------------------------------------------------------
|
||||
virtual const core::aabbox3df& getBoundingBox() const { return m_bbox; }
|
||||
// ------------------------------------------------------------------------
|
||||
void init(core::stringw text, FontWithFace* face);
|
||||
// ------------------------------------------------------------------------
|
||||
void initLegacy(core::stringw text, FontWithFace* face);
|
||||
// ------------------------------------------------------------------------
|
||||
void draw(video::ITexture* tex) const
|
||||
{
|
||||
#ifndef SERVER_ONLY
|
||||
|
@ -3299,35 +3299,18 @@ void Kart::setOnScreenText(const wchar_t *text)
|
||||
return;
|
||||
|
||||
BoldFace* bold_face = font_manager->getFont<BoldFace>();
|
||||
core::dimension2d<u32> textsize = bold_face->getDimension(text);
|
||||
|
||||
STKTextBillboard* tb =
|
||||
new STKTextBillboard(
|
||||
GUIEngine::getSkin()->getColor("font::bottom"),
|
||||
GUIEngine::getSkin()->getColor("font::top"),
|
||||
getNode(), irr_driver->getSceneManager(), -1,
|
||||
core::vector3df(0.0f, 1.5f, 0.0f),
|
||||
core::vector3df(0.35f, 0.35f, 0.35f));
|
||||
if (CVS->isGLSL())
|
||||
{
|
||||
STKTextBillboard* tb =
|
||||
new STKTextBillboard(
|
||||
GUIEngine::getSkin()->getColor("font::bottom"),
|
||||
GUIEngine::getSkin()->getColor("font::top"),
|
||||
getNode(), irr_driver->getSceneManager(), -1,
|
||||
core::vector3df(0.0f, 1.5f, 0.0f),
|
||||
core::vector3df(0.35f, 0.35f, 0.35f));
|
||||
tb->init(text, bold_face);
|
||||
tb->drop();
|
||||
}
|
||||
else
|
||||
{
|
||||
scene::ISceneManager* sm = irr_driver->getSceneManager();
|
||||
sm->addBillboardTextSceneNode(GUIEngine::getFont() ? GUIEngine::getFont()
|
||||
: GUIEngine::getTitleFont(),
|
||||
text,
|
||||
getNode(),
|
||||
core::dimension2df(textsize.Width/55.0f,
|
||||
textsize.Height/55.0f),
|
||||
core::vector3df(0.0f, 1.5f, 0.0f),
|
||||
-1, // id
|
||||
GUIEngine::getSkin()->getColor("font::bottom"),
|
||||
GUIEngine::getSkin()->getColor("font::top"));
|
||||
}
|
||||
|
||||
tb->initLegacy(text, bold_face);
|
||||
tb->drop();
|
||||
// No need to store the reference to the billboard scene node:
|
||||
// It has one reference to the parent, and will get deleted
|
||||
// when the parent is deleted.
|
||||
|
@ -109,39 +109,20 @@ namespace Scripting
|
||||
{
|
||||
core::stringw wtext = StringUtils::utf8ToWide(*text);
|
||||
DigitFace* digit_face = font_manager->getFont<DigitFace>();
|
||||
core::dimension2d<u32> textsize = digit_face->getDimension(wtext.c_str());
|
||||
|
||||
core::vector3df xyz(location->getX(), location->getY(), location->getZ());
|
||||
#ifndef SERVER_ONLY
|
||||
STKTextBillboard* tb = new STKTextBillboard(
|
||||
GUIEngine::getSkin()->getColor("font::bottom"),
|
||||
GUIEngine::getSkin()->getColor("font::top"),
|
||||
irr_driver->getSceneManager()->getRootSceneNode(),
|
||||
irr_driver->getSceneManager(), -1, xyz,
|
||||
core::vector3df(1.5f, 1.5f, 1.5f));
|
||||
if (CVS->isGLSL())
|
||||
{
|
||||
STKTextBillboard* tb = new STKTextBillboard(
|
||||
GUIEngine::getSkin()->getColor("font::bottom"),
|
||||
GUIEngine::getSkin()->getColor("font::top"),
|
||||
irr_driver->getSceneManager()->getRootSceneNode(),
|
||||
irr_driver->getSceneManager(), -1, xyz,
|
||||
core::vector3df(1.5f, 1.5f, 1.5f));
|
||||
tb->init(wtext.c_str(), digit_face);
|
||||
|
||||
::Track::getCurrentTrack()->addNode(tb);
|
||||
tb->drop();
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(GUIEngine::getHighresDigitFont() != NULL);
|
||||
scene::ISceneManager* sm = irr_driver->getSceneManager();
|
||||
scene::ISceneNode* sn =
|
||||
sm->addBillboardTextSceneNode(GUIEngine::getHighresDigitFont(),
|
||||
wtext.c_str(),
|
||||
NULL,
|
||||
core::dimension2df(textsize.Width / 35.0f,
|
||||
textsize.Height / 35.0f),
|
||||
xyz,
|
||||
-1, // id
|
||||
GUIEngine::getSkin()->getColor("font::bottom"),
|
||||
GUIEngine::getSkin()->getColor("font::top"));
|
||||
::Track::getCurrentTrack()->addNode(sn);
|
||||
}
|
||||
tb->initLegacy(wtext.c_str(), digit_face);
|
||||
::Track::getCurrentTrack()->addNode(tb);
|
||||
tb->drop();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user