Имеет ли SDL2.0 SetRenderDrawColor и TTF_RenderUNICODE_Blended проблемы с памятью? - PullRequest
0 голосов
/ 10 января 2020

У меня есть связанный с работой проект C / C ++ SDL 2.0 - первоначально разработанный и скомпилированный на компьютере Win7 для платформы x86 (с MS Visual Studio), который работал все время. Поскольку программа должна была работать и на новых устройствах Win10 x64, я перенес все решение на новый компьютер Win10 x64, изменил все библиотеки SDL2, файлы заголовков и т. Д. c. для версии x64 и перестроил решение для архитектуры x64.

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

После перекомпиляции для платформы x64 я заметил, что цвета некоторых элементов абсолютно отключены. Например, прямоугольник, который должен быть серым (используется SDL_SetRenderDrawColor за один шаг до рисования прямоугольника.) Внезапно становится зеленым, несмотря на то, что в качестве входных аргументов указаны серые номера RGB. Даже функция SDL_GetRenderDrawColor, вызываемая до и / или после рисования прямоугольника, возвращает значения 195, 195, 195, но прямоугольник отображается зеленым.

Функция рисования прямоугольника:

void DrawRectangle(SDL_Color color, int pozX, int pozY, int width, int height)
{
    SDL_Rect Proportions = { pozX, pozY, width, height };
    SDL_SetRenderDrawColor(gRenderer, color.r, color.g, color.b, 0xFF);
    SDL_RenderFillRect(gRenderer, &Proportions);
}

Рисование прямоугольника call:

DrawRectangle(grey, pocpozX, 182, width, height);

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

Функция рисования текста:

void DrawText(std::wstring text, TTF_Font *font, int pozX, int pozY, SDL_Color color)
{
    typedef std::basic_string<Uint16, std::char_traits<Uint16>, std::allocator<Uint16> > u16string;
    std::wstring text_sf_str = text;
    u16string utext_sf_str(text_sf_str.begin(), text_sf_str.end());
    SDL_Surface* text_sf = TTF_RenderUNICODE_Blended(font, utext_sf_str.c_str(), color);
    SDL_Texture* text_Tx = SDL_CreateTextureFromSurface(gRenderer, text_sf);
    int text_TxW;
    int text_TxH;
    SDL_QueryTexture(text_Tx, NULL, NULL, &text_TxW, &text_TxH);
    SDL_Rect textrect = { pozX, pozY, text_TxW, text_TxH };
    SDL_RenderCopy(gRenderer, text_Tx, NULL, &textrect);
    SDL_FreeSurface(text_sf);
    SDL_DestroyTexture(text_Tx);
}

Обратите внимание на все эти преобразования, необходимые для отображения текста wstring с некоторые необычно используемые символы Юникода. Я не совсем понимаю, почему SDL нужно передавать каждый символ как номер Uint16, это можно было бы сделать лучше. Я также не понимаю необходимость использования SDL_QueryTexture только для правильного отображения пропорций текста. Я ожидал бы, что пользователь захочет отобразить текст, по крайней мере не растянутый по умолчанию. Все это кажется мне излишне сложным.

Забавно, что если я удаляю тег SDL_DestroyTexture, то, конечно, происходит огромная утечка памяти, но проблема исчезает.

Вызов рисования текста - в течение для l oop, этот доктор aws цифра c помечает на оси спидометра:

if (i % 20 == 0)
        {
            if (i <= 160)
            {
                DrawText(str2, font, posX, posY, grey);
            }
            else
            {
                DrawText(str2, font, posX, posY, green);
            }
        }

... И этот самый "зеленый" в качестве последнего аргумента вызов вызывает то, что прямоугольник также становится зеленым - несмотря на то, что между этим текстом и прямоугольником нарисовано больше элементов, поэтому SDL_SetRenderDrawColor вызывается несколько раз.

Я также заметил, что некоторые показанные числа предназначены для немного в то время как каждую n-ую секунду я получаю некоторые бессмысленные значения, так что я думаю, что это проблема памяти. Конечно, есть больше проблем с цветом, это было только для примера. Из-за политики компании, я не могу более подробно указать c или выложить полный код здесь.

Если я вернусь к конфигурации x86 (с правильными библиотеками, конечно), проблема останется прежней.

...