Ejemplo n.º 1
0
        internal ConstantBuffer(GraphicsDevice graphicsDevice, ResourceUsage usage, DataArray data)
            : base(graphicsDevice, new System.Diagnostics.StackTrace())
        {
            if (data.IsNull)
            {
                throw new ArgumentNullException("data.Pointer");
            }
            if (data.Size <= 0)
            {
                throw new ArgumentOutOfRangeException("data.Size", data.Size, "Size must be bigger than 0.");
            }
            if (data.Size > graphicsDevice.OpenGLCapabilities.MaxUniformBlockSize)
            {
                throw new PlatformNotSupportedException(string.Format("data.Size {0} is too big. Supported maximum is {1}", data.Size, graphicsDevice.OpenGLCapabilities.MaxUniformBlockSize));
            }

            this.Usage = usage;

            UboId = GL.GenBuffer();
            graphicsDevice.CheckGLError();

            if (!data.IsNull)
            {
                this.SizeBytes = data.Size;

                if (graphicsDevice.OpenGLCapabilities.DirectStateAccess == DirectStateAccess.None)
                {
                    graphicsDevice.BindManager.ConstantBuffer = this;
                    GL.BufferData(BufferTarget.UniformBuffer, new IntPtr(SizeBytes), data.Pointer, EnumConverter.Convert(Usage));
                }
                else if (graphicsDevice.OpenGLCapabilities.DirectStateAccess == DirectStateAccess.Extension)
                {
                    OpenTK.Graphics.OpenGL.GL.Ext.NamedBufferData(UboId, new IntPtr(SizeBytes), data.Pointer, (OpenTK.Graphics.OpenGL.ExtDirectStateAccess)EnumConverter.Convert(Usage));
                }
            }

            graphicsDevice.CheckGLError("Constant Buffer Constructor");
        }
Ejemplo n.º 2
0
        internal ConstantBuffer(GraphicsDevice graphicsDevice, int sizeBytes, ResourceUsage usage)
            : base(graphicsDevice, new System.Diagnostics.StackTrace())
        {
            if (usage == ResourceUsage.Immutable)
            {
                throw new ArgumentException("data", "Immutable buffers must be initialized with data.");
            }
            if (sizeBytes <= 0)
            {
                throw new ArgumentOutOfRangeException("sizeBytes", sizeBytes, "Size must be bigger than 0.");
            }

            this.SizeBytes = sizeBytes;
            this.Usage     = usage;

            UboId = GL.GenBuffer();

            if (graphicsDevice.OpenGLCapabilities.DirectStateAccess == DirectStateAccess.None)
            {
                graphicsDevice.BindManager.ConstantBuffer = this;
                GL.BufferData(BufferTarget.UniformBuffer, new IntPtr(SizeBytes), IntPtr.Zero, EnumConverter.Convert(Usage));
            }
            else if (graphicsDevice.OpenGLCapabilities.DirectStateAccess == DirectStateAccess.Extension)
            {
                OpenTK.Graphics.OpenGL.GL.Ext.NamedBufferData(UboId, new IntPtr(SizeBytes), IntPtr.Zero, (OpenTK.Graphics.OpenGL.ExtDirectStateAccess)EnumConverter.Convert(Usage));
            }

            graphicsDevice.CheckGLError("Constant Buffer Constructor");
        }
