orthoProject freetype opengl
Я пытаюсь использовать freetype с OpenGL. Сначала я попытался написать свой материал, и, поскольку он не работал, я просто загружаю код, который хорошо работает из этого урока. Как я уже сказал, это работает хорошо, но проекция отличается от того, что я хочу. В уроке мы имеем это:
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);
и теперь это больше не работает, у меня нет текста на экране. другой объект правильно отображается, кроме текста. Обратите внимание, что с двумя предыдущими проекциями я получил текст, но присутствовали другие объекты, но с перевернутой стороной (нормально).
мой вопрос, почему, если я нарисую текст в (0,0), ожидая увидеть его в левом верхнем углу, у меня ничего не будет вообще. но с другой проекцией у меня это внизу слева, как и ожидалось?
Я мог бы просто сохранить прогноз и переместить его, но я действительно хочу понять, почему он не работает.
NB: я пытался увидеть результат проекции * Положение. скажем, P1 орто с 0 на и P2 орто с 0 на дне.
для х, у = (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, код для текстового рендера. но это в первой ссылке
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);
}
1 ответ
Вопрос заключается в отбраковке лица:
Вы включили отбор граней, и вершины текстовых примитивов расположены в направлении против часовой стрелки:
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 viespace переворачивается, и порядок намотки примитивов поворачивается против часовой стрелки к часовой стрелке путем преобразования с помощью матрицы ортографической проекции в вершинном шейдере.
Измените порядок намотки, который определяет фронтальные полигоны, 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 }
};