Reputation: 59
I am trying to render some text inside a button (which is just a vec2 of button size and vec2 of button position), and I am trying to center the text inside the button. and it works for characters with the same height, such as 'a', 'c', 'x', 'z', and all the capital letters. But as soon as I add in a letter with a different height, the text centering gets all messed up.
And this is the code I use to render text:
for (auto& item : buttons)
{
buttonShader->use();
buttonShader->setTexture2D("texture1", defaultTexture, 0);
// Calculate the transform matrix for the button (NOT the text), i think it's relevant
glm::mat4 transform = glm::mat4(1.0f);
transform = glm::translate(transform, glm::vec3(item.position.x, item.position.y, 0.0f));
transform = glm::scale(transform, glm::vec3(item.buttonSize.x, item.buttonSize.y, 1.0f));
// This is where I set the uniforms inside the shader, irrelevant code
// This is where I render the button with glDrawElements, irrelevant
shader->use();
glBindVertexArray(VAO);
const std::string& text = item.text;
const std::string& fontPath = item.font;
float buttonWidth = item.buttonSize.x;
float buttonHeight = item.buttonSize.y;
float x = item.position.x - buttonWidth / 2.0f;
float y = item.position.y - buttonHeight / 2.0f;
glm::vec2 scale = item.textSize;
glm::vec3 color = glm::vec3(item.textColor.x, item.textColor.y, item.textColor.z);
shader->setVec3("textColor", color);
// Calculate the total width and height of the text
float totalWidth = 0.0f;
float maxHeight = 0.0f;
for (auto c = text.begin(); c != text.end(); ++c) {
Character ch = Fonts[fontPath][*c];
totalWidth += (ch.Advance >> 6) * scale.x; // Advance is in 1/64 pixels
maxHeight = std::max(maxHeight, static_cast<float>(ch.Size.y));
}
float startX = x + (buttonWidth - totalWidth) / 2.0f;
float startY = y + (buttonHeight - maxHeight * scale.y) / 2.0f;
for (auto c = text.begin(); c != text.end(); ++c) {
Character ch = Fonts[fontPath][*c];
float xpos = startX + ch.Bearing.x * scale.x; // Apply x scaling
float ypos = startY + (ch.Size.y - ch.Bearing.y) * scale.y;
float w = ch.Size.x * scale.x;
float h = ch.Size.y * scale.y;
float vertices[6][4] = {
{ xpos, ypos + h, 0.0f, 0.0f },
{ xpos, ypos, 0.0f, 1.0f },
{ xpos + w, ypos, 1.0f, 1.0f },
{ xpos, ypos + h, 0.0f, 0.0f },
{ xpos + w, ypos, 1.0f, 1.0f },
{ xpos + w, ypos + h, 1.0f, 0.0f }
};
glBindTexture(GL_TEXTURE_2D, ch.TextureID);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glDrawArrays(GL_TRIANGLES, 0, 6);
startX += (ch.Advance >> 6) * scale.x;
}
}
Upvotes: -2
Views: 89
Reputation: 399
I see two issues:
p
and d
will have similar Size values, but are positioned differently on the baseline, so you will underestimate the size you need for the button the way you are calculating it.Upvotes: 1