Example #1
0
        /// <summary>
        /// Attempts to create a new instance of the specified Ultraviolet subsystem by dynamically loading it from the specified assembly.
        /// </summary>
        /// <typeparam name="TSubsystem">The subsystem interface type.</typeparam>
        /// <param name="assembly">The assembly from which to load the subsystem implementation.</param>
        /// <param name="configuration">The Ultraviolet context configuration.</param>
        /// <param name="instance">The subsystem instance that was created.</param>
        /// <returns><see langword="true"/> if the subsystem instance was created; otherwise, <see langword="false"/>.</returns>
        private Boolean TryCreateSubsystemInstance <TSubsystem>(Assembly assembly, UltravioletConfiguration configuration, out TSubsystem instance)
        {
            var types = (from t in assembly.GetTypes()
                         where
                         t.IsClass && !t.IsAbstract &&
                         t.GetInterfaces().Contains(typeof(TSubsystem))
                         select t).ToList();

            if (!types.Any() || types.Count > 1)
            {
                throw new InvalidOperationException(SDL2Strings.InvalidAudioAssembly);
            }

            var type = types.Single();

            var ctorWithConfig = type.GetConstructor(new[] { typeof(UltravioletContext), typeof(UltravioletConfiguration) });

            if (ctorWithConfig != null)
            {
                instance = (TSubsystem)ctorWithConfig.Invoke(new object[] { this, configuration });
                return(true);
            }

            var ctorWithoutConfig = type.GetConstructor(new[] { typeof(UltravioletContext) });

            if (ctorWithoutConfig != null)
            {
                instance = (TSubsystem)ctorWithoutConfig.Invoke(new object[] { this });
                return(true);
            }

            instance = default(TSubsystem);
            return(false);
        }
        /// <summary>
        /// Initializes debug output for this context.
        /// </summary>
        /// <param name="configuration">The Ultraviolet Framework configuration settings for the current context.</param>
        private void InitializeDebugOutput(UltravioletConfiguration configuration)
        {
            if (!gl.IsExtensionSupported("GL_ARB_debug_output"))
            {
                Debug.WriteLine(OpenGLStrings.DebugOutputNotSupported);
                return;
            }

            debugCallback       = configuration.DebugCallback;
            debugCallbackOpenGL = DebugCallbackThunk;

            gl.DebugMessageControl(gl.GL_DONT_CARE, gl.GL_DONT_CARE, gl.GL_DONT_CARE, 0, IntPtr.Zero, false);

            if ((configuration.DebugLevels & DebugLevels.Info) == DebugLevels.Info)
            {
                gl.DebugMessageControl(gl.GL_DONT_CARE, gl.GL_DONT_CARE, gl.DEBUG_SEVERITY_LOW, 0, IntPtr.Zero, true);
                gl.DebugMessageControl(gl.GL_DONT_CARE, gl.GL_DONT_CARE, gl.DEBUG_SEVERITY_NOTIFICATION, 0, IntPtr.Zero, true);
            }
            if ((configuration.DebugLevels & DebugLevels.Warning) == DebugLevels.Warning)
            {
                gl.DebugMessageControl(gl.GL_DONT_CARE, gl.GL_DONT_CARE, gl.DEBUG_SEVERITY_MEDIUM, 0, IntPtr.Zero, true);
            }
            if ((configuration.DebugLevels & DebugLevels.Error) == DebugLevels.Error)
            {
                gl.DebugMessageControl(gl.GL_DONT_CARE, gl.GL_DONT_CARE, gl.DEBUG_SEVERITY_HIGH, 0, IntPtr.Zero, true);
            }

            gl.DebugMessageCallback(debugCallbackOpenGL, IntPtr.Zero);
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="SDL2UltravioletContext"/> class.
 /// </summary>
 /// <param name="host">The object that is hosting the Ultraviolet context.</param>
 /// <param name="configuration">The Ultraviolet Framework configuration settings for this context.</param>
 protected unsafe SDL2UltravioletContext(IUltravioletHost host, UltravioletConfiguration configuration)
     : base(host, configuration)
 {
     eventFilter    = new SDL_EventFilter(SDLEventFilter);
     eventFilterPtr = Marshal.GetFunctionPointerForDelegate(eventFilter);
     SDL_SetEventFilter(eventFilterPtr, IntPtr.Zero);
 }
        /// <summary>
        /// Initializes a new instance of the <see cref="SDL2UltravioletWindowInfo"/> class.
        /// </summary>
        /// <param name="uv">The Ultraviolet context.</param>
        /// <param name="configuration">The Ultraviolet configuration settings for the current context.</param>
        internal SDL2UltravioletWindowInfo(UltravioletContext uv, UltravioletConfiguration configuration)
        {
            Contract.Require(uv, nameof(uv));
            Contract.Require(configuration, nameof(configuration));

            this.Ultraviolet = uv;
        }
        /// <inheritdoc/>
        public override void Configure(UltravioletConfiguration ultravioletConfig)
        {
            Contract.Require(ultravioletConfig, nameof(ultravioletConfig));

            ultravioletConfig.ViewProviderAssembly      = typeof(ImGuiPlugin).Assembly.FullName;
            ultravioletConfig.ViewProviderConfiguration = null;
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="SDL2UltravioletPlatform"/> class.
 /// </summary>
 /// <param name="uv">The Ultraviolet context.</param>
 /// <param name="uvconfig">The Ultraviolet Framework's configuration settings.</param>
 /// <param name="sdlconfig">The SDL2 platform configuration settings.</param>
 public SDL2UltravioletPlatform(UltravioletContext uv, UltravioletConfiguration uvconfig, SDL2PlatformConfiguration sdlconfig)
     : base(uv)
 {
     this.clipboard         = ClipboardService.Create();
     this.messageBoxService = MessageBoxService.Create();
     this.windows           = new SDL2UltravioletWindowInfoOpenGL(uv, uvconfig, sdlconfig);
     this.displays          = new SDL2UltravioletDisplayInfo(uv);
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="SDL2UltravioletPlatform"/> class.
 /// </summary>
 /// <param name="uv">The Ultraviolet context.</param>
 /// <param name="configuration">The Ultraviolet Framework's configuration settings.</param>
 public SDL2UltravioletPlatform(UltravioletContext uv, UltravioletConfiguration configuration)
     : base(uv)
 {
     this.clipboard         = ClipboardService.Create();
     this.messageBoxService = MessageBoxService.Create();
     this.windows           = new SDL2UltravioletWindowInfoOpenGL(uv, configuration);
     this.displays          = new SDL2UltravioletDisplayInfo(uv);
     this.isCursorVisible   = SDL_ShowCursor(SDL_QUERY) != 0;
 }
        /// <summary>
        /// Initializes a new instance of the <see cref="SDL2UltravioletWindowInfo"/> class.
        /// </summary>
        /// <param name="uv">The Ultraviolet context.</param>
        /// <param name="uvconfig">The Ultraviolet configuration settings for the current context.</param>
        /// <param name="winconfig">The window configuration settings for the current context.</param>
        internal SDL2UltravioletWindowInfo(UltravioletContext uv, UltravioletConfiguration uvconfig, SDL2PlatformConfiguration winconfig)
        {
            Contract.Require(uv, nameof(uv));
            Contract.Require(uvconfig, nameof(uvconfig));
            Contract.Require(winconfig, nameof(winconfig));

            this.uv = uv;

            InitializePrimaryWindow(uvconfig, winconfig);
        }
Example #9
0
        /// <summary>
        /// Initializes a new instance of the <see cref="UltravioletUI"/> class.
        /// </summary>
        /// <param name="uv">The Ultraviolet context.</param>
        /// <param name="configuration">The Ultraviolet Framework configuration settings for the current context.</param>
        public UltravioletUI(UltravioletContext uv, UltravioletConfiguration configuration)
            : base(uv)
        {
            screenStacks = new UIScreenStackCollection(uv);

            if (uv.Platform != UltravioletPlatform.Android && uv.Platform != UltravioletPlatform.iOS)
            {
                WatchingViewFilesForChanges = configuration.WatchViewFilesForChanges;
            }
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="UltravioletUI"/> class.
        /// </summary>
        /// <param name="uv">The Ultraviolet context.</param>
        /// <param name="configuration">The Ultraviolet Framework configuration settings for the current context.</param>
        public UltravioletUI(UltravioletContext uv, UltravioletConfiguration configuration)
            : base(uv)
        {
            screenStacks = new UIScreenStackCollection(uv);

            if (ContentManager.IsWatchedContentSupported)
            {
                WatchingViewFilesForChanges = configuration.WatchViewFilesForChanges;
            }
        }
Example #11
0
        /// <inheritdoc/>
        public override void Register(UltravioletConfiguration configuration)
        {
            Contract.Require(configuration, nameof(configuration));

            var asm = typeof(BASSAudioPlugin).Assembly;

            configuration.AudioSubsystemAssembly = $"{asm.GetName().Name}, Version={asm.GetName().Version}, Culture=neutral, PublicKeyToken=78da2f4877323311, processorArchitecture=MSIL";

            base.Register(configuration);
        }
Example #12
0
        /// <summary>
        /// Loads the context's subsystem assemblies.
        /// </summary>
        /// <param name="configuration">The context's configuration settings.</param>
        private void LoadSubsystemAssemblies(UltravioletConfiguration configuration)
        {
            if (IsRunningInServiceMode)
            {
                return;
            }

            Assembly LoadSubsystemAssembly(String name)
            {
                try
                {
                    return(Assembly.Load(name));
                }
                catch (Exception e)
                {
                    if (e is FileNotFoundException || e is FileLoadException || e is BadImageFormatException)
                    {
                        return(null);
                    }
                    throw;
                }
            }

            if (String.IsNullOrEmpty(configuration.GraphicsSubsystemAssembly))
            {
                throw new InvalidOperationException(SDL2Strings.MissingGraphicsAssembly);
            }

            if (String.IsNullOrEmpty(configuration.AudioSubsystemAssembly))
            {
                throw new InvalidOperationException(SDL2Strings.MissingAudioAssembly);
            }

            this.GraphicsSubsystemAssembly = LoadSubsystemAssembly(configuration.GraphicsSubsystemAssembly);
            if (this.GraphicsSubsystemAssembly == null)
            {
                throw new InvalidOperationException(SDL2Strings.InvalidGraphicsAssembly);
            }

            this.AudioSubsystemAssembly = LoadSubsystemAssembly(configuration.AudioSubsystemAssembly);
            if (this.AudioSubsystemAssembly == null)
            {
                throw new InvalidOperationException(SDL2Strings.InvalidAudioAssembly);
            }

            var distinctAssemblies = new[] { this.GraphicsSubsystemAssembly, this.AudioSubsystemAssembly }.Distinct();

            foreach (var distinctAssembly in distinctAssemblies)
            {
                InitializeFactoryMethodsInAssembly(distinctAssembly);
            }
        }
Example #13
0
 /// <summary>
 /// Initializes the context's platform subsystem.
 /// </summary>
 /// <param name="configuration">The Ultraviolet Framework configuration settings for this context.</param>
 /// <returns>The platform subsystem.</returns>
 private IUltravioletPlatform InitializePlatformSubsystem(UltravioletConfiguration configuration)
 {
     if (IsRunningInServiceMode)
     {
         return(new DummyUltravioletPlatform(this));
     }
     else
     {
         var platform = new SDL2UltravioletPlatform(this, configuration);
         PumpEvents();
         return(platform);
     }
 }
        /// <summary>
        /// Initializes SDL2.
        /// </summary>
        /// <param name="configuration">The Ultraviolet Framework configuration settings for this context.</param>
        /// <returns><see langword="true"/> if SDL2 was successfully initialized; otherwise, <see langword="false"/>.</returns>
        protected Boolean InitSDL(UltravioletConfiguration configuration)
        {
            var sdlFlags = configuration.EnableServiceMode ?
                           SDL_INIT_TIMER | SDL_INIT_EVENTS :
                           SDL_INIT_TIMER | SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER | SDL_INIT_EVENTS;

            if (Platform == UltravioletPlatform.Windows)
            {
                SDL_SetHint(SDL_HINT_WINDOWS_DISABLE_THREAD_NAMING, "1");
            }

            return(SDL_Init(sdlFlags) == 0);
        }
Example #15
0
        /// <summary>
        /// Initializes the context's graphics subsystem.
        /// </summary>
        /// <param name="configuration">The Ultraviolet Framework configuration settings for this context.</param>
        /// <returns>The graphics subsystem.</returns>
        private IUltravioletGraphics InitializeGraphicsSubsystem(UltravioletConfiguration configuration)
        {
            if (IsRunningInServiceMode)
            {
                return(new DummyUltravioletGraphics(this));
            }

            if (!TryCreateSubsystemInstance <IUltravioletGraphics>(GraphicsSubsystemAssembly, configuration, out var graphics))
            {
                throw new InvalidOperationException(SDL2Strings.InvalidGraphicsAssembly);
            }

            return(graphics);
        }
Example #16
0
        /// <summary>
        /// Initializes the context's audio subsystem.
        /// </summary>
        /// <param name="configuration">The Ultraviolet Framework configuration settings for this context.</param>
        /// <returns>The audio subsystem.</returns>
        private IUltravioletAudio InitializeAudioSubsystem(UltravioletConfiguration configuration)
        {
            if (IsRunningInServiceMode)
            {
                return(new DummyUltravioletAudio(this));
            }

            if (!TryCreateSubsystemInstance <IUltravioletAudio>(AudioSubsystemAssembly, configuration, out var audio))
            {
                throw new InvalidOperationException(SDL2Strings.InvalidAudioAssembly);
            }

            return(audio);
        }
        /// <inheritdoc/>
        public void InitializePrimaryWindow(UltravioletConfiguration configuration)
        {
            if (configuration == null)
            {
                throw new ArgumentNullException(nameof(configuration));
            }

            if (IsPrimaryWindowInitialized)
            {
                throw new InvalidOperationException();
            }

            this.windows.InitializePrimaryWindow(Ultraviolet, configuration);
            this.IsPrimaryWindowInitialized = true;
        }
        /// <summary>
        /// Initializes debug output for this context.
        /// </summary>
        /// <param name="configuration">The Ultraviolet Framework configuration settings for the current context.</param>
        private void InitializeDebugOutput(UltravioletConfiguration configuration)
        {
            if (!gl.IsExtensionSupported("GL_ARB_debug_output"))
            {
                Debug.WriteLine(OpenGLStrings.DebugOutputNotSupported);
                return;
            }

            debugCallback       = configuration.DebugCallback;
            debugCallbackOpenGL = (source, type, id, severity, length, message, userParam) =>
            {
                var messageString = Marshal.PtrToStringAnsi(message, length);
                var messageLevel  = DebugLevels.Info;
                switch (severity)
                {
                case gl.DEBUG_SEVERITY_MEDIUM:
                    messageLevel = DebugLevels.Warning;
                    break;

                case gl.DEBUG_SEVERITY_HIGH:
                    messageLevel = DebugLevels.Error;
                    break;
                }
                debugCallback(Ultraviolet, messageLevel, messageString);
            };

            gl.DebugMessageControl(gl.GL_DONT_CARE, gl.GL_DONT_CARE, gl.GL_DONT_CARE, 0, IntPtr.Zero, false);

            if ((configuration.DebugLevels & DebugLevels.Info) == DebugLevels.Info)
            {
                gl.DebugMessageControl(gl.GL_DONT_CARE, gl.GL_DONT_CARE, gl.DEBUG_SEVERITY_LOW, 0, IntPtr.Zero, true);
                gl.DebugMessageControl(gl.GL_DONT_CARE, gl.GL_DONT_CARE, gl.DEBUG_SEVERITY_NOTIFICATION, 0, IntPtr.Zero, true);
            }
            if ((configuration.DebugLevels & DebugLevels.Warning) == DebugLevels.Warning)
            {
                gl.DebugMessageControl(gl.GL_DONT_CARE, gl.GL_DONT_CARE, gl.DEBUG_SEVERITY_MEDIUM, 0, IntPtr.Zero, true);
            }
            if ((configuration.DebugLevels & DebugLevels.Error) == DebugLevels.Error)
            {
                gl.DebugMessageControl(gl.GL_DONT_CARE, gl.GL_DONT_CARE, gl.DEBUG_SEVERITY_HIGH, 0, IntPtr.Zero, true);
            }

            gl.DebugMessageCallback(debugCallbackOpenGL, IntPtr.Zero);
        }
        /// <summary>
        /// Initializes a new instance of the OpenGLUltravioletGraphics class.
        /// </summary>
        /// <param name="uv">The Ultraviolet context.</param>
        /// <param name="configuration">The Ultraviolet Framework configuration settings for the current context.</param>
        public OpenGLUltravioletGraphics(OpenGLUltravioletContext uv, UltravioletConfiguration configuration)
            : base(uv)
        {
            if (configuration.Debug)
            {
                SDL.GL_SetAttribute(SDL_GLattr.CONTEXT_FLAGS, (int)SDL_GLcontextFlag.DEBUG);
            }

            var masterptr = ((OpenGLUltravioletWindowInfo)uv.GetPlatform().Windows).GetMasterPointer();            
            if ((this.context = SDL.GL_CreateContext(masterptr)) == IntPtr.Zero)
                throw new SDL2Exception();

            if (SDL.GL_SetSwapInterval(0) < 0)
                throw new SDL2Exception();

            if (gl.Initialized)
            {
                gl.Uninitialize();
            }
            gl.Initialize(new OpenGLInitializer());

            OpenGLState.ResetCache();

            if (!VerifyCapabilities())
                throw new NotSupportedException(OpenGLStrings.UnsupportedGraphicsDevice);

            if (configuration.Debug && configuration.DebugCallback != null)
            {
                InitializeDebugOutput(configuration);
            }

            this.maxTextureStages = Math.Min(16, gl.GetInteger(gl.GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS));
            this.textures = new Texture2D[maxTextureStages];
            this.samplerStates = new SamplerState[maxTextureStages];

            this.capabilities = new OpenGLGraphicsCapabilities();

            ResetDeviceStates();
        }
        /// <summary>
        /// Initializes a new instance of the OpenGLUltravioletGraphics class.
        /// </summary>
        /// <param name="uv">The Ultraviolet context.</param>
        /// <param name="configuration">The Ultraviolet Framework configuration settings for the current context.</param>
        public OpenGLUltravioletGraphics(OpenGLUltravioletContext uv, UltravioletConfiguration configuration)
            : base(uv)
        {
            if (configuration.Debug)
            {
                SDL.GL_SetAttribute(SDL_GLattr.CONTEXT_FLAGS, (int)SDL_GLcontextFlag.DEBUG);
            }

            var masterptr = ((OpenGLUltravioletWindowInfo)uv.GetPlatform().Windows).GetMasterPointer();

            if ((this.context = SDL.GL_CreateContext(masterptr)) == IntPtr.Zero)
            {
                if (configuration.Debug)
                {
                    SDL.GL_SetAttribute(SDL_GLattr.CONTEXT_FLAGS, 0);

                    if ((this.context = SDL.GL_CreateContext(masterptr)) == IntPtr.Zero)
                    {
                        throw new SDL2Exception();
                    }
                }
                else
                {
                    throw new SDL2Exception();
                }
            }

            if (SDL.GL_SetSwapInterval(1) < 0)
            {
                throw new SDL2Exception();
            }

            if (gl.Initialized)
            {
                gl.Uninitialize();
            }
            gl.Initialize(new OpenGLInitializer());

            OpenGLState.ResetCache();

            if (!VerifyCapabilities())
            {
                throw new NotSupportedException(OpenGLStrings.UnsupportedGraphicsDevice);
            }

            if (configuration.Debug && configuration.DebugCallback != null)
            {
                InitializeDebugOutput(configuration);
            }

            this.capabilities = new OpenGLGraphicsCapabilities();

            this.maxTextureStages            = gl.GetInteger(gl.GL_MAX_TEXTURE_IMAGE_UNITS);
            this.textures                    = new Texture2D[maxTextureStages];
            this.samplerStates               = new SamplerState[maxTextureStages];
            this.samplerObjects              = capabilities.SupportsIndependentSamplerState ? new OpenGLSamplerObject[maxTextureStages] : null;
            this.backBufferRenderTargetUsage = configuration.BackBufferRenderTargetUsage;

            if (samplerObjects != null)
            {
                for (int i = 0; i < samplerObjects.Length; i++)
                {
                    samplerObjects[i] = new OpenGLSamplerObject(Ultraviolet);
                    samplerObjects[i].Bind((uint)i);
                }
            }

            OpenGLState.VerifyCache();

            ResetDeviceStates();
        }
Example #21
0
 /// <summary>
 /// Initializes a new instance of the <see cref="SDL2UltravioletWindowInfoOpenGL"/> class.
 /// </summary>
 /// <param name="uv">The Ultraviolet context.</param>
 /// <param name="configuration">The Ultraviolet configuration settings for the current context.</param>
 public SDL2UltravioletWindowInfoOpenGL(UltravioletContext uv, UltravioletConfiguration configuration)
     : base(uv, configuration)
 {
 }
        /// <summary>
        /// Initializes the context's primary window.
        /// </summary>
        internal void InitializePrimaryWindow(UltravioletContext uv, UltravioletConfiguration configuration)
        {
            if (Master != null)
            {
                throw new InvalidOperationException(UltravioletStrings.PrimaryWindowAlreadyInitialized);
            }

            // Initialize the rendering API.
            InitializeRenderingAPI(configuration.GraphicsConfiguration, 0);

            // If we're running on Android or iOS, we can't create a headless context.
            var isRunningOnMobile = (Ultraviolet.Platform == UltravioletPlatform.Android || Ultraviolet.Platform == UltravioletPlatform.iOS);

            if (isRunningOnMobile && configuration.Headless)
            {
                throw new InvalidOperationException(SDL2Strings.CannotCreateHeadlessContextOnMobile);
            }

            // Initialize the hidden master window used to create the OpenGL context.
            var masterWidth  = 0;
            var masterHeight = 0;
            var masterFlags  = (RenderingApi == SDL2PlatformRenderingAPI.OpenGL) ? SDL_WINDOW_OPENGL : 0;

            if (Ultraviolet.Properties.SupportsHighDensityDisplayModes)
            {
                masterFlags |= SDL_WINDOW_ALLOW_HIGHDPI;
            }

            if (isRunningOnMobile)
            {
                masterFlags |= SDL_WINDOW_FULLSCREEN | SDL_WINDOW_RESIZABLE;
            }
            else
            {
                masterFlags |= SDL_WINDOW_HIDDEN;
            }

            // Attempt to create the master window. If that fails, reduce our requirements and try again before failing.
            var caption   = String.IsNullOrEmpty(uv.Host.ApplicationName) ? (String)UltravioletStrings.DefaultWindowCaption : uv.Host.ApplicationName;
            var masterptr = SDL_CreateWindow(isRunningOnMobile ? caption : String.Empty, 0, 0, masterWidth, masterHeight, masterFlags);

            if (masterptr == IntPtr.Zero)
            {
                var fallbackAttempt = 1;
                while (InitializeRenderingAPI(configuration.GraphicsConfiguration, fallbackAttempt++))
                {
                    masterptr = SDL_CreateWindow(isRunningOnMobile ? caption : String.Empty, 0, 0, masterWidth, masterHeight, masterFlags);
                    if (masterptr != IntPtr.Zero)
                    {
                        break;
                    }
                }

                if (masterptr == IntPtr.Zero)
                {
                    throw new SDL2Exception();
                }

                // Fallback might have disabled sRGB, so update our configuration to reflect our current state.
                var srgbFramebufferEnabled = 0;
                unsafe
                {
                    if (SDL_GL_GetAttribute(SDL_GLattr.SDL_GL_FRAMEBUFFER_SRGB_CAPABLE, &srgbFramebufferEnabled) < 0)
                    {
                        throw new SDL2Exception();
                    }
                }
                configuration.GraphicsConfiguration.SrgbBuffersEnabled = (srgbFramebufferEnabled > 0);
            }

            this.Master = new SDL2UltravioletWindow(Ultraviolet, masterptr, isRunningOnMobile);

            // Set SDL_HINT_VIDEO_WINDOW_SHARE_PIXEL_FORMAT so that enlisted windows
            // will be OpenGL-enabled and set to the correct pixel format.
            if (!SDL_SetHint(SDL_HINT_VIDEO_WINDOW_SHARE_PIXEL_FORMAT, masterptr.ToStringHex()))
            {
                throw new SDL2Exception();
            }

            // If this is not a headless context, create the primary application window.
            if (!configuration.Headless)
            {
                if (isRunningOnMobile)
                {
                    this.windows.Add(this.Master);
                    DesignatePrimary(this.Master);
                }
                else
                {
                    var flags = configuration.WindowIsVisible ? WindowFlags.None : WindowFlags.Hidden;

                    if (configuration.WindowIsResizable)
                    {
                        flags |= WindowFlags.Resizable;
                    }

                    if (configuration.WindowIsBorderless)
                    {
                        flags |= WindowFlags.Borderless;
                    }

                    if (configuration.WindowIsShownImmediately)
                    {
                        flags |= WindowFlags.ShownImmediately;
                    }

                    var primary = Create(caption,
                                         configuration.InitialWindowPosition.X,
                                         configuration.InitialWindowPosition.Y,
                                         configuration.InitialWindowPosition.Width,
                                         configuration.InitialWindowPosition.Height, flags);
                    DesignatePrimary(primary);
                }
            }
        }
        /// <summary>
        /// Initializes debug output for this context.
        /// </summary>
        /// <param name="configuration">The Ultraviolet Framework configuration settings for the current context.</param>
        private void InitializeDebugOutput(UltravioletConfiguration configuration)
        {
            if (!gl.IsExtensionSupported("GL_ARB_debug_output"))
            {
                Debug.WriteLine(OpenGLStrings.DebugOutputNotSupported);
                return;
            }

            debugCallback = configuration.DebugCallback;
            debugCallbackOpenGL = DebugCallbackThunk;

            gl.DebugMessageControl(gl.GL_DONT_CARE, gl.GL_DONT_CARE, gl.GL_DONT_CARE, 0, IntPtr.Zero, false);

            if ((configuration.DebugLevels & DebugLevels.Info) == DebugLevels.Info)
            {
                gl.DebugMessageControl(gl.GL_DONT_CARE, gl.GL_DONT_CARE, gl.DEBUG_SEVERITY_LOW, 0, IntPtr.Zero, true);
                gl.DebugMessageControl(gl.GL_DONT_CARE, gl.GL_DONT_CARE, gl.DEBUG_SEVERITY_NOTIFICATION, 0, IntPtr.Zero, true);
            }
            if ((configuration.DebugLevels & DebugLevels.Warning) == DebugLevels.Warning)
                gl.DebugMessageControl(gl.GL_DONT_CARE, gl.GL_DONT_CARE, gl.DEBUG_SEVERITY_MEDIUM, 0, IntPtr.Zero, true);
            if ((configuration.DebugLevels & DebugLevels.Error) == DebugLevels.Error)
                gl.DebugMessageControl(gl.GL_DONT_CARE, gl.GL_DONT_CARE, gl.DEBUG_SEVERITY_HIGH, 0, IntPtr.Zero, true);

            gl.DebugMessageCallback(debugCallbackOpenGL, IntPtr.Zero);
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="OpenGLGraphicsCapabilities"/> class.
        /// </summary>
        /// <param name="configuration">The configuration settings for the Ultraviolet context.</param>
        internal unsafe OpenGLGraphicsCapabilities(UltravioletConfiguration configuration)
        {
            var glGraphicsConfiguration = configuration.GraphicsConfiguration as OpenGLGraphicsConfiguration;

            if (glGraphicsConfiguration == null)
            {
                throw new InvalidOperationException(OpenGLStrings.InvalidGraphicsConfiguration);
            }

            this.MaximumTextureSize = gl.GetInteger(gl.GL_MAX_TEXTURE_SIZE);
            gl.ThrowIfError();

            var viewportDims = stackalloc int[2];

            gl.GetIntegerv(gl.GL_MAX_VIEWPORT_DIMS, viewportDims);
            gl.ThrowIfError();

            this.MaximumViewportWidth  = viewportDims[0];
            this.MaximumViewportHeight = viewportDims[1];

            this.SupportsInstancedRendering   = gl.IsInstancedRenderingAvailable;
            this.Supports3DTextures           = gl.IsTexture3DAvailable;
            this.SupportsDepthStencilTextures = gl.IsCombinedDepthStencilAvailable;

            if (gl.IsGLES2 && !this.SupportsDepthStencilTextures)
            {
                // HACK: Guess what? The Visual Studio Emulator for Android flat-out lies about this.
                // So it seems the only reliable way to determine support for depth/stencil is to
                // actually try to create one and see if it fails. I hate Android emulators.
                var rb = gl.GenRenderbuffer();
                using (var state = OpenGLState.ScopedBindRenderbuffer(rb, true))
                {
                    gl.RenderbufferStorage(gl.GL_RENDERBUFFER, gl.GL_DEPTH24_STENCIL8, 32, 32);
                    this.SupportsDepthStencilTextures = (gl.GetError() == gl.GL_NO_ERROR);
                }
                gl.DeleteRenderBuffers(rb);
            }

            this.SupportsNonZeroBaseInstance             = gl.IsNonZeroBaseInstanceAvailable;
            this.SupportsIndependentSamplerState         = gl.IsSamplerObjectAvailable;
            this.SupportsIntegerVertexAttributes         = gl.IsIntegerVertexAttribAvailable;
            this.SupportsDoublePrecisionVertexAttributes = gl.IsDoublePrecisionVertexAttribAvailable;

            this.MinMapBufferAlignment = gl.IsExtensionSupported("GL_ARB_map_buffer_alignment") ?
                                         gl.GetInteger(gl.GL_MIN_MAP_BUFFER_ALIGNMENT) : 0;

            // SRGB is always supported unless we're on GLES2, in which case we need an extension.
            // If it wasn't explicitly enabled in the configuration, we treat it like it's not supported.
            this.SrgbEncodingEnabled = glGraphicsConfiguration.SrgbBuffersEnabled && gl.IsHardwareSrgbSupportAvailable;

            // There seems to be a bug in the version of Mesa which is distributed
            // with Ubuntu 16.04 that causes long stalls when using glMapBufferRange.
            // Testing indicates that this is fixed in 11.2.2.
            if (glGraphicsConfiguration.UseBufferMapping)
            {
                var version          = gl.GetString(gl.GL_VERSION);
                var versionMatchMesa = Regex.Match(version, "Mesa (?<major>\\d+).(?<minor>\\d+).(?<build>\\d+)");
                if (versionMatchMesa != null && versionMatchMesa.Success)
                {
                    var mesaMajor   = Int32.Parse(versionMatchMesa.Groups["major"].Value);
                    var mesaMinor   = Int32.Parse(versionMatchMesa.Groups["minor"].Value);
                    var mesaBuild   = Int32.Parse(versionMatchMesa.Groups["build"].Value);
                    var mesaVersion = new Version(mesaMajor, mesaMinor, mesaBuild);
                    if (mesaVersion < new Version(11, 2, 2))
                    {
                        glGraphicsConfiguration.UseBufferMapping = false;
                    }
                }
            }

            // If we've been explicitly told to disable buffer mapping, override the caps from the driver.
            if (!gl.IsMapBufferRangeAvailable || !glGraphicsConfiguration.UseBufferMapping)
            {
                this.MinMapBufferAlignment = Int32.MinValue;
            }
        }
        /// <summary>
        /// Initializes the context's primary window.
        /// </summary>
        private void InitializePrimaryWindow(UltravioletConfiguration uvconfig, SDL2PlatformConfiguration sdlconfig)
        {
            // Initialize the rendering API.
            if (sdlconfig.RenderingAPI != SDL2PlatformRenderingAPI.OpenGL)
            {
                throw new NotSupportedException();
            }

            InitializeRenderingAPI(sdlconfig);
            renderingAPI = sdlconfig.RenderingAPI;

            // Retrieve the caption for our window.
            var caption = Localization.Strings.Contains("WINDOW_CAPTION") ?
                          Localization.Get("WINDOW_CAPTION") : UltravioletStrings.DefaultWindowCaption.Value;

            // If we're running on Android or iOS, we can't create a headless context.
            var isRunningOnMobile = (Ultraviolet.Platform == UltravioletPlatform.Android || Ultraviolet.Platform == UltravioletPlatform.iOS);

            if (isRunningOnMobile && uvconfig.Headless)
            {
                throw new InvalidOperationException(SDL2Strings.CannotCreateHeadlessContextOnMobile);
            }

            // Initialize the hidden master window used to create the OpenGL context.
            var masterWidth  = 0;
            var masterHeight = 0;
            var masterFlags  = (renderingAPI == SDL2PlatformRenderingAPI.OpenGL) ? SDL_WINDOW_OPENGL : 0;

            if (Ultraviolet.Properties.SupportsHighDensityDisplayModes)
            {
                masterFlags |= SDL_WINDOW_ALLOW_HIGHDPI;
            }

            if (isRunningOnMobile)
            {
                masterFlags |= SDL_WINDOW_FULLSCREEN | SDL_WINDOW_RESIZABLE;
            }
            else
            {
                masterFlags |= SDL_WINDOW_HIDDEN;
            }

            // Attempt to create the master window. If that fails, reduce our requirements and try again before failing.
            var masterptr = SDL_CreateWindow(isRunningOnMobile ? caption : String.Empty, 0, 0, masterWidth, masterHeight, masterFlags);

            if (masterptr == IntPtr.Zero)
            {
                var fallbackAttempt = 0;
                while (InitializeRenderingAPIFallback(sdlconfig, fallbackAttempt++))
                {
                    masterptr = SDL_CreateWindow(isRunningOnMobile ? caption : String.Empty, 0, 0, masterWidth, masterHeight, masterFlags);
                    if (masterptr != IntPtr.Zero)
                    {
                        break;
                    }
                }

                if (masterptr == IntPtr.Zero)
                {
                    throw new SDL2Exception();
                }

                // Fallback might have disabled sRGB, so update our configuration to reflect our current state.
                var srgbFramebufferEnabled = 0;
                unsafe
                {
                    if (SDL_GL_GetAttribute(SDL_GLattr.SDL_GL_FRAMEBUFFER_SRGB_CAPABLE, &srgbFramebufferEnabled) < 0)
                    {
                        throw new SDL2Exception();
                    }
                }
                uvconfig.SrgbBuffersEnabled = (srgbFramebufferEnabled > 0);
            }

            this.master = new SDL2UltravioletWindow(Ultraviolet, masterptr);

            // Set SDL_HINT_VIDEO_WINDOW_SHARE_PIXEL_FORMAT so that enlisted windows
            // will be OpenGL-enabled and set to the correct pixel format.
            if (!SDL_SetHint(SDL_HINT_VIDEO_WINDOW_SHARE_PIXEL_FORMAT, masterptr.ToStringHex()))
            {
                throw new SDL2Exception();
            }

            // If this is not a headless context, create the primary application window.
            if (!uvconfig.Headless)
            {
                if (isRunningOnMobile)
                {
                    this.windows.Add(this.master);
                    DesignatePrimary(this.master);
                }
                else
                {
                    var flags = uvconfig.WindowIsVisible ? WindowFlags.None : WindowFlags.Hidden;

                    if (uvconfig.WindowIsResizable)
                    {
                        flags |= WindowFlags.Resizable;
                    }

                    if (uvconfig.WindowIsBorderless)
                    {
                        flags |= WindowFlags.Borderless;
                    }

                    var primary = Create(caption,
                                         uvconfig.InitialWindowPosition.X,
                                         uvconfig.InitialWindowPosition.Y,
                                         uvconfig.InitialWindowPosition.Width,
                                         uvconfig.InitialWindowPosition.Height, flags);
                    DesignatePrimary(primary);
                }
            }
        }
Example #26
0
 /// <summary>
 /// Initializes a new instance of the <see cref="UltravioletUI"/> class.
 /// </summary>
 /// <param name="uv">The Ultraviolet context.</param>
 /// <param name="configuration">The Ultraviolet Framework configuration settings for the current context.</param>
 public UltravioletUI(UltravioletContext uv, UltravioletConfiguration configuration)
     : base(uv)
 {
     screenStacks = new UIScreenStackCollection(uv);
 }
Example #27
0
        /// <summary>
        /// Initializes a new instance of the FMODUltravioletAudio class.
        /// </summary>
        /// <param name="uv">The Ultraviolet context.</param>
        /// <param name="configuration">The Ultraviolet configuration.</param>
        public FMODUltravioletAudio(UltravioletContext uv, UltravioletConfiguration configuration)
            : base(uv)
        {
            platformSpecificImpl = FMODPlatformSpecificImplementationDetails.Create();
            platformSpecificImpl.OnInitialized();

            InitializeLogging(configuration);

            FMOD_RESULT result;

            fixed(FMOD_SYSTEM **psystem = &system)
            {
                result = FMOD_System_Create(psystem);
                if (result != FMOD_OK)
                {
                    throw new FMODException(result);
                }
            }

            var version = 0u;

            result = FMOD_System_GetVersion(system, &version);
            if (result != FMOD_OK)
            {
                throw new FMODException(result);
            }

            if (version < FMOD_VERSION)
            {
                throw new Exception(FMODStrings.FMODVersionMismatch.Format(FMOD_VERSION, version));
            }

            var extradriverdata = default(void *);

            result = FMOD_System_Init(system, 256, FMOD_INIT_NORMAL, extradriverdata);
            if (result != FMOD_OK)
            {
                throw new FMODException(result);

                fixed(FMOD_CHANNELGROUP **pcgroupSongs = &cgroupSongs)
                {
                    result = FMOD_System_CreateChannelGroup(system, "Songs", pcgroupSongs);
                    if (result != FMOD_OK)
                    {
                        throw new FMODException(result);
                    }
                }

                fixed(FMOD_CHANNELGROUP **pcgroupSoundEffects = &cgroupSoundEffects)
                {
                    result = FMOD_System_CreateChannelGroup(system, "Sound Effects", pcgroupSoundEffects);
                    if (result != FMOD_OK)
                    {
                        throw new FMODException(result);
                    }
                }

                UpdateFileSource();
                UpdateAudioDevices();
                PlaybackDevice = GetDefaultDevice();

                uv.Messages.Subscribe(this, UltravioletMessages.ApplicationCreated);
                uv.Messages.Subscribe(this, UltravioletMessages.ApplicationTerminating);
                uv.Messages.Subscribe(this, UltravioletMessages.ApplicationSuspending);
                uv.Messages.Subscribe(this, UltravioletMessages.ApplicationResumed);
                uv.Messages.Subscribe(this, UltravioletMessages.FileSourceChanged);
        }

        /// <inheritdoc/>
        void IMessageSubscriber <UltravioletMessageID> .ReceiveMessage(UltravioletMessageID type, MessageData data)
        {
            if (type == UltravioletMessages.ApplicationCreated)
            {
                platformSpecificImpl.OnApplicationCreated();
                return;
            }

            if (type == UltravioletMessages.ApplicationTerminating)
            {
                platformSpecificImpl.OnApplicationTerminating();
                return;
            }

            if (type == UltravioletMessages.ApplicationSuspending)
            {
                if (!suspended)
                {
                    awaitingResume = true;
                    Suspend();
                }
                return;
            }

            if (type == UltravioletMessages.ApplicationResumed)
            {
                if (awaitingResume)
                {
                    awaitingResume = false;
                    Resume();
                }
                return;
            }

            if (type == UltravioletMessages.FileSourceChanged)
            {
                UpdateFileSource();
                return;
            }
        }
Example #28
0
 /// <summary>
 /// Initializes a new instance of the <see cref="UltravioletUI"/> class.
 /// </summary>
 /// <param name="uv">The Ultraviolet context.</param>
 /// <param name="configuration">The Ultraviolet Framework configuration settings for the current context.</param>
 public UltravioletUI(UltravioletContext uv, UltravioletConfiguration configuration)
     : base(uv)
 {
     screenStacks = new UIScreenStackCollection(uv);
 }
        /// <summary>
        /// Initializes debug output for this context.
        /// </summary>
        /// <param name="configuration">The Ultraviolet Framework configuration settings for the current context.</param>
        private void InitializeDebugOutput(UltravioletConfiguration configuration)
        {
            if (!gl.IsExtensionSupported("GL_ARB_debug_output"))
            {
                Debug.WriteLine(OpenGLStrings.DebugOutputNotSupported);
                return;
            }

            debugCallback = configuration.DebugCallback;
            debugCallbackOpenGL = (source, type, id, severity, length, message, userParam) =>
            {
                var messageString = Marshal.PtrToStringAnsi(message, length);
                var messageLevel = DebugLevels.Info;
                switch (severity)
                {
                    case gl.DEBUG_SEVERITY_MEDIUM:
                        messageLevel = DebugLevels.Warning;
                        break;

                    case gl.DEBUG_SEVERITY_HIGH:
                        messageLevel = DebugLevels.Error;
                        break;
                }
                debugCallback(Ultraviolet, messageLevel, messageString);
            };

            gl.DebugMessageControl(gl.GL_DONT_CARE, gl.GL_DONT_CARE, gl.GL_DONT_CARE, 0, IntPtr.Zero, false);

            if ((configuration.DebugLevels & DebugLevels.Info) == DebugLevels.Info)
            {
                gl.DebugMessageControl(gl.GL_DONT_CARE, gl.GL_DONT_CARE, gl.DEBUG_SEVERITY_LOW, 0, IntPtr.Zero, true);
                gl.DebugMessageControl(gl.GL_DONT_CARE, gl.GL_DONT_CARE, gl.DEBUG_SEVERITY_NOTIFICATION, 0, IntPtr.Zero, true);
            }
            if ((configuration.DebugLevels & DebugLevels.Warning) == DebugLevels.Warning)
                gl.DebugMessageControl(gl.GL_DONT_CARE, gl.GL_DONT_CARE, gl.DEBUG_SEVERITY_MEDIUM, 0, IntPtr.Zero, true);
            if ((configuration.DebugLevels & DebugLevels.Error) == DebugLevels.Error)
                gl.DebugMessageControl(gl.GL_DONT_CARE, gl.GL_DONT_CARE, gl.DEBUG_SEVERITY_HIGH, 0, IntPtr.Zero, true);

            gl.DebugMessageCallback(debugCallbackOpenGL, IntPtr.Zero);
        }
Example #30
0
 /// <inheritdoc/>
 public override void Register(UltravioletConfiguration configuration) =>
 PresentationFoundation.Configure(configuration, presentationConfig);
Example #31
0
 /// <summary>
 /// Initializes the context's UI subsystem.
 /// </summary>
 /// <param name="configuration">The Ultraviolet Framework configuration settings for this context.</param>
 /// <returns>The UI subsystem.</returns>
 private IUltravioletUI InitializeUISubsystem(UltravioletConfiguration configuration)
 {
     return(new UltravioletUI(this, configuration));
 }
Example #32
0
 private static void AddDebugConfig(UltravioletConfiguration configuration)
 {
     configuration.Debug         = true;
     configuration.DebugLevels   = DebugLevels.Error | DebugLevels.Warning;
     configuration.DebugCallback = (uv, level, message) => { System.Diagnostics.Debug.WriteLine(message); };
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="SDL2UltravioletWindowInfoOpenGL"/> class.
 /// </summary>
 /// <param name="uv">The Ultraviolet context.</param>
 /// <param name="uvconfig">The Ultraviolet configuration settings for the current context.</param>
 /// <param name="winconfig">The window configuration settings for the current context.</param>
 public SDL2UltravioletWindowInfoOpenGL(UltravioletContext uv, UltravioletConfiguration uvconfig, SDL2PlatformConfiguration winconfig)
     : base(uv, uvconfig, winconfig)
 {
 }
        /// <summary>
        /// Initializes a new instance of the OpenGLUltravioletGraphics class.
        /// </summary>
        /// <param name="uv">The Ultraviolet context.</param>
        /// <param name="configuration">The Ultraviolet Framework configuration settings for the current context.</param>
        public unsafe OpenGLUltravioletGraphics(UltravioletContext uv, UltravioletConfiguration configuration) : base(uv)
        {
            var glGraphicsConfiguration = configuration.GraphicsConfiguration as OpenGLGraphicsConfiguration;

            if (glGraphicsConfiguration == null)
            {
                throw new InvalidOperationException(OpenGLStrings.InvalidGraphicsConfiguration);
            }

            this.OpenGLEnvironment = uv.GetFactoryMethod <OpenGLEnvironmentFactory>()(uv);

            InitOpenGLVersion(glGraphicsConfiguration, out var versionRequested, out var versionRequired, out var isGLES);
            InitOpenGLEnvironment(glGraphicsConfiguration, isGLES);

            uv.GetPlatform().InitializePrimaryWindow(configuration);

            if (this.context == IntPtr.Zero && configuration.Debug)
            {
                this.context = TryCreateOpenGLContext(uv, OpenGLEnvironment, versionRequested, versionRequired, true, false) ?? IntPtr.Zero;
            }

            if (this.context == IntPtr.Zero)
            {
                this.context = TryCreateOpenGLContext(uv, OpenGLEnvironment, versionRequested, versionRequired, false, true) ?? IntPtr.Zero;
            }

            if (!OpenGLEnvironment.SetSwapInterval(1) && uv.Platform != UltravioletPlatform.iOS)
            {
                OpenGLEnvironment.ThrowPlatformErrorException();
            }

            if (gl.Initialized)
            {
                gl.Uninitialize();
            }

            gl.Initialize(new OpenGLInitializer(OpenGLEnvironment));

            if (!gl.IsVersionAtLeast(versionRequested ?? versionRequired))
            {
                throw new InvalidOperationException(OpenGLStrings.DoesNotMeetMinimumVersionRequirement.Format(gl.MajorVersion, gl.MinorVersion, versionRequested.Major, versionRequested.Minor));
            }

            OpenGLState.ResetCache();

            if (!VerifyCapabilities())
            {
                throw new NotSupportedException(OpenGLStrings.UnsupportedGraphicsDevice);
            }

            if (configuration.Debug && configuration.DebugCallback != null)
            {
                InitializeDebugOutput(configuration);
            }

            this.Capabilities = new OpenGLGraphicsCapabilities(configuration);

            if (Capabilities.SrgbEncodingEnabled && gl.IsFramebufferSrgbAvailable)
            {
                gl.Enable(gl.GL_FRAMEBUFFER_SRGB);
                gl.ThrowIfError();
            }

            this.maxTextureStages            = gl.GetInteger(gl.GL_MAX_TEXTURE_IMAGE_UNITS);
            this.textures                    = new Texture[maxTextureStages];
            this.samplerStates               = new SamplerState[maxTextureStages];
            this.samplerObjects              = Capabilities.SupportsIndependentSamplerState ? new OpenGLSamplerObject[maxTextureStages] : null;
            this.backBufferRenderTargetUsage = glGraphicsConfiguration.BackBufferRenderTargetUsage;

            if (samplerObjects != null)
            {
                for (int i = 0; i < samplerObjects.Length; i++)
                {
                    samplerObjects[i] = new OpenGLSamplerObject(Ultraviolet);
                    samplerObjects[i].Bind((uint)i);
                }
            }

            OpenGLState.VerifyCache();
            ResetDeviceStates();
        }