Как мне обновить / заменить массив пикселей SDL Surface новым / обновленным массивом пикселей в C? - PullRequest
1 голос
/ 25 мая 2020

Я пытаюсь использовать SDL, чтобы на экране появилось монохромное изображение chrome. Таким образом, в моем массиве будут значения 0x00 или 0xFF.

Для начала я создал небольшое окно размером 200x200, создал новую поверхность, используйте FillRect, чтобы просто сделать его черным. Когда я распечатываю формат шага и пикселя, я получаю 800 для шага и rgb888 для формата. Если я правильно понимаю, это означает, что размеры поверхности-> пикселей составляют 800x200, потому что к каждому пикселю прикреплены дополнительные 2 байта информации?

Я не понимаю, хочу ли я изменить этот массив пикселей поверхности на что-то совершенно другое, каков формат массива? Если бы у меня был простой массив из одного пикселя [0xFF], был бы тот, отформатированный для значений RGB поверхности, был бы [0xFF, 0xFF, 0xFF]? Для каждого пикселя, который я хочу изменить на экране, мне нужно обновить три значения в массиве?

После того, как я выясню, как отформатировать массив, это так же просто, как поверхность-> пикселей = newArray? Затем обновить поверхность окна после?

1 Ответ

1 голос
/ 26 мая 2020

Посмотрите на SDL_pixels.h:

#define SDL_DEFINE_PIXELFORMAT(type, order, layout, bits, bytes) \
    ((1 << 28) | ((type) << 24) | ((order) << 20) | ((layout) << 16) | \
     ((bits) << 8) | ((bytes) << 0))

И для RGB888 мы имеем:

    SDL_PIXELFORMAT_RGB888 =
        SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_XRGB,
                               SDL_PACKEDLAYOUT_8888, 24, 4),

Для SDL_PACKEDORDER_* имеем:

/** Packed component order, high bit -> low bit. */

Итак, каждый пиксель представляет собой [упакованное] 32 беззнаковое целое число, а порядок при извлечении в 32-битное целое число следующий:

X | R | G | B

Для машины с прямым порядком байтов порядок равен перевернутый в памяти :

B | G | R | X

Однако см. предостережение ниже ...


Если я правильно понимаю , это означает, что размеры поверхности-> пикселей составляют 800x200, потому что к каждому пикселю прикреплены дополнительные 2 байта информации?

Нет, каждый пиксель имеет размер 4 байта, в котором только 3 [полезно ] (в виде 32-битного целого числа, как указано выше).

Уравнение:

pitch = number_of_bytes_per_pixel_in_memory * width

Что для вас: 800 = 4 * 200


Формат может изменять порядок RGB байтов, а также то, имеет ли четвертый байт какие-либо значения (например, прозрачность / альфа-смешение, которое было бы для формата RGBA).

Для RGB888, ей Вот некоторые функции преобразования, которые я приготовил для иллюстрации:

typedef unsigned int u32;
typedef unsigned char byte;

enum {
    RSHF = 16,
    GSHF = 8,
    BSHF = 0,
};

// rgb2pixel -- convert RGB values to pixel value
u32
rgb2pixel(byte r,byte g,byte b)
{
    u32 pix;

    pix = 0;
    pix |= ((u32) r) << RSHF;
    pix |= ((u32) g) << GSHF;
    pix |= ((u32) b) << BSHF;

    return pix;
}

// pix2red -- extract red from RGB pixel
byte
pix2red(u32 pix)
{
    byte color;

    color = pix >> RSHF;

    return color;
}

// pix2green -- extract green from RGB pixel
byte
pix2green(u32 pix)
{
    byte color;

    color = pix >> GSHF;

    return color;
}

// pix2blue -- extract blue from RGB pixel
byte
pix2blue(u32 pix)
{
    byte color;

    color = pix >> BSHF;

    return color;
}

Предостережение: Я не совсем уверен, что означает «Порядок упакованных компонентов».

Моя интерпретация приведенного выше порядка предполагает, что это порядок после того, как пиксель был получен как 32-битное целое число.

Но это может означать, что это порядок в памяти, В этом случае диаграммы, которые я создал выше, будут перевернуты.

Если вы сохранили все значения из:

rgb2pixel(0xFF,0x00,0x00)

, вы должны получить красный фон. Если вместо этого вы получили синий цвет, то RSHF и BSHF следует поменять местами.

...