/// <summary>
        /// Releases resources associated with the object.
        /// </summary>
        /// <param name="disposing">true if the object is being disposed; false if the object is being finalized.</param>
        protected override void Dispose(Boolean disposing)
        {
            if (Disposed)
            {
                return;
            }

            if (samplerObjects != null)
            {
                for (int i = 0; i < samplerObjects.Length; i++)
                {
                    SafeDispose.Dispose(samplerObjects[i]);
                }
            }

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

            OpenGLEnvironment.DeleteOpenGLContext(context);
            context = IntPtr.Zero;

            SafeDispose.Dispose(OpenGLEnvironment);

            base.Dispose(disposing);
        }
        /// <summary>
        /// Sets the OpenGL environment attributes which correspond to the application's OpenGL settings.
        /// </summary>
        private void InitOpenGLEnvironment(OpenGLGraphicsConfiguration configuration, Boolean isGLES)
        {
            if (!OpenGLEnvironment.RequestOpenGLProfile(isGLES))
            {
                OpenGLEnvironment.ThrowPlatformErrorException();
            }

            if (!OpenGLEnvironment.RequestDepthSize(configuration.BackBufferDepthSize))
            {
                OpenGLEnvironment.ThrowPlatformErrorException();
            }

            if (!OpenGLEnvironment.RequestStencilSize(configuration.BackBufferStencilSize))
            {
                OpenGLEnvironment.ThrowPlatformErrorException();
            }

            if (configuration.Use32BitFramebuffer)
            {
                if (!OpenGLEnvironment.Request32BitFramebuffer())
                {
                    OpenGLEnvironment.ThrowPlatformErrorException();
                }
            }
            else
            {
                if (!OpenGLEnvironment.Request24BitFramebuffer())
                {
                    OpenGLEnvironment.ThrowPlatformErrorException();
                }
            }

            if (configuration.SrgbBuffersEnabled)
            {
                if (!OpenGLEnvironment.RequestSrgbCapableFramebuffer())
                {
                    OpenGLEnvironment.ThrowPlatformErrorException();
                }

                if (!OpenGLEnvironment.IsFramebufferSrgbCapable)
                {
                    configuration.SrgbBuffersEnabled = false;
                }
            }
        }
        /// <summary>
        /// Attempts to create an OpenGL context.
        /// </summary>
        private static IntPtr?TryCreateOpenGLContext(UltravioletContext uv, OpenGLEnvironment environment,
                                                     Version versionRequested, Version versionRequired, Boolean debug, Boolean throwOnFailure)
        {
            if (!environment.RequestDebugContext(debug))
            {
                environment.ThrowPlatformErrorException();
            }

            var gles                = (uv.Platform == UltravioletPlatform.Android || uv.Platform == UltravioletPlatform.iOS);
            var versionArray        = gles ? KnownOpenGLESVersions : KnownOpenGLVersions;
            var versionMin          = versionRequested ?? versionRequired;
            var versionCurrent      = versionRequested ?? versionArray[0];
            var versionCurrentIndex = Array.IndexOf(versionArray, versionCurrent);

            IntPtr context;

            do
            {
                if (versionCurrent < versionMin)
                {
                    if (throwOnFailure)
                    {
                        throw new InvalidOperationException(OpenGLStrings.DoesNotMeetMinimumVersionRequirement.Format(versionMin.Major, versionMin.Minor));
                    }

                    return(null);
                }

                if (!environment.RequestOpenGLVersion(versionCurrent))
                {
                    environment.ThrowPlatformErrorException();
                }

                versionCurrent = versionArray[++versionCurrentIndex];
            }while ((context = environment.CreateOpenGLContext()) == IntPtr.Zero);

            return(context);
        }
Пример #4
0
 /// <summary>
 /// Initializes a new instance of the <see cref="OpenGLInitializer"/> class.
 /// </summary>
 /// <param name="environment">The interface with which OpenGL communicates with its underlying platform environment.</param>
 public OpenGLInitializer(OpenGLEnvironment environment)
 {
     Contract.Require(environment, nameof(environment));
     this.environment = environment;
 }
        /// <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();
        }