Ejemplo n.º 3
0
        internal Texture2DArray(GraphicsDevice graphicsDevice, int width, int height, int arraySize, TextureFormat format, bool generateMipMaps, ResourceUsage usage = ResourceUsage.Normal, params DataRectangle[] data)
            : base(graphicsDevice, new System.Diagnostics.StackTrace(1))
        {
            if (width <= 0)
            {
                throw new ArgumentOutOfRangeException("width", "Width must be positive.");
            }
            if (height <= 0)
            {
                throw new ArgumentOutOfRangeException("height", "Height must be positive.");
            }
            if (format == TextureFormat.Unknown)
            {
                throw new ArgumentException("Format must not be TextureFormat.Unknown.", "format");
            }
            if (width > graphicsDevice.OpenGLCapabilities.MaxTextureSize)
            {
                throw new PlatformNotSupportedException("width exceeds the maximum texture size");
            }
            if (height > graphicsDevice.OpenGLCapabilities.MaxTextureSize)
            {
                throw new PlatformNotSupportedException("height exceeds the maximum texture size");
            }
            if ((width % 2 != 0 || height % 2 != 0) && graphicsDevice.OpenGLCapabilities.SupportsNonPowerOf2Textures)
            {
                throw new PlatformNotSupportedException("Driver doesn't support non power of two textures");
            }
            if (width != height)
            {
                throw new PlatformNotSupportedException("Texture arrays must be quadratic");
            }
            if (arraySize <= 0)
            {
                throw new ArgumentOutOfRangeException("Array Size must be at least one", "arraySize");
            }
            if (usage == ResourceUsage.Immutable && (data == null || data.Length == 0))
            {
                throw new ArgumentException("data", "Immutable textures must be initialized with data.");
            }
            if (data != null && data.Length != 0 && data.Length < arraySize)
            {
                throw new ArgumentOutOfRangeException("data", data.Length, string.Format("data Lenght is too small for specified arraySize, expected: {0}", arraySize));
            }

            this.Width     = width;
            this.Height    = height;
            this.ArraySize = arraySize;
            this.MipLevels = generateMipMaps ? OpenGL4.GraphicsDevice.MipLevels(width, height) : 1;
            this.Format    = format;
            this.Usage     = usage;
            var internalFormat = EnumConverter.Convert(Format);

            this.TextureID = GL.GenTexture();
            if (graphicsDevice.OpenGLCapabilities.DirectStateAccess == DirectStateAccess.None)
            {
                graphicsDevice.BindManager.SetTexture(this, 0);
                GL.TexParameter(TextureTarget.Texture2DArray, TextureParameterName.TextureMaxLevel, this.MipLevels - 1);
                if (!TextureFormatHelper.IsCompressed(Format))
                {
                    if (graphicsDevice.OpenGLCapabilities.SupportsTextureStorage && graphicsDevice.OpenGLCapabilities.OpenGLVersion > new Version(4, 2))
                    {
                        GL.TexStorage3D(TextureTarget3d.Texture2DArray, MipLevels, EnumConverter.ConvertSizedInternalFormat(Format), Width, Height, ArraySize);
                    }
                    else
                    {
                        GL.TexImage3D(TextureTarget.Texture2DArray, 0, internalFormat.Item1, width, height, arraySize, 0, internalFormat.Item2, internalFormat.Item3, IntPtr.Zero);
                    }
                }
            }
            else if (graphicsDevice.OpenGLCapabilities.DirectStateAccess == DirectStateAccess.Extension)
            {
                Ext.TextureParameter(TextureID, OpenTK.Graphics.OpenGL.TextureTarget.Texture2D, OpenTK.Graphics.OpenGL.TextureParameterName.TextureMaxLevel, this.MipLevels - 1);
                if (!TextureFormatHelper.IsCompressed(Format))
                {
                    if (graphicsDevice.OpenGLCapabilities.SupportsTextureStorage && graphicsDevice.OpenGLCapabilities.OpenGLVersion > new Version(4, 2))
                    {
                        Ext.TextureStorage3D(TextureID, (OpenTK.Graphics.OpenGL.ExtDirectStateAccess)TextureTarget3d.Texture2DArray, MipLevels, (OpenTK.Graphics.OpenGL.ExtDirectStateAccess)EnumConverter.ConvertSizedInternalFormat(Format), Width, Height, ArraySize);
                    }
                    else
                    {
                        Ext.TextureImage3D(TextureID, (OpenTK.Graphics.OpenGL.TextureTarget)TextureTarget.Texture3D, 0, (int)internalFormat.Item1, width, height, arraySize, 0, (OpenTK.Graphics.OpenGL.PixelFormat)internalFormat.Item2, (OpenTK.Graphics.OpenGL.PixelType)internalFormat.Item3, IntPtr.Zero);
                    }
                }
            }
            else if (graphicsDevice.OpenGLCapabilities.DirectStateAccess == DirectStateAccess.Core)
            {
            }

            if (data != null)
            {
                for (int i = 0; i < data.Length; i++)
                {
                    SetData(data[i], i, 0);
                }
            }

            graphicsDevice.CheckGLError();
        }
