2013-04-18 43 views
0

我在使用Windows和Linux平臺的渲染系統時遇到了一些麻煩。glXMakeCurrent給我不好匹配

在Windows平臺上它就像一個沙姆沙伊赫,而在Linux上我的應用程序有以下異常終止:

System.InvalidOperationException: context cannot be current ---> System.ComponentModel.Win32Exception: BadMatch (invalid parameter attributes) X error details: X event name: '' (0) Display: 0x8f17328 Resource ID: 4000011 Error code: 8 Major code: '' (135) Minor code: 5

at Derm.Render.RenderContext.MakeCurrent (IDeviceContext deviceContext, Boolean flag) at Derm.Render.RenderContext.CreateRenderContext (IDeviceContext deviceContext, Derm.Render.RenderContext hSharedContext, GLVersion version) Stacktrace:

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

...

at System.Windows.Forms.Control.CreateHandle() at 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打開了顯示。

回答

0

我找到了解決方案。

我寫了一個單元測試,爲每個可視化創建OpenGL對象,並且我找到了區分造成BadMatch錯誤的可視對象的變量:用於創建窗口的視覺的depth

具有32位深度的圖像導致BadMatch錯誤。幸運的是,驅動程序提供了具有24位深度的等效視覺效果,這非常完美。

使用Mono的System.Windows.Forms.XPlatUIX11實現,該窗口由框架創建(在我的情況下是一個UserControl)。由於它使用CopyFromParent常量,我的控制繼承了視覺深度,限制了可能的視覺選擇。

1

Do you have any idea to what it's going on?

只能猜測。對我來說,這個問題聽起來像上下文已經在其他線程中激活,並且glXMakeCurrent報告它無法使上下文處於活動狀態,因此; OpenGL上下文一次只能在一個線程中處於活動狀態。

我也對Glx.XLock做什麼感到困惑(我只能猜測它是XLockDisplay的副本,因爲它需要顯示參數)?你正在使用哪種C#OpenGL綁定,以便我可以閱讀文檔?

+0

上下文在其創建之後變爲當前,其中發生錯誤。 C#綁定是由我定義的,我完全可以控制。你對XLock課是對的。在tomorro之前,我可以上傳整個框架(由GPL編寫並由我編寫) – Luca

+0

@Luca:爲了學習的目的,您是否也編寫了一個純C程序來創建GLX上下文?只是看到一般的方法有效嗎?我在https://github.com/datenwolf/codesamples/tree/master/samples/OpenGL/x11argb_opengl – datenwolf

+0

上提供了一個基於X11 OpenGL FBConfig的上下文創建的非常簡單的例子。它的工作原理類似於sharm(很好的技巧)。 – Luca

相關問題