orthoProject freetype opengl
orthoProject freetype opengl
我正在尝试将 freetype 与 OpenGL 结合使用。我首先尝试编写我的东西,但由于它不起作用,我只下载了一个 code that works well from 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);
它仍然很好用。但我想要的是左上角而不是左按钮,所以我使用这个:
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 在上面,P2 是正交的,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);
然后通过vertex shader中的正交投影矩阵的变换,将视图空间的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 }
};
我正在尝试将 freetype 与 OpenGL 结合使用。我首先尝试编写我的东西,但由于它不起作用,我只下载了一个 code that works well from 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);
它仍然很好用。但我想要的是左上角而不是左按钮,所以我使用这个:
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 在上面,P2 是正交的,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);
然后通过vertex shader中的正交投影矩阵的变换,将视图空间的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 }
};