TTF_RenderUTF8_Blended Rendering Цветной текст

Я пытаюсь визуализировать текст, используя SDL_ttf и openGL.

Я открываю шрифт и отрисовываю текст на SDL_Surface, а затем прикрепляю эту поверхность к текстуре и связываю ее для openGL для ее рендеринга.

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

Единственные две функции, которые имеют значение, так как я в значительной степени сделал временную переменную, чтобы решить эту проблему. Они есть:

SDL_Surface* CFont::BlendedUTF8Surface() {
    SDL_Surface* Surf_Text;
    SDL_Color Blah;
    Blah.r = 0;
    Blah.b = 255;
    Blah.g = 0;
    if(!(Surf_Text = TTF_RenderUTF8_Blended(pFont,TxtMsg,Blah))) {
        char str[256];
        sprintf_s(str, "? %s \n", TTF_GetError());
        OutputDebugString(str);
    }
    return Surf_Text;

}

При этом используется SDL_ttf для визуализации текста на поверхности Surf_Text. Вы можете видеть, что я превысил синий канал. Я расскажу об этом через минуту. Вот рендеринг

void CLabel::OnRender(int xOff,int yOff) {

    if(Visible) {
        glColor4f(1.0,1.0,1.0,1.0);
        Font.Color(FontColors.r, FontColors.g, FontColors.b); //useless I overwrote the variable with Blah to test this
        SDL_Surface* Surf_Text; 
        Surf_Text = Font.BlendedUTF8Surface();
        Text_Font.OnLoad(Surf_Text);
        Text_Font.RenderQuad(_X+xOff,_Y+yOff);
        SDL_FreeSurface(Surf_Text);
        glColor4f(0.0,0.0,0.0,1.0);
    }
}

Хорошо, насколько я могу судить, проблема, вероятно, связана с текущим состоянием цвета и режимом текстурной среды.

Когда я отрисовываю текст таким способом, текст будет менять цвета, но это похоже на сужение каналов R и B. Если я сделаю красный 255, текст будет синим, а если я сделаю синий 255 - красным. Зеленый остается зеленым (RGB против BGR?).

Если я удалю glColor4f вызов в функции рендеринга, текст вообще отказался отображать цветной. Всегда черный (я обычно устанавливаю цвет обратно (0,0,0) каждый раз, когда что-то рендеринг, так что это возможно, так как режим является модулированным (R = 0 * Texture (Font) R и т. Д.), Поэтому он будет черным. Имеет смысл,

Если я установлю для среды Texture значение DECAL, текст станет черным, а поле за текстом - цветом, который я пытаюсь отобразить.

Я думаю, что просто не знаю правильный способ сделать это. Кто-нибудь имеет опыт работы с текстурными средами SDL_ttf и openGL, который может дать некоторые идеи?

Редактировать:

Я сделал несколько переписываний функций и тестирование поверхности и наконец понял несколько вещей. Если я использую GL_DECAL, текст отрисовывает правильный цвет, и значение пиксельных значений равно 0 везде на поверхности, где это не красный цвет, который я пытался отрисовать (который отрисовывается со значением 255, что странно, так как красный - первый канал, который должен было 255^3 (или с точки зрения гексагона FF0000) по крайней мере, я бы ожидал). С DECAL альфа-пространство (пробел вокруг текста, который имеет 0 для значения пикселя) показывает цвет текущего вызова glColor(). Если я использую Blended, альфа-зона исчезает, но мой текст также отображается как Blended (конечно), так что он смешивается с базовой текстурой фона.

Я думаю, что более уместный вопрос - как мне смешать только пробел, а не текст? Я предполагаю, что я мог бы вызвать новый glBlendFunc(); но я проверил параметры и я как ребенок в лесу. Понятия не имею, как получить желаемый результат.

Решение не полностью проверено, но формат поверхности действительно BGRA, но я не могу осуществить это исправление. Я собираюсь попытаться создать функцию замены цвета для этого, я думаю.

Это исправление не сработало. Вместо настройки BGR я подумал просто создать новую поверхность RGB:

if (Surface->format->Rmask == 0x00ff0000) {
                Surface = SDL_CreateRGBSurfaceFrom(Surface->pixels, Surface->w, Surface->h, 32, Surface->pitch, Surface->format->Rmask, Surface->format->Gmask, Surface->format->Bmask, Surface->format->Amask);
}

После того, как это не сработало, я попытался обменяться Surface->format->Bmask а также Surface->format->Rmask но это тоже не имело никакого эффекта.

1 ответ

Решение

Для того, чтобы справиться BGR а также RGB изменения, вы можете попробовать этот код, чтобы создать текстуру из SDL_Surface

int createTextureFromSurface(SDL_Surface *surface)
{
    int texture;
    // get the number of channels in the SDL surface
    GLint  nbOfColors = surface->format->BytesPerPixel;
    GLenum textureFormat = 0;

    switch (nbOfColors) {
    case 1:
        textureFormat = GL_ALPHA;
        break;
    case 3:     // no alpha channel
        if (surface->format->Rmask == 0x000000ff)
            textureFormat = GL_RGB;
        else
            textureFormat = GL_BGR;
        break;
    case 4:     // contains an alpha channel
        if (surface->format->Rmask == 0x000000ff)
            textureFormat = GL_RGBA;
        else
            textureFormat = GL_BGRA;
        break;
    default:
        qDebug() << "Warning: the image is not truecolor...";
        break;
    }

    glEnable( GL_TEXTURE_2D );
    // Have OpenGL generate a texture object handle for us
    glGenTextures( 1, &texture );

    // Bind the texture object
    glBindTexture( GL_TEXTURE_2D, texture );


    // Edit the texture object's image data using the information SDL_Surface gives us
    glTexImage2D( GL_TEXTURE_2D, 0, nbOfColors, surface->w, surface->h, 0,
                  textureFormat, GL_UNSIGNED_BYTE, surface->pixels );

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

    return texture;
}
Другие вопросы по тегам