0

問題の概要:

OpenGL glReadPixels を使用してスクリーンショットを取得していますが、バッファは変更されていません。glGetError を使用して最後の関数からエラーを取得すると、すべてが正常であるかのように 0 が返されます。

オンラインで徹底的に調査しましたが、このような問題に直面している人はいません。

詳細に:

基本的に OpenGL を C# にラップする CsGL.dll を使用しており、GL を使用するために必要な初期化を行いました。そして wglMakeCurrent(RC, DC) を呼び出します。


Windows API 関数の単純なラッパーを使用していることに注意してください。私が使用したこの初期化のコードは次のとおりです。

public unsafe void Init(IntPtr hWnd)
{
        this.DC = (IntPtr)User.GetDC(this.HWnd = hWnd);

        var pfd = new PIXELFORMATDESCRIPTOR();
        var sizeOf = Marshal.SizeOf(pfd);

        Kernel.ZeroMemory(new IntPtr(&pfd), sizeOf);
        pfd.nSize = (short)sizeOf;
        pfd.nVersion = 1;
        pfd.dwFlags = (int)(PixelFormatDescriptorFlagsEnum.PFD_DRAW_TO_WINDOW |
                            PixelFormatDescriptorFlagsEnum.PFD_SUPPORT_OPENGL |
                            PixelFormatDescriptorFlagsEnum.PFD_DOUBLEBUFFER);
        pfd.iPixelType = PIXELFORMATDESCRIPTOR.PFD_TYPE_RGBA;
        pfd.cColorBits = 24;
        pfd.cDepthBits = 16;
        pfd.iLayerType = PIXELFORMATDESCRIPTOR.PFD_MAIN_PLANE;

        var iFormat = GDI.ChoosePixelFormat(this.DC, ref pfd);
        GDI.SetPixelFormat(this.DC, iFormat, ref pfd);

        this.RC = wglCreateContext(this.DC);

        wglMakeCurrent(this.DC, this.RC);
}

User.GetForegroundWindow() を hWnd として送信しました。

この初期化の後、スクリーンショットを画像に取り込もうとします(また、それを単純なバイト配列に読み込もうとしました)

glReadPixels 使用の短い疑似コード:

var area = new Rectangle(0, 0, 100, 100);
var bmp = new Bitmap(area.Width, area.Height);
var data = bmp.LockBits(area, ILM.WriteOnly, PF.24bppRgb);

glReadBuffer(BACK);
glReadPixels(0, 0, area.Width, area.Height, BGR_EXT /*also tried RGB and RGBA*/, UNSIGNED_BYTE, data.Scan0);

bmp.UnlockBits(data);
bmp.Save(@"C:\Back.bmp");

data = bmp.LockBits(area, ILM.WriteOnly, PF.24bppRgb);

glReadBuffer(FRONT);
glReadPixels(0, 0, area.Width, area.Height, BGR_EXT /*also tried RGB and RGBA*/, UNSIGNED_BYTE, data.Scan0);

bmp.UnlockBits(data);
bmp.Save(@"C:\Front.bmp");

シンプルで小さい byte[] で試してみると、次のようになりました。

var bytes = new byte[10 * 10 * 3];
glReadPixels(0, 0, 10, 10, RGB, UNSIGNED_BYTE, bytes);

そして、byte[] はすべてゼロでした。また、配列のサイズを大きくして(0、0、10、10を保持して)試しましたが、それでも役に立ちません。


どちらの場合も、結果は同じです。glGetError 呼び出しは各 GL 関数呼び出しの後に 0 を返しますが、バッファーはまったく変更されません。

Back.bmp と Front.bmp は両方とも完全に黒です。

私が間違っていることを教えてください。ありがとう

4

1 に答える 1

3

レンダリングしたもののスクリーンショット、または一般的な画面のスクリーンショットを作成しようとしていますか?

glReadPixelsは、OpenGL フレームバッファのコンテンツに対してのみ機能することが保証されています。それ以外のもののスクリーンショットを撮るのには適していません (以前はこれが可能だった時期もありましたが、合成ウィンドウ マネージャーが登場して以来、そのような時代はなくなりました)。

したがって、一般的な画面キャプチャを実行しようとしている場合、glReadPixelsは間違った方法です。

ただし、レンダリングしたもののスクリーンショットを撮ろうとしている場合は、 glReadPixelsを呼び出すときに、レンダリングしたコンテキストもアクティブであることを確認する必要があります。

于 2011-09-21T08:49:02.800 に答える