Ejemplo n.º 4
0
        internal void Apply(IDepthStencilState compareTo, int stencilReference)
        {
            if (compareTo != null || this.stencilReference != stencilReference)
            {
                //Depth
                if (compareTo.Info.IsDepthEnabled != Info.IsDepthEnabled)
                {
                    if (Info.IsDepthEnabled)
                        GL.Enable(EnableCap.DepthTest);
                    else
                        GL.Disable(EnableCap.DepthTest);
                }

                if (compareTo.Info.DepthWriteMask != Info.DepthWriteMask)
                    GL.DepthMask(Info.DepthWriteMask == DepthWriteMask.All);


                if (compareTo.Info.DepthComparsion != Info.DepthComparsion)
                    GL.DepthFunc(EnumConverter.Convert(Info.DepthComparsion));

                //Stencil
                if (compareTo.Info.IsStencilEnabled != Info.IsStencilEnabled)
                {
                    if (Info.IsStencilEnabled)
                        GL.Enable(EnableCap.StencilTest);
                    else
                        GL.Disable(EnableCap.StencilTest);
                }

                if (compareTo.Info.StencilWriteMask != Info.StencilWriteMask)
                    GL.StencilMask(Info.StencilWriteMask);


                if (compareTo.Info.FrontFace.Comparsion != Info.FrontFace.Comparsion)
                {
                    GL.StencilFuncSeparate(StencilFace.Front, (StencilFunction)EnumConverter.Convert(Info.FrontFace.Comparsion), stencilReference, Info.StencilWriteMask);
                }
                if (compareTo.Info.FrontFace.DepthFailOperation != Info.FrontFace.DepthFailOperation || compareTo.Info.FrontFace.FailOperation != Info.FrontFace.FailOperation || compareTo.Info.FrontFace.PassOperation != Info.FrontFace.PassOperation)
                {
                    GL.StencilOpSeparate(StencilFace.Front, EnumConverter.Convert(Info.FrontFace.FailOperation), EnumConverter.Convert(Info.FrontFace.DepthFailOperation), EnumConverter.Convert(Info.FrontFace.PassOperation));
                }

                if (compareTo.Info.BackFace.Comparsion != Info.BackFace.Comparsion)
                {
                    GL.StencilFuncSeparate(StencilFace.Back, (StencilFunction)EnumConverter.Convert(Info.BackFace.Comparsion), stencilReference, Info.StencilWriteMask);
                }
                if (compareTo.Info.BackFace.DepthFailOperation != Info.BackFace.DepthFailOperation || compareTo.Info.BackFace.FailOperation != Info.BackFace.FailOperation || compareTo.Info.BackFace.PassOperation != Info.BackFace.PassOperation)
                {
                    GL.StencilOpSeparate(StencilFace.Back, EnumConverter.Convert(Info.BackFace.FailOperation), EnumConverter.Convert(Info.BackFace.DepthFailOperation), EnumConverter.Convert(Info.BackFace.PassOperation));
                }
            }
            else
            {
                //Depth
                if (Info.IsDepthEnabled)
                    GL.Enable(EnableCap.DepthTest);
                else
                    GL.Disable(EnableCap.DepthTest);

                GL.DepthMask(Info.DepthWriteMask == DepthWriteMask.All);

                GL.DepthFunc(EnumConverter.Convert(Info.DepthComparsion));

                //Stencil
                if (Info.IsStencilEnabled)
                    GL.Enable(EnableCap.StencilTest);
                else
                    GL.Disable(EnableCap.StencilTest);

                GL.StencilMask(Info.StencilWriteMask);

                GL.StencilFuncSeparate(StencilFace.Front, (StencilFunction)EnumConverter.Convert(Info.FrontFace.Comparsion), stencilReference, Info.StencilWriteMask);
                GL.StencilOpSeparate(StencilFace.Front, EnumConverter.Convert(Info.FrontFace.FailOperation), EnumConverter.Convert(Info.FrontFace.DepthFailOperation), EnumConverter.Convert(Info.FrontFace.PassOperation));
                GL.StencilFuncSeparate(StencilFace.Back, (StencilFunction)EnumConverter.Convert(Info.BackFace.Comparsion), stencilReference, Info.StencilWriteMask);
                GL.StencilOpSeparate(StencilFace.Back, EnumConverter.Convert(Info.BackFace.FailOperation), EnumConverter.Convert(Info.BackFace.DepthFailOperation), EnumConverter.Convert(Info.BackFace.PassOperation));
            }

            this.stencilReference = stencilReference;
        }
