Beispiel #1
0
        /// <summary>
        /// Get the display associated with this Control.
        /// </summary>
        /// <returns>
        /// It returns an <see cref="IntPtr"/> valid for GLX functions as display parameter.
        /// </returns>
        protected IntPtr GetDisplay()
        {
            Type xplatui = Type.GetType("System.Windows.Forms.XplatUIX11, System.Windows.Forms");

            if (xplatui != null)
            {
                // Get System.Windows.Forms display
                IntPtr display = (IntPtr)xplatui.GetField("DisplayHandle", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic).GetValue(null);
                KhronosApi.LogComment("System.Windows.Forms.XplatUIX11.DisplayHandle is 0x{0}", display.ToString("X"));
                if (display == IntPtr.Zero)
                {
                    throw new InvalidOperationException("unable to connect to X server using XPlatUI");
                }

                // Screen
                // _Screen = (int)xplatui.GetField("ScreenNo", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic).GetValue(null);
                // KhronosApi.LogComment("System.Windows.Forms.XplatUIX11.ScreenNo is {0}", _Screen);

                return(display);
            }
            else
            {
                return(IntPtr.Zero);
            }
        }
Beispiel #2
0
        /// <summary>
        /// Actually create this GraphicsWindow resources in Unix platform.
        /// </summary>
        /// <param name="surfaceFormat">
        /// A <see cref="GraphicsBuffersFormat"/> used for selecting the most appropriate visual.
        /// </param>
        internal void PreCreateObjectX11(GraphicsBuffersFormat surfaceFormat)
        {
            if (surfaceFormat == null)
            {
                throw new ArgumentNullException("surfaceFormat");
            }

            // Choose "best" pixel format matching with surface configuration
            _DeviceFormat = surfaceFormat.ChoosePixelFormat(_DeviceContext, ValidPixelFormat);

            sLog.Debug("Choosen frame buffer configuration: 0x{0} (visual 0x{1}).", _DeviceFormat.XFbConfig.ToString("X3"), _DeviceFormat.XVisualInfo.visualid.ToString("X3"));

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

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

            IntPtr display    = (IntPtr)xplatui.GetField("DisplayHandle", BindingFlags.Static | BindingFlags.NonPublic).GetValue(null);
            IntPtr rootWindow = (IntPtr)xplatui.GetField("RootWindow", BindingFlags.Static | BindingFlags.NonPublic).GetValue(null);
            IntPtr colorMap   = Glx.UnsafeNativeMethods.XCreateColormap(display, rootWindow, _DeviceFormat.XVisualInfo.visual, 0);
            // KhronosApi.LogFunction("XCreateColormap(0x{0}, {1}, {2}. 0) = {0}", display.ToString("X"), rootWindow.ToString("X"), _DeviceFormat.XVisualInfo.visual.ToString());

            IntPtr customVisual     = _DeviceFormat.XVisualInfo.visual;
            IntPtr origCustomVisual = (IntPtr)xplatui.GetField("CustomVisual", BindingFlags.Static | BindingFlags.NonPublic).GetValue(null);

            KhronosApi.LogComment("Set System.Windows.Forms.XplatUIX11.CustomVisual change from {0} to {1}", origCustomVisual.ToString("X"), customVisual.ToString("X"));
            xplatui.GetField("CustomVisual", BindingFlags.Static | BindingFlags.NonPublic).SetValue(null, customVisual);

            KhronosApi.LogComment("Create System.Windows.Forms.XplatUIX11.CustomColormap ({0})", colorMap.ToString("X"));
            xplatui.GetField("CustomColormap", BindingFlags.Static | BindingFlags.NonPublic).SetValue(null, colorMap);
        }
Beispiel #3
0
        /// <summary>
        /// Get the display associated with this Control.
        /// </summary>
        /// <returns>
        /// It returns an <see cref="IntPtr"/> valid for GLX functions as display parameter.
        /// </returns>
        protected IntPtr GetDisplay()
        {
            switch (Platform.CurrentPlatformId)
            {
            case Platform.Id.WindowsNT:
                return(IntPtr.Zero);

            case Platform.Id.Linux:
                Type xplatui = Type.GetType("System.Windows.Forms.XplatUIX11, System.Windows.Forms");
                if (xplatui == null)
                {
                    throw new InvalidOperationException("no XPlatUI implementation");
                }
                IntPtr display = (IntPtr)xplatui.GetField("DisplayHandle", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic).GetValue(null);
                KhronosApi.LogComment("System.Windows.Forms.XplatUIX11.DisplayHandle is 0x{0}", display.ToString("X"));
                if (display == IntPtr.Zero)
                {
                    throw new InvalidOperationException("unable to connect to X server using XPlatUI");
                }

                // Screen
                // _Screen = (int)xplatui.GetField("ScreenNo", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic).GetValue(null);
                // KhronosApi.LogComment("System.Windows.Forms.XplatUIX11.ScreenNo is {0}", _Screen);

                return(display);

            default:
                throw new NotSupportedException("platform " + Platform.CurrentPlatformId + " not supported");
            }
        }
