Используя SDL_ttf и OpenGL, TTF_RenderUTF8_Blended печатает красный прямоугольник

Когда я отрисовываю свой текст, используя TTF_RenderUTF8_Blended Я получаю сплошной прямоугольник на экране. Цвет зависит от того, который я выберу, в моем случае это красный прямоугольник.

Результат с использованием TTF_RenderUTF8_Blended

Что мне не хватает? Кажется, что я не получаю правильные значения альфа от поверхности, созданной с SDL_DisplayFormatAlpha(TTF_RenderUTF8_Blended( ... ))или я? Кто-нибудь признает или знает проблему?

Дополнительная информация

Если я использую TTF_RenderUTF8_Solid или же TTF_RenderUTF8_Shaded текст рисуется правильно, но не смешивается конечно.

Я также рисую другие текстуры на экране, поэтому я рисую текст в последнюю очередь, чтобы гарантировать, что смешивание будет учитывать текущую поверхность.

Редактировать:SDL_Color g_textColor = {255, 0, 0, 0}; <- Я пытался с и без значения альфа, но я получаю тот же результат.

Я попытался обобщить код, не удаляя слишком много деталей. Переменные с префиксом «g_» являются глобальными.

Функция Init ()

// This function creates the required texture.
bool Init()
{
// ...

g_pFont = TTF_OpenFont("../arial.ttf", 12);
if(g_pFont == NULL)
return false;

// Write text to surface
g_pText = SDL_DisplayFormatAlpha(TTF_RenderUTF8_Blended(g_pFont, "My first Text!", g_textColor)); //< Doesn't work

// Note that Solid and Shaded Does work properly if I uncomment them.
//g_pText = SDL_DisplayFormatAlpha(TTF_RenderUTF8_Solid(g_pFont, "My first Text!", g_textColor));
//g_pText = SDL_DisplayFormatAlpha(TTF_RenderUTF8_Shaded(g_pFont, "My first Text!", g_textColor, g_bgColor));

if(g_pText == NULL)
return false;

// Prepare the texture for the font
GLenum textFormat;
if(g_pText->format->BytesPerPixel == 4)
{
// alpha
if(g_pText->format->Rmask == 0x000000ff)
textFormat = GL_RGBA;
else
textFormat = GL_BGRA_EXT;
}

// Create the font's texture
glGenTextures(1, &g_FontTextureId);
glBindTexture(GL_TEXTURE_2D, g_FontTextureId);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, g_pText->format->BytesPerPixel, g_pText->w, g_pText->h, 0, textFormat, GL_UNSIGNED_BYTE, g_pText->pixels);

// ...
}

Функция DrawText ()

// this function is called each frame
void DrawText()
{
SDL_Rect sourceRect;
sourceRect.x = 0;
sourceRect.y = 0;
sourceRect.h = 10;
sourceRect.w = 173;

// DestRect is null so the rect is drawn at 0,0
SDL_BlitSurface(g_pText, &sourceRect, g_pSurfaceDisplay, NULL);

glBindTexture(GL_TEXTURE_2D, g_FontTextureId);
glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
glBegin( GL_QUADS );

glTexCoord2f(0.0f, 0.0f);
glVertex2f(0.0f, 0.0f);

glTexCoord2f(0.0f, 1.0f);
glVertex2f(0.0f, 10.0f);

glTexCoord2f(1.0f, 1.0f);
glVertex2f(173.0f, 10.0f);

glTexCoord2f(1.0f, 0.0f);
glVertex2f(173.0f, 0.0f);

glEnd();
glDisable(GL_BLEND);
glDisable(GL_TEXTURE_2D);
}

4

Решение

Вы сделали довольно распространенную ошибку. Это на конце OpenGL вещей.

Когда вы рендерите текстурированный квад в DrawText()Вы включаете возможность смешивания OpenGL, но никогда не указываете функцию смешивания (т.е. как это должно быть смешано)!

Вам нужен этот код для включения обычного альфа-смешивания в OpenGL:

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

Эта информация раньше была на сайте OpenGL, но я не могу найти ее сейчас.

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

Я заметил еще несколько небольших проблем в вашей программе.

в DrawText() функция, вы стираете поверхность с помощью SDL а также рендеринг с OpenGL. Вы не должны использовать регулярные блики SDL при использовании OpenGL; это не работает Так что этой строки там быть не должно:

SDL_BlitSurface(g_pText, &sourceRect, g_pSurfaceDisplay, NULL);

Также эта строка пропускает память:

g_pText = SDL_DisplayFormatAlpha( TTF_RenderUTF8_Blended(...) );

TTF_RenderUTF8_Blended() возвращает указатель на SDL_Surface, который должен быть освобожден с SDL_FreeSurface(), Так как вы передаете его в SDL_DisplayFormatAlpha()вы теряете его, и он никогда не освобождается (отсюда и утечка памяти).

Хорошей новостью является то, что вам не нужно SDL_DisplayFormatAlpha здесь, потому что TTF_RenderUTF8_Blended в любом случае возвращает 32-битную поверхность с альфа-каналом! Таким образом, вы можете переписать эту строку как:

g_pText = TTF_RenderUTF8_Blended(g_pFont, "My first Text!", g_textColor);
4

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]