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));
}
コンテキストが作成されますが、次にglXMakeCurrent
X サーバーから問題のエラー (BadMatch) が送信されます。
私はCreateContextAttribsARB
引数について疑った:x11DeviceContext.Display
とx11DeviceContext.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
。