/// <summary> /// Get the OpenGL context current on the calling thread. /// </summary> /// <returns> /// It returns the handle of the OpenGL context current on the calling thread. It may return <see cref="IntPtr.Zero"/> /// indicating that no OpenGL context is current. /// </returns> public static IntPtr GetCurrentContext() { #if !MONODROID if (!Egl.IsRequired) { switch (Platform.CurrentPlatformId) { case Platform.Id.WindowsNT: return(Wgl.GetCurrentContext()); case Platform.Id.Linux: return(Glx.GetCurrentContext()); case Platform.Id.MacOS: if (Glx.IsRequired) { return(Glx.GetCurrentContext()); } else { throw new NotSupportedException("platform MacOS not supported without Glx.IsRequired=true"); } default: throw new NotSupportedException($"platform {Platform.CurrentPlatformId} not supported"); } } else #endif return(Egl.GetCurrentContext()); }
/// <summary> /// Get the OpenGL context current on the calling thread. /// </summary> /// <returns> /// It returns the handle of the OpenGL context current on the calling thread. It may return <see cref="IntPtr.Zero"/> /// indicating that no OpenGL context is current. /// </returns> public static IntPtr GetCurrentContext() { if (Egl.IsRequired == false) { switch (Platform.CurrentPlatformId) { case Platform.Id.WindowsNT: return(Wgl.GetCurrentContext()); case Platform.Id.Linux: return(Glx.GetCurrentContext()); case Platform.Id.MacOS: if (Glx.IsRequired) { return(Glx.GetCurrentContext()); } else { throw new NotSupportedException("platform MacOS not supported without Glx.IsRequired=true"); } default: throw new NotSupportedException(String.Format("platform {0} not supported", Platform.CurrentPlatformId)); } } else { return(Egl.GetCurrentContext()); } }
/// <summary> /// Control the the buffers swap of a device. /// </summary> /// <param name="interval"> /// A <see cref="System.Int32"/> that specifies the minimum number of video frames that are displayed /// before a buffer swap will occur. /// </param> /// <returns> /// It returns a boolean value indicating whether the operation was successful. /// </returns> public override bool SwapInterval(int interval) { // Keep into account the SwapIntervalEXT and SwapIntervalSGI entry points, relative to // two equivalent GLX extensions #if false using (Glx.XLock displayLock = new Glx.XLock(Display)) { if (Glx.Delegates.pglXSwapIntervalEXT != null) { Glx.SwapIntervalEXT(Display, _WindowHandle, interval); return(true); } else if (Glx.Delegates.pglXSwapIntervalSGI != null) { return(Glx.SwapIntervalSGI(interval) == 0); } else { throw new InvalidOperationException("binding point SwapInterval{EXT|SGI} cannot be found"); } } #else return(false); #endif }
public static IntPtr CreateGLXPixmapMESA(IntPtr dpy, Glx.XVisualInfo visual, IntPtr pixmap, IntPtr cmap) { IntPtr retValue; Debug.Assert(Delegates.pglXCreateGLXPixmapMESA != null, "pglXCreateGLXPixmapMESA not implemented"); retValue = Delegates.pglXCreateGLXPixmapMESA(dpy, visual, pixmap, cmap); CallLog("glXCreateGLXPixmapMESA(0x{0}, {1}, 0x{2}, 0x{3}) = {4}", dpy.ToString("X8"), visual, pixmap.ToString("X8"), cmap.ToString("X8"), retValue.ToString("X8")); return (retValue); }
/// <summary> /// Query the GLX version supported by current implementation. /// </summary> private void QueryVersion() { using (Glx.XLock xLock = new Glx.XLock(Display)) { int[] majorArg = new int[1], minorArg = new int[1]; Glx.QueryVersion(Display, majorArg, minorArg); _GlxVersion = new KhronosVersion(majorArg[0], minorArg[0], KhronosVersion.ApiGlx); } }
/// <summary> /// Creates a context. /// </summary> /// <param name="sharedContext"> /// A <see cref="IntPtr"/> that specify a context that will share objects with the returned one. If /// it is IntPtr.Zero, no sharing is performed. /// </param> /// <returns> /// A <see cref="IntPtr"/> that represents the handle of the created context. If the context cannot be /// created, it returns IntPtr.Zero. /// </returns> /// <exception cref="InvalidOperationException"> /// Exception thrown in the case <paramref name="sharedContext"/> is different from IntPtr.Zero, and the objects /// cannot be shared with it. /// </exception> public override IntPtr CreateContext(IntPtr sharedContext) { if (XVisualInfo == null) { throw new InvalidOperationException("no visual information"); } using (Glx.XLock displayLock = new Glx.XLock(Display)) { return(Glx.CreateContext(Display, XVisualInfo, sharedContext, true)); } }
/// <summary> /// Deletes a context. /// </summary> /// <param name="ctx"> /// A <see cref="IntPtr"/> that specify the context to be deleted. /// </param> /// <returns> /// It returns a boolean value indicating whether the operation was successful. If it returns false, /// query the exception by calling <see cref="GetPlatformException"/>. /// </returns> /// <remarks> /// <para>The context <paramref name="ctx"/> must not be current on any thread.</para> /// </remarks> /// <exception cref="ArgumentException"> /// Exception thrown if <paramref name="ctx"/> is IntPtr.Zero. /// </exception> public override bool DeleteContext(IntPtr ctx) { if (ctx == IntPtr.Zero) { throw new ArgumentException("ctx"); } using (Glx.XLock displayLock = new Glx.XLock(Display)) { Glx.DestroyContext(Display, ctx); } return(true); }
/// <summary> /// Creates a context. /// </summary> /// <param name="sharedContext"> /// A <see cref="IntPtr"/> that specify a context that will share objects with the returned one. If /// it is IntPtr.Zero, no sharing is performed. /// </param> /// <returns> /// A <see cref="IntPtr"/> that represents the handle of the created context. If the context cannot be /// created, it returns IntPtr.Zero. /// </returns> /// <exception cref="InvalidOperationException"> /// Exception thrown in the case <paramref name="sharedContext"/> is different from IntPtr.Zero, and the objects /// cannot be shared with it. /// </exception> public override IntPtr CreateContext(IntPtr sharedContext) { if (Glx.CurrentExtensions == null || Glx.CurrentExtensions.CreateContext_ARB == false) { using (Glx.XLock displayLock = new Glx.XLock(Display)) { // Get the corresponding X visual info Glx.XVisualInfo xVisualInfo = _XVisualInfo != null ? _XVisualInfo : GetVisualInfoFromXWindow(_WindowHandle); Debug.Assert(xVisualInfo != null, "SetPixelFormat not executed or undetected XVisualInfo"); return(Glx.CreateContext(Display, xVisualInfo, sharedContext, true)); } } else { return(CreateContextAttrib(sharedContext, new int[] { Gl.NONE })); } }
/// <summary> /// Creates an OpenGL context from a Unix/Linux platform. /// </summary> /// <returns> /// A <see cref="IDeviceContext"/> that specify the device context. /// </returns> private static IntPtr CreateX11SimpleContext(IDeviceContext rDevice) { XServerDeviceContext x11DeviceCtx = (XServerDeviceContext)rDevice; IntPtr rContext; using (Glx.XLock xLock = 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, choosenConfigCount); if (choosenConfigCount[0] == 0) { throw new InvalidOperationException("unable to find basic visual"); } IntPtr choosenConfig = *choosenConfigs; x11DeviceCtx.XVisualInfo = Glx.GetVisualFromFBConfig(x11DeviceCtx.Display, choosenConfig); x11DeviceCtx.FBConfig = choosenConfig; Glx.UnsafeNativeMethods.XFree((IntPtr)choosenConfigs); } // Create direct context rContext = x11DeviceCtx.CreateContext(IntPtr.Zero); 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); } }
/// <summary> /// Creates a context, specifying attributes. /// </summary> /// <param name="sharedContext"> /// A <see cref="IntPtr"/> that specify a context that will share objects with the returned one. If /// it is IntPtr.Zero, no sharing is performed. /// </param> /// <param name="attribsList"> /// A <see cref="T:Int32[]"/> that specifies the attributes list. /// </param> /// <returns> /// A <see cref="IntPtr"/> that represents the handle of the created context. If the context cannot be /// created, it returns IntPtr.Zero. /// </returns> /// <exception cref="ArgumentNullException"> /// Exception thrown if <see cref="attribsList"/> is null. /// </exception> /// <exception cref="ArgumentException"> /// Exception thrown if <paramref name="attribsList"/> length is zero or if the last item of <paramref name="attribsList"/> /// is not zero. /// </exception> public override IntPtr CreateContextAttrib(IntPtr sharedContext, int[] attribsList) { if (attribsList == null) { throw new ArgumentNullException("attribsList"); } if (attribsList.Length == 0) { throw new ArgumentException("zero length array", "attribsList"); } if (attribsList[attribsList.Length - 1] != 0) { throw new ArgumentException("not zero-terminated array", "attribsList"); } using (Glx.XLock displayLock = new Glx.XLock(Display)) { return(Glx.CreateContextAttribsARB(Display, FBConfig, sharedContext, true, attribsList)); } }
/// <summary> /// Initialize LTS information for the calling thread. /// </summary> public static void InitializeThread() { #if !MONODROID if (Egl.IsRequired == false) { switch (Platform.CurrentPlatformId) { case Platform.Id.WindowsNT: Wgl.BindAPI(); break; case Platform.Id.Linux: Glx.BindAPI(); break; case Platform.Id.MacOS: if (Glx.IsRequired) { Glx.BindAPI(); } else { throw new NotSupportedException("platform MacOS not supported without Glx.IsRequired=true"); } break; case Platform.Id.Android: Egl.BindAPI(); break; default: throw new NotSupportedException(String.Format("platform {0} not supported", Platform.CurrentPlatformId)); } } else #endif Egl.BindAPI(); }
/// <summary> /// Get the <see cref="Glx.XVisualInfo"/> set on the specified X window. /// </summary> /// <param name="xWindow"> /// The <see cref="IntPtr"/> that specifies the handle of the X window. /// </param> /// <returns> /// It returns the <see cref="Glx.XVisualInfo"/> set on <paramref name="xWindow"/>. /// </returns> private Glx.XVisualInfo GetVisualInfoFromXWindow(IntPtr xWindow) { Glx.XVisualInfo xVisualInfo; uint[] windowFBConfigId = new uint[1]; int screen = Glx.XDefaultScreen(_Display); // Get the FB configuration associated to the native window Glx.QueryDrawable(_Display, _WindowHandle, Glx.FBCONFIG_ID, windowFBConfigId); if (windowFBConfigId[0] == 0) { KhronosApi.LogComment("Glx.QueryDrawable cannot query Glx.FBCONFIG_ID. Query manually."); return(NativeWindow._InternalVisual); } unsafe { int[] attributes = new int[] { Glx.FBCONFIG_ID, (int)windowFBConfigId[0], 0, }; int[] choosenConfigCount = new int[1]; IntPtr *choosenConfigs = Glx.ChooseFBConfig(_Display, screen, attributes, choosenConfigCount); if (choosenConfigCount[0] == 0) { throw new InvalidOperationException("unable to find X Window visual configuration"); } IntPtr configId = *choosenConfigs; xVisualInfo = Glx.GetVisualFromFBConfig(_Display, configId); Glx.XFree((IntPtr)choosenConfigs); } return(xVisualInfo); }
/// <summary> /// Query the extensions supported by current platform. /// </summary> /// <param name="deviceContext"> /// A <see cref="XServerDeviceContext"/> that specifies the device context to query extensions for. /// </param> public void Query(XServerDeviceContext deviceContext) { if (deviceContext == null) { throw new ArgumentNullException("deviceContext"); } LogComment("Query GLX extensions."); string glxExtensions = null; int[] majorArg = new int[1], minorArg = new int[1]; using (Glx.XLock xLock = new Glx.XLock(deviceContext.Display)) { Glx.QueryVersion(deviceContext.Display, majorArg, minorArg); if ((majorArg[0] >= 1) && (minorArg[0] >= 1)) { glxExtensions = Glx.QueryExtensionsString(deviceContext.Display, 0); } } Query(new KhronosVersion(majorArg[0], minorArg[1], KhronosVersion.ApiGlx), glxExtensions ?? String.Empty); }
/// <summary> /// Creates a context, specifying attributes. /// </summary> /// <param name="sharedContext"> /// A <see cref="IntPtr"/> that specify a context that will share objects with the returned one. If /// it is IntPtr.Zero, no sharing is performed. /// </param> /// <param name="attribsList"> /// A <see cref="T:Int32[]"/> that specifies the attributes list. /// </param> /// <param name="api"> /// A <see cref="KhronosVersion"/> that specifies the API to be implemented by the returned context. It can be null indicating the /// default API for this DeviceContext implementation. If it is possible, try to determine the API version also. /// </param> /// <returns> /// A <see cref="IntPtr"/> that represents the handle of the created context. If the context cannot be /// created, it returns IntPtr.Zero. /// </returns> /// <exception cref="ArgumentNullException"> /// Exception thrown if <see cref="attribsList"/> is null. /// </exception> /// <exception cref="ArgumentException"> /// Exception thrown if <paramref name="attribsList"/> length is zero or if the last item of <paramref name="attribsList"/> /// is not zero. /// </exception> public override IntPtr CreateContextAttrib(IntPtr sharedContext, int[] attribsList, KhronosVersion api) { if (api != null && api.Api != KhronosVersion.ApiGl) { List <int> adulteredAttribs = new List <int>(attribsList); // Support check switch (api.Api) { case KhronosVersion.ApiGles1: case KhronosVersion.ApiGles2: if (Glx.CurrentExtensions.CreateContextEsProfile_EXT == false) { throw new NotSupportedException("OpenGL ES API not supported"); } break; default: throw new NotSupportedException(String.Format("'{0}' API not supported", api.Api)); } // Remove trailing 0 if (adulteredAttribs.Count > 0 && adulteredAttribs[adulteredAttribs.Count - 1] == Gl.NONE) { adulteredAttribs.RemoveAt(adulteredAttribs.Count - 1); } // Add required attributes int majorVersionIndex = adulteredAttribs.FindIndex(delegate(int item) { return(item == Gl.MAJOR_VERSION); }); int minorVersionIndex = adulteredAttribs.FindIndex(delegate(int item) { return(item == Gl.MINOR_VERSION); }); int profileMaskIndex = adulteredAttribs.FindIndex(delegate(int item) { return(item == Gl.CONTEXT_PROFILE_MASK); }); if (majorVersionIndex < 0) { adulteredAttribs.AddRange(new int[] { Gl.MAJOR_VERSION, api.Major }); majorVersionIndex = adulteredAttribs.Count - 2; } if (minorVersionIndex < 0) { adulteredAttribs.AddRange(new int[] { Gl.MINOR_VERSION, api.Minor }); minorVersionIndex = adulteredAttribs.Count - 2; } if (profileMaskIndex < 0) { adulteredAttribs.AddRange(new int[] { Gl.CONTEXT_PROFILE_MASK, 0 }); profileMaskIndex = adulteredAttribs.Count - 2; } switch (api.Api) { case KhronosVersion.ApiGles1: // Ignore API version: force always to 1.0 adulteredAttribs[majorVersionIndex + 1] = 1; adulteredAttribs[minorVersionIndex + 1] = 1; adulteredAttribs[profileMaskIndex + 1] |= (int)Glx.CONTEXT_ES_PROFILE_BIT_EXT; break; case KhronosVersion.ApiGles2: // Uses API version: it may be greater than 2.0(?) adulteredAttribs[majorVersionIndex + 1] = api.Major; adulteredAttribs[minorVersionIndex + 1] = api.Minor; adulteredAttribs[profileMaskIndex + 1] |= (int)Glx.CONTEXT_ES_PROFILE_BIT_EXT; break; default: throw new NotSupportedException(String.Format("'{0}' API not supported", api.Api)); } // Restore trailing 0 adulteredAttribs.Add(Gl.NONE); using (Glx.XLock displayLock = new Glx.XLock(Display)) { Debug.Assert(_FBConfig != IntPtr.Zero, "SetPixelFormat not executed"); return(Glx.CreateContextAttribsARB(Display, _FBConfig, sharedContext, true, adulteredAttribs.ToArray())); } } else { using (Glx.XLock displayLock = new Glx.XLock(Display)) { Debug.Assert(_FBConfig != IntPtr.Zero, "SetPixelFormat not executed"); return(Glx.CreateContextAttribsARB(Display, _FBConfig, sharedContext, true, attribsList)); } } }
public static IntPtr CreateContext(IntPtr dpy, Glx.XVisualInfo vis, IntPtr shareList, bool direct) { IntPtr retValue; Debug.Assert(Delegates.pglXCreateContext != null, "pglXCreateContext not implemented"); retValue = Delegates.pglXCreateContext(dpy, vis, shareList, direct); LogFunction("glXCreateContext(0x{0}, {1}, 0x{2}, {3}) = {4}", dpy.ToString("X8"), vis, shareList.ToString("X8"), direct, retValue.ToString("X8")); return (retValue); }
public static IntPtr CreateGLXPixmap(IntPtr dpy, Glx.XVisualInfo visual, IntPtr pixmap) { IntPtr retValue; Debug.Assert(Delegates.pglXCreateGLXPixmap != null, "pglXCreateGLXPixmap not implemented"); retValue = Delegates.pglXCreateGLXPixmap(dpy, visual, pixmap); LogFunction("glXCreateGLXPixmap(0x{0}, {1}, 0x{2}) = {3}", dpy.ToString("X8"), visual, pixmap.ToString("X8"), retValue.ToString("X8")); return (retValue); }
/// <summary> /// Default constructor. /// </summary> public NativeWindow(int x, int y, uint width, uint height) { try { // Open display if ((_Display = Glx.XOpenDisplay(IntPtr.Zero)) == IntPtr.Zero) { throw new InvalidOperationException("unable to connect to X server"); } Glx.XVisualInfo visual; IntPtr config; int[] attributes = new int[] { Glx.DRAWABLE_TYPE, (int)Glx.WINDOW_BIT, Glx.RENDER_TYPE, (int)Glx.RGBA_BIT, Glx.DOUBLEBUFFER, unchecked ((int)Glx.DONT_CARE), Glx.RED_SIZE, 1, Glx.GREEN_SIZE, 1, Glx.BLUE_SIZE, 1, 0 }; int screen = Glx.XDefaultScreen(_Display); // Get basic visual unsafe { int[] choosenConfigCount = new int[1]; IntPtr *choosenConfigs = Glx.ChooseFBConfig(_Display, screen, attributes, choosenConfigCount); if (choosenConfigCount[0] == 0) { throw new InvalidOperationException("unable to find basic visual"); } config = *choosenConfigs; KhronosApi.LogComment("Choosen config is 0x{0}", config.ToString("X8")); visual = Glx.GetVisualFromFBConfig(_Display, config); KhronosApi.LogComment("Choosen visual is {0}", visual); Glx.XFree((IntPtr)choosenConfigs); _InternalConfig = config; _InternalVisual = visual; } Glx.XSetWindowAttributes setWindowAttrs = new Glx.XSetWindowAttributes(); IntPtr rootWindow = Glx.XRootWindow(_Display, screen); ulong setWindowAttrFlags = /* CWBorderPixel | CWColormap | CWEventMask*/ (1L << 3) | (1L << 13) | (1L << 11); setWindowAttrs.border_pixel = IntPtr.Zero; setWindowAttrs.event_mask = /* StructureNotifyMask */new IntPtr(1L << 17); setWindowAttrs.colormap = Glx.XCreateColormap(_Display, rootWindow, visual.visual, /* AllocNone */ 0); if ((_Handle = Glx.XCreateWindow(_Display, rootWindow, x, y, (int)width, (int)height, 0, visual.depth, /* InputOutput */ 0, visual.visual, new UIntPtr(setWindowAttrFlags), ref setWindowAttrs)) == IntPtr.Zero) { throw new InvalidOperationException("unable to create window"); } // Assign FB configuration to window: essential to make CreateContext(IntPtr) working _GlxHandle = Glx.CreateWindow(_Display, config, _Handle, null); } catch { Dispose(); throw; } }
public static int GetConfig(IntPtr dpy, Glx.XVisualInfo visual, int attrib, [Out] int[] value) { int retValue; unsafe { fixed (int* p_value = value) { Debug.Assert(Delegates.pglXGetConfig != null, "pglXGetConfig not implemented"); retValue = Delegates.pglXGetConfig(dpy, visual, attrib, p_value); LogFunction("glXGetConfig(0x{0}, {1}, {2}, {3}) = {4}", dpy.ToString("X8"), visual, attrib, LogValue(value), retValue); } } return (retValue); }
internal extern static unsafe IntPtr glXGetFBConfigFromVisualSGIX(IntPtr dpy, Glx.XVisualInfo vis);
/// <summary> /// The XServer error handler, invoked each time a X/GLX routine raise an error. /// </summary> /// <param name="displayHandle"> /// A <see cref="IntPtr"/> that specifies the handle of the display on which the error occurred. /// </param> /// <param name="error_event"> /// A <see cref="Glx.XErrorEvent"/> that describe the error. /// </param> /// <returns> /// It returns always 0. /// </returns> private static int XServerErrorHandler(IntPtr displayHandle, ref Glx.XErrorEvent error_event) { lock (_DisplayErrorsLock) { _DisplayErrors[displayHandle] = new GlxException(displayHandle, ref error_event); } return (0); }
internal extern static unsafe IntPtr glXCreateGLXPixmapMESA(IntPtr dpy, Glx.XVisualInfo visual, IntPtr pixmap, IntPtr cmap);
internal extern static unsafe int glXGetConfig(IntPtr dpy, Glx.XVisualInfo visual, int attrib, int* value);
/// <summary> /// Returns a description of the error code. /// </summary> /// <param name="DisplayHandle"> /// A <see cref="IntPtr"/> that specifies the handle of the display on which the error occurred. /// </param> /// <param name="error_event"> /// A <see cref="Glx.XErrorEvent"/> that describe the error. /// </param> /// <returns> /// It returns a description of <paramref name="error_event"/>. /// </returns> private static string GetErrorMessage(IntPtr DisplayHandle, ref Glx.XErrorEvent error_event) { StringBuilder sb = new StringBuilder(1024); Glx.UnsafeNativeMethods.XGetErrorText(DisplayHandle, error_event.error_code, sb, 1024); string eventName = Enum.GetName(typeof(Glx.XEventName), error_event.type); string requestName = Enum.GetName(typeof(Glx.XRequest), error_event.request_code); if (String.IsNullOrEmpty(eventName)) eventName = "Unknown"; if (String.IsNullOrEmpty(requestName)) requestName = "Unknown"; // Additional details sb.AppendLine("\nX error details:"); sb.AppendFormat(" X event name: '{0}' ({1})\n", eventName, error_event.type); sb.AppendFormat(" Display: 0x{0}\n", error_event.display.ToInt64().ToString("x")); sb.AppendFormat(" Resource ID: {0}\n", error_event.resourceid.ToInt64().ToString("x")); sb.AppendFormat(" Error code: {0}\n", error_event.error_code); sb.AppendFormat(" Major code: '{0}' ({1})\n", requestName, error_event.request_code); sb.AppendFormat(" Minor code: {0}", error_event.minor_code); return (sb.ToString()); }
/// <summary> /// Swap the buffers of a device. /// </summary> public override void SwapBuffers() { using (Glx.XLock displayLock = new Glx.XLock(Display)) { Glx.SwapBuffers(Display, _WindowHandle); } }
/// <summary> /// Construct a GlxException. /// </summary> /// <param name="displayHandle"> /// A <see cref="IntPtr"/> that specifies the handle of the display on which the error occurred. /// </param> /// <param name="error_event"> /// A <see cref="Glx.XErrorEvent"/> that describe the error. /// </param> /// <param name="message"> /// A <see cref="String"/> that specifies the exception message. /// </param> public GlxException(IntPtr displayHandle, ref Glx.XErrorEvent error_event, String message) : base(error_event.error_code, message, new Win32Exception(error_event.error_code, GetErrorMessage(displayHandle, ref error_event))) { }
/// <summary> /// Makes the context current on the calling thread. /// </summary> /// <param name="ctx"> /// A <see cref="IntPtr"/> that specify the context to be current on the calling thread, bound to /// thise device context. It can be IntPtr.Zero indicating that no context will be current. /// </param> /// <returns> /// It returns a boolean value indicating whether the operation was successful. /// </returns> /// <exception cref="NotSupportedException"> /// Exception thrown if the current platform is not supported. /// </exception> protected override bool MakeCurrentCore(IntPtr ctx) { using (Glx.XLock displayLock = new Glx.XLock(Display)) { return(Glx.MakeCurrent(Display, ctx != IntPtr.Zero ? _WindowHandle : IntPtr.Zero, ctx)); } }
public static IntPtr GetFBConfigFromVisualSGIX(IntPtr dpy, Glx.XVisualInfo vis) { IntPtr retValue; Debug.Assert(Delegates.pglXGetFBConfigFromVisualSGIX != null, "pglXGetFBConfigFromVisualSGIX not implemented"); retValue = Delegates.pglXGetFBConfigFromVisualSGIX(dpy, vis); CallLog("glXGetFBConfigFromVisualSGIX(0x{0}, {1}) = {2}", dpy.ToString("X8"), vis, retValue.ToString("X8")); return (retValue); }
/// <summary> /// The XServer error handler, invoked each time a X/GLX routine raise an error. /// </summary> /// <param name="DisplayHandle"> /// A <see cref="IntPtr"/> that specifies the handle of the display on which the error occurred. /// </param> /// <param name="error_event"> /// A <see cref="Glx.XErrorEvent"/> that describe the error. /// </param> /// <returns> /// It returns always 0. /// </returns> internal static int XServerErrorHandler(IntPtr DisplayHandle, ref Glx.XErrorEvent error_event) { lock (mDisplayErrorsLock) { StringBuilder sb = new StringBuilder(1024); Glx.XGetErrorText(DisplayHandle, error_event.error_code, sb, 1024); string eventName = Enum.GetName(typeof(Glx.XEventName), error_event.type); string requestName = Enum.GetName(typeof(Glx.XRequest), error_event.request_code); if (String.IsNullOrEmpty(eventName)) eventName = "Unknown"; if (String.IsNullOrEmpty(requestName)) requestName = "Unknown"; // Additional details sb.AppendLine("\nX error details:"); sb.AppendFormat(" X event name: '{0}' ({1})\n", eventName, error_event.type); sb.AppendFormat(" Display: 0x{0}\n", error_event.display.ToInt64().ToString("x")); sb.AppendFormat(" Resource ID: {0}\n", error_event.resourceid.ToInt64().ToString("x")); sb.AppendFormat(" Error code: {0}\n", error_event.error_code); sb.AppendFormat(" Major code: '{0}' ({1})\n", requestName, error_event.request_code); sb.AppendFormat(" Minor code: {0}", error_event.minor_code); mDisplayErrors[DisplayHandle] = new System.ComponentModel.Win32Exception(error_event.error_code, sb.ToString()); } return (0); }
/// <summary> /// Construct a GlxException. /// </summary> /// <param name="displayHandle"> /// A <see cref="IntPtr"/> that specifies the handle of the display on which the error occurred. /// </param> /// <param name="error_event"> /// A <see cref="Glx.XErrorEvent"/> that describe the error. /// </param> /// <param name="message"> /// A <see cref="String"/> that specifies the exception message. /// </param> /// <param name="innerException"> /// The <see cref="Exception"/> wrapped by this Exception. /// </param> public GlxException(IntPtr displayHandle, ref Glx.XErrorEvent error_event, String message, Exception innerException) : base(error_event.error_code, message, innerException) { }
/// <summary> /// Set the device pixel format. /// </summary> /// <param name="pixelFormat"> /// A <see cref="DevicePixelFormat"/> that specifies the pixel format to set. /// </param> public override void ChoosePixelFormat(DevicePixelFormat pixelFormat) { if (pixelFormat == null) { throw new ArgumentNullException("pixelFormat"); } int screen = Glx.XDefaultScreen(_Display); // Get basic visual Glx.XVisualInfo visual; IntPtr config; List <int> attributes = new List <int>(); if (pixelFormat.RenderWindow) { attributes.AddRange(new int[] { Glx.DRAWABLE_TYPE, (int)Glx.WINDOW_BIT }); } if (pixelFormat.RgbaUnsigned) { attributes.AddRange(new int[] { Glx.RENDER_TYPE, (int)Glx.RGBA_BIT }); } if (pixelFormat.RgbaFloat) { attributes.AddRange(new int[] { Glx.RENDER_TYPE, (int)Glx.RGBA_FLOAT_BIT_ARB }); } if (pixelFormat.DoubleBuffer) { attributes.AddRange(new int[] { Glx.DOUBLEBUFFER, Gl.TRUE }); } if (pixelFormat.ColorBits > 0) { switch (pixelFormat.ColorBits) { case 16: attributes.AddRange(new int[] { Glx.RED_SIZE, 5, Glx.GREEN_SIZE, 6, Glx.BLUE_SIZE, 8, Glx.ALPHA_SIZE, 5 }); break; case 24: attributes.AddRange(new int[] { Glx.RED_SIZE, 8, Glx.GREEN_SIZE, 8, Glx.BLUE_SIZE, 8 }); break; case 32: attributes.AddRange(new int[] { Glx.RED_SIZE, 8, Glx.GREEN_SIZE, 8, Glx.BLUE_SIZE, 8, Glx.ALPHA_SIZE, 8 }); break; default: if (pixelFormat.ColorBits < 16) { attributes.AddRange(new int[] { Glx.RED_SIZE, 1, Glx.GREEN_SIZE, 1, Glx.BLUE_SIZE, 1 }); } else { int bits = pixelFormat.ColorBits / 4; attributes.AddRange(new int[] { Glx.RED_SIZE, bits, Glx.GREEN_SIZE, bits, Glx.BLUE_SIZE, bits }); } break; } } if (pixelFormat.DepthBits > 0) { attributes.AddRange(new int[] { Glx.DEPTH_SIZE, pixelFormat.DepthBits }); } if (pixelFormat.StencilBits > 0) { attributes.AddRange(new int[] { Glx.STENCIL_SIZE, pixelFormat.StencilBits }); } attributes.Add(0); unsafe { int[] choosenConfigCount = new int[1]; IntPtr *choosenConfigs = Glx.ChooseFBConfig(_Display, screen, attributes.ToArray(), choosenConfigCount); if (choosenConfigCount[0] == 0) { throw new InvalidOperationException("unable to choose visual"); } config = *choosenConfigs; KhronosApi.LogComment("Choosen config is 0x{0}", config.ToString("X8")); visual = Glx.GetVisualFromFBConfig(_Display, config); KhronosApi.LogComment("Choosen visual is {0}", visual); Glx.XFree((IntPtr)choosenConfigs); } _FBConfig = config; _XVisualInfo = visual; IsPixelFormatSet = true; }
internal extern static unsafe IntPtr glXCreateContext(IntPtr dpy, Glx.XVisualInfo vis, IntPtr shareList, bool direct);