How to draw text in OpenGL?

1.1k views Asked by At

I'm trying to draw text with OpenGL, but it doesn't display right, or even consistently. From what I gather, it is in the creation or binding of the bitmap that doesn't work. I'll admit that I don't fully understand the FT_Load_Char method or the glTexImage2D method, so it's likely that one of those methods is the issue.

Here is my code:

#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>
#include <gl/gl.h>
#include <ft2build.h>
#include FT_FREETYPE_H

void drawText(char* text, FT_Face face)
{
    int i = 0;
    while (*(text + i) != '\0')
    {
        auto error = FT_Load_Char( face, text[i], FT_LOAD_RENDER );
        if (!error)
        {
            FT_GlyphSlot glyphSlot = face->glyph;
            FT_Bitmap bitmap = face->glyph->bitmap;
            unsigned char* buffer = face->glyph->bitmap.buffer;

            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
            glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, face->glyph->bitmap.width, face->glyph->bitmap.rows, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, face->glyph->bitmap.buffer);
            glColor3f (1.0, 1.0, 1.0);
            glBegin (GL_QUADS);
            glTexCoord2f (0,0);
            glVertex2d (-0.9375 + 0.25*(i%8), 0.9375 - .25*(i/8));
            glTexCoord2f (0,1);
            glVertex2d (-0.9375 + 0.25*(i%8), 0.8125 - .25*(i/8));
            glTexCoord2f (1,1);
            glVertex2d (-0.8125 + 0.25*(i%8), 0.8125 - .25*(i/8));
            glTexCoord2f (1,0);
            glVertex2d (-0.8125 + 0.25*(i%8), 0.9375 - .25*(i/8));
            glEnd ();
        }
        i++;
    }
}

int main()
{
    // Create the main window
    sf::Window App(sf::VideoMode(500, 500, 32), "Text Test");

    // Set color and depth clear value
    glClearDepth(1.f);
    glClearColor(0.f, 0.f, 0.f, 0.f);

    glEnable (GL_BLEND);
    glEnable (GL_TEXTURE_2D);
    glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    FT_Library library;
    FT_Face face;

    auto error = FT_Init_FreeType( &library );
    if ( error )
    {
        return 1;
    }

    error = FT_New_Face( library,
                       "arial.ttf",
                       0,
                       &face );
    if ( error == FT_Err_Unknown_File_Format )
    {
        return 2;
    }
    else if ( error )
    {
        return 3;
    }

    error = FT_Set_Char_Size(
            face,    /* handle to face object           */
            0,       /* char_width in 1/64th of points  */
            16*64,   /* char_height in 1/64th of points */
            300,     /* horizontal device resolution    */
            300 );   /* vertical device resolution      */
            if ( error )
    {
        return 4;
    }

    char * text = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890";

    // Start game loop
    while (App.isOpen())
    {
        // Process events
        sf::Event Event;
        while (App.pollEvent(Event))
        {
            // Close window : exit
            if (Event.type == sf::Event::Closed)
                App.close();

            if ((Event.type == sf::Event::KeyPressed))
            {
                if (Event.key.code == sf::Keyboard::Escape)// Escape key : exit
                {
                    App.close();
                }
            }
        }
        glPopMatrix();

        // Clear color and depth buffer
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        drawText(text, face);
        glPushMatrix();

        // Finally, display rendered frame on screen
        App.display();
    }

    return EXIT_SUCCESS;
}

When I run this, this is the result: broken text

Does anyone have any idea what I'm doing wrong or how to fix my problem?

0

There are 0 answers