Delphi XE2 で、OpenGL の ViewPort のレンダリングされたコンテンツをビットマップ ファイルに保存する方法について、助けが必要です。
基本的に私がやりたいことは、いくつかのレンダリングが行われた後、FrameBuffer の内容をビットマップ (フルカラー形式) ファイルにダンプすることです。これを達成するはずのコードの抜粋を次に示します。
procedure TForm1.saveBtnClick(Sender: TObject);
var
//TBitmap object holding the newly created Bitmap.
srcBitmap: TBitmap;
// the array to hold pixels value while reading from the FrameBuffer
pixels: Array of GLUbyte;
dimensions: Array [0 .. 3] of Integer;
//Stream between the memory location of pixels and my bitmap.
MS: TMemoryStream;
I: Integer;
begin
if SaveDialog1.Execute then
begin
//create the bitmap and set it to Full Color Format; Open the Memory Stream
srcBitmap := TBitmap.Create;
srcBitmap.PixelFormat:=pf24bit;
MS:= TMemoryStream.Create;
//get the dimensions info for the current ViewPort
glGetIntegerv(GL_VIEWPORT, @dimensions);
srcBitmap.Width := dimensions[2];
srcBitmap.Height :=dimensions[3];
//allocate enough memory for pixels;
SetLength(pixels, dimensions[2] * dimensions[3] * 3);
//this is the function that is supposed to read the contents from the Frame
// Buffer and write them to pixels
glReadPixels(0, 0, dimensions[2], dimensions[3], GL_RGB,
GL_UNSIGNED_BYTE, @pixels);
//Do something if an error occured
ErrorHandler;
// Below I attempt to create a bitmap file from the read in pixels
MS.Read(pixels,dimensions[2] * dimensions[3] * 3) ;
srcBitmap.LoadFromStream(MS);
Edit2.Text := SaveDialog1.FileName;
srcBitmap.SaveToFile(Edit2.Text);
MS.Free;
srcBitmap.Free;
end;
end;
私が遭遇する主な問題は次のとおりです。
1)ViewPortサイズが大きすぎる場合のスタックオーバーフローエラー(サイズ256 * 256で画像を保存しようとするとSOエラーが発生します)。これは、「glReadPixels」関数がFrameBufferをプロセッサーメモリに読み込むためだと思います(メインメモリではなく、L2 キャッシュである必要があり、これはイメージ全体を内部に収めることができません。これは事実ですか?もしそうなら、FrameBufferをメインメモリに読み込む方法について何か考えがありますか?
2) 1) のエラーを回避するために、小さいビューポート (25x25) でテストすると、「ピクセル」配列に格納されている値にアクセスしようとすると、アクセス違反エラーが発生します。これは、glReadPixels がバッファから適切に読み取られないことを意味します。この理由は、関数に渡すパラメータとの不一致であると考えられますglReadPixels(0, 0, dimensions[2], dimensions[3], GL_RGB,GL_UNSIGNED_BYTE, @pixels)
。