我正在尝试在按钮内渲染一些文本(这只是按钮大小的 vec2 和按钮位置的 vec2),并且我正在尝试将按钮内的文本居中。它适用于具有相同高度的字符,例如“a”、“c”、“x”、“z”以及所有大写字母。但是一旦我添加了不同高度的字母,文本居中就会变得混乱。
这是我用来渲染文本的代码:
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;
}
}
我看到两个问题:
p
和 d
将具有相似的“大小”值,但在基线上的位置不同,因此您在计算时会低估按钮所需的大小。