我正在尝试在OpenGL中使用freetype。我首先尝试写我的东西,但由于它不起作用,我只是从code下载了一个效果很好的this tutorial。正如我所说的那样,效果很好,但预测与我想要的有所不同。在本教程中,我们有:
glm::mat4 projection = glm::ortho(0.0f, static_cast<GLfloat>(WIDTH), 0.0f, static_cast<GLfloat>(HEIGHT));
我改变了
glm::mat4 projection = glm::ortho(0.0f, static_cast<GLfloat>(WIDTH), 0.0f, static_cast<GLfloat>(HEIGHT), -1.0f, 1.0f);
而且仍然有效。但是我想要的是起源于左上角而不是buttom-left,所以我使用了这个:
glm::mat4 projection = glm::ortho(0.0f, static_cast<GLfloat>(WIDTH), static_cast<GLfloat>(HEIGHT),0.0f, -1.0f, 1.0f);
现在不起作用了,我在屏幕上没有文字。正确渲染的其他对象(文本除外)。请注意,使用之前的2个投影,我得到了文字,但存在其他物体,但是具有上下颠倒的效果(正常)。
我的问题是为什么如果我在(0,0)处绘制文本并希望在左上角看到它,那么我什么都没有。但是根据其他预测,我将其按预期的那样放在左下角了吗?
我可以保留投影并移动它,但我真的很想了解为什么它不起作用。
注意:我试图查看投影*位置的结果。
假设P1正交为0,底部为0。
对于x,y =(92.8000,99.7000)我得到了:
P1 * (x, y, 0.0, 1.0) = [ 0.2320 0.3323 0.0000 -192.5000]
P2 * (x, y, 0.0, 1.0) = [ 0.2320 -0.3323 0.0000 6.9000]
如预期的y1 =-y2。
按照@ vu1p3n0x代码要求的textrender。但它在the first link中
void RenderText(Shader &shader, std::string text, GLfloat x, GLfloat y, GLfloat scale, glm::vec3 color)
{
shader.Use();
glUniform3f(glGetUniformLocation(shader.Program, "textColor"), color.x, color.y, color.z);
glActiveTexture(GL_TEXTURE0);
glBindVertexArray(VAO);
std::string::const_iterator c;
for (c = text.begin(); c != text.end(); c++)
{
Character ch = Characters[*c];
GLfloat xpos = x + ch.Bearing.x * scale;
GLfloat ypos = y - (ch.Size.y - ch.Bearing.y) * scale;
GLfloat w = ch.Size.x * scale;
GLfloat h = ch.Size.y * scale;
GLfloat vertices[6][4] = {
{ xpos, ypos + h, 0.0, 0.0 },
{ xpos, ypos, 0.0, 1.0 },
{ xpos + w, ypos, 1.0, 1.0 },
{ xpos, ypos + h, 0.0, 0.0 },
{ xpos + w, ypos, 1.0, 1.0 },
{ xpos + w, ypos + h, 1.0, 0.0 }
};
// Render glyph texture over quad
glBindTexture(GL_TEXTURE_2D, ch.TextureID);
// Update content of VBO memory
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices);
glBindBuffer(GL_ARRAY_BUFFER, 0);
// Render quad
glDrawArrays(GL_TRIANGLES, 0, 6);
// Now advance cursors for next glyph (note that advance is number of 1/64 pixels)
x += (ch.Advance >> 6) * scale; // Bitshift by 6 to get value in pixels (2^6 = 64 (divide amount of 1/64th pixels by 64 to get amount of pixels))
}
glBindVertexArray(0);
glBindTexture(GL_TEXTURE_2D, 0);
}
最佳答案
问题是Face Culling:
启用了面剔除,并且文本图元的顶点处于逆时针方向:
GLfloat vertices[6][4] = {
{ xpos, ypos + h, 0.0, 0.0 },
{ xpos, ypos, 0.0, 1.0 },
{ xpos + w, ypos, 1.0, 1.0 },
{ xpos, ypos + h, 0.0, 0.0 },
{ xpos + w, ypos, 1.0, 1.0 },
{ xpos + w, ypos + h, 1.0, 0.0 }
};
如果投影矩阵是
glm::mat4 projection = glm::ortho(
0.0f, static_cast<GLfloat>(WIDTH),
0.0f, static_cast<GLfloat>(HEIGHT));
那么就不会剔除这些面,因为默认情况下会剔除背面(请参见
glCullFace
)缠绕顺序为逆时针(请参阅
glFrontFace
)。当你做
glm::mat4 projection = glm::ortho(
0.0f, static_cast<GLfloat>(WIDTH),
static_cast<GLfloat>(HEIGHT), 0.0f);
然后,通过使用顶点着色器中的正交投影矩阵进行变换,将视域的y轴翻转,并且图元的缠绕顺序从逆时针方向变为顺时针方向。
通过
glFrontFace(GL_CW)
更改定义正面多边形的绕线顺序,以解决此问题:glCullFace( GL_BACK ); // that is default
glFrontFace( GL_CW ); // that is NOT default
glEnable(GL_CULL_FACE);
当然,您也可以更改顶点的缠绕顺序(并翻转纹理坐标的y轴):
GLfloat xpos = x + ch.Bearing.x * scale;
GLfloat ypos = y + (ch.Size.y - ch.Bearing.y) * scale;
GLfloat w = ch.Size.x * scale;
GLfloat h = ch.Size.y * scale;
GLfloat vertices[6][4] = {
{ xpos, ypos - h, 0.0, 0.0 },
{ xpos, ypos, 0.0, 1.0 },
{ xpos + w, ypos, 1.0, 1.0 },
{ xpos, ypos - h, 0.0, 0.0 },
{ xpos + w, ypos, 1.0, 1.0 },
{ xpos + w, ypos - h, 1.0, 0.0 }
};