Ejemplo n.º 5
0
        internal void SetData(DataRectangle data, int arrayIndex, int mipLevel)
        {
            var format = EnumConverter.Convert(Format);

            if (graphicsDevice.OpenGLCapabilities.DirectStateAccess == DirectStateAccess.None)
            {
                graphicsDevice.BindManager.SetTexture(this, 0);

                if (!TextureFormatHelper.IsCompressed(Format))
                {
                    GL.TexSubImage3D(TextureTarget.Texture2DArray, mipLevel, 0, 0, 0, Width, Height, ArraySize, format.Item2, format.Item3, data.Pointer);
                }
                else
                {
                    GL.CompressedTexImage3D(TextureTarget.Texture2DArray, mipLevel, format.Item1, Width, Height, ArraySize, 0, data.Size, data.Pointer);
                }

                GL.TexParameter(TextureTarget.Texture2DArray, TextureParameterName.TextureMaxLevel, this.MipLevels - 1);
            }
            else if (graphicsDevice.OpenGLCapabilities.DirectStateAccess == DirectStateAccess.Extension)
            {
                if (!TextureFormatHelper.IsCompressed(Format))
                {
                    Ext.TextureSubImage3D(TextureID, (OpenTK.Graphics.OpenGL.TextureTarget)TextureTarget.Texture2DArray, mipLevel, 0, 0, 0, Width, Height, ArraySize, (OpenTK.Graphics.OpenGL.PixelFormat)format.Item2, (OpenTK.Graphics.OpenGL.PixelType)format.Item3, data.Pointer);
                }
                else
                {
                    Ext.CompressedTextureImage3D(TextureID, (OpenTK.Graphics.OpenGL.TextureTarget)TextureTarget.Texture2DArray, mipLevel, (OpenTK.Graphics.OpenGL.ExtDirectStateAccess)EnumConverter.Convert(Format).Item1, Width, Height, ArraySize, 0, Marshal.SizeOf(data), data.Pointer);
                }

                OpenTK.Graphics.OpenGL.GL.Ext.TextureParameter(TextureID, (OpenTK.Graphics.OpenGL.TextureTarget)TextureTarget.Texture2DArray, OpenTK.Graphics.OpenGL.TextureParameterName.TextureMaxLevel, this.MipLevels - 1);
            }
            else if (graphicsDevice.OpenGLCapabilities.DirectStateAccess == DirectStateAccess.Core)
            {
                //OpenGL 4.5
            }

            graphicsDevice.CheckGLError("Texture2DArray SetData");
        }
