0

Windows プラットフォームと Linux プラットフォームの両方でレンダリング システムを動作させるのに問題があります。

Windows プラットフォームでは sharm のように動作しますが、Linux ではアプリケーションが次の例外で終了します。

System.InvalidOperationException: コンテキストを最新にすることはできません ---> System.ComponentModel.Win32Exception: BadMatch (無効なパラメーター属性) X エラーの詳細: X イベント名: '' (0) 表示: 0x8f17328 リソース ID: 4000011 エラー コード: 8 メジャー コード: '' (135) マイナー コード: 5

Derm.Render.RenderContext.MakeCurrent (IDeviceContext deviceContext、ブール値フラグ) で Derm.Render.RenderContext.CreateRenderContext (IDeviceContext deviceContext、Derm.Render.RenderContext hSharedContext、GLVersion バージョン) スタックトレース:

at (ラッパー管理からネイティブ) System.Windows.Forms.XplatUIX11.XFlush (intptr) at System.Windows.Forms.XplatUIX11.PostQuitMessage (int)

...

System.Windows.Forms.Control.CreateHandle () で System.Windows.Forms.Control.CreateControl() で

次のルーチンを使用して、「単純な」レンダリング コンテキストを作成できます。

private static IntPtr CreateX11SimpleContext(IDeviceContext rDevice)
{
    XServerDeviceContext x11DeviceCtx = (XServerDeviceContext)rDevice;

    using (new Glx.XLock(x11DeviceCtx.Display)) {
        int[] attributes = new int[] {
            Glx.RENDER_TYPE, (int)Glx.RGBA_BIT,
            0
        };

        // Get basic visual

        unsafe {
            int[] choosenConfigCount = new int[1];
            IntPtr *choosenConfigs = Glx.ChooseFBConfig(x11DeviceCtx.Display, x11DeviceCtx.Screen, attributes, ref choosenConfigCount);

            if (choosenConfigCount[0] == 0)
                throw new InvalidOperationException("unable to find basic visual");

            IntPtr choosenConfig = *choosenConfigs;
            IntPtr visual = Glx.GetVisualFromFBConfig(x11DeviceCtx.Display, choosenConfig);

            x11DeviceCtx.XVisualInfo = (Glx.XVisualInfo)Marshal.PtrToStructure(visual, typeof(Glx.XVisualInfo));
            x11DeviceCtx.FBConfig = choosenConfig;

            Glx.XFree((IntPtr)choosenConfigs);
        }

        // Create direct context
        IntPtr rContext = Glx.CreateContext(x11DeviceCtx.Display, x11DeviceCtx.XVisualInfo, IntPtr.Zero, true);
        if (rContext == IntPtr.Zero) {
            // Fallback to not direct context
            rContext = Glx.CreateContext(x11DeviceCtx.Display, x11DeviceCtx.XVisualInfo, IntPtr.Zero, false);
        }

        if (rContext == IntPtr.Zero)
            throw new InvalidOperationException("unable to create context");

        return (rContext);
    }
}

私が直面している問題は、上記のコンテキストが OpenGL 情報 (拡張機能、レンダラーなど) をフェッチするために使用され、その後破棄されることです。続いて、属性を使用してコンテキストを作成します。

XServerDeviceContext x11DeviceContext = (XServerDeviceContext)deviceContext;

using (Glx.XLock displayLock = new Glx.XLock(x11DeviceContext.Display)) {
    return (Glx.CreateContextAttribsARB(x11DeviceContext.Display, x11DeviceContext.FBConfig, sharedContext, true, attribsList));
}

コンテキストが作成されますが、次にglXMakeCurrentX サーバーから問題のエラー (BadMatch) が送信されます。

私はCreateContextAttribsARB引数について疑った:x11DeviceContext.Displayx11DeviceContext.FBConfig. 実際、私が使用している「ドローアブル」は、実際にはMono実装System.Windows.Formsによって提供されるコントロールです。

これらの変数を初期化する方法を示すいくつかのスニペットを次に示します。

どうすれば初期化できますx11DeviceContext.Displayか?

Type xplatui = Type.GetType("System.Windows.Forms.XplatUIX11, System.Windows.Forms");

Type xplatui = Type.GetType("System.Windows.Forms.XplatUIX11, System.Windows.Forms");

if (xplatui == null)
    throw new PlatformNotSupportedException("mono runtime version no supported");

// Get System.Windows.Forms display
mDisplay = (IntPtr)xplatui.GetField("DisplayHandle", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic).GetValue(null);
if (mDisplay == IntPtr.Zero)
    throw new InvalidOperationException("unable to connect to X server");

どうすれば初期化できますx11DeviceContext.FBConfigか?

IntPtr* configs = Glx.GetFBConfigs(x11DeviceContext.Display, x11DeviceContext.Screen, out configsCount);

// Then, a value is selected using a custom seletcion algo, using GetFBConfigAttrib

短いサンプル プログラムを提供できなくて申し訳ありませんが、コード ベースは非常に大きく複雑です。

何が起こっているのか分かりますか?


編集:

さらなる調査により、特定のビジュアルを使用して正しくレンダリングできることが明らかになりましたBadMatch。理由はわかりませんが、線と三角形が表示されます (ただし、ビジュアルがダブル バッファリングされていなくてもスワップする必要があります...)。

以前はBadMatch、「適合していない」ビジュアルを認識していなかったため、エラーが発生しました。実際、それらのいずれかを選択しました。ただし、ほとんどのビジュアルでエラーが発生します。

Mono 実装のクラスを確認しXplatUIX11、実際に でディスプレイを開きますXOpenDisplay

4

2 に答える 2

1

何が起こっているのか分かりますか?

推測のみ。私には、この問題はコンテキストが他のスレッドで既にアクティブになっているように聞こえますが、glXMakeCurrent はコンテキストをアクティブにできないと報告しています。OpenGL コンテキストは、一度に 1 つのスレッドでのみアクティブにできます。

また、何が機能するかについても混乱してGlx.XLockいます(表示パラメーターを取ることを考えると、XLockDisplayに対応しているとしか推測できません)?ドキュメントを読むことができるように、どの C# OpenGL バインディングを使用していますか?

于 2013-04-19T09:12:13.660 に答える
1

解決策を見つけました。

各ビジュアルの OpenGL コンテキストを作成する単体テストを作成し、BadMatchエラーの原因となるビジュアルを識別する変数、つまりウィンドウの作成に使用されるビジュアルの深さを見つけました。

深度が 32 ビットのビジュアルでBadMatchエラーが発生します。幸いなことに、ドライバーは 24 ビット深度の同等のビジュアルを提供し、完全に機能します。

Mono のSystem.Windows.Forms.XPlatUIX11実装を使用すると、フレームワーク (私の場合は UserControl) によってウィンドウが作成されます。定数を使用するCopyFromParentため、私のコントロールはビジュアルの深さを継承し、選択できるビジュアルを制限します。

于 2013-06-15T19:35:57.597 に答える