CheckGLError() private method

private CheckGLError ( ) : void
return void
        internal void Activate(TextureTarget target, bool useMipmaps = false)
        {
            switch (Filter)
            {
            case TextureFilter.Point:
                if (GraphicsCapabilities.SupportsTextureFilterAnisotropic)
                {
                    GL.TexParameter(target, TextureParameterNameTextureMaxAnisotropy, 1.0f);
                    GraphicsExtensions.CheckGLError();
                }
                GL.TexParameter(target, TextureParameterName.TextureMinFilter, (int)(useMipmaps ? TextureMinFilter.NearestMipmapNearest : TextureMinFilter.Nearest));
                GraphicsExtensions.CheckGLError();
                GL.TexParameter(target, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Nearest);
                GraphicsExtensions.CheckGLError();
                break;

            case TextureFilter.Linear:
                if (GraphicsCapabilities.SupportsTextureFilterAnisotropic)
                {
                    GL.TexParameter(target, TextureParameterNameTextureMaxAnisotropy, 1.0f);
                    GraphicsExtensions.CheckGLError();
                }
                GL.TexParameter(target, TextureParameterName.TextureMinFilter, (int)(useMipmaps ? TextureMinFilter.LinearMipmapLinear : TextureMinFilter.Linear));
                GraphicsExtensions.CheckGLError();
                GL.TexParameter(target, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
                GraphicsExtensions.CheckGLError();
                break;

            case TextureFilter.Anisotropic:
                if (GraphicsCapabilities.SupportsTextureFilterAnisotropic)
                {
                    GL.TexParameter(target, TextureParameterNameTextureMaxAnisotropy, MathHelper.Clamp(this.MaxAnisotropy, 1.0f, SamplerState.MaxTextureMaxAnisotropy));
                    GraphicsExtensions.CheckGLError();
                }
                GL.TexParameter(target, TextureParameterName.TextureMinFilter, (int)(useMipmaps ? TextureMinFilter.LinearMipmapLinear : TextureMinFilter.Linear));
                GraphicsExtensions.CheckGLError();
                GL.TexParameter(target, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
                GraphicsExtensions.CheckGLError();
                break;

            case TextureFilter.PointMipLinear:
                if (GraphicsCapabilities.SupportsTextureFilterAnisotropic)
                {
                    GL.TexParameter(target, TextureParameterNameTextureMaxAnisotropy, 1.0f);
                    GraphicsExtensions.CheckGLError();
                }
                GL.TexParameter(target, TextureParameterName.TextureMinFilter, (int)(useMipmaps ? TextureMinFilter.NearestMipmapLinear : TextureMinFilter.Nearest));
                GraphicsExtensions.CheckGLError();
                GL.TexParameter(target, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Nearest);
                GraphicsExtensions.CheckGLError();
                break;

            case TextureFilter.LinearMipPoint:
                if (GraphicsCapabilities.SupportsTextureFilterAnisotropic)
                {
                    GL.TexParameter(target, TextureParameterNameTextureMaxAnisotropy, 1.0f);
                    GraphicsExtensions.CheckGLError();
                }
                GL.TexParameter(target, TextureParameterName.TextureMinFilter, (int)(useMipmaps ? TextureMinFilter.LinearMipmapNearest : TextureMinFilter.Linear));
                GraphicsExtensions.CheckGLError();
                GL.TexParameter(target, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
                GraphicsExtensions.CheckGLError();
                break;

            case TextureFilter.MinLinearMagPointMipLinear:
                if (GraphicsCapabilities.SupportsTextureFilterAnisotropic)
                {
                    GL.TexParameter(target, TextureParameterNameTextureMaxAnisotropy, 1.0f);
                    GraphicsExtensions.CheckGLError();
                }
                GL.TexParameter(target, TextureParameterName.TextureMinFilter, (int)(useMipmaps ? TextureMinFilter.LinearMipmapLinear : TextureMinFilter.Linear));
                GraphicsExtensions.CheckGLError();
                GL.TexParameter(target, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Nearest);
                GraphicsExtensions.CheckGLError();
                break;

            case TextureFilter.MinLinearMagPointMipPoint:
                if (GraphicsCapabilities.SupportsTextureFilterAnisotropic)
                {
                    GL.TexParameter(target, TextureParameterNameTextureMaxAnisotropy, 1.0f);
                    GraphicsExtensions.CheckGLError();
                }
                GL.TexParameter(target, TextureParameterName.TextureMinFilter, (int)(useMipmaps ? TextureMinFilter.LinearMipmapNearest: TextureMinFilter.Linear));
                GraphicsExtensions.CheckGLError();
                GL.TexParameter(target, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Nearest);
                GraphicsExtensions.CheckGLError();
                break;

            case TextureFilter.MinPointMagLinearMipLinear:
                if (GraphicsCapabilities.SupportsTextureFilterAnisotropic)
                {
                    GL.TexParameter(target, TextureParameterNameTextureMaxAnisotropy, 1.0f);
                    GraphicsExtensions.CheckGLError();
                }
                GL.TexParameter(target, TextureParameterName.TextureMinFilter, (int)(useMipmaps ? TextureMinFilter.NearestMipmapLinear: TextureMinFilter.Nearest));
                GraphicsExtensions.CheckGLError();
                GL.TexParameter(target, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
                GraphicsExtensions.CheckGLError();
                break;

            case TextureFilter.MinPointMagLinearMipPoint:
                if (GraphicsCapabilities.SupportsTextureFilterAnisotropic)
                {
                    GL.TexParameter(target, TextureParameterNameTextureMaxAnisotropy, 1.0f);
                    GraphicsExtensions.CheckGLError();
                }
                GL.TexParameter(target, TextureParameterName.TextureMinFilter, (int)(useMipmaps ? TextureMinFilter.NearestMipmapNearest: TextureMinFilter.Nearest));
                GraphicsExtensions.CheckGLError();
                GL.TexParameter(target, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
                GraphicsExtensions.CheckGLError();
                break;

            default:
                throw new NotSupportedException();
            }

            // Set up texture addressing.
            GL.TexParameter(target, TextureParameterName.TextureWrapS, (int)GetWrapMode(AddressU));
            GraphicsExtensions.CheckGLError();
            GL.TexParameter(target, TextureParameterName.TextureWrapT, (int)GetWrapMode(AddressV));
            GraphicsExtensions.CheckGLError();
#if !GLES
            // LOD bias is not supported by glTexParameter in OpenGL ES 2.0
            GL.TexParameter(target, TextureParameterName.TextureLodBias, MipMapLevelOfDetailBias);
            GraphicsExtensions.CheckGLError();
#endif
        }
Example #2
0
        public void PlatformClear(ClearOptions options, Vector4 color, float depth, int stencil)
        {
            // TODO: We need to figure out how to detect if we have a
            // depth stencil buffer or not, and clear options relating
            // to them if not attached.

            // Unlike with XNA and DirectX...  GL.Clear() obeys several
            // different render states:
            //
            //  - The color write flags.
            //  - The scissor rectangle.
            //  - The depth/stencil state.
            //
            // So overwrite these states with what is needed to perform
            // the clear correctly and restore it afterwards.
            //
            var prevScissorRect       = ScissorRectangle;
            var prevDepthStencilState = DepthStencilState;
            var prevBlendState        = BlendState;

            ScissorRectangle = _viewport.Bounds;
            // DepthStencilState.Default has the Stencil Test disabled;
            // make sure stencil test is enabled before we clear since
            // some drivers won't clear with stencil test disabled
            DepthStencilState = this.clearDepthStencilState;
            BlendState        = BlendState.Opaque;
            ApplyState(false);

            ClearBufferMask bufferMask = 0;

            if ((options & ClearOptions.Target) == ClearOptions.Target)
            {
                if (color != _lastClearColor)
                {
                    GL.ClearColor(color.X, color.Y, color.Z, color.W);
                    GraphicsExtensions.CheckGLError();
                    _lastClearColor = color;
                }
                bufferMask = bufferMask | ClearBufferMask.ColorBufferBit;
            }
            if ((options & ClearOptions.Stencil) == ClearOptions.Stencil)
            {
                if (stencil != _lastClearStencil)
                {
                    GL.ClearStencil(stencil);
                    GraphicsExtensions.CheckGLError();
                    _lastClearStencil = stencil;
                }
                bufferMask = bufferMask | ClearBufferMask.StencilBufferBit;
            }

            if ((options & ClearOptions.DepthBuffer) == ClearOptions.DepthBuffer)
            {
                if (depth != _lastClearDepth)
                {
                    GL.ClearDepth(depth);
                    GraphicsExtensions.CheckGLError();
                    _lastClearDepth = depth;
                }
                bufferMask = bufferMask | ClearBufferMask.DepthBufferBit;
            }


            GL.Clear(bufferMask);
            GraphicsExtensions.CheckGLError();

            // Restore the previous render state.
            ScissorRectangle  = prevScissorRect;
            DepthStencilState = prevDepthStencilState;
            BlendState        = prevBlendState;
        }
Example #3
0
        /// <summary>
        /// Activates the Current Vertex/Pixel shader pair into a program.
        /// </summary>
        private unsafe void ActivateShaderProgram()
        {
            // Lookup the shader program.
            var shaderProgram = _programCache.GetProgram(VertexShader, PixelShader);

            if (shaderProgram.Program == -1)
            {
                return;
            }
            // Set the new program if it has changed.
            if (_shaderProgram != shaderProgram)
            {
                GL.UseProgram(shaderProgram.Program);
                GraphicsExtensions.CheckGLError();
                _shaderProgram = shaderProgram;
            }

            var posFixupLoc = shaderProgram.GetUniformLocation("posFixup");

            if (posFixupLoc == -1)
            {
                return;
            }

            // Apply vertex shader fix:
            // The following two lines are appended to the end of vertex shaders
            // to account for rendering differences between OpenGL and DirectX:
            //
            // gl_Position.y = gl_Position.y * posFixup.y;
            // gl_Position.xy += posFixup.zw * gl_Position.ww;
            //
            // (the following paraphrased from wine, wined3d/state.c and wined3d/glsl_shader.c)
            //
            // - We need to flip along the y-axis in case of offscreen rendering.
            // - D3D coordinates refer to pixel centers while GL coordinates refer
            //   to pixel corners.
            // - D3D has a top-left filling convention. We need to maintain this
            //   even after the y-flip mentioned above.
            // In order to handle the last two points, we translate by
            // (63.0 / 128.0) / VPw and (63.0 / 128.0) / VPh. This is equivalent to
            // translating slightly less than half a pixel. We want the difference to
            // be large enough that it doesn't get lost due to rounding inside the
            // driver, but small enough to prevent it from interfering with any
            // anti-aliasing.
            //
            // OpenGL coordinates specify the center of the pixel while d3d coords specify
            // the corner. The offsets are stored in z and w in posFixup. posFixup.y contains
            // 1.0 or -1.0 to turn the rendering upside down for offscreen rendering. PosFixup.x
            // contains 1.0 to allow a mad.

            _posFixup[0] = 1.0f;
            _posFixup[1] = 1.0f;
            _posFixup[2] = (63.0f / 64.0f) / Viewport.Width;
            _posFixup[3] = -(63.0f / 64.0f) / Viewport.Height;

            //If we have a render target bound (rendering offscreen)
            if (IsRenderTargetBound)
            {
                //flip vertically
                _posFixup[1] *= -1.0f;
                _posFixup[3] *= -1.0f;
            }

            fixed(float *floatPtr = _posFixup)
            {
                GL.Uniform4(posFixupLoc, 1, floatPtr);
            }

            GraphicsExtensions.CheckGLError();
        }
        internal void PlatformApplyState(GraphicsDevice device, bool force = false)
        {
            var blendEnabled = !(this.ColorSourceBlend == Blend.One &&
                                 this.ColorDestinationBlend == Blend.Zero &&
                                 this.AlphaSourceBlend == Blend.One &&
                                 this.AlphaDestinationBlend == Blend.Zero);

            if (force || blendEnabled != device._lastBlendEnable)
            {
                if (blendEnabled)
                {
                    GL.Enable(EnableCap.Blend);
                }
                else
                {
                    GL.Disable(EnableCap.Blend);
                }
                GraphicsExtensions.CheckGLError();
                device._lastBlendEnable = blendEnabled;
            }

            if (force || this.BlendFactor != device._lastBlendState.BlendFactor)
            {
                GL.BlendColor(
                    this.BlendFactor.R / 255.0f,
                    this.BlendFactor.G / 255.0f,
                    this.BlendFactor.B / 255.0f,
                    this.BlendFactor.A / 255.0f);
                GraphicsExtensions.CheckGLError();
                device._lastBlendState.BlendFactor = this.BlendFactor;
            }

            if (force ||
                this.ColorBlendFunction != device._lastBlendState.ColorBlendFunction ||
                this.AlphaBlendFunction != device._lastBlendState.AlphaBlendFunction)
            {
                GL.BlendEquationSeparate(
                    this.ColorBlendFunction.GetBlendEquationMode(),
                    this.AlphaBlendFunction.GetBlendEquationMode());
                GraphicsExtensions.CheckGLError();
                device._lastBlendState.ColorBlendFunction = this.ColorBlendFunction;
                device._lastBlendState.AlphaBlendFunction = this.AlphaBlendFunction;
            }

            if (force ||
                this.ColorSourceBlend != device._lastBlendState.ColorSourceBlend ||
                this.ColorDestinationBlend != device._lastBlendState.ColorDestinationBlend ||
                this.AlphaSourceBlend != device._lastBlendState.AlphaSourceBlend ||
                this.AlphaDestinationBlend != device._lastBlendState.AlphaDestinationBlend)
            {
                GL.BlendFuncSeparate(
                    this.ColorSourceBlend.GetBlendFactorSrc(),
                    this.ColorDestinationBlend.GetBlendFactorDest(),
                    this.AlphaSourceBlend.GetBlendFactorSrc(),
                    this.AlphaDestinationBlend.GetBlendFactorDest());
                GraphicsExtensions.CheckGLError();
                device._lastBlendState.ColorSourceBlend      = this.ColorSourceBlend;
                device._lastBlendState.ColorDestinationBlend = this.ColorDestinationBlend;
                device._lastBlendState.AlphaSourceBlend      = this.AlphaSourceBlend;
                device._lastBlendState.AlphaDestinationBlend = this.AlphaDestinationBlend;
            }

            if (force || this.ColorWriteChannels != device._lastBlendState.ColorWriteChannels)
            {
                GL.ColorMask(
                    (this.ColorWriteChannels & ColorWriteChannels.Red) != 0,
                    (this.ColorWriteChannels & ColorWriteChannels.Green) != 0,
                    (this.ColorWriteChannels & ColorWriteChannels.Blue) != 0,
                    (this.ColorWriteChannels & ColorWriteChannels.Alpha) != 0);
                GraphicsExtensions.CheckGLError();
                device._lastBlendState.ColorWriteChannels = this.ColorWriteChannels;
            }
        }
Example #5
0
        internal void SetSamplers(GraphicsDevice device)
        {
#if DIRECTX
            // Skip out if nothing has changed.
            if (_d3dDirty == 0)
            {
                return;
            }

            // NOTE: We make the assumption here that the caller has
            // locked the d3dContext for us to use.
            var pixelShaderStage = device._d3dContext.PixelShader;

            for (var i = 0; i < _samplers.Length; i++)
            {
                var mask = 1 << i;
                if ((_d3dDirty & mask) == 0)
                {
                    continue;
                }

                var sampler = _samplers[i];
                SharpDX.Direct3D11.SamplerState state = null;
                if (sampler != null)
                {
                    state = sampler.GetState(device);
                }

                pixelShaderStage.SetSampler(i, state);

                _d3dDirty &= ~mask;
                if (_d3dDirty == 0)
                {
                    break;
                }
            }

            _d3dDirty = 0;
#elif OPENGL
            for (var i = 0; i < _samplers.Length; i++)
            {
                var sampler = _samplers[i];
                var texture = device.Textures[i];

                if (sampler != null && texture != null && sampler != texture.glLastSamplerState)
                {
                    // TODO: Avoid doing this redundantly (see TextureCollection.SetTextures())
                    // However, I suspect that rendering from the same texture with different sampling modes
                    // is a relatively rare occurrence...
                    GL.ActiveTexture(TextureUnit.Texture0 + i);
                    GraphicsExtensions.CheckGLError();

                    // NOTE: We don't have to bind the texture here because it is already bound in
                    // TextureCollection.SetTextures(). This, of course, assumes that SetTextures() is called
                    // before this method is called. If that ever changes this code will misbehave.
                    // GL.BindTexture(texture.glTarget, texture.glTexture);
                    // GraphicsExtensions.CheckGLError();

                    sampler.Activate(texture.glTarget, texture.LevelCount > 1);
                    texture.glLastSamplerState = sampler;
                }
            }
#elif PSM
            for (var i = 0; i < _samplers.Length; i++)
            {
                var sampler = _samplers[i];
                var texture = device.Textures[i] as Texture2D;
                if (texture == null)
                {
                    continue;
                }

                var psmTexture = texture._texture2D;

                // FIXME: Handle mip attributes

                // FIXME: Separable filters
                psmTexture.SetFilter(
                    sampler.Filter == TextureFilter.Point
                        ? Sce.PlayStation.Core.Graphics.TextureFilterMode.Nearest
                        : Sce.PlayStation.Core.Graphics.TextureFilterMode.Linear
                    );
                // FIXME: The third address mode
                psmTexture.SetWrap(
                    sampler.AddressU == TextureAddressMode.Clamp
                        ? Sce.PlayStation.Core.Graphics.TextureWrapMode.ClampToEdge
                        : Sce.PlayStation.Core.Graphics.TextureWrapMode.Repeat,
                    sampler.AddressV == TextureAddressMode.Clamp
                        ? Sce.PlayStation.Core.Graphics.TextureWrapMode.ClampToEdge
                        : Sce.PlayStation.Core.Graphics.TextureWrapMode.Repeat
                    );
            }
#endif
        }
Example #6
0
        internal void ApplyState(GraphicsDevice device)
        {
            // When rendering offscreen the faces change order.
            var offscreen = device.GetRenderTargets().Length > 0;

            if (CullMode == CullMode.None)
            {
                GL.Disable(EnableCap.CullFace);
                GraphicsExtensions.CheckGLError();
            }
            else
            {
                GL.Enable(EnableCap.CullFace);
                GraphicsExtensions.CheckGLError();
                GL.CullFace(CullFaceMode.Back);
                GraphicsExtensions.CheckGLError();

                if (CullMode == CullMode.CullClockwiseFace)
                {
                    if (offscreen)
                    {
                        GL.FrontFace(FrontFaceDirection.Cw);
                    }
                    else
                    {
                        GL.FrontFace(FrontFaceDirection.Ccw);
                    }
                    GraphicsExtensions.CheckGLError();
                }
                else
                {
                    if (offscreen)
                    {
                        GL.FrontFace(FrontFaceDirection.Ccw);
                    }
                    else
                    {
                        GL.FrontFace(FrontFaceDirection.Cw);
                    }
                    GraphicsExtensions.CheckGLError();
                }
            }

#if SDL2
            if (FillMode == FillMode.Solid)
            {
                GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Fill);
            }
            else
            {
                GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Line);
            }
#else
            if (FillMode != FillMode.Solid)
            {
                throw new NotImplementedException();
            }
#endif

            if (ScissorTestEnable)
            {
                GL.Enable(EnableCap.ScissorTest);
            }
            else
            {
                GL.Disable(EnableCap.ScissorTest);
            }
            GraphicsExtensions.CheckGLError();

            if (this.DepthBias != 0 || this.SlopeScaleDepthBias != 0)
            {
                GL.Enable(EnableCap.PolygonOffsetFill);
                GL.PolygonOffset(this.SlopeScaleDepthBias, this.DepthBias);
            }
            else
            {
                GL.Disable(EnableCap.PolygonOffsetFill);
            }
            GraphicsExtensions.CheckGLError();

            // TODO: Implement MultiSampleAntiAlias
        }
        public RenderTarget2D(GraphicsDevice graphicsDevice, int width, int height, bool mipMap, SurfaceFormat preferredFormat, DepthFormat preferredDepthFormat, int preferredMultiSampleCount, RenderTargetUsage usage)
            : base(graphicsDevice, width, height, mipMap, preferredFormat, true)
        {
            DepthStencilFormat = preferredDepthFormat;
            MultiSampleCount   = preferredMultiSampleCount;
            RenderTargetUsage  = usage;

#if DIRECTX
            // Create a view interface on the rendertarget to use on bind.
            _renderTargetView = new SharpDX.Direct3D11.RenderTargetView(graphicsDevice._d3dDevice, _texture);
#endif

            // If we don't need a depth buffer then we're done.
            if (preferredDepthFormat == DepthFormat.None)
            {
                return;
            }

#if DIRECTX
            // Setup the multisampling description.
            var multisampleDesc = new SharpDX.DXGI.SampleDescription(1, 0);
            if (preferredMultiSampleCount > 1)
            {
                multisampleDesc.Count   = preferredMultiSampleCount;
                multisampleDesc.Quality = (int)SharpDX.Direct3D11.StandardMultisampleQualityLevels.StandardMultisamplePattern;
            }

            // Create a descriptor for the depth/stencil buffer.
            // Allocate a 2-D surface as the depth/stencil buffer.
            // Create a DepthStencil view on this surface to use on bind.
            using (var depthBuffer = new SharpDX.Direct3D11.Texture2D(graphicsDevice._d3dDevice, new SharpDX.Direct3D11.Texture2DDescription()
            {
                Format = SharpDXHelper.ToFormat(preferredDepthFormat),
                ArraySize = 1,
                MipLevels = 1,
                Width = width,
                Height = height,
                SampleDescription = multisampleDesc,
                BindFlags = SharpDX.Direct3D11.BindFlags.DepthStencil,
            }))

                // Create the view for binding to the device.
                _depthStencilView = new SharpDX.Direct3D11.DepthStencilView(graphicsDevice._d3dDevice, depthBuffer,
                                                                            new SharpDX.Direct3D11.DepthStencilViewDescription()
                {
                    Format    = SharpDXHelper.ToFormat(preferredDepthFormat),
                    Dimension = SharpDX.Direct3D11.DepthStencilViewDimension.Texture2D
                });
#elif OPENGL
#if GLES
            GL.GenRenderbuffers(1, ref glDepthStencilBuffer);
#else
            GL.GenRenderbuffers(1, out glDepthStencilBuffer);
#endif
            GraphicsExtensions.CheckGLError();
            GL.BindRenderbuffer(RenderbufferTarget.Renderbuffer, this.glDepthStencilBuffer);
            GraphicsExtensions.CheckGLError();
            var glDepthStencilFormat = GLDepthComponent16;
            switch (preferredDepthFormat)
            {
            case DepthFormat.Depth16: glDepthStencilFormat = GLDepthComponent16; break;

            case DepthFormat.Depth24: glDepthStencilFormat = GLDepthComponent24; break;

            case DepthFormat.Depth24Stencil8: glDepthStencilFormat = GLDepth24Stencil8; break;
            }
            GL.RenderbufferStorage(GLRenderbuffer, glDepthStencilFormat, this.width, this.height);
            GraphicsExtensions.CheckGLError();
#endif
        }
 internal virtual void DeleteFramebuffer(int framebuffer)
 {
     GL.DeleteFramebuffers(1, ref framebuffer);
     GraphicsExtensions.CheckGLError();
 }
 internal virtual void FramebufferTexture2D(int attachement, int target, int texture, int level = 0, int samples = 0)
 {
     GL.FramebufferTexture2D(FramebufferTarget.Framebuffer, (FramebufferAttachment)attachement, (TextureTarget)target, texture, level);
     GraphicsExtensions.CheckGLError();
 }
Example #10
0
        public void SetData<T>(int level, Rectangle? rect, T[] data, int startIndex, int elementCount) where T : struct 
        {
            if (data == null)
				throw new ArgumentNullException("data");

#if OPENGL
            Threading.BlockOnUIThread(() =>
            {
#endif
#if !PSM
                var elementSizeInByte = Marshal.SizeOf(typeof(T));
                var dataHandle = GCHandle.Alloc(data, GCHandleType.Pinned);
                // Use try..finally to make sure dataHandle is freed in case of an error
                try
                {
                    var startBytes = startIndex * elementSizeInByte;
                    var dataPtr = (IntPtr)(dataHandle.AddrOfPinnedObject().ToInt64() + startBytes);
#endif
                    int x, y, w, h;
                    if (rect.HasValue)
                    {
                        x = rect.Value.X;
                        y = rect.Value.Y;
                        w = rect.Value.Width;
                        h = rect.Value.Height;
                    }
                    else
                    {
                        x = 0;
                        y = 0;
                        w = Math.Max(width >> level, 1);
                        h = Math.Max(height >> level, 1);

                        // For DXT textures the width and height of each level is a multiple of 4.
                        // OpenGL only: The last two mip levels require the width and height to be 
                        // passed as 2x2 and 1x1, but there needs to be enough data passed to occupy 
                        // a 4x4 block. 
                        // Ref: http://www.mentby.com/Group/mac-opengl/issue-with-dxt-mipmapped-textures.html 
                        if (_format == SurfaceFormat.Dxt1 ||
                            _format == SurfaceFormat.Dxt1a ||
                            _format == SurfaceFormat.Dxt3 ||
                            _format == SurfaceFormat.Dxt5)
                        {
#if DIRECTX
                            w = (w + 3) & ~3;
                            h = (h + 3) & ~3;
#else
                            if (w > 4)
                                w = (w + 3) & ~3;
                            if (h > 4)
                                h = (h + 3) & ~3;
#endif
                        }
                    }

#if DIRECTX
                    var box = new SharpDX.DataBox(dataPtr, GetPitch(w), 0);

                    var region = new SharpDX.Direct3D11.ResourceRegion();
                    region.Top = y;
                    region.Front = 0;
                    region.Back = 1;
                    region.Bottom = y + h;
                    region.Left = x;
                    region.Right = x + w;

                    // TODO: We need to deal with threaded contexts here!
                    var d3dContext = GraphicsDevice._d3dContext;
                    lock (d3dContext)
						d3dContext.UpdateSubresource(box, GetTexture(), level, region);

#elif PSM
                    _texture2D.SetPixels(level, data, _texture2D.Format, startIndex, 0, x, y, w, h);
#elif OPENGL

                    // Store the current bound texture.
                    var prevTexture = GraphicsExtensions.GetBoundTexture2D();

                    GenerateGLTextureIfRequired();

                    GL.BindTexture(TextureTarget.Texture2D, this.glTexture);
                    GraphicsExtensions.CheckGLError();
                    if (glFormat == (GLPixelFormat)All.CompressedTextureFormats)
                    {
                        if (rect.HasValue)
                        {
                            GL.CompressedTexSubImage2D(TextureTarget.Texture2D,
                                level, x, y, w, h,
#if GLES
                                glInternalFormat,
#else
                                glFormat,
#endif
                                data.Length - startBytes, dataPtr);
                            GraphicsExtensions.CheckGLError();
                        }
                        else
                        {
                            GL.CompressedTexImage2D(TextureTarget.Texture2D, level, glInternalFormat, w, h, 0, data.Length - startBytes, dataPtr);
                            GraphicsExtensions.CheckGLError();
                        }
                    }
                    else
                    {
                        // Set pixel alignment to match texel size in bytes
                        GL.PixelStore(PixelStoreParameter.UnpackAlignment, GraphicsExtensions.Size(this.Format));
                        if (rect.HasValue)
                        {
                            GL.TexSubImage2D(TextureTarget.Texture2D, level,
                                            x, y, w, h,
                                            glFormat, glType, dataPtr);
                            GraphicsExtensions.CheckGLError();
                        }
                        else
                        {
                            GL.TexImage2D(TextureTarget.Texture2D, level,
#if GLES
                                (int)glInternalFormat,
#else
                                glInternalFormat,
#endif
                                w, h, 0, glFormat, glType, dataPtr);
                            GraphicsExtensions.CheckGLError();
                        }
                        // Return to default pixel alignment
                        GL.PixelStore(PixelStoreParameter.UnpackAlignment, 4);
                    }

#if !ANDROID
                    GL.Finish();
                    GraphicsExtensions.CheckGLError();
#endif
                    // Restore the bound texture.
                    GL.BindTexture(TextureTarget.Texture2D, prevTexture);
                    GraphicsExtensions.CheckGLError();

#endif // OPENGL

#if !PSM
                }
                finally
                {
                    dataHandle.Free();
                }
#endif

#if OPENGL
#if !ANDROID
                // Required to make sure that any texture uploads on a thread are completed
                // before the main thread tries to use the texture.
                GL.Finish();
#endif
            });
#endif
        }
Example #11
0
        internal void SetTextures(GraphicsDevice device)
        {
#if !DIRECTX
            Threading.EnsureUIThread();
#endif

            // Skip out if nothing has changed.
            if (_dirty == 0)
            {
                return;
            }

#if DIRECTX
            // NOTE: We make the assumption here that the caller has
            // locked the d3dContext for us to use.
            var pixelShaderStage = device._d3dContext.PixelShader;
#endif

            for (var i = 0; i < _textures.Length; i++)
            {
                var mask = 1 << i;
                if ((_dirty & mask) == 0)
                {
                    continue;
                }

                var tex = _textures[i];
#if OPENGL
                GL.ActiveTexture(TextureUnit.Texture0 + i);
                GraphicsExtensions.CheckGLError();

                // Clear the previous binding if the
                // target is different from the new one.
                if (_targets[i] != 0 && (tex == null || _targets[i] != tex.glTarget))
                {
                    GL.BindTexture(_targets[i], 0);
                    GraphicsExtensions.CheckGLError();
                }

                if (tex != null)
                {
                    _targets[i] = tex.glTarget;
                    GL.BindTexture(tex.glTarget, tex.glTexture);
                    GraphicsExtensions.CheckGLError();
                }
#elif DIRECTX
                if (_textures[i] == null)
                {
                    pixelShaderStage.SetShaderResource(i, null);
                }
                else
                {
                    pixelShaderStage.SetShaderResource(i, _textures[i].GetShaderResourceView());
                }
#endif

                _dirty &= ~mask;
                if (_dirty == 0)
                {
                    break;
                }
            }

            _dirty = 0;
        }
Example #12
0
        protected Texture2D(GraphicsDevice graphicsDevice, int width, int height, bool mipmap, SurfaceFormat format, SurfaceType type, bool shared)
		{
            if (graphicsDevice == null)
                throw new ArgumentNullException("Graphics Device Cannot Be Null");

            this.GraphicsDevice = graphicsDevice;
            this.width = width;
            this.height = height;
            this._format = format;
            this._levelCount = mipmap ? CalculateMipLevels(width, height) : 1;

            // Texture will be assigned by the swap chain.
		    if (type == SurfaceType.SwapChainRenderTarget)
		        return;

#if DIRECTX
            _shared = shared;

            _renderTarget = (type == SurfaceType.RenderTarget);
            _mipmap = mipmap;

            // Create texture
            GetTexture();

#elif PSM
            PixelBufferOption option = PixelBufferOption.None;
            if (type == SurfaceType.RenderTarget)
			    option = PixelBufferOption.Renderable;
            _texture2D = new Sce.PlayStation.Core.Graphics.Texture2D(width, height, mipmap, PSSHelper.ToFormat(format),option);
#else

            this.glTarget = TextureTarget.Texture2D;
            
            Threading.BlockOnUIThread(() =>
            {
                // Store the current bound texture.
                var prevTexture = GraphicsExtensions.GetBoundTexture2D();

                GenerateGLTextureIfRequired();

                format.GetGLFormat(out glInternalFormat, out glFormat, out glType);

                if (glFormat == (GLPixelFormat)All.CompressedTextureFormats)
                {
                    var imageSize = 0;
                    switch (format)
                    {
                        case SurfaceFormat.RgbPvrtc2Bpp:
                        case SurfaceFormat.RgbaPvrtc2Bpp:
                            imageSize = (Math.Max(this.width, 16) * Math.Max(this.height, 8) * 2 + 7) / 8;
                            break;
                        case SurfaceFormat.RgbPvrtc4Bpp:
                        case SurfaceFormat.RgbaPvrtc4Bpp:
                            imageSize = (Math.Max(this.width, 8) * Math.Max(this.height, 8) * 4 + 7) / 8;
                            break;
                        case SurfaceFormat.RgbEtc1:
                        case SurfaceFormat.Dxt1:
                        case SurfaceFormat.Dxt1a:
                        case SurfaceFormat.Dxt3:
                        case SurfaceFormat.Dxt5:
                            imageSize = ((this.width + 3) / 4) * ((this.height + 3) / 4) * format.Size();
                            break;
                        default:
                            throw new NotSupportedException();
                    }

                    GL.CompressedTexImage2D(TextureTarget.Texture2D, 0, glInternalFormat,
                                            this.width, this.height, 0,
                                            imageSize, IntPtr.Zero);
                    GraphicsExtensions.CheckGLError();
                }
                else
                {
                    GL.TexImage2D(TextureTarget.Texture2D, 0,
#if IOS || ANDROID
                        (int)glInternalFormat,
#else				           
					    glInternalFormat,
#endif
                        this.width, this.height, 0,
                        glFormat, glType, IntPtr.Zero);
                    GraphicsExtensions.CheckGLError();
                }

                // Restore the bound texture.
                GL.BindTexture(TextureTarget.Texture2D, prevTexture);
                GraphicsExtensions.CheckGLError();
            });
#endif
        }
Example #13
0
		private byte[] GetTextureData(int ThreadPriorityLevel)
		{
			int framebufferId = -1;
            int renderBufferID = -1;
            
			GL.GenFramebuffers(1, ref framebufferId);
            GraphicsExtensions.CheckGLError();
            GL.BindFramebuffer(All.Framebuffer, framebufferId);
            GraphicsExtensions.CheckGLError();
            //renderBufferIDs = new int[currentRenderTargets];
            GL.GenRenderbuffers(1, ref renderBufferID);
            GraphicsExtensions.CheckGLError();

            // attach the texture to FBO color attachment point
            GL.FramebufferTexture2D(All.Framebuffer, All.ColorAttachment0,
                All.Texture2D, this.glTexture, 0);
            GraphicsExtensions.CheckGLError();

            // create a renderbuffer object to store depth info
            GL.BindRenderbuffer(All.Renderbuffer, renderBufferID);
            GraphicsExtensions.CheckGLError();

			var glDepthFormat = GraphicsCapabilities.SupportsDepth24 ? All.DepthComponent24Oes : GraphicsCapabilities.SupportsDepthNonLinear ? (OpenTK.Graphics.ES20.All)0x8E2C /*GLDepthComponent16NonLinear */: All.DepthComponent16;
			GL.RenderbufferStorage(All.Renderbuffer, glDepthFormat, Width, Height);
            GraphicsExtensions.CheckGLError();

            // attach the renderbuffer to depth attachment point
            GL.FramebufferRenderbuffer(All.Framebuffer, All.DepthAttachment,
                All.Renderbuffer, renderBufferID);
            GraphicsExtensions.CheckGLError();

            All status = GL.CheckFramebufferStatus(All.Framebuffer);

            if (status != All.FramebufferComplete)
                throw new Exception("Error creating framebuffer: " + status);	
			byte[] imageInfo;
            int sz = 0;

            switch (this.Format)
            {
                case SurfaceFormat.Color: //kTexture2DPixelFormat_RGBA8888
                case SurfaceFormat.Dxt3:

                    sz = 4;
                    imageInfo = new byte[(Width * Height) * sz];
                    break;
                case SurfaceFormat.Bgra4444: //kTexture2DPixelFormat_RGBA4444
                    sz = 2;
                    imageInfo = new byte[(Width * Height) * sz];

                    break;
                case SurfaceFormat.Bgra5551: //kTexture2DPixelFormat_RGB5A1
                    sz = 2;
                    imageInfo = new byte[(Width * Height) * sz];
                    break;
                case SurfaceFormat.Alpha8:  // kTexture2DPixelFormat_A8 
                    sz = 1;
                    imageInfo = new byte[(Width * Height) * sz];
                    break;
                default:
                    throw new NotSupportedException("Texture format");
            }

			GL.ReadPixels(0,0,Width, Height, All.Rgba, All.UnsignedByte, imageInfo);
            GraphicsExtensions.CheckGLError();
            GL.FramebufferRenderbuffer(All.Framebuffer, All.DepthAttachment, All.Renderbuffer, 0);
            GraphicsExtensions.CheckGLError();
            GL.DeleteRenderbuffers(1, ref renderBufferID);
            GraphicsExtensions.CheckGLError();
            GL.DeleteFramebuffers(1, ref framebufferId);
            GraphicsExtensions.CheckGLError();
            GL.BindFramebuffer(All.Framebuffer, 0);
            GraphicsExtensions.CheckGLError();
            return imageInfo;
		}
        static SamplerState()
        {
#if OPENGL
#if GLES
            if (GraphicsCapabilities.SupportsTextureFilterAnisotropic)
            {
                GL.GetFloat(GetPNameMaxTextureMaxAnisotropy, ref SamplerState.MaxTextureMaxAnisotropy);
            }
#else
            GL.GetFloat(GetPNameMaxTextureMaxAnisotropy, out SamplerState.MaxTextureMaxAnisotropy);
#endif
            GraphicsExtensions.CheckGLError();
#endif

            _anisotropicClamp = new Utilities.ObjectFactoryWithReset <SamplerState>(() => new SamplerState
            {
                Name     = "SamplerState.AnisotropicClamp",
                Filter   = TextureFilter.Anisotropic,
                AddressU = TextureAddressMode.Clamp,
                AddressV = TextureAddressMode.Clamp,
                AddressW = TextureAddressMode.Clamp,
            });

            _anisotropicWrap = new Utilities.ObjectFactoryWithReset <SamplerState>(() => new SamplerState
            {
                Name     = "SamplerState.AnisotropicWrap",
                Filter   = TextureFilter.Anisotropic,
                AddressU = TextureAddressMode.Wrap,
                AddressV = TextureAddressMode.Wrap,
                AddressW = TextureAddressMode.Wrap,
            });

            _linearClamp = new Utilities.ObjectFactoryWithReset <SamplerState>(() => new SamplerState
            {
                Name     = "SamplerState.LinearClamp",
                Filter   = TextureFilter.Linear,
                AddressU = TextureAddressMode.Clamp,
                AddressV = TextureAddressMode.Clamp,
                AddressW = TextureAddressMode.Clamp,
            });

            _linearWrap = new Utilities.ObjectFactoryWithReset <SamplerState>(() => new SamplerState
            {
                Name     = "SamplerState.LinearWrap",
                Filter   = TextureFilter.Linear,
                AddressU = TextureAddressMode.Wrap,
                AddressV = TextureAddressMode.Wrap,
                AddressW = TextureAddressMode.Wrap,
            });

            _pointClamp = new Utilities.ObjectFactoryWithReset <SamplerState>(() => new SamplerState
            {
                Name     = "SamplerState.PointClamp",
                Filter   = TextureFilter.Point,
                AddressU = TextureAddressMode.Clamp,
                AddressV = TextureAddressMode.Clamp,
                AddressW = TextureAddressMode.Clamp,
            });

            _pointWrap = new Utilities.ObjectFactoryWithReset <SamplerState>(() => new SamplerState
            {
                Name     = "SamplerState.PointWrap",
                Filter   = TextureFilter.Point,
                AddressU = TextureAddressMode.Wrap,
                AddressV = TextureAddressMode.Wrap,
                AddressW = TextureAddressMode.Wrap,
            });
        }
Example #15
0
        internal void PlatformApplyState(bool applyShaders)
        {
            if (_scissorRectangleDirty)
            {
                var scissorRect = _scissorRectangle;
                if (!IsRenderTargetBound)
                {
                    scissorRect.Y = PresentationParameters.BackBufferHeight - (scissorRect.Y + scissorRect.Height);
                }
                gl.scissor(scissorRect.X, scissorRect.Y, scissorRect.Width, scissorRect.Height);
                GraphicsExtensions.CheckGLError();
                _scissorRectangleDirty = false;
            }

            // If we're not applying shaders then early out now.
            if (!applyShaders)
            {
                return;
            }

            if (_indexBufferDirty)
            {
                if (_indexBuffer != null)
                {
                    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, _indexBuffer.ibo);
                    GraphicsExtensions.CheckGLError();
                }
                _indexBufferDirty = false;
            }

            if (_vertexShader == null)
            {
                throw new InvalidOperationException("A vertex shader must be set!");
            }
            if (_pixelShader == null)
            {
                throw new InvalidOperationException("A pixel shader must be set!");
            }

            if (_vertexShaderDirty || _pixelShaderDirty)
            {
                ActivateShaderProgram();

                if (_vertexShaderDirty)
                {
                    unchecked
                    {
                        _graphicsMetrics._vertexShaderCount++;
                    }
                }

                if (_pixelShaderDirty)
                {
                    unchecked
                    {
                        _graphicsMetrics._pixelShaderCount++;
                    }
                }

                _vertexShaderDirty = _pixelShaderDirty = false;
            }

            _vertexConstantBuffers.SetConstantBuffers(this, _shaderProgram);
            _pixelConstantBuffers.SetConstantBuffers(this, _shaderProgram);

            Textures.SetTextures(this);
            SamplerStates.PlatformSetSamplers(this);
        }
 internal virtual void FramebufferRenderbuffer(int attachement, int renderbuffer, int level = 0)
 {
     GL.FramebufferRenderbuffer(FramebufferTarget.Framebuffer, (FramebufferAttachment)attachement, RenderbufferTarget.Renderbuffer, renderbuffer);
     GraphicsExtensions.CheckGLError();
 }
        internal void ApplyState(GraphicsDevice device)
        {
            if (!DepthBufferEnable)
            {
                GL.Disable(EnableCap.DepthTest);
                GraphicsExtensions.CheckGLError();
            }
            else
            {
                // enable Depth Buffer
                GL.Enable(EnableCap.DepthTest);
                GraphicsExtensions.CheckGLError();

                DepthFunction func;
                switch (DepthBufferFunction)
                {
                default:
                case CompareFunction.Always:
                    func = DepthFunction.Always;
                    break;

                case CompareFunction.Equal:
                    func = DepthFunction.Equal;
                    break;

                case CompareFunction.Greater:
                    func = DepthFunction.Greater;
                    break;

                case CompareFunction.GreaterEqual:
                    func = DepthFunction.Gequal;
                    break;

                case CompareFunction.Less:
                    func = DepthFunction.Less;
                    break;

                case CompareFunction.LessEqual:
                    func = DepthFunction.Lequal;
                    break;

                case CompareFunction.Never:
                    func = DepthFunction.Never;
                    break;

                case CompareFunction.NotEqual:
                    func = DepthFunction.Notequal;
                    break;
                }

                GL.DepthFunc(func);
                GraphicsExtensions.CheckGLError();
            }

            GL.DepthMask(DepthBufferWriteEnable);
            GraphicsExtensions.CheckGLError();

            if (!StencilEnable)
            {
                GL.Disable(EnableCap.StencilTest);
                GraphicsExtensions.CheckGLError();
            }
            else
            {
                // enable Stencil
                GL.Enable(EnableCap.StencilTest);
                GraphicsExtensions.CheckGLError();

                // Set color mask - not needed
                //GL.ColorMask(false, false, false, false); //Disable drawing colors to the screen
                // set function
                GLStencilFunction func;
                switch (StencilFunction)
                {
                default:
                case CompareFunction.Always:
                    func = GLStencilFunction.Always;
                    break;

                case CompareFunction.Equal:
                    func = GLStencilFunction.Equal;
                    break;

                case CompareFunction.Greater:
                    func = GLStencilFunction.Greater;
                    break;

                case CompareFunction.GreaterEqual:
                    func = GLStencilFunction.Gequal;
                    break;

                case CompareFunction.Less:
                    func = GLStencilFunction.Less;
                    break;

                case CompareFunction.LessEqual:
                    func = GLStencilFunction.Lequal;
                    break;

                case CompareFunction.Never:
                    func = GLStencilFunction.Never;
                    break;

                case CompareFunction.NotEqual:
                    func = GLStencilFunction.Notequal;
                    break;
                }

                GL.StencilFunc(func, ReferenceStencil, StencilMask);
                GraphicsExtensions.CheckGLError();

                GL.StencilOp(GetStencilOp(StencilFail),
                             GetStencilOp(StencilDepthBufferFail),
                             GetStencilOp(StencilPass));
                GraphicsExtensions.CheckGLError();
            }
        }
 internal virtual void GenerateMipmap(int target)
 {
     GL.GenerateMipmap((GenerateMipmapTarget)target);
     GraphicsExtensions.CheckGLError();
 }
Example #19
0
        private void PlatformConstruct(GraphicsDevice graphicsDevice, int size, bool mipMap, SurfaceFormat format, bool renderTarget)
        {
            this.glTarget = gl.TEXTURE_CUBE_MAP;

            this.glTexture = gl.createTexture();
            GraphicsExtensions.CheckGLError();
            gl.bindTexture(gl.TEXTURE_CUBE_MAP, this.glTexture);
            GraphicsExtensions.CheckGLError();
            gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, mipMap ? gl.LINEAR_MIPMAP_LINEAR : gl.LINEAR);
            GraphicsExtensions.CheckGLError();
            gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
            GraphicsExtensions.CheckGLError();
            gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
            GraphicsExtensions.CheckGLError();
            gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
            GraphicsExtensions.CheckGLError();


            format.GetGLFormat(GraphicsDevice, out glInternalFormat, out glFormat, out glType);

            for (var i = 0; i < 6; i++)
            {
                var target = GetGLCubeFace((CubeMapFace)i);

                if (glFormat == gl.COMPRESSED_TEXTURE_FORMATS)
                {
                    var imageSize = 0;
                    switch (format)
                    {
                    case SurfaceFormat.RgbPvrtc2Bpp:
                    case SurfaceFormat.RgbaPvrtc2Bpp:
                        imageSize = (Math.Max(size, 16) * Math.Max(size, 8) * 2 + 7) / 8;
                        break;

                    case SurfaceFormat.RgbPvrtc4Bpp:
                    case SurfaceFormat.RgbaPvrtc4Bpp:
                        imageSize = (Math.Max(size, 8) * Math.Max(size, 8) * 4 + 7) / 8;
                        break;

                    case SurfaceFormat.Dxt1:
                    case SurfaceFormat.Dxt1a:
                    case SurfaceFormat.Dxt1SRgb:
                    case SurfaceFormat.Dxt3:
                    case SurfaceFormat.Dxt3SRgb:
                    case SurfaceFormat.Dxt5:
                    case SurfaceFormat.Dxt5SRgb:
                    case SurfaceFormat.RgbEtc1:
                    case SurfaceFormat.RgbaAtcExplicitAlpha:
                    case SurfaceFormat.RgbaAtcInterpolatedAlpha:
                        imageSize = (size + 3) / 4 * ((size + 3) / 4) * format.GetSize();
                        break;

                    default:
                        throw new NotSupportedException();
                    }
                    gl.compressedTexImage2D(target, 0, glInternalFormat, size, size, 0, new Int8Array(0));
                    GraphicsExtensions.CheckGLError();
                }
                else
                {
                    gl.texImage2D(target, 0, glInternalFormat, size, size, 0, glFormat, glType, new Int8Array(0).As <ArrayBufferView>());
                    GraphicsExtensions.CheckGLError();
                }
            }

            if (mipMap)
            {
                gl.generateMipmap(gl.TEXTURE_CUBE_MAP);
                GraphicsExtensions.CheckGLError();
            }
        }
 internal virtual void GenRenderbuffer(out int renderbuffer)
 {
     GL.GenRenderbuffers(1, out renderbuffer);
     GraphicsExtensions.CheckGLError();
 }
Example #21
0
        protected void SetDataInternal <T>(int offsetInBytes, T[] data, int startIndex, int elementCount, SetDataOptions options) where T : struct
        {
            if (data == null)
            {
                throw new ArgumentNullException("data is null");
            }
            if (data.Length < (startIndex + elementCount))
            {
                throw new InvalidOperationException("The array specified in the data parameter is not the correct size for the amount of data requested.");
            }

#if DIRECTX
            if (_isDynamic)
            {
                // We assume discard by default.
                var mode = SharpDX.Direct3D11.MapMode.WriteDiscard;
                if ((options & SetDataOptions.NoOverwrite) == SetDataOptions.NoOverwrite)
                {
                    mode = SharpDX.Direct3D11.MapMode.WriteNoOverwrite;
                }

                SharpDX.DataStream stream;
                lock (graphicsDevice._d3dContext)
                {
                    graphicsDevice._d3dContext.MapSubresource(
                        _buffer,
                        mode,
                        SharpDX.Direct3D11.MapFlags.None,
                        out stream);

                    stream.Position = offsetInBytes;
                    stream.WriteRange(data, startIndex, elementCount);

                    graphicsDevice._d3dContext.UnmapSubresource(_buffer, 0);
                }
            }
            else
            {
                var elementSizeInBytes = Marshal.SizeOf(typeof(T));
                var dataHandle         = GCHandle.Alloc(data, GCHandleType.Pinned);
                var startBytes         = startIndex * elementSizeInBytes;
                var dataPtr            = (IntPtr)(dataHandle.AddrOfPinnedObject().ToInt64() + startBytes);

                var box = new SharpDX.DataBox(dataPtr, 1, 0);

                var region = new SharpDX.Direct3D11.ResourceRegion();
                region.Top    = 0;
                region.Front  = 0;
                region.Back   = 1;
                region.Bottom = 1;
                region.Left   = offsetInBytes;
                region.Right  = offsetInBytes + (elementCount * elementSizeInBytes);

                // TODO: We need to deal with threaded contexts here!
                lock (graphicsDevice._d3dContext)
                    graphicsDevice._d3dContext.UpdateSubresource(box, _buffer, 0, region);

                dataHandle.Free();
            }
#elif PSS
            if (typeof(T) == typeof(ushort))
            {
                Array.Copy(data, offsetInBytes / sizeof(ushort), _buffer, startIndex, elementCount);
            }
            else
            {
                throw new NotImplementedException("PSS Currently only supports ushort (SixteenBits) index elements");
                //Something like as follows probably works if you really need this, but really just make a ushort array!

                /*
                 * int indexOffset = offsetInBytes / sizeof(T);
                 * for (int i = 0; i < elementCount; i++)
                 *  _buffer[i + startIndex] = (ushort)(object)data[i + indexOffset];
                 */
            }
#else
            Threading.BlockOnUIThread(() =>
            {
                var elementSizeInByte = Marshal.SizeOf(typeof(T));
                var sizeInBytes       = elementSizeInByte * elementCount;
                var dataHandle        = GCHandle.Alloc(data, GCHandleType.Pinned);
                var dataPtr           = (IntPtr)(dataHandle.AddrOfPinnedObject().ToInt64() + startIndex * elementSizeInByte);
                var bufferSize        = IndexCount * (IndexElementSize == IndexElementSize.SixteenBits ? 2 : 4);

                GL.BindBuffer(BufferTarget.ElementArrayBuffer, ibo);
                GraphicsExtensions.CheckGLError();

                if (options == SetDataOptions.Discard)
                {
                    // By assigning NULL data to the buffer this gives a hint
                    // to the device to discard the previous content.
                    GL.BufferData(BufferTarget.ElementArrayBuffer,
                                  (IntPtr)bufferSize,
                                  IntPtr.Zero,
                                  _isDynamic ? BufferUsageHint.StreamDraw : BufferUsageHint.StaticDraw);
                    GraphicsExtensions.CheckGLError();
                }

                GL.BufferSubData(BufferTarget.ElementArrayBuffer, (IntPtr)offsetInBytes, (IntPtr)sizeInBytes, dataPtr);
                GraphicsExtensions.CheckGLError();

                dataHandle.Free();
            });
#endif
        }
 internal virtual void BindRenderbuffer(int renderbuffer)
 {
     GL.BindRenderbuffer(RenderbufferTarget.Renderbuffer, renderbuffer);
     GraphicsExtensions.CheckGLError();
 }
Example #23
0
        private void PlatformGetData <T>(int level, int arraySlice, Rectangle rect, T[] data, int startIndex, int elementCount) where T : struct
        {
            Threading.EnsureUIThread();

#if GLES
            // TODO: check for for non renderable formats (formats that can't be attached to FBO)

            var framebufferId = 0;
            GL.GenFramebuffers(1, out framebufferId);
            GraphicsExtensions.CheckGLError();
            GL.BindFramebuffer(FramebufferTarget.Framebuffer, framebufferId);
            GraphicsExtensions.CheckGLError();
            GL.FramebufferTexture2D(FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0, TextureTarget.Texture2D, this.glTexture, 0);
            GraphicsExtensions.CheckGLError();

            GL.ReadPixels(rect.X, rect.Y, rect.Width, rect.Height, this.glFormat, this.glType, data);
            GraphicsExtensions.CheckGLError();
            GraphicsDevice.DisposeFramebuffer(framebufferId);
#else
            var tSizeInByte = ReflectionHelpers.SizeOf <T> .Get();

            GL.BindTexture(TextureTarget.Texture2D, this.glTexture);
            GL.PixelStore(PixelStoreParameter.PackAlignment, Math.Min(tSizeInByte, 8));

            if (glFormat == (PixelFormat)GLPixelFormat.CompressedTextureFormats)
            {
                // Note: for compressed format Format.GetSize() returns the size of a 4x4 block
                var pixelToT   = Format.GetSize() / tSizeInByte;
                var tFullWidth = Math.Max(this.width >> level, 1) / 4 * pixelToT;
                var temp       = new T[Math.Max(this.height >> level, 1) / 4 * tFullWidth];
                GL.GetCompressedTexImage(TextureTarget.Texture2D, level, temp);
                GraphicsExtensions.CheckGLError();

                var rowCount   = rect.Height / 4;
                var tRectWidth = rect.Width / 4 * Format.GetSize() / tSizeInByte;
                for (var r = 0; r < rowCount; r++)
                {
                    var tempStart = rect.X / 4 * pixelToT + (rect.Top / 4 + r) * tFullWidth;
                    var dataStart = startIndex + r * tRectWidth;
                    Array.Copy(temp, tempStart, data, dataStart, tRectWidth);
                }
            }
            else
            {
                // we need to convert from our format size to the size of T here
                var tFullWidth = Math.Max(this.width >> level, 1) * Format.GetSize() / tSizeInByte;
                var temp       = new T[Math.Max(this.height >> level, 1) * tFullWidth];
                GL.GetTexImage(TextureTarget.Texture2D, level, glFormat, glType, temp);
                GraphicsExtensions.CheckGLError();

                var pixelToT   = Format.GetSize() / tSizeInByte;
                var rowCount   = rect.Height;
                var tRectWidth = rect.Width * pixelToT;
                for (var r = 0; r < rowCount; r++)
                {
                    var tempStart = rect.X * pixelToT + (r + rect.Top) * tFullWidth;
                    var dataStart = startIndex + r * tRectWidth;
                    Array.Copy(temp, tempStart, data, dataStart, tRectWidth);
                }
            }
#endif
        }
 internal virtual void DeleteRenderbuffer(int renderbuffer)
 {
     GL.DeleteRenderbuffers(1, ref renderbuffer);
     GraphicsExtensions.CheckGLError();
 }
Example #25
0
        internal void PlatformApplyState(GraphicsDevice device, bool force = false)
        {
            if (force || this.DepthBufferEnable != device._lastDepthStencilState.DepthBufferEnable)
            {
                if (!DepthBufferEnable)
                {
                    GL.Disable(EnableCap.DepthTest);
                    GraphicsExtensions.CheckGLError();
                }
                else
                {
                    // enable Depth Buffer
                    GL.Enable(EnableCap.DepthTest);
                    GraphicsExtensions.CheckGLError();
                }
                device._lastDepthStencilState.DepthBufferEnable = this.DepthBufferEnable;
            }

            if (force || this.DepthBufferFunction != device._lastDepthStencilState.DepthBufferFunction)
            {
                GL.DepthFunc(DepthBufferFunction.GetDepthFunction());
                GraphicsExtensions.CheckGLError();
                device._lastDepthStencilState.DepthBufferFunction = this.DepthBufferFunction;
            }

            if (force || this.DepthBufferWriteEnable != device._lastDepthStencilState.DepthBufferWriteEnable)
            {
                GL.DepthMask(DepthBufferWriteEnable);
                GraphicsExtensions.CheckGLError();
                device._lastDepthStencilState.DepthBufferWriteEnable = this.DepthBufferWriteEnable;
            }

            if (force || this.StencilEnable != device._lastDepthStencilState.StencilEnable)
            {
                if (!StencilEnable)
                {
                    GL.Disable(EnableCap.StencilTest);
                    GraphicsExtensions.CheckGLError();
                }
                else
                {
                    // enable Stencil
                    GL.Enable(EnableCap.StencilTest);
                    GraphicsExtensions.CheckGLError();
                }
                device._lastDepthStencilState.StencilEnable = this.StencilEnable;
            }

            // set function
            if (this.TwoSidedStencilMode)
            {
                var cullFaceModeFront = StencilFace.Front;
                var cullFaceModeBack  = StencilFace.Back;
                var stencilFaceFront  = StencilFace.Front;
                var stencilFaceBack   = StencilFace.Back;

                if (force ||
                    this.TwoSidedStencilMode != device._lastDepthStencilState.TwoSidedStencilMode ||
                    this.StencilFunction != device._lastDepthStencilState.StencilFunction ||
                    this.ReferenceStencil != device._lastDepthStencilState.ReferenceStencil ||
                    this.StencilMask != device._lastDepthStencilState.StencilMask)
                {
                    GL.StencilFuncSeparate(cullFaceModeFront, GetStencilFunc(this.StencilFunction),
                                           this.ReferenceStencil, this.StencilMask);
                    GraphicsExtensions.CheckGLError();
                    device._lastDepthStencilState.StencilFunction  = this.StencilFunction;
                    device._lastDepthStencilState.ReferenceStencil = this.ReferenceStencil;
                    device._lastDepthStencilState.StencilMask      = this.StencilMask;
                }

                if (force ||
                    this.TwoSidedStencilMode != device._lastDepthStencilState.TwoSidedStencilMode ||
                    this.CounterClockwiseStencilFunction != device._lastDepthStencilState.CounterClockwiseStencilFunction ||
                    this.ReferenceStencil != device._lastDepthStencilState.ReferenceStencil ||
                    this.StencilMask != device._lastDepthStencilState.StencilMask)
                {
                    GL.StencilFuncSeparate(cullFaceModeBack, GetStencilFunc(this.CounterClockwiseStencilFunction),
                                           this.ReferenceStencil, this.StencilMask);
                    GraphicsExtensions.CheckGLError();
                    device._lastDepthStencilState.CounterClockwiseStencilFunction = this.CounterClockwiseStencilFunction;
                    device._lastDepthStencilState.ReferenceStencil = this.ReferenceStencil;
                    device._lastDepthStencilState.StencilMask      = this.StencilMask;
                }


                if (force ||
                    this.TwoSidedStencilMode != device._lastDepthStencilState.TwoSidedStencilMode ||
                    this.StencilFail != device._lastDepthStencilState.StencilFail ||
                    this.StencilDepthBufferFail != device._lastDepthStencilState.StencilDepthBufferFail ||
                    this.StencilPass != device._lastDepthStencilState.StencilPass)
                {
                    GL.StencilOpSeparate(stencilFaceFront, GetStencilOp(this.StencilFail),
                                         GetStencilOp(this.StencilDepthBufferFail),
                                         GetStencilOp(this.StencilPass));
                    GraphicsExtensions.CheckGLError();
                    device._lastDepthStencilState.StencilFail            = this.StencilFail;
                    device._lastDepthStencilState.StencilDepthBufferFail = this.StencilDepthBufferFail;
                    device._lastDepthStencilState.StencilPass            = this.StencilPass;
                }

                if (force ||
                    this.TwoSidedStencilMode != device._lastDepthStencilState.TwoSidedStencilMode ||
                    this.CounterClockwiseStencilFail != device._lastDepthStencilState.CounterClockwiseStencilFail ||
                    this.CounterClockwiseStencilDepthBufferFail != device._lastDepthStencilState.CounterClockwiseStencilDepthBufferFail ||
                    this.CounterClockwiseStencilPass != device._lastDepthStencilState.CounterClockwiseStencilPass)
                {
                    GL.StencilOpSeparate(stencilFaceBack, GetStencilOp(this.CounterClockwiseStencilFail),
                                         GetStencilOp(this.CounterClockwiseStencilDepthBufferFail),
                                         GetStencilOp(this.CounterClockwiseStencilPass));
                    GraphicsExtensions.CheckGLError();
                    device._lastDepthStencilState.CounterClockwiseStencilFail            = this.CounterClockwiseStencilFail;
                    device._lastDepthStencilState.CounterClockwiseStencilDepthBufferFail = this.CounterClockwiseStencilDepthBufferFail;
                    device._lastDepthStencilState.CounterClockwiseStencilPass            = this.CounterClockwiseStencilPass;
                }
            }
            else
            {
                if (force ||
                    this.TwoSidedStencilMode != device._lastDepthStencilState.TwoSidedStencilMode ||
                    this.StencilFunction != device._lastDepthStencilState.StencilFunction ||
                    this.ReferenceStencil != device._lastDepthStencilState.ReferenceStencil ||
                    this.StencilMask != device._lastDepthStencilState.StencilMask)
                {
                    GL.StencilFunc(GetStencilFunc(this.StencilFunction), ReferenceStencil, StencilMask);
                    GraphicsExtensions.CheckGLError();
                    device._lastDepthStencilState.StencilFunction  = this.StencilFunction;
                    device._lastDepthStencilState.ReferenceStencil = this.ReferenceStencil;
                    device._lastDepthStencilState.StencilMask      = this.StencilMask;
                }

                if (force ||
                    this.TwoSidedStencilMode != device._lastDepthStencilState.TwoSidedStencilMode ||
                    this.StencilFail != device._lastDepthStencilState.StencilFail ||
                    this.StencilDepthBufferFail != device._lastDepthStencilState.StencilDepthBufferFail ||
                    this.StencilPass != device._lastDepthStencilState.StencilPass)
                {
                    GL.StencilOp(GetStencilOp(StencilFail),
                                 GetStencilOp(StencilDepthBufferFail),
                                 GetStencilOp(StencilPass));
                    GraphicsExtensions.CheckGLError();
                    device._lastDepthStencilState.StencilFail            = this.StencilFail;
                    device._lastDepthStencilState.StencilDepthBufferFail = this.StencilDepthBufferFail;
                    device._lastDepthStencilState.StencilPass            = this.StencilPass;
                }
            }

            device._lastDepthStencilState.TwoSidedStencilMode = this.TwoSidedStencilMode;

            if (force || this.StencilWriteMask != device._lastDepthStencilState.StencilWriteMask)
            {
                GL.StencilMask(this.StencilWriteMask);
                GraphicsExtensions.CheckGLError();
                device._lastDepthStencilState.StencilWriteMask = this.StencilWriteMask;
            }
        }
 internal virtual void GenFramebuffer(out int framebuffer)
 {
     GL.GenFramebuffers(1, out framebuffer);
     GraphicsExtensions.CheckGLError();
 }
Example #27
0
        private void PlatformResolveRenderTargets()
        {
            if (this._currentRenderTargetCount == 0)
            {
                return;
            }

            var renderTargetBinding = this._currentRenderTargetBindings[0];
            var renderTarget        = renderTargetBinding.RenderTarget as IRenderTarget;

            if (renderTarget.MultiSampleCount > 0 && this.framebufferHelper.SupportsBlitFramebuffer)
            {
                var glResolveFramebuffer = 0;
                if (!this.glResolveFramebuffers.TryGetValue(this._currentRenderTargetBindings, out glResolveFramebuffer))
                {
                    this.framebufferHelper.GenFramebuffer(out glResolveFramebuffer);
                    this.framebufferHelper.BindFramebuffer(glResolveFramebuffer);
                    for (var i = 0; i < this._currentRenderTargetCount; ++i)
                    {
                        this.framebufferHelper.FramebufferTexture2D((int)(FramebufferAttachment.ColorAttachment0 + i), (int)renderTarget.GetFramebufferTarget(renderTargetBinding), renderTarget.GLTexture);
                    }
                    this.glResolveFramebuffers.Add((RenderTargetBinding[])this._currentRenderTargetBindings.Clone(), glResolveFramebuffer);
                }
                else
                {
                    this.framebufferHelper.BindFramebuffer(glResolveFramebuffer);
                }
                // The only fragment operations which affect the resolve are the pixel ownership test, the scissor test, and dithering.
                if (this._lastRasterizerState.ScissorTestEnable)
                {
                    GL.Disable(EnableCap.ScissorTest);
                    GraphicsExtensions.CheckGLError();
                }
                var glFramebuffer = this.glFramebuffers[this._currentRenderTargetBindings];
                this.framebufferHelper.BindReadFramebuffer(glFramebuffer);
                for (var i = 0; i < this._currentRenderTargetCount; ++i)
                {
                    renderTargetBinding = this._currentRenderTargetBindings[i];
                    renderTarget        = renderTargetBinding.RenderTarget as IRenderTarget;
                    this.framebufferHelper.BlitFramebuffer(i, renderTarget.Width, renderTarget.Height);
                }
                if (renderTarget.RenderTargetUsage == RenderTargetUsage.DiscardContents && this.framebufferHelper.SupportsInvalidateFramebuffer)
                {
                    this.framebufferHelper.InvalidateReadFramebuffer();
                }
                if (this._lastRasterizerState.ScissorTestEnable)
                {
                    GL.Enable(EnableCap.ScissorTest);
                    GraphicsExtensions.CheckGLError();
                }
            }
            for (var i = 0; i < this._currentRenderTargetCount; ++i)
            {
                renderTargetBinding = this._currentRenderTargetBindings[i];
                renderTarget        = renderTargetBinding.RenderTarget as IRenderTarget;
                if (renderTarget.LevelCount > 1)
                {
                    GL.BindTexture((TextureTarget)renderTarget.GLTarget, renderTarget.GLTexture);
                    GraphicsExtensions.CheckGLError();
                    this.framebufferHelper.GenerateMipmap((int)renderTarget.GLTarget);
                }
            }
        }
 internal virtual void BindReadFramebuffer(int readFramebuffer)
 {
     GL.BindFramebuffer(FramebufferTarget.ReadFramebuffer, readFramebuffer);
     GraphicsExtensions.CheckGLError();
 }
Example #29
0
        internal void PlatformApplyState(bool applyShaders)
        {
            if (_scissorRectangleDirty)
            {
                var scissorRect = _scissorRectangle;
                if (!IsRenderTargetBound)
                {
                    scissorRect.Y = _viewport.Height - scissorRect.Y - scissorRect.Height;
                }
                GL.Scissor(scissorRect.X, scissorRect.Y, scissorRect.Width, scissorRect.Height);
                GraphicsExtensions.CheckGLError();
                _scissorRectangleDirty = false;
            }

            // If we're not applying shaders then early out now.
            if (!applyShaders)
            {
                return;
            }

            if (_indexBufferDirty)
            {
                if (_indexBuffer != null)
                {
                    GL.BindBuffer(BufferTarget.ElementArrayBuffer, _indexBuffer.ibo);
                    GraphicsExtensions.CheckGLError();
                }
                _indexBufferDirty = false;
            }

            if (_vertexBuffersDirty)
            {
                if (_vertexBuffers.Count > 0)
                {
                    GL.BindBuffer(BufferTarget.ArrayBuffer, _vertexBuffers.Get(0).VertexBuffer.vbo);
                    GraphicsExtensions.CheckGLError();
                }
                _vertexBuffersDirty = false;
            }

            if (_vertexShader == null)
            {
                throw new InvalidOperationException("A vertex shader must be set!");
            }
            if (_pixelShader == null)
            {
                throw new InvalidOperationException("A pixel shader must be set!");
            }

            if (_vertexShaderDirty || _pixelShaderDirty)
            {
                ActivateShaderProgram();

                if (_vertexShaderDirty)
                {
                    unchecked
                    {
                        _graphicsMetrics._vertexShaderCount++;
                    }
                }

                if (_pixelShaderDirty)
                {
                    unchecked
                    {
                        _graphicsMetrics._pixelShaderCount++;
                    }
                }

                _vertexShaderDirty = _pixelShaderDirty = false;
            }

            _vertexConstantBuffers.SetConstantBuffers(this, _shaderProgram);
            _pixelConstantBuffers.SetConstantBuffers(this, _shaderProgram);

            Textures.SetTextures(this);
            SamplerStates.PlatformSetSamplers(this);
        }
Example #30
0
        internal void Activate(GraphicsDevice device, TextureTarget target, bool useMipmaps = false)
        {
            if (GraphicsDevice == null)
            {
                // We're now bound to a device... no one should
                // be changing the state of this object now!
                GraphicsDevice = device;
            }
            Debug.Assert(GraphicsDevice == device, "The state was created for a different device!");

            switch (Filter)
            {
            case TextureFilter.Point:
                if (GraphicsDevice.GraphicsCapabilities.SupportsTextureFilterAnisotropic)
                {
                    GL.TexParameter(target, TextureParameterNameTextureMaxAnisotropy, 1.0f);
                    GraphicsExtensions.CheckGLError();
                }
                GL.TexParameter(target, TextureParameterName.TextureMinFilter, (int)(useMipmaps ? TextureMinFilter.NearestMipmapNearest : TextureMinFilter.Nearest));
                GraphicsExtensions.CheckGLError();
                GL.TexParameter(target, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Nearest);
                GraphicsExtensions.CheckGLError();
                break;

            case TextureFilter.Linear:
                if (GraphicsDevice.GraphicsCapabilities.SupportsTextureFilterAnisotropic)
                {
                    GL.TexParameter(target, TextureParameterNameTextureMaxAnisotropy, 1.0f);
                    GraphicsExtensions.CheckGLError();
                }
                GL.TexParameter(target, TextureParameterName.TextureMinFilter, (int)(useMipmaps ? TextureMinFilter.LinearMipmapLinear : TextureMinFilter.Linear));
                GraphicsExtensions.CheckGLError();
                GL.TexParameter(target, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
                GraphicsExtensions.CheckGLError();
                break;

            case TextureFilter.Anisotropic:
                if (GraphicsDevice.GraphicsCapabilities.SupportsTextureFilterAnisotropic)
                {
                    GL.TexParameter(target, TextureParameterNameTextureMaxAnisotropy, MathHelper.Clamp(this.MaxAnisotropy, 1.0f, GraphicsDevice.GraphicsCapabilities.MaxTextureAnisotropy));
                    GraphicsExtensions.CheckGLError();
                }
                GL.TexParameter(target, TextureParameterName.TextureMinFilter, (int)(useMipmaps ? TextureMinFilter.LinearMipmapLinear : TextureMinFilter.Linear));
                GraphicsExtensions.CheckGLError();
                GL.TexParameter(target, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
                GraphicsExtensions.CheckGLError();
                break;

            case TextureFilter.PointMipLinear:
                if (GraphicsDevice.GraphicsCapabilities.SupportsTextureFilterAnisotropic)
                {
                    GL.TexParameter(target, TextureParameterNameTextureMaxAnisotropy, 1.0f);
                    GraphicsExtensions.CheckGLError();
                }
                GL.TexParameter(target, TextureParameterName.TextureMinFilter, (int)(useMipmaps ? TextureMinFilter.NearestMipmapLinear : TextureMinFilter.Nearest));
                GraphicsExtensions.CheckGLError();
                GL.TexParameter(target, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Nearest);
                GraphicsExtensions.CheckGLError();
                break;

            case TextureFilter.LinearMipPoint:
                if (GraphicsDevice.GraphicsCapabilities.SupportsTextureFilterAnisotropic)
                {
                    GL.TexParameter(target, TextureParameterNameTextureMaxAnisotropy, 1.0f);
                    GraphicsExtensions.CheckGLError();
                }
                GL.TexParameter(target, TextureParameterName.TextureMinFilter, (int)(useMipmaps ? TextureMinFilter.LinearMipmapNearest : TextureMinFilter.Linear));
                GraphicsExtensions.CheckGLError();
                GL.TexParameter(target, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
                GraphicsExtensions.CheckGLError();
                break;

            case TextureFilter.MinLinearMagPointMipLinear:
                if (GraphicsDevice.GraphicsCapabilities.SupportsTextureFilterAnisotropic)
                {
                    GL.TexParameter(target, TextureParameterNameTextureMaxAnisotropy, 1.0f);
                    GraphicsExtensions.CheckGLError();
                }
                GL.TexParameter(target, TextureParameterName.TextureMinFilter, (int)(useMipmaps ? TextureMinFilter.LinearMipmapLinear : TextureMinFilter.Linear));
                GraphicsExtensions.CheckGLError();
                GL.TexParameter(target, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Nearest);
                GraphicsExtensions.CheckGLError();
                break;

            case TextureFilter.MinLinearMagPointMipPoint:
                if (GraphicsDevice.GraphicsCapabilities.SupportsTextureFilterAnisotropic)
                {
                    GL.TexParameter(target, TextureParameterNameTextureMaxAnisotropy, 1.0f);
                    GraphicsExtensions.CheckGLError();
                }
                GL.TexParameter(target, TextureParameterName.TextureMinFilter, (int)(useMipmaps ? TextureMinFilter.LinearMipmapNearest: TextureMinFilter.Linear));
                GraphicsExtensions.CheckGLError();
                GL.TexParameter(target, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Nearest);
                GraphicsExtensions.CheckGLError();
                break;

            case TextureFilter.MinPointMagLinearMipLinear:
                if (GraphicsDevice.GraphicsCapabilities.SupportsTextureFilterAnisotropic)
                {
                    GL.TexParameter(target, TextureParameterNameTextureMaxAnisotropy, 1.0f);
                    GraphicsExtensions.CheckGLError();
                }
                GL.TexParameter(target, TextureParameterName.TextureMinFilter, (int)(useMipmaps ? TextureMinFilter.NearestMipmapLinear: TextureMinFilter.Nearest));
                GraphicsExtensions.CheckGLError();
                GL.TexParameter(target, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
                GraphicsExtensions.CheckGLError();
                break;

            case TextureFilter.MinPointMagLinearMipPoint:
                if (GraphicsDevice.GraphicsCapabilities.SupportsTextureFilterAnisotropic)
                {
                    GL.TexParameter(target, TextureParameterNameTextureMaxAnisotropy, 1.0f);
                    GraphicsExtensions.CheckGLError();
                }
                GL.TexParameter(target, TextureParameterName.TextureMinFilter, (int)(useMipmaps ? TextureMinFilter.NearestMipmapNearest: TextureMinFilter.Nearest));
                GraphicsExtensions.CheckGLError();
                GL.TexParameter(target, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
                GraphicsExtensions.CheckGLError();
                break;

            default:
                throw new NotSupportedException();
            }

            // Set up texture addressing.
            GL.TexParameter(target, TextureParameterName.TextureWrapS, (int)GetWrapMode(AddressU));
            GraphicsExtensions.CheckGLError();
            GL.TexParameter(target, TextureParameterName.TextureWrapT, (int)GetWrapMode(AddressV));
            GraphicsExtensions.CheckGLError();
#if !GLES
            // Border color is not supported by glTexParameter in OpenGL ES 2.0
            _openGLBorderColor[0] = BorderColor.R / 255.0f;
            _openGLBorderColor[1] = BorderColor.G / 255.0f;
            _openGLBorderColor[2] = BorderColor.B / 255.0f;
            _openGLBorderColor[3] = BorderColor.A / 255.0f;
            GL.TexParameter(target, TextureParameterName.TextureBorderColor, _openGLBorderColor);
            GraphicsExtensions.CheckGLError();
            // LOD bias is not supported by glTexParameter in OpenGL ES 2.0
            GL.TexParameter(target, TextureParameterName.TextureLodBias, MipMapLevelOfDetailBias);
            GraphicsExtensions.CheckGLError();
            // Comparison samplers are not supported in OpenGL ES 2.0 (without an extension, anyway)
            if (ComparisonFunction != CompareFunction.Never)
            {
                GL.TexParameter(target, TextureParameterName.TextureCompareMode, (int)TextureCompareMode.CompareRefToTexture);
                GraphicsExtensions.CheckGLError();
                GL.TexParameter(target, TextureParameterName.TextureCompareFunc, (int)ComparisonFunction.GetDepthFunction());
                GraphicsExtensions.CheckGLError();
            }
            else
            {
                GL.TexParameter(target, TextureParameterName.TextureCompareMode, (int)TextureCompareMode.None);
                GraphicsExtensions.CheckGLError();
            }
#endif
            if (GraphicsDevice.GraphicsCapabilities.SupportsTextureMaxLevel)
            {
                if (this.MaxMipLevel > 0)
                {
                    GL.TexParameter(TextureTarget.Texture2D, TextureParameterNameTextureMaxLevel, this.MaxMipLevel);
                }
                else
                {
                    GL.TexParameter(TextureTarget.Texture2D, TextureParameterNameTextureMaxLevel, 1000);
                }
            }
        }