Ejemplo n.º 6
0
        internal Texture2DArray(GraphicsDevice graphicsDevice, int width, int height, int arraySize, TextureFormat format, int mipLevels, ResourceUsage usage = ResourceUsage.Normal, params DataRectangle[] data)
            : base(graphicsDevice, new System.Diagnostics.StackTrace(1))
        {
            if (width <= 0)
            {
                throw new ArgumentOutOfRangeException("width", "Width must be positive.");
            }
            if (height <= 0)
            {
                throw new ArgumentOutOfRangeException("height", "Height must be positive.");
            }
            if (mipLevels < 0)
            {
                throw new ArgumentOutOfRangeException("mipLevels", "MipLevels must not be negative.");
            }
            if (format == TextureFormat.Unknown)
            {
                throw new ArgumentException("Format must not be TextureFormat.Unknown.", "format");
            }
            if (width > graphicsDevice.OpenGLCapabilities.MaxTextureSize)
            {
                throw new PlatformNotSupportedException("width exceeds the maximum texture size");
            }
            if (height > graphicsDevice.OpenGLCapabilities.MaxTextureSize)
            {
                throw new PlatformNotSupportedException("height exceeds the maximum texture size");
            }
            if (width != height)
            {
                throw new PlatformNotSupportedException("Texture arrays must be quadratic");
            }
            if (arraySize <= 0)
            {
                throw new ArgumentOutOfRangeException("Array Size must be at least one", "arraySize");
            }
            if (data != null && data.Length != 0 && data.Length < mipLevels * arraySize)
            {
                throw new ArgumentOutOfRangeException("data", data.Length, string.Format("data Lenght is too small for specified arraySize and mipLevels, expected: {0}", mipLevels * arraySize));
            }

            this.Width     = width;
            this.Height    = height;
            this.ArraySize = arraySize;
            this.MipLevels = mipLevels > 0 ? mipLevels : 1;
            this.Format    = format;
            this.Usage     = usage;
            var internalFormat = EnumConverter.Convert(Format);

            this.TextureID = GL.GenTexture();
            if (graphicsDevice.OpenGLCapabilities.DirectStateAccess == DirectStateAccess.None)
            {
                graphicsDevice.BindManager.SetTexture(this, 0);
                GL.TexParameter(TextureTarget.Texture2DArray, TextureParameterName.TextureMaxLevel, this.MipLevels - 1);
                if (!TextureFormatHelper.IsCompressed(Format))
                {
                    if (graphicsDevice.OpenGLCapabilities.SupportsTextureStorage && graphicsDevice.OpenGLCapabilities.OpenGLVersion > new Version(4, 2))
                    {
                        GL.TexStorage3D(TextureTarget3d.Texture2DArray, MipLevels, EnumConverter.ConvertSizedInternalFormat(Format), Width, Height, ArraySize);
                    }
                    else
                    {
                        GL.TexImage3D(TextureTarget.Texture2DArray, 0, internalFormat.Item1, width, height, arraySize, 0, internalFormat.Item2, internalFormat.Item3, IntPtr.Zero);
                    }
                }
            }
            else if (graphicsDevice.OpenGLCapabilities.DirectStateAccess == DirectStateAccess.Extension)
            {
                Ext.TextureParameter(TextureID, OpenTK.Graphics.OpenGL.TextureTarget.Texture2D, OpenTK.Graphics.OpenGL.TextureParameterName.TextureMaxLevel, this.MipLevels - 1);
                if (!TextureFormatHelper.IsCompressed(Format))
                {
                    if (graphicsDevice.OpenGLCapabilities.SupportsTextureStorage && graphicsDevice.OpenGLCapabilities.OpenGLVersion > new Version(4, 2))
                    {
                        Ext.TextureStorage3D(TextureID, (OpenTK.Graphics.OpenGL.ExtDirectStateAccess)TextureTarget3d.Texture2DArray, MipLevels, (OpenTK.Graphics.OpenGL.ExtDirectStateAccess)EnumConverter.ConvertSizedInternalFormat(Format), Width, Height, ArraySize);
                    }
                    else
                    {
                        Ext.TextureImage3D(TextureID, (OpenTK.Graphics.OpenGL.TextureTarget)TextureTarget.Texture3D, 0, (int)internalFormat.Item1, width, height, arraySize, 0, (OpenTK.Graphics.OpenGL.PixelFormat)internalFormat.Item2, (OpenTK.Graphics.OpenGL.PixelType)internalFormat.Item3, IntPtr.Zero);
                    }
                }
            }
            else if (graphicsDevice.OpenGLCapabilities.DirectStateAccess == DirectStateAccess.Core)
            {
            }

            if (data != null)
            {
                for (int i = 0; i < data.Length; i++)
                {
                    int arrayIndex = i / MipLevels;
                    int mipIndex   = i - arrayIndex * MipLevels; //Macht Sinn weil int gerundet wird
                    SetData(data[i], arrayIndex, 0);
                }
            }

            graphicsDevice.CheckGLError();
        }
