SDL_image Ошибка прозрачности PNG - PullRequest
5 голосов
/ 06 ноября 2011

Я загружаю файл PNG (с некоторыми прозрачными местами) в свое приложение SDL.

Погуглил, как это сделать, предоставил мне пример кода:

SDL_Surface *LoadImage(std::string filename)
{
    SDL_Surface* loaded_image = 0, compatible_image = 0;

    if (!filename.c_str())
        return 0;

    loaded_image = IMG_Load(filename.c_str());

    if (!loaded_image)
        return 0;

    compatible_image = SDL_DisplayFormat(loaded_image);

    SDL_FreeSurface(loaded_image);

    return compatible_image;
}

Но при достижении строки compatible_image = SDL_DisplayFormat(loaded_image); приложение останавливается с неуловимым исключением (даже try { /* ... */ } catch (...) { /* ... */ } не помогает). Замена SDL_DisplayFormat() на SDL_DisplayFormatAlpha() тоже не помогла. Итак, я просто удалил строки, которые могут быть исключены, и заставил этот код работать для загрузки изображений:

SDL_Surface *LoadImage(std::string filename)
{
    if (!filename.c_str())
        return 0;

    return IMG_Load(filename.c_str());
}

И я обнаружил такую ​​неприятную вещь: когда один спрайт перекрывается прозрачными частями другого, появляются артефакты. Примерно так:

normal state

artifacts appearing

Я оживляю своего "героя" с помощью этого простого алгоритма:

// SDL_Surface sprite = LoadImage("hero.bmp");
// hero.bmp contains animation frames followed one-by-one in a single line
// spriteFrameCnt is a number of animation frames
// spriteWidth and spriteHeight contain single frame params

SDL_Rect srcRect;
srcRect.x = spriteFrame * spriteWidth;
srcRect.w = spriteWidth;
srcRect.y = 0;
srcRect.h = spriteHeight;
spriteFrame = ++spriteFrame % spriteFrameCnt;

SDL_BlitSurface(sprite, &srcRect, screen, &rcSprite);

Как это можно объяснить и исправить?

Ответы [ 3 ]

6 голосов
/ 07 ноября 2011

Используйте SDL_DisplayFormatAlpha вместо SDL_DisplayFormat. Это правильно сохраняет прозрачность.

1 голос
/ 07 ноября 2011

Нашел решение: когда рисуется плитка с прозрачными кусочками и другой спрайт рисуется поверх первого, появляются артефакты.Конечно, они будут, потому что ничто не скрывается за этим первым спрайтом!

Первое и самое быстрое решение - заполнить весь фон цветом перед дальнейшими бликами.

Второй и самый красивый способ (в моем случае) - нарисоватьфоновое изображение (как показано на рисунке).

Вот результаты:

first example

second example

Как видите, артефактов нетпоявляться.Молодец я!=)

1 голос
/ 06 ноября 2011

Не уверен, что это проблема, но вы должны убедиться, что вызываете SDL_Init до SDL_DisplayFormat

...