SDL_Surface* SDL_CreateRGBSurfaceFrom(void* pixels, int width, int height, int depth, int pitch, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask)
pixels | 既存のピクセルデータへのポインタ |
width | サーフェイスの幅 |
height | サーフェイスの高さ |
depth | サーフェイスのビット深度 (詳細を参照すること) |
pitch | 水平方向のバイト数 |
Rmask | ピクセルの赤マスク |
Gmask | ピクセルの緑マスク |
Bmask | ピクセルの青マスク |
Amask | ピクセルのαマスク |
// stb_image.hを使って読み込んだ画像ファイルからSDL_Surface*を生成するサンプル
// (https://github.com/nothings/stb/)
// stb_imageに要求する出力のカラー形式
// αチャネルを求めない/必要ないならばSTBI_rgbを使うこと
int req_format = STBI_rgb_alpha;
int width, height, orig_format;
unsigned char* data = stbi_load("./test.png", &width, &height, &orig_format, req_format);
if(data == NULL) {
SDL_Log("画像ファイルの読み込みに失敗した: %s", stbi_failure_reason());
exit(1);
}
// RGB(A)バイト配列のためのピクセル形式のカラーマスクを設定する
// これはSTBI_rgb (3)とSTBI_rgb_alpha (4)のみ対応している!
Uint32 rmask, gmask, bmask, amask;
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
int shift = (req_format == STBI_rgb) ? 8 : 0;
rmask = 0xff000000 >> shift;
gmask = 0x00ff0000 >> shift;
bmask = 0x0000ff00 >> shift;
amask = 0x000000ff >> shift;
#else // little endian, like x86
rmask = 0x000000ff;
gmask = 0x0000ff00;
bmask = 0x00ff0000;
amask = (req_format == STBI_rgb) ? 0 : 0xff000000;
#endif
int depth, pitch;
if (req_format == STBI_rgb) {
depth = 24;
pitch = 3*width; // 1ピクセルあたり3byte * 1行のピクセル数
} else { // STBI_rgb_alpha (RGBA)
depth = 32;
pitch = 4*width;
}
SDL_Surface* surf = SDL_CreateRGBSurfaceFrom((void*)data, width, height, depth, pitch,
rmask, gmask, bmask, amask);
if (surf == NULL) {
SDL_Log("サーフェイスの生成に失敗した: %s", SDL_GetError());
stbi_image_free(data);
exit(1);
}
// ... ここでサーフェイスを使う ...
// ...
// サーフェイスが必要なくなったら解放する...
SDL_FreeSurface(surf);
// .. *そして* サーフェイスで使ったデータも!
stbi_image_free(data);
この関数の動作はSDL_CreateRGBSurface()とよく似ているが, ピクセルデータのメモリを確保せず, 代わりに指定された既存のデータバッファをサーフェイスで使用する.
ピクセルデータはコピーされない. ピクセルデータは管理外である. つまり, サーフェイスを解放した後はピクセルデータも解放する必要がある.