Ejemplo n.º 7
0
        public void DrawIndexed(int indexCount, int firstIndexLocation, int firstVertexLocation)
        {
            if (currentVertexBuffer == null)
            {
                throw new InvalidOperationException("Tried to draw without a vertexbuffer set.");
            }
            if (currentIndexBuffer == null)
            {
                throw new InvalidOperationException("Tried to draw without an indexbuffer set.");
            }

            ApplyState();
            GL.DrawElements((BeginMode)EnumConverter.Convert(currentState.PrimitiveType), indexCount, EnumConverter.Convert(currentIndexBuffer.Format), firstVertexLocation * graphicsDevice.GetSizeOf(currentIndexBuffer.Format));
        }
Ejemplo n.º 8
0
        private void ApplyState()
        {
            if (currentState.Shader == null)
            {
                throw new InvalidOperationException("A shader is not set to the render context.");
            }

            var shader = graphicsDevice.Cast <Shader>(currentState.Shader, "currentState.Shader");

            graphicsDevice.BindManager.Shader = shader;

            if (currentState.Rasterizer != null && currentState.Rasterizer != currentRasterizer)
            {
                RasterizerState rasterizer = graphicsDevice.Cast <RasterizerState>(currentState.Rasterizer, "currentState.Rasterizer");

                rasterizer.Apply(currentRasterizer);
                currentRasterizer = rasterizer;
            }

            if (currentState.Blend != null && currentState.Blend != currentBlend)
            {
                BlendState blend = graphicsDevice.Cast <BlendState>(currentState.Blend, "currentState.Blend");

                blend.Apply(currentBlend);
                currentBlend = blend;
            }

            if (currentState.DepthStencil != null && currentState.DepthStencil != currentDepthStencil)
            {
                DepthStencilState depthStencil = graphicsDevice.Cast <DepthStencilState>(currentState.DepthStencil, "currentState.DepthStencil");

                depthStencil.Apply(currentDepthStencil, currentStencilReference);
                currentDepthStencil = depthStencil;
            }

            // Das VertexArrayObject speichert die Attribute calls eines bestimmten Shaders
            // Falls ein anderer Shader gesetzt ist oder diese Attribute gesetzt sind, müssen diese VertexAttributePointer gesetzt werden

            if (currentVertexBuffer.Shader != currentState.Shader)
            {
                if (!currentState.Shader.VertexDescription.EqualsIgnoreOrder(currentVertexBuffer.Description))
                {
                    throw new GraphicsException("Current shader VertexDescription doesn't match the description of the current VertexBuffer");
                }

                VertexElement[] elements = currentVertexBuffer.Description.GetElements();
                for (int i = 0; i < currentVertexBuffer.Description.ElementCount; i++)
                {
                    GL.BindAttribLocation(shader.ProgramID, i, EnumConverter.Convert(elements[i].Usage));
                }

                currentVertexBuffer.Shader = shader;
            }

            if (!graphicsDevice.OpenGLCapabilities.VertexAttribBinding)
            {
                graphicsDevice.BindManager.VertexArray = currentVertexBuffer.VaoID;

                if (currentVertexBuffer.LayoutDirty)
                {
                    if (!currentState.Shader.VertexDescription.EqualsIgnoreOrder(currentVertexBuffer.Description))
                    {
                        throw new GraphicsException("Current shader VertexDescription doesn't match the description of the current VertexBuffer");
                    }

                    graphicsDevice.BindManager.VertexBuffer = currentVertexBuffer;

                    int             offset   = 0;
                    VertexElement[] elements = currentVertexBuffer.Description.GetElements();
                    for (int i = 0; i < graphicsDevice.OpenGLCapabilities.MaxVertexAttribs; i++)
                    {
                        if (i < currentVertexBuffer.Description.ElementCount)
                        {
                            GL.EnableVertexAttribArray(i);

                            GL.VertexAttribPointer(i, graphicsDevice.GetComponentsOf(elements[i].Type), VertexAttribPointerType.Float, false, graphicsDevice.GetSizeOf(currentVertexBuffer.Description), offset);
                            offset += graphicsDevice.GetSizeOf(elements[i].Type);
                        }
                        else
                        {
                            GL.DisableVertexAttribArray(i);
                        }
                    }

                    currentVertexBuffer.LayoutDirty = false;
                }
            }
            else
            {
                if (!currentState.Shader.VertexDescription.EqualsIgnoreOrder(currentVertexBuffer.Description))
                {
                    throw new GraphicsException("Current shader VertexDescription doesn't match the description of the current VertexBuffer");
                }

                graphicsDevice.BindManager.VertexBuffer = null;
                int layout = graphicsDevice.GetLayout(currentVertexBuffer.Description, graphicsDevice.Cast <Shader>(currentState.Shader, "currentState.shader"));
                graphicsDevice.BindManager.VertexArray = layout;

                graphicsDevice.BindManager.SetVertexBuffer(0, currentVertexBuffer);
            }

            graphicsDevice.BindManager.IndexBuffer = currentIndexBuffer;

            graphicsDevice.CheckGLError("RenderContext.ApplyState");
        }
