Отображение текста с SDL TTF с SDL2 и OpenGL - PullRequest
3 голосов
/ 26 мая 2019

Я пытаюсь отобразить текст, используя SDL2 TTF и OpenGL.В окне появляется странная текстура, она имеет правильный размер и правильную позицию, но вы не видите букв.

Я пытался использовать SDL_CreateRGBSurface (), думая, что это может быть более чистый способвосстановить пиксели, но это тоже не сработало.Моя поверхность никогда не равна NULL и всегда проходит тест проверки.

Я использую функцию get_front () перед циклом while () и функцию displayMoney () внутри нее, сразу после использования glClear (GL_COLOR_BUFFER_BIT).

SDL, TTF и OpenGL правильно инициализированы, и я создал контекст OpenGL.Вот проблемный код:

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

Нет сообщений об ошибках.Кроме того, вместо того, чтобы использовать поверхность, я протестировал свой код с изображением с помощью функции stbi_load, и он работал на отлично.Поэтому проблема, похоже, связана с SDL-частью.

EDIT : я недавно обнаружил, что поверхность, которую я получаю из моего текста, имеет следующие свойства: Rmask = Gmask = Bmask = Amask= 0. Это, очевидно, проблема, но я не знаю, как это исправить ...

1 Ответ

1 голос
/ 27 мая 2019

Как указано в документации SDL_ttf на https://www.libsdl.org/projects/SDL_ttf/docs/SDL_ttf.html#SEC42,

Затенение: Создайте 8-битную палитризованную поверхность и визуализируйте данный текст с высоким качеством с заданным шрифтом и цветами. Значение 0 пикселей - это фон, в то время как другие пиксели имеют различную степень цвета переднего плана от цвета фона.

Таким образом, ваша результирующая поверхность индексируется с помощью 8-битной палитры, а не RGBA (также отмеченной отсутствующими цветными масками в формате поверхности, как вы заметили). Поверхность RGBA с альфа-каналом производится, например, TTF_RenderText_Blended, либо используйте другой формат текстуры, либо выполните преобразование формата. Вам необходимо передать ширину / высоту поверхности в glTexImage2D вместо 128/64 констант, так как размер поверхности может варьироваться.

У вас также есть несколько утечек ресурсов в коде вопроса: создание новой текстуры при каждом рисовании и никогда ее не удалять (что также не требуется, если текст не изменяется), и никогда не закрывать шрифт с помощью TTF_CloseFont.

...