Beispiel #4
0
		/// <summary>
		/// Log an enumeration value.
		/// </summary>
		/// <param name="enumValue">
		/// A <see cref="Int32"/> that specifies the enumeration value.
		/// </param>
		/// <returns>
		/// It returns a <see cref="String"/> that represents <paramref name="enumValue"/> as hexadecimal value. If the
		/// name of the enumeration value is detected, it returns the relative OpenGL specification name.
		/// </returns>
		protected static new string LogEnumName(int enumValue)
		{
			string enumName;

			if (_LogContext.EnumNames != null && _LogContext.EnumNames.TryGetValue(enumValue, out enumName))
				return (enumName);
			else
				return (Gl.LogEnumName(enumValue) ?? KhronosApi.LogEnumName(enumValue));
		}
        /// <summary>
        /// Get a function pointer from the OpenGL driver.
        /// </summary>
        /// <param name="function">
        /// A <see cref="String"/> that specifies the function name.
        /// </param>
        /// <returns>
        /// It returns an <see cref="IntPtr"/> that specifies the address of the function <paramref name="function"/>.
        /// </returns>
        public IntPtr GetOpenGLProcAddress(string function)
        {
            IntPtr procAddress = UnsafeNativeMethods.wglGetProcAddress(function);

#if PLATFORM_LOG_ENABLED
            KhronosApi.LogFunction("wglGetProcAddress({0}) = 0x{1}", function, procAddress.ToString("X8"));
#endif

            return(procAddress);
        }
 /// <summary>
 /// Performs application-defined tasks associated with freeing, releasing, or resetting managed/unmanaged resources.
 /// </summary>
 /// <param name="disposing">
 ///
 /// A <see cref="System.Boolean"/> indicating whether the disposition is requested explictly.
 /// </param>
 protected override void Dispose(bool disposing)
 {
     if (disposing)
     {
         if ((_OwnDisplay == true) && (Display != IntPtr.Zero))
         {
             Glx.UnsafeNativeMethods.XCloseDisplay(Display);
             KhronosApi.LogFunction("XCloseDisplay({0})", Display.ToString("X"));
         }
     }
 }
Beispiel #7
0
        /// <summary>
        /// Log an bitmask value.
        /// </summary>
        /// <param name="bitmaskName">
        /// A <see cref="String"/> that specifies the enumeration bitmask name.
        /// </param>
        /// <param name="bitmaskValue">
        /// A <see cref="Int32"/> that specifies the enumeration bitmask value.
        /// </param>
        /// <returns>
        /// It returns a <see cref="String"/> that represents <paramref name="bitmaskValue"/>.
        /// </returns>
        protected static new string LogEnumBitmask(string bitmaskName, long bitmaskValue)
        {
            Dictionary <long, String> bitmaskNames;

            if (_LogContext.EnumBitmasks.TryGetValue(bitmaskName, out bitmaskNames) == false)
            {
                return(KhronosApi.LogEnumBitmask(bitmaskName, bitmaskValue));
            }

            return(KhronosApi.LogEnumBitmask(bitmaskValue, bitmaskNames));
        }