Ejemplo n.º 9
0
        internal Sampler(GraphicsDevice graphicsDevice, SamplerInfo info)
            : base(graphicsDevice, new System.Diagnostics.StackTrace(1))
        {
            Info = info;

            if ((Info.MagFilter == TextureFilter.Anisotropic || Info.MinFilter == TextureFilter.Anisotropic) && (!graphicsDevice.OpenGLCapabilities.SupportsAnisotropicFiltering || Info.MaximumAnisotropy > graphicsDevice.OpenGLCapabilities.MaxAnisotropicFiltering))
            {
                throw new PlatformNotSupportedException("Anisotropic filtering is not supported at that level or at all.");
            }

            if (Info.MaximumAnisotropy == 0 && (Info.MagFilter == TextureFilter.Anisotropic || Info.MinFilter == TextureFilter.Anisotropic))
            {
                throw new ArgumentException("MaximumAnisotropy must not be 0");
            }

            if (Info.MipLodBias > graphicsDevice.OpenGLCapabilities.MaxTextureLoDBias)
            {
                throw new PlatformNotSupportedException("MipLoDBias is higher than max lod bias.");
            }


            SamplerID = GL.GenSampler();

            //AddressMode
            GL.SamplerParameter(SamplerID, SamplerParameterName.TextureWrapS, (float)EnumConverter.Convert(Info.AddressU));
            GL.SamplerParameter(SamplerID, SamplerParameterName.TextureWrapT, (float)EnumConverter.Convert(Info.AddressV));
            GL.SamplerParameter(SamplerID, SamplerParameterName.TextureWrapR, (float)EnumConverter.Convert(Info.AddressW));
            graphicsDevice.CheckGLError();

            //Filtering
            Tuple <TextureMinFilter, TextureMagFilter> filter = EnumConverter.Convert(Info.MinFilter, Info.MagFilter, Info.MipFilter);
            TextureMinFilter min = (TextureMinFilter)filter.Item1;
            TextureMagFilter mag = (TextureMagFilter)filter.Item2;

            GL.SamplerParameter(SamplerID, SamplerParameterName.TextureMinFilter, (float)min);
            GL.SamplerParameter(SamplerID, SamplerParameterName.TextureMagFilter, (float)mag);
            GL.SamplerParameter(SamplerID, SamplerParameterName.TextureMaxAnisotropyExt, Info.MaximumAnisotropy);

            //Border color
            GL.SamplerParameter(SamplerID, SamplerParameterName.TextureBorderColor, new float[] { Info.BorderColor.R, Info.BorderColor.G, Info.BorderColor.B, Info.BorderColor.A });

            //Compare modes
            if (Info.Type == SamplerType.Comparison)
            {
                GL.SamplerParameter(SamplerID, SamplerParameterName.TextureCompareMode, (float)TextureCompareMode.CompareRefToTexture);
                GL.SamplerParameter(SamplerID, SamplerParameterName.TextureCompareFunc, (float)EnumConverter.Convert(Info.ComparisonFunction));
            }
            else
            {
                GL.SamplerParameter(SamplerID, SamplerParameterName.TextureCompareMode, (float)TextureCompareMode.None);
            }

            //LoD
            GL.SamplerParameter(SamplerID, SamplerParameterName.TextureMinLod, Info.MinimumLod);
            GL.SamplerParameter(SamplerID, SamplerParameterName.TextureMaxLod, Info.MaximumLod);
            GL.SamplerParameter(SamplerID, SamplerParameterName.TextureLodBias, Info.MipLodBias);


            graphicsDevice.CheckGLError();
        }