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(); }
internal Shader(GraphicsDevice graphicsDevice, byte[] binaryCode) : base(graphicsDevice, new System.Diagnostics.StackTrace(1)) { this.binaryCode = binaryCode; ProgramID = GL.CreateProgram(); using (MemoryStream stream = new MemoryStream(binaryCode)) using (BinaryReader reader = new BinaryReader(stream)) { if (reader.ReadString() != "OPENGL4") { throw new ArgumentException("Invalid header of binary code.", "binaryCode"); } int format = reader.ReadInt32(); int codeSize = reader.ReadInt32(); byte[] code = reader.ReadBytes(codeSize); GL.ProgramBinary(ProgramID, (BinaryFormat)format, code, code.Length); int linkStatus; GL.GetProgram(ProgramID, GetProgramParameterName.LinkStatus, out linkStatus); if (linkStatus == 0) { throw new GraphicsException(GL.GetProgramInfoLog(ProgramID)); } graphicsDevice.CheckGLError(); } FindUniforms(); FindUniformBlocks(); }
public IndexBuffer(GraphicsDevice graphicsDevice, IndexFormat format, ResourceUsage usage, int indexCount) : base(graphicsDevice, new System.Diagnostics.StackTrace(1)) { if (indexCount <= 0) { throw new ArgumentOutOfRangeException("indexCount", indexCount, "indexCount must be bigger than zero."); } if (usage == ResourceUsage.Immutable) { throw new ArgumentException("data", "Immutable buffers must be initialized with data."); } EnumConverter.Convert(Format); //Check whether format is supported this.Usage = usage; this.Format = format; SizeBytes = indexCount * graphicsDevice.GetSizeOf(format); IboID = GL.GenBuffer(); if (graphicsDevice.OpenGLCapabilities.DirectStateAccess == DirectStateAccess.None) { graphicsDevice.BindManager.IndexBuffer = this; GL.BufferData(BufferTarget.ElementArrayBuffer, new IntPtr(SizeBytes), IntPtr.Zero, EnumConverter.Convert(Usage)); } else if (graphicsDevice.OpenGLCapabilities.DirectStateAccess == DirectStateAccess.Extension) { OpenTK.Graphics.OpenGL.GL.Ext.NamedBufferData(IboID, new IntPtr(SizeBytes), IntPtr.Zero, (OpenTK.Graphics.OpenGL.ExtDirectStateAccess)EnumConverter.Convert(Usage)); } graphicsDevice.CheckGLError("IndexBuffer Constructor"); }
public IndexBuffer(GraphicsDevice graphicsDevice, IndexFormat format, ResourceUsage usage, DataArray data) : base(graphicsDevice, new System.Diagnostics.StackTrace(1)) { 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."); } EnumConverter.Convert(Format); //Check whether format is supported this.Usage = usage; this.Format = format; IboID = GL.GenBuffer(); if (!data.IsNull) { SizeBytes = data.Size; if (graphicsDevice.OpenGLCapabilities.DirectStateAccess == DirectStateAccess.None) { graphicsDevice.BindManager.IndexBuffer = this; GL.BufferData(BufferTarget.ElementArrayBuffer, new IntPtr(SizeBytes), data.Pointer, EnumConverter.Convert(Usage)); } else if (graphicsDevice.OpenGLCapabilities.DirectStateAccess == DirectStateAccess.Extension) { OpenTK.Graphics.OpenGL.GL.Ext.NamedBufferData(IboID, new IntPtr(SizeBytes), data.Pointer, (OpenTK.Graphics.OpenGL.ExtDirectStateAccess)EnumConverter.Convert(Usage)); } } graphicsDevice.CheckGLError("IndexBuffer Constructor"); }
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"); }
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"); }
internal ShaderPart(GraphicsDevice graphicsDevice, string shaderSource, ShaderType shaderType) { //Comile and attach Vertex shader ID = GL.CreateShader(shaderType); GL.ShaderSource(ID, shaderSource); GL.CompileShader(ID); int vertexShaderStatus; GL.GetShader(ID, ShaderParameter.CompileStatus, out vertexShaderStatus); if (vertexShaderStatus == 0) { throw new DotGame.Graphics.GraphicsException(string.Format("{0}: {1}", shaderType.ToString(), GL.GetShaderInfoLog(ID))); } graphicsDevice.CheckGLError(); }
internal VertexBuffer(GraphicsDevice graphicsDevice, VertexDescription description, ResourceUsage usage, DataArray data) : base(graphicsDevice, new System.Diagnostics.StackTrace(1)) { 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."); } this.Description = description; this.Usage = usage; VboID = GL.GenBuffer(); if (!graphicsDevice.OpenGLCapabilities.VertexAttribBinding) { VaoID = GL.GenVertexArray(); LayoutDirty = true; } if (!data.IsNull) { SizeBytes = data.Size; if (graphicsDevice.OpenGLCapabilities.DirectStateAccess == DirectStateAccess.None) { graphicsDevice.BindManager.VertexBuffer = this; GL.BufferData(BufferTarget.ArrayBuffer, new IntPtr(SizeBytes), data.Pointer, EnumConverter.Convert(Usage)); } else if (graphicsDevice.OpenGLCapabilities.DirectStateAccess == DirectStateAccess.Extension) { OpenTK.Graphics.OpenGL.GL.Ext.NamedBufferData(VboID, new IntPtr(SizeBytes), data.Pointer, (OpenTK.Graphics.OpenGL.ExtDirectStateAccess)EnumConverter.Convert(Usage)); } } graphicsDevice.CheckGLError("VertexBuffer Constructor"); }
internal VertexBuffer(GraphicsDevice graphicsDevice, VertexDescription description, ResourceUsage usage, int vertexCount) : base(graphicsDevice, new System.Diagnostics.StackTrace(1)) { if (vertexCount <= 0) { throw new ArgumentException("vertexCount must not be smaller than/ equal to zero.", "vertexCount"); } if (usage == ResourceUsage.Immutable) { throw new ArgumentException("data", "Immutable buffers must be initialized with data."); } this.Description = description; this.Usage = usage; VboID = GL.GenBuffer(); if (!graphicsDevice.OpenGLCapabilities.VertexAttribBinding) { VaoID = GL.GenVertexArray(); LayoutDirty = true; } SizeBytes = vertexCount * graphicsDevice.GetSizeOf(description); if (graphicsDevice.OpenGLCapabilities.DirectStateAccess == DirectStateAccess.None) { graphicsDevice.BindManager.VertexBuffer = this; GL.BufferData(BufferTarget.ArrayBuffer, new IntPtr(SizeBytes), IntPtr.Zero, EnumConverter.Convert(Usage)); } else if (graphicsDevice.OpenGLCapabilities.DirectStateAccess == DirectStateAccess.Extension) { OpenTK.Graphics.OpenGL.GL.Ext.NamedBufferData(VboID, new IntPtr(SizeBytes), IntPtr.Zero, (OpenTK.Graphics.OpenGL.ExtDirectStateAccess)EnumConverter.Convert(Usage)); } graphicsDevice.CheckGLError("VertexBuffer Constructor"); }
} internal Texture3D(GraphicsDevice graphicsDevice, int width, int height, int length, TextureFormat format, bool generateMipMaps, ResourceUsage usage = ResourceUsage.Normal, DataBox data = new DataBox()) : 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 || length % 2 != 0) && graphicsDevice.OpenGLCapabilities.SupportsNonPowerOf2Textures) { throw new PlatformNotSupportedException("Driver doesn't support non power of two textures"); } if (length > graphicsDevice.OpenGLCapabilities.MaxTextureSize) { throw new PlatformNotSupportedException("length exceeds the maximum texture size"); } if (usage == ResourceUsage.Immutable && (data.IsNull)) { throw new ArgumentException("data", "Immutable textures must be initialized with data."); } this.Width = width; this.Height = height; this.Length = length; 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); //Höchstes Mipmap-Level setzen GL.TexParameter(TextureTarget.Texture3D, TextureParameterName.TextureMaxLevel, this.MipLevels - 1); //Die Textur erstellen (Null Daten funktionieren nicht mit Compression) if (graphicsDevice.OpenGLCapabilities.SupportsTextureStorage && graphicsDevice.OpenGLCapabilities.OpenGLVersion > new Version(4, 2)) { GL.TexStorage3D(TextureTarget3d.Texture3D, MipLevels, EnumConverter.ConvertSizedInternalFormat(Format), Width, Height, Length); } else { int size = 0; IntPtr ptr = IntPtr.Zero; if (!data.IsNull) { size = data.Size; ptr = data.Pointer; } if (!TextureFormatHelper.IsCompressed(Format)) { GL.TexImage3D(TextureTarget.Texture3D, 0, internalFormat.Item1, width, height, length, 0, internalFormat.Item2, internalFormat.Item3, ptr); } else if (ptr != IntPtr.Zero) { GL.CompressedTexImage3D(TextureTarget.Texture3D, 0, internalFormat.Item1, width, height, length, 0, size, ptr); isInitialized = true; } } } else if (graphicsDevice.OpenGLCapabilities.DirectStateAccess == DirectStateAccess.Extension) { //Höchstes Mipmap-Level setzen OpenTK.Graphics.OpenGL.GL.Ext.TextureParameter(TextureID, OpenTK.Graphics.OpenGL.TextureTarget.Texture3D, OpenTK.Graphics.OpenGL.TextureParameterName.TextureMaxLevel, this.MipLevels - 1); //Die Textur erstellen (Null Daten funktionieren nicht mit Compression) if (graphicsDevice.OpenGLCapabilities.SupportsTextureStorage && graphicsDevice.OpenGLCapabilities.OpenGLVersion > new Version(4, 2) && !TextureFormatHelper.IsCompressed(Format)) { Ext.TextureStorage3D(TextureID, (OpenTK.Graphics.OpenGL.ExtDirectStateAccess)TextureTarget3d.Texture3D, MipLevels, (OpenTK.Graphics.OpenGL.ExtDirectStateAccess)EnumConverter.ConvertSizedInternalFormat(Format), Width, Height, Length); } else { int size = 0; IntPtr ptr = IntPtr.Zero; if (!data.IsNull) { size = data.Size; ptr = data.Pointer; } if (!TextureFormatHelper.IsCompressed(Format)) { Ext.TextureImage3D(TextureID, (OpenTK.Graphics.OpenGL.TextureTarget)TextureTarget.Texture3D, 0, (int)internalFormat.Item1, width, height, length, 0, (OpenTK.Graphics.OpenGL.PixelFormat)internalFormat.Item2, (OpenTK.Graphics.OpenGL.PixelType)internalFormat.Item3, ptr); } else if (ptr != IntPtr.Zero) { Ext.CompressedTextureImage3D(TextureID, OpenTK.Graphics.OpenGL.TextureTarget.Texture3D, 0, (OpenTK.Graphics.OpenGL.ExtDirectStateAccess)internalFormat.Item1, width, height, length, 0, size, ptr); isInitialized = true; } } } else if (graphicsDevice.OpenGLCapabilities.DirectStateAccess == DirectStateAccess.Core) { } graphicsDevice.CheckGLError("Texture3D Constructor"); }
internal Texture2D(GraphicsDevice graphicsDevice, int width, int height, 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 (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 < mipLevels) { throw new ArgumentOutOfRangeException("data", data.Length, string.Format("data Lenght is too small for specified mipLevels, expected: {0}", mipLevels)); } this.Width = width; this.Height = height; this.Format = format; this.Usage = usage; var internalFormat = EnumConverter.Convert(Format); this.MipLevels = mipLevels > 0 ? mipLevels : 1; this.TextureID = GL.GenTexture(); if (graphicsDevice.OpenGLCapabilities.DirectStateAccess == DirectStateAccess.None) { graphicsDevice.BindManager.SetTexture(this, 0); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMaxLevel, this.MipLevels - 1); if (graphicsDevice.OpenGLCapabilities.SupportsTextureStorage && graphicsDevice.OpenGLCapabilities.OpenGLVersion > new Version(4, 2) && !TextureFormatHelper.IsCompressed(Format)) { GL.TexStorage2D(TextureTarget2d.Texture2D, MipLevels, EnumConverter.ConvertSizedInternalFormat(Format), Width, Height); } else { int size = 0; IntPtr ptr = IntPtr.Zero; if (data != null && data.Length > 0) { size = data[0].Size; ptr = data[0].Pointer; } if (!TextureFormatHelper.IsCompressed(Format)) { GL.TexImage2D(TextureTarget.Texture2D, 0, internalFormat.Item1, width, height, 0, internalFormat.Item2, internalFormat.Item3, ptr); } else if (ptr != IntPtr.Zero) { GL.CompressedTexImage2D(TextureTarget.Texture2D, 0, internalFormat.Item1, width, height, 0, size, ptr); } } } else if (graphicsDevice.OpenGLCapabilities.DirectStateAccess == DirectStateAccess.Extension) { OpenTK.Graphics.OpenGL.GL.Ext.TextureParameter(TextureID, OpenTK.Graphics.OpenGL.TextureTarget.Texture2D, OpenTK.Graphics.OpenGL.TextureParameterName.TextureMaxLevel, this.MipLevels - 1); if (graphicsDevice.OpenGLCapabilities.SupportsTextureStorage && graphicsDevice.OpenGLCapabilities.OpenGLVersion > new Version(4, 2) && !TextureFormatHelper.IsCompressed(Format)) { Ext.TextureStorage2D(TextureID, (OpenTK.Graphics.OpenGL.ExtDirectStateAccess)TextureTarget2d.Texture2D, MipLevels, (OpenTK.Graphics.OpenGL.ExtDirectStateAccess)EnumConverter.ConvertSizedInternalFormat(Format), Width, Height); } else { int size = 0; IntPtr ptr = IntPtr.Zero; if (data != null && data.Length > 0) { size = data[0].Size; ptr = data[0].Pointer; } if (!TextureFormatHelper.IsCompressed(Format)) { Ext.TextureImage2D(TextureID, (OpenTK.Graphics.OpenGL.TextureTarget)TextureTarget.Texture2D, 0, (int)internalFormat.Item1, width, height, 0, (OpenTK.Graphics.OpenGL.PixelFormat)internalFormat.Item2, (OpenTK.Graphics.OpenGL.PixelType)internalFormat.Item3, ptr); } else if (ptr != IntPtr.Zero) { Ext.CompressedTextureImage2D(TextureID, (OpenTK.Graphics.OpenGL.TextureTarget)TextureTarget.Texture2D, 0, (OpenTK.Graphics.OpenGL.ExtDirectStateAccess)internalFormat.Item1, width, height, 0, size, ptr); isInitialized = true; } } } else if (graphicsDevice.OpenGLCapabilities.DirectStateAccess == DirectStateAccess.Core) { } graphicsDevice.CheckGLError("Texture2D Constructor"); if (data != null && data.Length > 1) { for (int i = 1; i < data.Length; i++) { SetData(data[i], i); } } }
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(); }
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(); }