typedef struct{
SDL_Palette *palette;
Uint8 BitsPerPixel;
Uint8 BytesPerPixel;
Uint32 Rmask, Gmask, Bmask, Amask;
Uint8 Rshift, Gshift, Bshift, Ashift;
Uint8 Rloss, Gloss, Bloss, Aloss;
Uint32 colorkey;
Uint8 alpha;
} SDL_PixelFormat;| palette | palette へのポインタ、 あるいは BitsPerPixel > 8 ならば NULL。 |
| BitsPerPixel | サーフェスの各ピクセルを表わすのに使われるビット数。 普通は 8, 16, 24, 32 のどれか。 |
| BytesPerPixel | サーフェスの各ピクセルを表わすのに使われるバイト数。 普通は 1〜4。 |
| [RGBA]mask | 各チャンネルの値を取得するのに使われるビットマスク。 |
| [RGBA]loss | 各チャンネルで失われる精度。 (2[RGBA]loss) |
| [RGBA]shift | ピクセル値の各チャンネルの 2 進数の左シフト数。 |
| colorkey | 透明ピクセルのピクセル値。 |
| alpha | サーフェス全体のα値。 |
SDL_PixelFormat は SDL_Surface の pixels 領域に格納されるピクセルデータの形式を 表します。
サーフェス上においてピクセルレベルの変更をしたい場合は、 SDL が色情報をどのように格納するか理解することが必要不可欠です。
8 ビットのピクセルフォーマットが最も理解が容易です。 8 ビットの形式なので、8 BitsPerPixel であり、 1 BytesPerPixel です。 1 BytesPerPixel なので、全てのピクセルは palette->colorsを指す インデックスを含む Uint8 によって表現されます。 そのため、8 ビットサーフェスにおいてピクセル値を決定するためには、 surface->pixels から 色のインデックスを読み出し、そして surface->format->palette->colors から SDL_Color を 読み出すためにそのインデックスを使います。 以下のようになります:
SDL_Surface *surface;
SDL_PixelFormat *fmt;
SDL_Color *color;
Uint8 index;
.
.
/* サーフェスを作成 */
.
.
fmt=surface->format;
/* Check the bitdepth of the surface */
if(fmt->BitsPerPixel!=8){
fprintf(stderr, "8 ビットサーフェスではありません。\n");
return(-1);
}
/* サーフェスをロック */
SDL_LockSurface(surface);
/* 左上のピクセルを取得 */
index=*(Uint8 *)surface->pixels;
color=fmt->palette->colors[index];
/* サーフェスをアンロック */
SDL_UnlockSurface(surface);
printf("ピクセルの色-> 赤: %d, 緑: %d, 青: %d. インデックス: %d\n",
color->r, color->g, color->b, index);
.
.
8 ビット以上のピクセルフォーマットは全く異なります。 それらは "TrueColor" フォーマットと見なされ、色情報はパレットではなく ピクセルそのものに格納されます。 mask, shift, そして loss のフィールドによって 色情報がどのようにエンコードされているかがわかります。 mask フィールドによって色の各チャンネルを取り出すことが可能になり、 shift フィールドによってピクセル値の各チャンネルの右側にあるビット数がわかり、 loss フィールドによってピクセルの 各チャンネル 8 ビットの値をパッキングする時に失われるビット数がわかります。
/* 32 ビットのピクセル値から各チャンネルの値を抽出する */
SDL_PixelFormat *fmt;
SDL_Surface *surface;
Uint32 temp, pixel;
Uint8 red, green, blue, alpha;
.
.
.
fmt=surface->format;
SDL_LockSurface(surface);
pixel=*((Uint32*)surface->pixels);
SDL_UnlockSurface(surface);
/* R チャンネルの値を取得 */
temp=pixel&fmt->Rmask; /* R を取り出す */
temp=temp>>fmt->Rshift;/* シフト して 8 ビットに落とす */
temp=temp<<fmt->Rloss; /* 完全な 8 ビットの値に引き伸ばす */
red=(Uint8)temp;
/* G チャンネルの値を取得 */
temp=pixel&fmt->Gmask; /* G を取り出す */
temp=temp>>fmt->Gshift;/* シフト して 8 ビットに落とす */
temp=temp<<fmt->Gloss; /* 完全な 8 ビットの値に引き伸ばす */
green=(Uint8)temp;
/* B チャンネルの値を取得 */
temp=pixel&fmt->Bmask; /* B を取り出す */
temp=temp>>fmt->Bshift;/* シフト して 8 ビットに落とす */
temp=temp<<fmt->Bloss; /* 完全な 8 ビットの値に引き伸ばす */
blue=(Uint8)temp;
/* αチャンネルの値を取得 */
temp=pixel&fmt->Amask; /* αを取り出す */
temp=temp>>fmt->Ashift;/* シフト して 8 ビットに落とす */
temp=temp<<fmt->Aloss; /* 完全な 8 ビットの値に引き伸ばす */
alpha=(Uint8)temp;
printf("ピクセルの色 -> R: %d, G: %d, B: %d, A: %d\n", red, green, blue, alpha);
.
.
.