Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Displaying text with SDL TTF with SDL2 and OpenGL

I'm trying to display text using SDL2 TTF and OpenGL. A weird texture appears in the window, it's got the right size and the right position but you can't see any letters.

I've tried using the SDL_CreateRGBSurface() thinking that it might be a cleaner way to recuperate the pixels, but it didn't work either. My surface is never NULL and always passes the validation test.

I use the get_front() function before the while() loop, and the displayMoney() function inside it, right after using glClear(GL_COLOR_BUFFER_BIT).

SDL, TTF and OpenGL are initialized properly and I have created an OpenGL context. Here's the problematic code:

SDL_Surface* get_font()
{
    TTF_Font *font;
    font = TTF_OpenFont("lib/ariali.ttf", 35);
    if (!font) cout << "problem loading font" << endl;
    SDL_Color white = {150,200,200};
    SDL_Color black = {0,100,0};
    SDL_Surface* text = TTF_RenderText_Shaded(font, "MO", white, black);
    if (!text) cout << "text not loaded" << endl;

    return text;
}

void displayMoney(SDL_Surface* surface)
{
    glEnable( GL_BLEND );
    glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
    glEnable(GL_TEXTURE_2D);
    GLuint TextureID = 0;
    glGenTextures(1, &TextureID);
    glBindTexture(GL_TEXTURE_2D, TextureID);
        int Mode = GL_RGB;
        if(surface->format->BytesPerPixel == 4) {
            Mode = GL_RGBA;
        }

        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexImage2D(GL_TEXTURE_2D, 0, Mode, 128, 64, 0, Mode, GL_UNSIGNED_BYTE, surface->pixels);

        glPushMatrix();
            glTranslated(100,100,0);
            glScalef(100,100,0);
            glBegin(GL_QUADS);
                glTexCoord2f(0, 1); glVertex2f(-0.5f, -0.5f);  
                glTexCoord2f(1, 1); glVertex2f(0.5f, -0.5f); 
                glTexCoord2f(1, 0); glVertex2f(0.5f, 0.5f); 
                glTexCoord2f(0, 0); glVertex2f(-0.5f, 0.5f);  
            glEnd();
        glPopMatrix();
    glBindTexture(GL_TEXTURE_2D, 0); 
}

#include <SDL2/SDL.h>
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
using namespace std;
#include <GL/gl.h>
#include <GL/glu.h>
#include <stb_image/stb_image.h>
#include <SDL2_ttf/SDL_ttf.h>
#include "init.h"


int main(int argc, char **argv) {

    SDL_Window* window = init();
    if (window == nullptr) {
        cout << "Error window init" << endl;
    }

    if (TTF_Init() < 0) {
        cout << "Error TTF init" << endl;
    }

    SDL_Surface* text = get_font(); 

    while (loop) {

        glClear(GL_COLOR_BUFFER_BIT);

        displayMoney(text);

...

       SDL_GL_SwapWindow(window);

There aren't any error messages. Also, instead of using my surface, I tested my code with an image by using the stbi_load function and it worked perfectly well. The issue therefore seems to be with the SDL part.

EDIT : I've recently found out the surface I get from my text has the following properties: Rmask=Gmask=Bmask=Amask = 0. This is obviously a problem but I've no idea how to fix it...

like image 736
Monica Avatar asked May 26 '19 17:05

Monica


1 Answers

As stated in SDL_ttf documentation at https://www.libsdl.org/projects/SDL_ttf/docs/SDL_ttf.html#SEC42 ,

Shaded: Create an 8-bit palettized surface and render the given text at high quality with the given font and colors. The 0 pixel value is background, while other pixels have varying degrees of the foreground color from the background color.

So your resulting surface is indexed with 8-bit palette, not an RGBA (also indicated by missing colour masks in surface format, as you've noted). RGBA surface with alpha channel is produced by e.g. TTF_RenderText_Blended, or use different texture format, or perform format conversion. You need to pass surface width/height to glTexImage2D instead of 128/64 constants as surface size may vary.

You also have several resource leaks in question's code: creating new texture on each draw and never deleting it (which is also unnecessary if text isn't changing), and never closing font with TTF_CloseFont.

like image 72
keltar Avatar answered Oct 19 '22 07:10

keltar