给我坏匹配

本文关键字: | 更新日期: 2023-09-27 18:09:51

我在Windows和Linux平台上都有一个渲染系统。

在Windows平台上,它像一个sharm,而在Linux上,我的应用程序以以下例外终止:

系统。InvalidOperationException:上下文不能是当前的——>System.ComponentModel。Win32Exception: BadMatch(无效参数)X事件名称:" (0)Display: 0x8f17328 . X error detail: X event name:资源ID: 4000011错误码:8重要码:"(135)次要代码:5

at derm . render . rendercontext . makeccurrent (IDeviceContext deviceContext, Boolean flag)在Derm.Render.RenderContext. createrendercontext (IDeviceContext deviceContext, Derm.Render.RenderContext hSharedContext, GLVersion版本)加:

at (wrapper managed-to-native) System.Windows.Forms.XplatUIX11。XFlush (intptr)在System.Windows.Forms.XplatUIX11。PostQuitMessage (int)

at 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.Displayx11DeviceContext.FBConfig。事实上,我使用的"drawable"实际上是一个System.Windows.Forms控件,由Mono实现提供。

下面是一些显示如何初始化这些变量的代码片段:

如何初始化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错误,因为我没有意识到"不符合"视觉,实际上我选择了其中一个;然而,大多数的视觉给了我错误。

我已经检查了单声道实现的XplatUIX11类,并实际打开XOpenDisplay显示

给我坏匹配

你知道是怎么回事吗?

只有猜测。对我来说,这个问题听起来就像上下文已经在其他线程中活跃,glxmakeccurrent报告它不能使上下文活跃,因为;一个OpenGL上下文一次只能在一个线程中被激活。

我也对Glx.XLock的作用感到困惑(我只能猜测它是XLockDisplay的对应项,因为它需要一个显示参数)?你使用哪个c# OpenGL绑定,以便我可以阅读文档?

我找到解决办法了。

我写了一个单元测试,为每个视觉效果创建OpenGL上下文,我发现了导致BadMatch错误的视觉效果的变量:用于创建窗口的视觉效果的深度。

具有32位深度的视觉效果导致BadMatch错误。幸运的是,驱动程序提供了24位深度的等效视觉效果,效果非常好。

使用System.Windows.Forms。XPlatUIX11实现的Mono,窗口是由框架创建的(在我的例子中是UserControl)。因为它使用了CopyFromParent常量,我的控件继承了视觉深度,限制了可能的视觉选择。

相关文章:
  • 没有找到相关文章