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 }           
};
Другие вопросы по тегам