0

今日、OpenTK への依存を取り除きました。私のアプリケーションは、OpenGL コンテキストを作成するために OpenTK に依存しなくなりました。ただし、Mesa 3D (ソフトウェアでレンダリングされた OpenGL の実装) で実行すると、私のコードは適切に機能しなくなりました。私のコードは実行されますが、FPS は約 0.001 FPS (OpenTK のコンテキスト作成を使用した場合の約 16+FPS と比較して) であり、通常は FBO に描画されるものが構成されているようにウィンドウに表示されます。Mesa 3D を使用せずにコードを実行すると (Windows 7 で) 通常のパフォーマンスが得られますが、正常に動作するのは偶然かもしれないと心配しています。glGetErrorチェックはエラーを表示していません。おそらく、コンテキストの作成で何か間違ったことをしていると思いますか?

m_controlHandle = m_winForm.Handle; /* HWND */
m_controlDC = Win32.GetDC(m_controlHandle); /* HWND's DC*/
Win32.PixelFormatDescriptor pixelFormat = new Win32.PixelFormatDescriptor();
pixelFormat.Size = (short)Marshal.SizeOf(typeof(Win32.PixelFormatDescriptor));
pixelFormat.Version = 1;
pixelFormat.Flags =
    Win32.PixelFormatDescriptorFlags.DRAW_TO_WINDOW |
    Win32.PixelFormatDescriptorFlags.SUPPORT_OPENGL |
    Win32.PixelFormatDescriptorFlags.DOUBLEBUFFER;
pixelFormat.PixelType = Win32.PixelType.RGBA;
pixelFormat.ColorBits = 32;
pixelFormat.DepthBits = 0; /* yes, I don't use a depth buffer; 2D sprite game */
pixelFormat.LayerType = Win32.PixelFormatLayerType.MAIN_PLANE;
int formatCode = Win32.ChoosePixelFormat(m_controlDC, ref pixelFormat);
if (formatCode == 0)
    throw new Win32Exception(Marshal.GetLastWin32Error());
if (!Win32.SetPixelFormat(m_controlDC, formatCode, ref pixelFormat))
    throw new Win32Exception(Marshal.GetLastWin32Error());
m_openGLContext = Win32.wglCreateContext(m_controlDC);
if (m_openGLContext == IntPtr.Zero)
throw new Win32Exception(Marshal.GetLastWin32Error());
if (!Win32.wglMakeCurrent(m_controlDC, m_openGLContext))
    throw new Exception("Could not wglMakeCurrent.");

これは正しいです?Mesa3D が突然おかしくなった原因を追跡するための提案はありますか?

4

2 に答える 2

0

ソフトウェアの実装を避けたい場合、ピクセル形式を選択するロジックに大きな欠陥があります。WGL は、要求されたパラメーターを最低限満たすすべてのピクセル形式のセットを探すパターン マッチング ヒューリスティックを使用することを思い出してください (または初めて学習します)。要求されたパラメーターを 0 に設定しておくほど、「最良の」(最も近い) 一致を解決するときにあいまいさが残ります。

32 ビットのカラー バッファーと組み合わせた 0 ビットの深度バッファーが悪い考えである理由を理解したい場合は、ディスプレイ ドライバーによって提供されるすべてのピクセル フォーマットを列挙し、完全にハードウェア アクセラレーションされているものを調べることができます (それらはflag:PFD_GENERIC_FORMATまたはsetはありませんPFD_GENERIC_ACCELERATED)。あなたのためにこれを行うソフトウェアがありますが、私は頭のてっぺんから何かを思いつくことはできません-実際にこれを行うことにした場合は、何百ものピクセル形式のリストを調べる準備をしてください...

パラメータの多くの奇妙な組み合わせはソフトウェア (GDI) で実装されますが、ハードウェアでは実装されません。ハードウェア形式を取得するために試すのに最適なビット深度の 1 つは、32 ビット RGBA、24 ビット深度、8 ビット Stencil です。最新のハードウェアでは、これはほとんどの場合、ドライバーが入力パラメーターの最も適切な組み合わせに対して「最も近い」一致として選択するものです。正確なハードウェア ピクセル フォーマットの選択に近づくほど、Win32 / WGL が GDI ピクセル フォーマットを提供しない可能性が高くなります。


私自身の観察に基づいて:

ピクセル形式を手動で列挙ChoosePixelFormat (...)し、ドライバーのバグを回避するために の動作を上書きする必要がありました。パターン マッチングの動作が常に有利に働くとは限りません。

OpenTK の場合、実際には を使用していると思わwglChoosePixelFormatARB (...)れます。これは、ピクセル形式を選択するためのより洗練されたインターフェイスです (マルチサンプル アンチエイリアシングをサポートするために必要です)。wglChoosePixelFormatARBは、Installable Client Driver (ICD) によって実装されるため、入力パラメーターを GDI ピクセル形式と一致させようとすることはありません。

GDI は 32 ビット RGBA + 0 ビット Z ピクセル形式を提供していると思われますが、ICD は提供していません。最も近い一致が常に優先され、ChoosePixelFormatGDI ピクセル形式が表示されるため、これが問題である理由がわかります。

32 ビット RGBA (24 ビット カラー、8 ビット アルファ) + 24 ビット Z + 8 ビット ステンシルを試して、パフォーマンスが向上するかどうかを確認してください...


アップデート:

一部の愚かなドライバーをつまずかせている可能性がある別の問題があります。ColorBitsは、RGBA ピクセル形式 (通常は 24) の RGB ビット数と見なされますAlphaBitsは、A ビットの数 (通常は 8) であると想定されます。多くのドライバーは 32 ビットColorBitsと 0 の組み合わせをAlphaBits認識し、暗黙の動作 (24 ビット RGB + 8 ビット パディング) を理解しますが、コードの記述方法が問題になる可能性があります。技術的には、この種のピクセル形式は呼び出されますRGBX8(X は未使用ビットを示します)。

24ColorBitsと 8を使用するとAlphaBits、よりポータブルな結果が得られる可能性があります。

于 2013-09-20T23:53:25.240 に答える