Когда я отрисовываю свой текст, используя TTF_RenderUTF8_Blended
Я получаю сплошной прямоугольник на экране. Цвет зависит от того, который я выберу, в моем случае это красный прямоугольник.
Что мне не хватает? Кажется, что я не получаю правильные значения альфа от поверхности, созданной с SDL_DisplayFormatAlpha(TTF_RenderUTF8_Blended( ... ))
или я? Кто-нибудь признает или знает проблему?
Если я использую TTF_RenderUTF8_Solid
или же TTF_RenderUTF8_Shaded
текст рисуется правильно, но не смешивается конечно.
Я также рисую другие текстуры на экране, поэтому я рисую текст в последнюю очередь, чтобы гарантировать, что смешивание будет учитывать текущую поверхность.
Редактировать:SDL_Color g_textColor = {255, 0, 0, 0};
<- Я пытался с и без значения альфа, но я получаю тот же результат.
Я попытался обобщить код, не удаляя слишком много деталей. Переменные с префиксом «g_» являются глобальными.
// 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);
// ...
}
// 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);
}
Вы сделали довольно распространенную ошибку. Это на конце 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);
Других решений пока нет …