3

ここのパズルのピースのいくつかがわかりません。C++ 開発者はwglCreateContext、コンテキスト (ダミー コンテキストかメイン コンテキストか) を設定するために 1 回呼び出すだけで済みます。AC# 開発者は、 wglCreateContext 2 回呼び出してコンテキストをセットアップすることをお勧めします (最初の呼び出しが失敗した場合は、その結果を無視します)。

たとえば、これはOpenTKのソース コードからの抜粋です。

Handle = new ContextHandle(Wgl.Imports.CreateContext(window.DeviceContext));
if (Handle == ContextHandle.Zero)
    Handle = new ContextHandle(Wgl.Imports.CreateContext(window.DeviceContext));
if (Handle == ContextHandle.Zero)
    throw new GraphicsContextException(
        String.Format("Context creation failed. Wgl.CreateContext() error: {0}.",
            Marshal.GetLastWin32Error()));

私が理解しているように、公開opengl32.dllする API の一部( . C++ では、ライブラリをリンクする順序が重要であることを意味すると思います。C# では、ライブラリをリンクせず、遅延読み込みを行うため、関数を 2 回呼び出すと、最終的に正しい順序が得られると思います。gdi32.dllChoosePixelFormatDllImport

誰が何が起こっているのか確認できますか?

4

1 に答える 1

1

それは正しい、Microsoft の Installable Client Driver (ICD) / OpenGL 用の Mini Client Driver モデルの奇妙な結果の 1 つです。opengl32.dll含まれていない関数を呼び出すことができればgdi32.dll(それらはたくさんあります)、C# でopengl32.dllgdi32 の上に のシンボル テーブルをインポートすることができます。

glGetError (...)コンテキストを作成するプロセスを開始する直前に呼び出すだけで、おそらく同じことを達成できます。明らかに、glGetError (...)アクティブなコンテキストなしで呼び出すのはエラーですが、それは問題ではありません。DLL シンボルをインポートするボールを転がす API 呼び出しが必要なだけです。

C/C++ では、DLL へのリンケージがビルド時に部分的に解決されるため、はるかに簡単です (DLL のインポート順序は、リンカー スイッチのライブラリの順序によって確立されます)。C/C++ では、opengl32.lib の前に gdi32.lib にリンクするだけで、この問題は解決されます。

考え方は同じですが、ChoosePixelFormat (...)要求されたフォーマット パラメータを一連のハードウェア アクセラレーション ピクセル フォーマットと一致させるために、ハードウェア ベンダーが配布する OpenGL ICD によってオーバーライドする必要があります。の gdi32 のバージョンを使用するChoosePixelFormat (...)と、ハードウェア アクセラレーション ピクセル フォーマットを取得できなくなります。Windows NT/95 OSR2 以降、GDI の上にレイヤー化されたお粗末なソフトウェア ベースの OpenGL 1.1 リファレンス実装が得られるだけです。リファレンス実装は拡張可能ではないため、GDI ピクセル形式を使用した場合、OpenGL 1.1 に永遠に行き詰まることになります。

于 2013-09-29T22:17:54.003 に答える