예제 #1
0
        /// <summary>
        /// Reallocates the renderbuffer's storage.
        /// </summary>
        /// <param name="width">The renderbuffer's width in pixels.</param>
        /// <param name="height">The renderbuffer's height in pixels.</param>
        private void AllocateRenderbufferStorage(Int32 width, Int32 height)
        {
            using (OpenGLState.ScopedBindRenderbuffer(renderbuffer, true))
            {
                switch (format)
                {
                case RenderBufferFormat.Color:
                    gl.RenderbufferStorage(gl.GL_RENDERBUFFER, gl.IsGLES2 ? gl.GL_RGBA4 : gl.GL_RGBA8, width, height);
                    gl.ThrowIfError();
                    break;

                case RenderBufferFormat.Depth24Stencil8:
                    gl.RenderbufferStorage(gl.GL_RENDERBUFFER, gl.GL_DEPTH24_STENCIL8, width, height);
                    gl.ThrowIfError();
                    break;

                case RenderBufferFormat.Depth32:
                    gl.RenderbufferStorage(gl.GL_RENDERBUFFER, gl.GL_DEPTH_COMPONENT32, width, height);
                    gl.ThrowIfError();
                    break;

                case RenderBufferFormat.Depth16:
                    gl.RenderbufferStorage(gl.GL_RENDERBUFFER, gl.GL_DEPTH_COMPONENT16, width, height);
                    gl.ThrowIfError();
                    break;

                case RenderBufferFormat.Stencil8:
                    gl.RenderbufferStorage(gl.GL_RENDERBUFFER, gl.GL_STENCIL_INDEX8, width, height);
                    break;

                default:
                    throw new NotSupportedException("format");
                }
            }
        }
예제 #2
0
        /// <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(OpenGLUltravioletConfiguration configuration)
        {
            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.supportsDepthStencilTextures = !gl.IsGLES2 || gl.IsExtensionSupported("GL_OES_packed_depth_stencil");

            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 = SupportsInstancedRendering && !gl.IsGLES &&
                                               (gl.IsVersionAtLeast(4, 2) || gl.IsExtensionSupported("GL_ARB_base_instance"));

            this.SupportsIndependentSamplerState = (gl.IsGLES ? gl.IsVersionAtLeast(3, 0) : gl.IsVersionAtLeast(3, 3)) ||
                                                   gl.IsExtensionSupported("GL_ARB_sampler_objects");

            this.SupportsIntegerVertexAttributes         = !gl.IsGLES2 || gl.IsExtensionSupported("GL_EXT_gpu_shader4");
            this.SupportsDoublePrecisionVertexAttributes = !gl.IsGLES && gl.IsVersionAtLeast(4, 1);

            this.SupportsMapBufferRange = true;
            if (gl.IsGLES2)
            {
                this.SupportsMapBufferRange =
                    gl.IsExtensionSupported("GL_ARB_map_buffer_range") ||
                    gl.IsExtensionSupported("GL_EXT_map_buffer_range");
            }

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

            // 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.
            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))
                {
                    configuration.UseBufferMapping = false;
                }
            }

            // If we've been explicitly told to disable buffer mapping, override the caps from the driver.
            if (!configuration.UseBufferMapping)
            {
                this.SupportsMapBufferRange = false;
            }
        }