Проблемы с чтением (и сравнением) пикселей в SDL2

Я загружаю файл PNG в SDL2 и пытаюсь найти «особые» цвета пикселей для отслеживания во время анимации спрайтов. Я поместил эти пиксели в свое изображение, но мой код их не находит.

Я использую этот код для чтения пикселей (взято из Интернета, завернуто в мой собственный класс текстуры):

Uint32 getpixel(SDL_Surface *surface, int x, int y)
{
int bpp = surface->format->BytesPerPixel;
/* Here p is the address to the pixel we want to retrieve */
Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;

switch(bpp) {
case 1:
    return *p;
    break;

case 2:
    return *(Uint16 *)p;
    break;

case 3:
    if(SDL_BYTEORDER == SDL_BIG_ENDIAN)
        return p[0] << 16 | p[1] << 8 | p[2];
    else
        return p[0] | p[1] << 8 | p[2] << 16;
    break;

case 4:
    return *(Uint32 *)p;
    break;

default:
    return 0;       /* shouldn't happen, but avoids warnings */
}
}

И это важные фрагменты кода, которые я использую для сравнения пикселей со «специальными» значениями, которые я установил ранее:

        // convert special SDL_Color to Uint32
        Uint32 spec1 = SDL_MapRGBA(_texture->GetSDLSurface()->format, _spec1.r, _spec1.g, _spec1.b, 255);
        Uint32 spec2 = SDL_MapRGBA(_texture->GetSDLSurface()->format, _spec2.r, _spec2.g, _spec2.b, 255);

...и, перебирая все пиксели в каждом кадре спрайта...

                    // get pixel at (x, y)
                    Uint32 pix = _texture->GetPixel(x, y);

                    // if pixel is a special value, store it in animation
                    if (pix == spec1)
                    {
                        SDL_Point pt = {x, y};
                        anim->Special1.push_back(pt);
                        found1 = true;
                    }
                    else if (pix == spec2)
                    {
                        SDL_Point pt = {x, y};
                        anim->Special2.push_back(pt);
                        found2 = true;
                    }

Теперь я устанавливаю точку останова в этих операторах if, чтобы проверить, был ли найден цвет, но точка останова никогда не достигается. Кто-нибудь знает, в чем проблема?

P.S. Я также пробовал использовать SDL_MapRGB(), но это тоже не работает.

[редактировать]

Хорошо, поэтому я попытался поместить пиксель в 0,0 всего изображения со значениями RGB 66, 77 и 88. Он считывал их как 84, 96 и 107, поэтому очевидно, что цвета либо меняются, либо не считываются должным образом. Однако, когда я пробую это с определенным значением альфа, он отлично его считывает. Я бы изменил свою систему, чтобы использовать только альфа-значения, но кажется, что редактор пикселей, который я использую, удаляет альфа-значение, как только вы вставляете пиксель, и смешивает его с остальной частью изображения.


person Zotoaster    schedule 12.01.2014    source источник


Ответы (1)


Ваша формула для смещения неверна, она должна быть:

Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x

(x не нужно умножать на bpp)

Из документов

pitch Длина строки развертки поверхности в байтах

Шаг, также называемый шагом, вычисляется следующим образом:

pitch = width * bytes per pixel

bytes per pixel = (bits per pixel + 7) / 8

Когда вы находитесь в правильном смещении байтов, получите от него Uint32 (для изображения 32bpp) и выполните сравнение.

person aybe    schedule 13.01.2014