Beispiel #8
0
        /// <summary>
        /// Configure the logging system.
        /// </summary>
        public static void Configure(LogFlags flags)
        {
            // Configure base system
            XmlConfigurator.Configure();

            // Log OpenGL method calls
            KhronosApi.RegisterApplicationLogDelegate(delegate(string format, object[] args) {
                _ProcedureLogger.Debug(format, args);
            });
            // Enabe procedure logging
            KhronosApi.LogEnabled = true;
        }
        /// <summary>
        /// Initializes the X11 multithreading.
        /// </summary>
        /// <exception cref='InvalidOperationException'>
        /// Is thrown when an operation cannot be performed.
        /// </exception>
        public static void InitializeMultithreading()
        {
            // Ensure to have X11 thread system initialized
            int initialized = Glx.UnsafeNativeMethods.XInitThreads();

            KhronosApi.LogCommand("XInitThreads", initialized);

            if (initialized == 0)
            {
                throw new InvalidOperationException("platform does not support multithreading");
            }

            _MultithreadingInitialized = true;
        }
        /// <summary>
        /// Construct a <see cref="Derm.Render.XServerDeviceContext"/> class that opens the specified display.
        /// </summary>
        /// <param name="display">
        /// A <see cref="System.IntpPtr"/> that will be argument of <see cref="Glx.XOpenDisplay"/>, indeed
        /// specifying the display to connect to.
        /// </param>
        /// <remarks>
        /// The property <see cref="WindowHandle"/> must be set to a valid value, since no window is created. The
        /// window handle shall be created using the display <see cref="Display"/>.
        /// </remarks>
        /// <exception cref='InvalidOperationException'>
        /// Exception thrown in the case it is not possible to connect with the display <paramref name="display"/>.
        /// </exception>
        public XServerDeviceContext(IntPtr display)
        {
            // Open display (follows DISPLAY environment variable)
            _Display = Glx.UnsafeNativeMethods.XOpenDisplay(display);
            KhronosApi.LogFunction("XOpenDisplay(0x0) = 0x{0}", _Display.ToString("X"));
            if (_Display == IntPtr.Zero)
            {
                throw new InvalidOperationException(String.Format("unable to connect to X server display {0}", display.ToInt32()));
            }
            // Need to close display
            _OwnDisplay = true;
            // Screen
            _Screen = Glx.UnsafeNativeMethods.XDefaultScreen(_Display);

            // Query GLX extensions
            QueryVersion();
        }
Beispiel #11
0
        /// <summary>
        /// Get a function pointer from a library, specified by handle.
        /// </summary>
        /// <param name="library">
        /// A <see cref="IntPtr"/> which represents an opaque handle to the library containing the function.
        /// </param>
        /// <param name="function">
        /// A <see cref="String"/> that specifies the function name.
        /// </param>
        /// <returns>
        /// It returns an <see cref="IntPtr"/> that specifies the address of the function <paramref name="function"/>.
        /// </returns>
        private IntPtr GetProcAddress(IntPtr library, string function)
        {
            if (library == IntPtr.Zero)
            {
                throw new ArgumentNullException("library");
            }
            if (function == null)
            {
                throw new ArgumentNullException("function");
            }

            IntPtr procAddress = UnsafeNativeMethods.Win32GetProcAddress(library, function);

#if PLATFORM_LOG_ENABLED
            KhronosApi.LogFunction("GetProcAddress(0x{0}, {1}) = 0x{2}", library.ToString("X8"), function, procAddress.ToString("X8"));
#endif

            return(procAddress);
        }
        /// <summary>
        /// Query OpenGL implementation extensions.
        /// </summary>
        /// <param name="ctx"></param>
        /// <returns></returns>
        public static GraphicsCapabilities Query(GraphicsContext ctx, IDeviceContext deviceContext)
        {
            GraphicsCapabilities graphicsCapabilities = new GraphicsCapabilities();

            KhronosApi.LogComment("Query OpenGL extensions.");

            #region Platform Extension Reload

            // Since at this point there's a current OpenGL context, it's possible to use
            // {glx|wgl}GetExtensionsString to retrieve platform specific extensions

            switch (Environment.OSVersion.Platform)
            {
            case PlatformID.Win32NT:
            case PlatformID.Win32Windows:
            case PlatformID.Win32S:
            case PlatformID.WinCE:
                // Wgl.SyncDelegates();
                break;
            }

            #endregion

            // OpenGL extensions
            graphicsCapabilities._GlExtensions.Query();
            // Windows OpenGL extensions
            WindowsDeviceContext windowsDeviceContext = deviceContext as WindowsDeviceContext;
            if (windowsDeviceContext != null)
            {
                graphicsCapabilities._WglExtensions.Query(windowsDeviceContext);
            }
            // GLX OpenGL extensions
            XServerDeviceContext xserverDeviceContext = deviceContext as XServerDeviceContext;
            if (xserverDeviceContext != null)
            {
                graphicsCapabilities._GlxExtensions.Query(xserverDeviceContext);
            }

            // Query implementation limits
            graphicsCapabilities._GraphicsLimits = GraphicsLimits.Query(graphicsCapabilities._GlExtensions);

            return(graphicsCapabilities);
        }
