Uint32 | format | SDL_PixelFormatEnumの値の1つ |
SDL_Palette* | palette | ピクセル形式に関連付けられたSDL_Paletteの配列, NULLのときパレットを持たない |
Uint8 | BitsPerPixel | ピクセル値の有効なビット数. 例: 8, 15, 16, 24, 32 |
Uint8 | BytesPerPixel | ピクセル値に必要なバイト数. 例: 1, 2, 3, 4 (詳細を参照すること) |
Uint32 | Rmask | ピクセルの赤成分の位置を表すマスク |
Uint32 | Gmask | ピクセルの緑成分の位置を表すマスク |
Uint32 | Bmask | ピクセルの青成分の位置を表すマスク |
Uint32 | Amask | ピクセルのα成分の位置を表すマスク. 0ならばα成分を持たない |
Uint8 | Rloss | (内部で使用) |
Uint8 | Gloss | (内部で使用) |
Uint8 | Bloss | (内部で使用) |
Uint8 | Aloss | (内部で使用) |
Uint8 | RShift | (内部で使用) |
Uint8 | GShift | (内部で使用) |
Uint8 | BShift | (内部で使用) |
Uint8 | AShift | (内部で使用) |
int | refcount | (内部で使用) |
SDL_PixelFormat* | next | (内部で使用) |
8bit形式は最も理解しやすい.
8bit形式では, BitsPerPixelは8で, BytesPerPixelは1である.
BytesPerPixelが1なので, 全てのピクセルはUint8で表され, その値はpalette->colorsの添え字である.
よって8bitサーフェイスのピクセルの色は次のように得る:
surface->pixelsから色の値を得る. そしてそれを添え字としてSDL_Color構造体のsurface->format->palette->colorsを読む.
以下のようになる:
SDL_Surface *surface;
SDL_PixelFormat *fmt;
SDL_Color *color;
Uint8 index;
/* ... */
/* ここでサーフェイスを生成する */
/* ... */
fmt=surface->format;
/* サーフェイスのビット深度をチェックする */
if(fmt->BitsPerPixel!=8){
fprintf(stderr, "8bitサーフェイスではない¥n");
return(-1);
}
/* サーフェイスをロックする */
SDL_LockSurface(surface);
/* 左上の角のピクセルを得る */
index=*(Uint8 *)surface->pixels;
color=fmt->palette->colors[index];
/* サーフェイスのロックを解除する */
SDL_UnlockSurface(surface);
printf("Pixel Color-> Red: %d, Green: %d, Blue: %d. Index: %d¥n",
color->r, color->g, color->b, index);
/* ... */
8bitを超えるピクセルは別の考え方が必要になる.
それらは"TrueColor"形式であり, 色情報はパレットではなくピクセル自身に格納されている.
mask, shift, lossフィールドでどのように色をエンコードしているかわかる.
maskフィールドでそれぞれの色成分を分離することができ, shiftフィールドはピクセル値のそれぞれの色成分が右から何ビット目かを知ることができ, そしてlossフィールドはこのピクセル値が8bitの色成分に対して何ビット失われているかを知ることができる.
/* 32bitピクセル値から色成分を得る */
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);
/* 赤成分を得る */
temp = pixel & fmt->Rmask; /* 赤成分を分離する */
temp = temp >> fmt->Rshift; /* 8bitまで下ろす */
temp = temp << fmt->Rloss; /* 8bitフルまで拡張する */
red = (Uint8)temp;
/* 緑成分を得る */
temp = pixel & fmt->Gmask; /* 緑成分を分離する */
temp = temp >> fmt->Gshift; /* 8bitまで下ろす */
temp = temp << fmt->Gloss; /* 8bitフルまで拡張する */
green = (Uint8)temp;
/* 青成分を得る */
temp = pixel & fmt->Bmask; /* 青成分を分離する */
temp = temp >> fmt->Bshift; /* 8bitまで下ろす */
temp = temp << fmt->Bloss; /* 8bitフルまで拡張する */
blue = (Uint8)temp;
/* α成分を得る */
temp = pixel & fmt->Amask; /* α成分を分離する */
temp = temp >> fmt->Ashift; /* 8bitまで下ろす */
temp = temp << fmt->Aloss; /* 8bitフルまで拡張する */
alpha = (Uint8)temp;
printf("Pixel Color -> R: %d, G: %d, B: %d, A: %d¥n", red, green, blue, alpha);
/* ... */
この構造体のフィールドは全て読み取り専用である.
ピクセル形式はパレットかマスクのいずれかである. パレットならば, Rmask, Gmask, Bmask, Amaskは全て0である.
ピクセルのバイト数に対するデータ型は以下の通りある.
1ピクセルあたりのバイト数 | データ型 |
---|---|
1 | Uint8 |
2 | Uint16 |
3 | 3つのUint8 |
4 | Uint32 |
SDL_PixelFormatは, SDL_Surfaceのpixelsフィールドに格納されたピクセルの形式を記述する. サーフェイスのformatフィールドにはSDL_PixelFormatが格納されている.
ピクセルのレベルを変えたいならば, SDLがどのように色情報を格納しているかを理解しなければならない. サンプルコードに詳細な情報がある.
現代的なピクセル色空間の情報は以下のWikipediaの項目にある: http://en.wikipedia.org/wiki/RGBA_color_space