これを行う方法は次のとおりです。
IDirect3DDevice9 :: GetBackBuffer:現在取得しているのと同じように、バックバッファーを表すIDirect3DSurface9へのアクセスを取得します。この呼び出しが参照カウントをインクリメントするので、完了したらこのサーフェスを解放することを忘れないでください!
IDirect3DSurface :: GetDesc:バックバッファサーフェスの説明を取得します。これにより、幅、高さ、およびフォーマットがわかります。
IDirect3DDevice9 :: CreateOffscreenPlainSurface:D3DPOOL_SCRATCHに新しいサーフェスオブジェクトを作成します。通常、同じ幅、高さ、および形式を使用する必要があります(ただし、実際にはこのメソッドを使用する必要はありません)。繰り返しますが、完了したらリリースします。この操作をフレームごとに実行する場合(この場合は、実行しようとしていることに対するシェーダーベースのアプローチなどの代替手段を検討する方が良いでしょう)、起動時に1回だけオフスクリーンプレーンサーフェスを作成して再利用できます。フレームごとに作成するのではなく、
D3DXLoadSurfaceFromSurface:バックバッファーサーフェスからオフシーンのプレーンサーフェスにコピーします。これにより、サイズ変更とフォーマット変換が自動的に行われます。または、フォーマットを変更したくない、または変更する必要がある場合は、IDirect3DDevice9 :: GetRenderTargetDataを使用できますが、その場合は、代わりにD3DPOOL_SYSTEMMEMにオフスクリーンプレーンサーフェスを作成します。
IDirect3DSurface9 :: LockRect:オフスクリーンプレーンサーフェスのデータにアクセスし、それを使って独自の邪悪な方法を持つ。完了したら、UnlockRect。
これははるかに多くのコードのように見えますが、glReadPixelsと同じくらい高速であり、フォーマット変換を実行する必要がない場合はさらに高速になる可能性があります(GL_RGBを使用するglReadPixelsはほぼ確実に実行します)。
追加して編集:スクリーンショットにこのメソッドを使用するのに役立つ可能性があるいくつかの(rought 'n' ready)ヘルパー関数も持っています。
// assumes pitch is measured in 32-bit texels, not bytes; use locked_rect.Pitch >> 2
void CollapseRowPitch (unsigned *data, int width, int height, int pitch)
{
if (width != pitch)
{
unsigned *out = data;
// as a minor optimization we can skip the first row
// since out and data point to the same this is OK
out += width;
data += pitch;
for (int h = 1; h < height; h++)
{
for (int w = 0; w < width; w++)
out[w] = data[w];
out += width;
data += pitch;
}
}
}
void Compress32To24 (byte *data, int width, int height)
{
byte *out = data;
for (int h = 0; h < height; h++)
{
for (int w = 0; w < width; w++, data += 4, out += 3)
{
out[0] = data[0];
out[1] = data[1];
out[2] = data[2];
}
}
}
// bpp is bits, not bytes
void WriteDataToTGA (char *name, void *data, int width, int height, int bpp)
{
if ((bpp == 24 || bpp == 8) && name && data && width > 0 && height > 0)
{
FILE *f = fopen (name, "wb");
if (f)
{
byte header[18];
memset (header, 0, 18);
header[2] = 2;
header[12] = width & 255;
header[13] = width >> 8;
header[14] = height & 255;
header[15] = height >> 8;
header[16] = bpp;
header[17] = 0x20;
fwrite (header, 18, 1, f);
fwrite (data, (width * height * bpp) >> 3, 1, f);
fclose (f);
}
}
}