Beispiel #13
0
        private IntPtr GetLibraryHandle(string libraryPath)
        {
            IntPtr libraryHandle;

            if (_LibraryHandles.TryGetValue(libraryPath, out libraryHandle) == false)
            {
                libraryHandle = UnsafeNativeMethods.LoadLibrary(libraryPath);
#if PLATFORM_LOG_ENABLED
                KhronosApi.LogFunction("LoadLibrary({0}) = 0x{1}", libraryPath, libraryHandle.ToString("X8"));
#endif

                _LibraryHandles.Add(libraryPath, libraryHandle);
            }

            if (libraryHandle == IntPtr.Zero)
            {
                throw new InvalidOperationException(String.Format("unable to load library at {0}", libraryPath));
            }

            return(libraryHandle);
        }
        /// <summary>
        /// Construct a fullscreen window.
        /// </summary>
        public VideoCoreWindow()
        {
            try {
                int width, height;

                KhronosApi.LogComment("Creating VideoCore IV native window");

                if (Bcm.graphics_get_display_size(0 /* LCD */, out width, out height) < 0)
                {
                    throw new InvalidOperationException("unable to get BCM display size");
                }

                Bcm.VC_RECT_T dstRect = new Bcm.VC_RECT_T(0, 0, width, height);
                Bcm.VC_RECT_T srcRect = new Bcm.VC_RECT_T(0, 0, width << 16, height << 16);

                if ((_DispManxDisplay = Bcm.vc_dispmanx_display_open(0 /* LCD */)) == 0)
                {
                    throw new InvalidOperationException("unable to open DispManX display");
                }

                // Update - Add element
                uint updateHandle = Bcm.vc_dispmanx_update_start(0);
                _ElementHandle = Bcm.vc_dispmanx_element_add(updateHandle, _DispManxDisplay, 0, dstRect, 0, srcRect, 0, IntPtr.Zero, IntPtr.Zero, Bcm.DISPMANX_TRANSFORM_T.DISPMANX_NO_ROTATE);
                Bcm.vc_dispmanx_update_submit_sync(updateHandle);

                // Native window
                _NativeWindow         = new EGL_DISPMANX_WINDOW_T();
                _NativeWindow.element = _ElementHandle;
                _NativeWindow.width   = width;
                _NativeWindow.height  = height;

                // Keep native window pinned
                _NativeWindowLock = new MemoryLock(_NativeWindow);

                KhronosApi.LogComment("VideoCore IV Native Window is 0x{0}", _NativeWindowLock.Address.ToString("X"));
            } catch {
                Dispose();
                throw;
            }
        }
        /// <summary>
        /// Construct a <see cref="Derm.Render.XServerDeviceContext"/> class, initialized with the display of a control.
        /// </summary>
        /// <param name="control">
        /// Control.
        /// </param>
        /// <exception cref="ArgumentNullException">
        /// Exception thrown if <paramref name="control"/> is null.
        /// </exception>
        /// <exception cref="ArgumentException">
        /// Exception thrown if <paramref name="control"/> handle is not created.
        /// </exception>
        /// <exception cref="PlatformNotSupportedException">
        /// Exception thrown if the current assembly is not executed by a (supported) Mono runtime.
        /// </exception>
        /// <exception cref="InvalidOperationException">
        /// Exception thrown if the current Mono runtime has not yet opened a display connection.
        /// </exception>
        public XServerDeviceContext(Control control)
        {
            if (control == null)
            {
                throw new ArgumentNullException("control");
            }

            IntPtr controlHandle = control.Handle;

            if (control.IsHandleCreated == false)
            {
                throw new ArgumentException("handle not created", "control");
            }

            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
            _Display = (IntPtr)xplatui.GetField("DisplayHandle", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic).GetValue(null);
            KhronosApi.LogComment("System.Windows.Forms.XplatUIX11.DisplayHandle is 0x{0}", _Display.ToString("X"));
            if (_Display == IntPtr.Zero)
            {
                throw new InvalidOperationException("unable to connect to X server using XPlatUI");
            }

            // Screen
            _Screen = (int)xplatui.GetField("ScreenNo", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic).GetValue(null);
            KhronosApi.LogComment("System.Windows.Forms.XplatUIX11.ScreenNo is {0}", _Screen);

            // Window handle
            _WindowHandle = controlHandle;

            // Query GLX extensions
            QueryVersion();
        }
        /// <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>
        /// 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;
        }
            /// <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;
                }
            }
