I'm trying to apply a transformation matrix to sf::Text class, and when I change its size, the sf::Text just disappears.
I had the same problem with a sf::Sprite, but there I'd solved it by rewriting the whole class. Furthermore, I know where's the problem. It is in the sf::Transformable part and the scale SFML politic that the size elements in a transform matrix have to be scale coefficients. I don't like it because I want to work with my objects using math.
Anyway, like in the sf::Sprite, this problem is in the vertex array generating inside sf::Text class, but I cannot reimplement it because our sf::Text class is a friend for a sf::Texture class
Someone... Help...
P.S. If you need more information about this problem, please, continue to read.
So. Here's a detailed problem description.
I have some system, which read JSON like that and make some scene stuff:
"title": {
"type": "node",
"enabled": true,
"components": {
"color": "magenta",
"layout": {
"priority": 1,
"anchor": { "x": 0.5, "y": 0.05 },
"pivot": { "x": 0.5, "y": 0 },
"size": { "x": "80%", "y": "20%" },
"draw_rect": true
},
"text": {
"priority": 2,
"settings": {
"data": "Some Lode Runner",
"size": 40,
"letter_spacing": 1.0,
"line_spacing": 1.0,
"style": "regular"
},
"outline": {
"color": "white",
"thickness": 1.0
},
"font": {
"path": "res/fonts/win_cmd.ttf",
"smooth": true
}
}
}
}
And, as you can notice, the priority says which component will be used first. And it works perfectly with my rewrote sprite, because the SFML sprite has the following implementation:
void Sprite::updatePositions()
{
FloatRect bounds = getLocalBounds();
m_vertices[0].position = Vector2f(0, 0);
m_vertices[1].position = Vector2f(0, bounds.height);
m_vertices[2].position = Vector2f(bounds.width, 0);
m_vertices[3].position = Vector2f(bounds.width, bounds.height);
}
void Sprite::updateTexCoords()
{
FloatRect convertedTextureRect(m_textureRect);
float left = convertedTextureRect.left;
float right = left + convertedTextureRect.width;
float top = convertedTextureRect.top;
float bottom = top + convertedTextureRect.height;
m_vertices[0].texCoords = Vector2f(left, top);
m_vertices[1].texCoords = Vector2f(left, bottom);
m_vertices[2].texCoords = Vector2f(right, top);
m_vertices[3].texCoords = Vector2f(right, bottom);
}
If you know the OpenGL a little, you have to know that the vertex and the texture coordinates can be implemented as [-1, 1] for the first one, and [0, 1] for the second one.
And to fix it, I rewrote the SFML sprite class like that:
void Sprite::updateVertices() {
mVertices[asID(Corner::LeftDown)].position = { 0.0f , 0.0f };
mVertices[asID(Corner::LeftUp)].position = { 0.0f , 1.0f };
mVertices[asID(Corner::RightUp)].position = { 1.0f , 0.0f };
mVertices[asID(Corner::RightDown)].position = { 1.0f , 1.0f };
}
void Sprite::updateTextureCoords() {
const auto &[width, height]{ mTexture.mData->getSize() };
const float left = mTextureCoords.left * width;
const float right = left + mTextureCoords.width * width;
const float top = mTextureCoords.top * height;
const float bottom = top + mTextureCoords.height * height;
mVertices[asID(Corner::LeftDown)].texCoords = { left , top };
mVertices[asID(Corner::LeftUp)].texCoords = { left , bottom };
mVertices[asID(Corner::RightUp)].texCoords = { right, top };
mVertices[asID(Corner::RightDown)].texCoords = { right, bottom };
}
And it works perfectly. Now I can apply to my sprite transform like that:
render->pushTransform(transform);
render->draw(mySprite);
render->popTransform();
So, I understand that the sf::Text class has the same problem because when I put set my transform component size like 2 and 1 pixel, the text size become so large:
But I need to set size in a normal things like [1024, 720] or, as you can notice, by percents.
So, I have to change the vertex position and textures inside the sf::Text sprite, but I cannot rewrite it like a sprite because of this 431 line in <SFML/Graphics/Text.cpp> file:
// Save the current fonts texture id
m_fontTextureId = m_font->getTexture(m_characterSize).m_cacheId;
The m_cacheId is a sf::Texture's private member, and if we look up inside texture class, we find those lines:
private:
friend class Text;
friend class RenderTexture;
friend class RenderTarget;
It means that I cannot reimplement my own Text class without touching SFML sources :c
But in the SFML original site I found this information about rewriting sf::Text stuff, but I don't really want to spend a lot of time for making bicycle with glyphs

