ортопроект 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 внизу.

для 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. но это в первой ссылке

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);
}

person lilington    schedule 06.06.2018    source источник
comment
Как отображается этот текст? В вашей ссылке не ясно, и весь соответствующий код должен быть включен в ваш вопрос.   -  person kmdreko    schedule 06.06.2018
comment
Я добавляю часть рендеринга, это может быть полезно. код был в первой ссылке, но я все равно его опубликую.   -  person lilington    schedule 06.06.2018


Ответы (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 пространства просмотра переворачивается, и порядок намотки примитивов меняется с против часовой стрелки на по часовой стрелке посредством преобразования с матрицей ортогональной проекции в вершинном шейдере.

Измените порядок намотки, который определяет лицевые многоугольники, на glFrontFace(GL_CW)< /a>, чтобы решить проблему:

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 }           
};
person Rabbid76    schedule 07.06.2018
comment
Спасибо, это работает, когда я делаю то, что вы объяснили. Но поскольку у меня уже есть полная среда, я оставлю ее такой и изменю порядок вершин, чтобы сохранить GL_CCW. - person lilington; 07.06.2018