Beispiel #19
0
        /// <summary>
        /// Query the OpenGL implementation limits.
        /// </summary>
        /// <param name="glExtensions">
        /// A <see cref="Gl.Extensions"/> that specify the supported OpenGL extension by the current
        /// implementation.
        /// </param>
        /// <returns>
        /// It returns a <see cref="GraphicsLimits"/> that specify the current OpenGL implementation limits.
        /// </returns>
        /// <remarks>
        /// It is assumed to have a valid OpenGL context current on the calling thread.
        /// </remarks>
        public static GraphicsLimits Query(Gl.Extensions glExtensions)
        {
            if (glExtensions == null)
            {
                throw new ArgumentNullException("glExtensions");
            }

            KhronosApi.LogComment("Query OpenGL implementation imits.");

            GraphicsLimits graphicsLimits = new GraphicsLimits();

            FieldInfo[] graphicsLimitsFields = typeof(GraphicsLimits).GetFields(BindingFlags.Public | BindingFlags.Instance);

            foreach (FieldInfo field in graphicsLimitsFields)
            {
                GraphicsLimitAttribute graphicsLimitAttribute      = (GraphicsLimitAttribute)Attribute.GetCustomAttribute(field, typeof(GraphicsLimitAttribute));
                Attribute[]            graphicsExtensionAttributes = Attribute.GetCustomAttributes(field, typeof(KhronosApi.ExtensionAttribute));
                MethodInfo             getMethod;

                if (graphicsLimitAttribute == null)
                {
                    continue;
                }

                // Check extension support
                if ((graphicsExtensionAttributes != null) && (graphicsExtensionAttributes.Length > 0))
                {
                    bool supported = Array.Exists(graphicsExtensionAttributes, delegate(Attribute item) {
                        return(glExtensions.HasExtensions(((KhronosApi.ExtensionAttribute)item).ExtensionName));
                    });

                    if (supported == false)
                    {
                        continue;
                    }
                }

                // Determine which method is used to get the OpenGL limit
                if (field.FieldType != typeof(String))
                {
                    if (field.FieldType.IsArray == true)
                    {
                        getMethod = typeof(Gl).GetMethod("Get", BindingFlags.Public | BindingFlags.Static, null, new Type[] { typeof(Int32), field.FieldType }, null);
                    }
                    else
                    {
                        getMethod = typeof(Gl).GetMethod("Get", BindingFlags.Public | BindingFlags.Static, null, new Type[] { typeof(Int32), field.FieldType.MakeByRefType() }, null);
                    }
                }
                else
                {
                    getMethod = typeof(Gl).GetMethod("GetString", BindingFlags.Public | BindingFlags.Static, null, new Type[] { typeof(Int32) }, null);
                }

                if (getMethod != null)
                {
                    if (field.FieldType != typeof(String))
                    {
                        object obj;

                        if (field.FieldType.IsArray == false)
                        {
                            obj = Activator.CreateInstance(field.FieldType);
                        }
                        else
                        {
                            obj = Array.CreateInstance(field.FieldType.GetElementType(), graphicsLimitAttribute.ArrayLenght);
                        }
                        object[] @params = new object[] { graphicsLimitAttribute.EnumValue, obj };

                        try {
                            getMethod.Invoke(null, @params);

                            field.SetValue(graphicsLimits, @params[1]);
                        } catch (Exception) {
                        }
                    }
                    else
                    {
                        try {
                            string s = (string)getMethod.Invoke(null, new object[] { graphicsLimitAttribute.EnumValue });

                            field.SetValue(graphicsLimits, s);
                        } catch (Exception) {
                        }
                    }
                }
                else
                {
                    throw new InvalidOperationException("GraphicsLimits field " + field.Name + " doesn't have a OpenGL compatible type");
                }

                string fieldValueString;
                object fieldValue = field.GetValue(graphicsLimits);

                if (fieldValue is Array)
                {
                    StringBuilder sb = new StringBuilder();

                    sb.Append("{ ");
                    if (((Array)fieldValue).Length > 0)
                    {
                        foreach (object arrayItem in (Array)fieldValue)
                        {
                            sb.AppendFormat("{0}, ", arrayItem);
                        }
                        sb.Remove(sb.Length - 2, 2);
                    }
                    sb.Append(" }");

                    fieldValueString = sb.ToString();
                }
                else
                {
                    fieldValueString = fieldValue.ToString();
                }
            }

            return(graphicsLimits);
        }