我正在尝试使用SDL使单色图像出现在屏幕上。因此,我拥有的数组将具有0x00或0xFF的值。
首先,我制作了一个200x200的小窗口,创建了一个新表面,使用FillRect使其变黑。当我打印出间距和像素格式时,间距为800,格式为rgb888。如果我了解这一权利,这意味着Surface-> pixels的尺寸为800x200,因为每个像素都附加了2个字节的信息?]
我不明白,如果我想将表面像素阵列更改为完全不同的东西,该阵列的格式是什么?如果我有一个简单的由一个像素[0xFF]组成的数组,那么为表面的RGB值格式化的那个数组将为[0xFF,0xFF,0xFF]吗?对于我要在屏幕上更改的每个像素,我需要更新数组中的三个值吗?
我弄清楚数组的格式之后,它是否像surface-> pixels = newArray一样简单?然后更新窗口表面?
看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无符号int,并且被提取为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
格式将具有透明度/ alpha混合)。
对于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
应该互换。