private void PlatformConstruct(GraphicsDevice graphicsDevice, int size, bool mipMap, SurfaceFormat format, bool renderTarget) { this.glTarget = TextureTarget.TextureCubeMap; Threading.BlockOnUIThread(() => { #if IOS || ANDROID GL.GenTextures(1, ref this.glTexture); #else GL.GenTextures(1, out this.glTexture); #endif GraphicsExtensions.CheckGLError(); GL.BindTexture(TextureTarget.TextureCubeMap, this.glTexture); GraphicsExtensions.CheckGLError(); GL.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.TextureMinFilter, mipMap ? (int)TextureMinFilter.LinearMipmapLinear : (int)TextureMinFilter.Linear); GraphicsExtensions.CheckGLError(); GL.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear); GraphicsExtensions.CheckGLError(); GL.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.TextureWrapS, (int)TextureWrapMode.ClampToEdge); GraphicsExtensions.CheckGLError(); GL.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.TextureWrapT, (int)TextureWrapMode.ClampToEdge); GraphicsExtensions.CheckGLError(); format.GetGLFormat(out glInternalFormat, out glFormat, out glType); for (int i = 0; i < 6; i++) { TextureTarget target = GetGLCubeFace((CubeMapFace)i); if (glFormat == (PixelFormat)All.CompressedTextureFormats) { throw new NotImplementedException(); } else { #if IOS || ANDROID GL.TexImage2D(target, 0, (int)glInternalFormat, size, size, 0, glFormat, glType, IntPtr.Zero); #else GL.TexImage2D(target, 0, glInternalFormat, size, size, 0, glFormat, glType, IntPtr.Zero); #endif GraphicsExtensions.CheckGLError(); } } if (mipMap) { #if IOS || ANDROID GL.GenerateMipmap(TextureTarget.TextureCubeMap); #else GL.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.GenerateMipmap, (int)All.True); #endif GraphicsExtensions.CheckGLError(); } }); }
private void PlatformConstruct(GraphicsDevice graphicsDevice, int width, int height, int depth, bool mipMap, SurfaceFormat format, bool renderTarget) { #if GLES throw new NotSupportedException("OpenGL ES 2.0 doesn't support 3D textures."); #else this.glTarget = TextureTarget.Texture3D; Threading.BlockOnUIThread(() => { GL.GenTextures(1, out this.glTexture); GraphicsExtensions.CheckGLError(); GL.BindTexture(glTarget, glTexture); GraphicsExtensions.CheckGLError(); format.GetGLFormat(GraphicsDevice, out glInternalFormat, out glFormat, out glType); GL.TexImage3D(glTarget, 0, glInternalFormat, width, height, depth, 0, glFormat, glType, IntPtr.Zero); GraphicsExtensions.CheckGLError(); }); if (mipMap) { throw new NotImplementedException("Texture3D does not yet support mipmaps."); } #endif }
public TextureCube(int size, bool mipMap, SurfaceFormat format) { ID = GL.GenTexture(); Size = size; Format = format; Format.GetGLFormat(out glInternalFormat, out glFormat, out glType); LevelCount = mipMap ? CalculateMipLevels(size, size) : 1; if (glFormat == GL.GL_NUM_COMPRESSED_TEXTURE_FORMATS) { throw new NotImplementedException("Compressed cubemaps"); } //Bind the new TextureCube BindTo(0); //enable filtering GL.TexParameteri(GL.GL_TEXTURE_CUBE_MAP, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR); GL.TexParameteri(GL.GL_TEXTURE_CUBE_MAP, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR); //initialise for (int i = 0; i < 6; i++) { var target = ((CubeMapFace)i).ToGL(); GL.TexImage2D(target, 0, glInternalFormat, size, size, 0, glFormat, glType, IntPtr.Zero); } if (mipMap) { //This isn't actually supported on GL 3, why is it here? //GL.TexParameteri(GL.GL_TEXTURE_CUBE_MAP, TextureParameterName.GenerateMipmap, 1); } }
private void PlatformConstruct( GraphicsDevice graphicsDevice, int width, int height, int depth, bool mipMap, SurfaceFormat format, bool renderTarget) { if (GL.IsES) { throw new PlatformNotSupportedException("OpenGL ES 2.0 doesn't support 3D textures."); } _glTarget = TextureTarget.Texture3D; if (mipMap) { throw new NotImplementedException(nameof(Texture3D) + " does not yet support mipmaps."); } _glTexture = GL.GenTexture(); GL.CheckError(); GL.BindTexture(_glTarget, _glTexture); GL.CheckError(); format.GetGLFormat(GraphicsDevice, out _glInternalFormat, out _glFormat, out _glType); GL.TexImage3D(_glTarget, 0, _glInternalFormat, width, height, depth, 0, _glFormat, _glType, IntPtr.Zero); GL.CheckError(); }
public TextureCube(int size, bool mipMap, SurfaceFormat format) { ID = GL.GenTexture(); Size = size; Format = format; Format.GetGLFormat(out glInternalFormat, out glFormat, out glType); LevelCount = mipMap ? CalculateMipLevels(size, size) : 1; //Bind the new TextureCube BindTo(4); //enable filtering GL.TexParameteri(GL.GL_TEXTURE_CUBE_MAP, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR); GL.TexParameteri(GL.GL_TEXTURE_CUBE_MAP, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR); //initialise if (glFormat == GL.GL_NUM_COMPRESSED_TEXTURE_FORMATS) { int imageSize = 0; if (GLExtensions.S3TC) { switch (Format) { case SurfaceFormat.Dxt1: case SurfaceFormat.Dxt3: case SurfaceFormat.Dxt5: imageSize = ((size + 3) / 4) * ((size + 3) / 4) * format.GetSize(); break; default: throw new NotSupportedException(); } } for (int i = 0; i < 6; i++) { var target = ((CubeMapFace)i).ToGL(); if (GLExtensions.S3TC) { GL.CompressedTexImage2D(target, 0, glInternalFormat, size, size, 0, imageSize, IntPtr.Zero); } else { GL.TexImage2D(target, 0, GL.GL_RGBA, size, size, 0, GL.GL_BGRA, GL.GL_UNSIGNED_BYTE, IntPtr.Zero); } } } else { for (int i = 0; i < 6; i++) { var target = ((CubeMapFace)i).ToGL(); GL.TexImage2D(target, 0, glInternalFormat, size, size, 0, glFormat, glType, IntPtr.Zero); } } }
/// <summary> /// /// </summary> /// <param name="width"></param> /// <param name="height"></param> /// <param name="mipmap"></param> /// <param name="format"></param> /// <param name="type"></param> /// <param name="shared"></param> private void PlatformConstruct(int width, int height, bool mipmap, SurfaceFormat format, SurfaceType type, bool shared) { this.glTarget = TextureTarget.Texture2D; Threading.BlockOnUIThread(() => { //Store the current bound texture var prevTexture = GraphicsExtensions.GetBoundTexture2D(); GenerateGLTextureIfRequired(); format.GetGLFormat(GraphicsDevice, out glInternalFormat, out glFormat, out glType); if (glFormat == (PixelFormat)GLPixelFormat.CompressedTextureFormats) { } else { GL.TexImage2D(TextureTarget.Texture2D, 0, glInternalFormat, this.width, this.height, 0, glFormat, glType, IntPtr.Zero); GraphicsExtensions.CheckGLError(); } if (mipmap) { #if IOS || ANDROID GL.GenerateMipmap(TextureTarget.TextureCubeMap); #else #endif } GL.BindTexture(TextureTarget.Texture2D, prevTexture); GraphicsExtensions.CheckGLError(); }); }
private void PlatformConstruct(int width, int height, bool mipmap, SurfaceFormat format, SurfaceType type, bool shared) { this.glTarget = TextureTarget.Texture2D; format.GetGLFormat(GraphicsDevice, out glInternalFormat, out glFormat, out glType); Threading.BlockOnUIThread(() => { GenerateGLTextureIfRequired(); int w = width; int h = height; int level = 0; while (true) { if (glFormat == (PixelFormat)GLPixelFormat.CompressedTextureFormats) { int imageSize = 0; // PVRTC has explicit calculations for imageSize // https://www.khronos.org/registry/OpenGL/extensions/IMG/IMG_texture_compression_pvrtc.txt if (format == SurfaceFormat.RgbPvrtc2Bpp || format == SurfaceFormat.RgbaPvrtc2Bpp) { imageSize = (Math.Max(w, 16) * Math.Max(h, 8) * 2 + 7) / 8; } else if (format == SurfaceFormat.RgbPvrtc4Bpp || format == SurfaceFormat.RgbaPvrtc4Bpp) { imageSize = (Math.Max(w, 8) * Math.Max(h, 8) * 4 + 7) / 8; } else { int blockSize = format.GetSize(); int blockWidth, blockHeight; format.GetBlockSize(out blockWidth, out blockHeight); int wBlocks = (w + (blockWidth - 1)) / blockWidth; int hBlocks = (h + (blockHeight - 1)) / blockHeight; imageSize = wBlocks * hBlocks * blockSize; } GL.CompressedTexImage2D(TextureTarget.Texture2D, level, glInternalFormat, w, h, 0, imageSize, IntPtr.Zero); GraphicsExtensions.CheckGLError(); } else { GL.TexImage2D(TextureTarget.Texture2D, level, glInternalFormat, w, h, 0, glFormat, glType, IntPtr.Zero); GraphicsExtensions.CheckGLError(); } if ((w == 1 && h == 1) || !mipmap) { break; } if (w > 1) { w = w / 2; } if (h > 1) { h = h / 2; } ++level; } }); }
private void PlatformConstruct(int width, int height, bool mipmap, SurfaceFormat format, SurfaceType type, bool shared) { 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) * GraphicsExtensions.GetSize(format); 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, glInternalFormat, this.width, this.height, 0, glFormat, glType, IntPtr.Zero); GraphicsExtensions.CheckGLError(); } // Restore the bound texture. GL.BindTexture(TextureTarget.Texture2D, prevTexture); GraphicsExtensions.CheckGLError(); }); }
private void PlatformConstruct(int width, int height, bool mipmap, SurfaceFormat format, SurfaceType type, bool shared) { this.glTarget = gl.TEXTURE_2D; format.GetGLFormat(GraphicsDevice, out glInternalFormat, out glFormat, out glType); GenerateGLTextureIfRequired(); int w = width; int h = height; int level = 0; while (true) { if (glFormat == gl.COMPRESSED_TEXTURE_FORMATS) { int imageSize = 0; // PVRTC has explicit calculations for imageSize // https://www.khronos.org/registry/OpenGL/extensions/IMG/IMG_texture_compression_pvrtc.txt if (format == SurfaceFormat.RgbPvrtc2Bpp || format == SurfaceFormat.RgbaPvrtc2Bpp) { imageSize = (Math.Max(w, 16) * Math.Max(h, 8) * 2 + 7) / 8; } else if (format == SurfaceFormat.RgbPvrtc4Bpp || format == SurfaceFormat.RgbaPvrtc4Bpp) { imageSize = (Math.Max(w, 8) * Math.Max(h, 8) * 4 + 7) / 8; } else { int blockSize = format.GetSize(); int blockWidth, blockHeight; format.GetBlockSize(out blockWidth, out blockHeight); int wBlocks = (w + (blockWidth - 1)) / blockWidth; int hBlocks = (h + (blockHeight - 1)) / blockHeight; imageSize = wBlocks * hBlocks * blockSize; } } gl.texImage2D(gl.TEXTURE_2D, level, glInternalFormat, glFormat, glType, (new ImageData(w, h).As <ImageBitmap>())); GraphicsExtensions.CheckGLError(); if ((w == 1 && h == 1) || !mipmap) { break; } if (w > 1) { w = w / 2; } if (h > 1) { h = h / 2; } ++level; } }
public Texture3D(GraphicsDevice graphicsDevice, int width, int height, int depth, bool mipMap, SurfaceFormat format) { if (graphicsDevice == null) { throw new ArgumentNullException("graphicsDevice"); } this.GraphicsDevice = graphicsDevice; this.width = width; this.height = height; this.depth = depth; this.levelCount = 1; #if OPENGL this.glTarget = TextureTarget.Texture3D; GL.GenTextures(1, out this.glTexture); GraphicsExtensions.CheckGLError(); GL.BindTexture(glTarget, glTexture); GraphicsExtensions.CheckGLError(); format.GetGLFormat(out glInternalFormat, out glFormat, out glType); GL.TexImage3D(glTarget, 0, glInternalFormat, width, height, depth, 0, glFormat, glType, IntPtr.Zero); GraphicsExtensions.CheckGLError(); if (mipMap) { throw new NotImplementedException("Texture3D does not yet support mipmaps."); } #elif DIRECTX if (mipMap) { this.levelCount = CalculateMipLevels(width, height, depth); } var description = new Texture3DDescription { Width = width, Height = height, Depth = depth, MipLevels = levelCount, Format = SharpDXHelper.ToFormat(format), BindFlags = BindFlags.ShaderResource, CpuAccessFlags = CpuAccessFlags.None, Usage = ResourceUsage.Default, OptionFlags = ResourceOptionFlags.None, }; _texture = new SharpDX.Direct3D11.Texture3D(graphicsDevice._d3dDevice, description); #endif }
public Texture2D(int width, int height, bool hasMipMaps, SurfaceFormat format) : this(true) { Width = width; Height = height; Format = format; Format.GetGLFormat(out glInternalFormat, out glFormat, out glType); LevelCount = hasMipMaps ? CalculateMipLevels(width, height) : 1; currentLevels = hasMipMaps ? (LevelCount - 1) : 0; //Bind the new TextureD GLBind.Trash(); GLBind.BindTexture(4, GL.GL_TEXTURE_2D, ID); //initialise the texture data var imageSize = 0; Dxt1 = format == SurfaceFormat.Dxt1; if (glFormat == GL.GL_NUM_COMPRESSED_TEXTURE_FORMATS) { if (GLExtensions.S3TC) { switch (Format) { case SurfaceFormat.Dxt1: case SurfaceFormat.Dxt3: case SurfaceFormat.Dxt5: imageSize = ((Width + 3) / 4) * ((Height + 3) / 4) * format.GetSize(); break; default: throw new NotSupportedException(); } GL.CompressedTexImage2D(GL.GL_TEXTURE_2D, 0, glInternalFormat, Width, Height, 0, imageSize, IntPtr.Zero); } else { GL.TexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_RGBA, Width, Height, 0, GL.GL_BGRA, GL.GL_UNSIGNED_BYTE, IntPtr.Zero); } } else { GL.TexImage2D(GL.GL_TEXTURE_2D, 0, glInternalFormat, Width, Height, 0, glFormat, glType, IntPtr.Zero); } //enable filtering GL.TexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR); GL.TexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR); }
protected Texture3D(GraphicsDevice graphicsDevice, int width, int height, int depth, bool mipMap, SurfaceFormat format, bool renderTarget) { if (graphicsDevice == null) { throw new ArgumentNullException("graphicsDevice"); } this.GraphicsDevice = graphicsDevice; this.width = width; this.height = height; this.depth = depth; this._levelCount = 1; this._format = format; #if OPENGL this.glTarget = TextureTarget.Texture3D; GL.GenTextures(1, out this.glTexture); GraphicsExtensions.CheckGLError(); GL.BindTexture(glTarget, glTexture); GraphicsExtensions.CheckGLError(); format.GetGLFormat(out glInternalFormat, out glFormat, out glType); GL.TexImage3D(glTarget, 0, glInternalFormat, width, height, depth, 0, glFormat, glType, IntPtr.Zero); GraphicsExtensions.CheckGLError(); if (mipMap) { throw new NotImplementedException("Texture3D does not yet support mipmaps."); } #elif DIRECTX this.renderTarget = renderTarget; this.mipMap = mipMap; if (mipMap) { this._levelCount = CalculateMipLevels(width, height, depth); } // Create texture GetTexture(); #endif }
public Texture3D(GraphicsDevice graphicsDevice, int width, int height, int depth, bool mipMap, SurfaceFormat format) { this.graphicsDevice = graphicsDevice; Width = width; Height = height; Depth = depth; this.glTarget = TextureTarget.Texture3D; GL.GenTextures(1, out this.glTexture); GL.BindTexture(glTarget, glTexture); format.GetGLFormat(out glInternalFormat, out glFormat, out glType); GL.TexImage3D(glTarget, 0, glInternalFormat, width, height, depth, 0, glFormat, glType, IntPtr.Zero); if (mipMap) { throw new NotImplementedException(); } }
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 // TODO: Move this to SetData() if we want to make Immutable textures! var desc = new SharpDX.Direct3D11.Texture2DDescription(); desc.Width = width; desc.Height = height; desc.MipLevels = _levelCount; desc.ArraySize = 1; desc.Format = SharpDXHelper.ToFormat(format); desc.BindFlags = SharpDX.Direct3D11.BindFlags.ShaderResource; desc.CpuAccessFlags = SharpDX.Direct3D11.CpuAccessFlags.None; desc.SampleDescription.Count = 1; desc.SampleDescription.Quality = 0; desc.Usage = SharpDX.Direct3D11.ResourceUsage.Default; desc.OptionFlags = SharpDX.Direct3D11.ResourceOptionFlags.None; if (type == SurfaceType.RenderTarget) { desc.BindFlags |= SharpDX.Direct3D11.BindFlags.RenderTarget; if (mipmap) { // Note: XNA 4 does not have a method Texture.GenerateMipMaps() // because generation of mipmaps is not supported on the Xbox 360. // TODO: New method Texture.GenerateMipMaps() required. desc.OptionFlags |= SharpDX.Direct3D11.ResourceOptionFlags.GenerateMipMaps; } } if (shared) desc.OptionFlags |= SharpDX.Direct3D11.ResourceOptionFlags.Shared; _texture = new SharpDX.Direct3D11.Texture2D(graphicsDevice._d3dDevice, desc); #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, 8) * Math.Max(this.height, 8) * 2 + 7) / 8; break; case SurfaceFormat.RgbPvrtc4Bpp: case SurfaceFormat.RgbaPvrtc4Bpp: imageSize = (Math.Max(this.width, 16) * Math.Max(this.height, 8) * 4 + 7) / 8; break; 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 NotImplementedException(); } 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 }
private void PlatformConstruct(int width, int height, bool mipmap, SurfaceFormat format, SurfaceType type, bool shared) { this.glTarget = TextureTarget.Texture2D; Threading.BlockOnUIThread(() => { // Store the current bound texture. var prevTexture = GraphicsExtensions.GetBoundTexture2D(); GenerateGLTextureIfRequired(); format.GetGLFormat(GraphicsDevice, out glInternalFormat, out glFormat, out glType); if (glFormat == (PixelFormat)GLPixelFormat.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.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 = ((this.width + 3) / 4) * ((this.height + 3) / 4) * GraphicsExtensions.GetSize(format); 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, glInternalFormat, this.width, this.height, 0, glFormat, glType, IntPtr.Zero); GraphicsExtensions.CheckGLError(); } if (mipmap) { #if IOS || ANDROID GL.GenerateMipmap(TextureTarget.TextureCubeMap); #else GraphicsDevice.FramebufferHelper.Get().GenerateMipmap((int)glTarget); // This updates the mipmaps after a change in the base texture GL.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.GenerateMipmap, 1); #endif } // Restore the bound texture. GL.BindTexture(TextureTarget.Texture2D, prevTexture); GraphicsExtensions.CheckGLError(); }); }
private void PlatformConstruct(GraphicsDevice graphicsDevice, int size, bool mipMap, SurfaceFormat format, bool renderTarget) { this.glTarget = TextureTarget.TextureCubeMap; Threading.BlockOnUIThread(() => { GL.GenTextures(1, out this.glTexture); GraphicsExtensions.CheckGLError(); GL.BindTexture(TextureTarget.TextureCubeMap, this.glTexture); GraphicsExtensions.CheckGLError(); GL.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.TextureMinFilter, mipMap ? (int)TextureMinFilter.LinearMipmapLinear : (int)TextureMinFilter.Linear); GraphicsExtensions.CheckGLError(); GL.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear); GraphicsExtensions.CheckGLError(); GL.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.TextureWrapS, (int)TextureWrapMode.ClampToEdge); GraphicsExtensions.CheckGLError(); GL.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.TextureWrapT, (int)TextureWrapMode.ClampToEdge); 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 == (PixelFormat)GLPixelFormat.CompressedTextureFormats) { 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, imageSize, IntPtr.Zero); GraphicsExtensions.CheckGLError(); } else { GL.TexImage2D(target, 0, glInternalFormat, size, size, 0, glFormat, glType, IntPtr.Zero); GraphicsExtensions.CheckGLError(); } } if (mipMap) { #if IOS || ANDROID GL.GenerateMipmap(TextureTarget.TextureCubeMap); #else GraphicsDevice.FramebufferHelper.Get().GenerateMipmap((int)glTarget); // This updates the mipmaps after a change in the base texture GL.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.GenerateMipmap, (int)Bool.True); #endif GraphicsExtensions.CheckGLError(); } }); }
protected Texture3D(GraphicsDevice graphicsDevice, int width, int height, int depth, bool mipMap, SurfaceFormat format, bool renderTarget) { if (graphicsDevice == null) { throw new ArgumentNullException("graphicsDevice"); } this.GraphicsDevice = graphicsDevice; this.width = width; this.height = height; this.depth = depth; this._levelCount = 1; this._format = format; #if OPENGL this.glTarget = TextureTarget.Texture3D; GL.GenTextures(1, out this.glTexture); GraphicsExtensions.CheckGLError(); GL.BindTexture(glTarget, glTexture); GraphicsExtensions.CheckGLError(); format.GetGLFormat(out glInternalFormat, out glFormat, out glType); GL.TexImage3D(glTarget, 0, glInternalFormat, width, height, depth, 0, glFormat, glType, IntPtr.Zero); GraphicsExtensions.CheckGLError(); if (mipMap) { throw new NotImplementedException("Texture3D does not yet support mipmaps."); } #elif DIRECTX if (mipMap) { this._levelCount = CalculateMipLevels(width, height, depth); } var description = new Texture3DDescription { Width = width, Height = height, Depth = depth, MipLevels = _levelCount, Format = SharpDXHelper.ToFormat(format), BindFlags = BindFlags.ShaderResource, CpuAccessFlags = CpuAccessFlags.None, Usage = ResourceUsage.Default, OptionFlags = ResourceOptionFlags.None, }; if (renderTarget) { description.BindFlags |= BindFlags.RenderTarget; if (mipMap) { // Note: XNA 4 does not have a method Texture.GenerateMipMaps() // because generation of mipmaps is not supported on the Xbox 360. // TODO: New method Texture.GenerateMipMaps() required. description.OptionFlags |= ResourceOptionFlags.GenerateMipMaps; } } _texture = new SharpDX.Direct3D11.Texture3D(graphicsDevice._d3dDevice, description); #endif }
internal TextureCube(GraphicsDevice graphicsDevice, int size, bool mipMap, SurfaceFormat format, bool renderTarget) { if (graphicsDevice == null) { throw new ArgumentNullException("graphicsDevice"); } this.GraphicsDevice = graphicsDevice; this.size = size; this._format = format; this._levelCount = mipMap ? CalculateMipLevels(size) : 1; #if DIRECTX _renderTarget = renderTarget; _mipMap = mipMap; // Create texture GetTexture(); #elif PSM //TODO #else this.glTarget = TextureTarget.TextureCubeMap; #if IOS || ANDROID GL.GenTextures(1, ref this.glTexture); #else GL.GenTextures(1, out this.glTexture); #endif GraphicsExtensions.CheckGLError(); GL.BindTexture(TextureTarget.TextureCubeMap, this.glTexture); GraphicsExtensions.CheckGLError(); GL.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.TextureMinFilter, mipMap ? (int)TextureMinFilter.LinearMipmapLinear : (int)TextureMinFilter.Linear); GraphicsExtensions.CheckGLError(); GL.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear); GraphicsExtensions.CheckGLError(); GL.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.TextureWrapS, (int)TextureWrapMode.ClampToEdge); GraphicsExtensions.CheckGLError(); GL.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.TextureWrapT, (int)TextureWrapMode.ClampToEdge); GraphicsExtensions.CheckGLError(); format.GetGLFormat(out glInternalFormat, out glFormat, out glType); for (int i = 0; i < 6; i++) { TextureTarget target = GetGLCubeFace((CubeMapFace)i); if (glFormat == (PixelFormat)All.CompressedTextureFormats) { throw new NotImplementedException(); } else { #if IOS || ANDROID GL.TexImage2D(target, 0, (int)glInternalFormat, size, size, 0, glFormat, glType, IntPtr.Zero); #else GL.TexImage2D(target, 0, glInternalFormat, size, size, 0, glFormat, glType, IntPtr.Zero); #endif GraphicsExtensions.CheckGLError(); } } if (mipMap) { #if IOS || ANDROID GL.GenerateMipmap(TextureTarget.TextureCubeMap); #else GL.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.GenerateMipmap, (int)All.True); #endif GraphicsExtensions.CheckGLError(); } #endif }
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 }
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 TextureCube(GraphicsDevice graphicsDevice, int size, bool mipMap, SurfaceFormat format, bool renderTarget) { if (graphicsDevice == null) { throw new ArgumentNullException("graphicsDevice"); } this.GraphicsDevice = graphicsDevice; this.size = size; this._format = format; this._levelCount = mipMap ? CalculateMipLevels(size) : 1; #if DIRECTX var description = new Texture2DDescription { Width = size, Height = size, MipLevels = _levelCount, ArraySize = 6, // A texture cube is a 2D texture array with 6 textures. Format = SharpDXHelper.ToFormat(format), BindFlags = BindFlags.ShaderResource, CpuAccessFlags = CpuAccessFlags.None, SampleDescription = { Count = 1, Quality = 0 }, Usage = ResourceUsage.Default, OptionFlags = ResourceOptionFlags.TextureCube }; if (renderTarget) { description.BindFlags |= BindFlags.RenderTarget; if (mipMap) { description.OptionFlags |= ResourceOptionFlags.GenerateMipMaps; } } _texture = new SharpDX.Direct3D11.Texture2D(graphicsDevice._d3dDevice, description); #elif PSM //TODO #else this.glTarget = TextureTarget.TextureCubeMap; #if IOS || ANDROID GL.GenTextures(1, ref this.glTexture); #else GL.GenTextures(1, out this.glTexture); #endif GraphicsExtensions.CheckGLError(); GL.BindTexture(TextureTarget.TextureCubeMap, this.glTexture); GraphicsExtensions.CheckGLError(); GL.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.TextureMinFilter, mipMap ? (int)TextureMinFilter.LinearMipmapLinear : (int)TextureMinFilter.Linear); GraphicsExtensions.CheckGLError(); GL.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear); GraphicsExtensions.CheckGLError(); GL.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.TextureWrapS, (int)TextureWrapMode.ClampToEdge); GraphicsExtensions.CheckGLError(); GL.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.TextureWrapT, (int)TextureWrapMode.ClampToEdge); GraphicsExtensions.CheckGLError(); format.GetGLFormat(out glInternalFormat, out glFormat, out glType); for (int i = 0; i < 6; i++) { TextureTarget target = GetGLCubeFace((CubeMapFace)i); if (glFormat == (PixelFormat)All.CompressedTextureFormats) { throw new NotImplementedException(); } else { #if IOS || ANDROID GL.TexImage2D(target, 0, (int)glInternalFormat, size, size, 0, glFormat, glType, IntPtr.Zero); #else GL.TexImage2D(target, 0, glInternalFormat, size, size, 0, glFormat, glType, IntPtr.Zero); #endif GraphicsExtensions.CheckGLError(); } } if (mipMap) { #if IOS || ANDROID GL.GenerateMipmap(TextureTarget.TextureCubeMap); #else GL.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.GenerateMipmap, (int)All.True); #endif GraphicsExtensions.CheckGLError(); } #endif }
public TextureCube(GraphicsDevice graphicsDevice, int size, bool mipMap, SurfaceFormat format) { this.size = size; this.levelCount = 1; #if WINRT #elif PSS //TODO #else this.glTarget = TextureTarget.TextureCubeMap; #if IPHONE || ANDROID GL.GenTextures(1, ref this.glTexture); #else GL.GenTextures(1, out this.glTexture); #endif GraphicsExtensions.CheckGLError(); GL.BindTexture(TextureTarget.TextureCubeMap, this.glTexture); GraphicsExtensions.CheckGLError(); GL.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.TextureMinFilter, mipMap ? (int)TextureMinFilter.LinearMipmapLinear : (int)TextureMinFilter.Linear); GraphicsExtensions.CheckGLError(); GL.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear); GraphicsExtensions.CheckGLError(); GL.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.TextureWrapS, (int)TextureWrapMode.ClampToEdge); GraphicsExtensions.CheckGLError(); GL.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.TextureWrapT, (int)TextureWrapMode.ClampToEdge); GraphicsExtensions.CheckGLError(); format.GetGLFormat(out glInternalFormat, out glFormat, out glType); for (int i = 0; i < 6; i++) { TextureTarget target = GetGLCubeFace((CubeMapFace)i); if (glFormat == (PixelFormat)All.CompressedTextureFormats) { throw new NotImplementedException(); } else { #if IPHONE || ANDROID GL.TexImage2D(target, 0, (int)glInternalFormat, size, size, 0, glFormat, glType, IntPtr.Zero); #else GL.TexImage2D(target, 0, glInternalFormat, size, size, 0, glFormat, glType, IntPtr.Zero); #endif GraphicsExtensions.CheckGLError(); } } if (mipMap) { #if IPHONE || ANDROID GL.GenerateMipmap(TextureTarget.TextureCubeMap); #else GL.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.GenerateMipmap, (int)All.True); #endif GraphicsExtensions.CheckGLError(); int v = this.size; while (v > 1) { v /= 2; this.levelCount++; } } #endif }
internal Texture2D(GraphicsDevice graphicsDevice, int width, int height, bool mipmap, SurfaceFormat format, bool renderTarget) { 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 = 1; if (mipmap) { int size = Math.Max(this.width, this.height); while (size > 1) { size = size / 2; this.levelCount++; } } #if DIRECTX // TODO: Move this to SetData() if we want to make Immutable textures! var desc = new SharpDX.Direct3D11.Texture2DDescription(); desc.Width = width; desc.Height = height; desc.MipLevels = levelCount; desc.ArraySize = 1; desc.Format = SharpDXHelper.ToFormat(format); desc.BindFlags = SharpDX.Direct3D11.BindFlags.ShaderResource; desc.CpuAccessFlags = SharpDX.Direct3D11.CpuAccessFlags.None; desc.SampleDescription.Count = 1; desc.SampleDescription.Quality = 0; desc.Usage = SharpDX.Direct3D11.ResourceUsage.Default; desc.OptionFlags = SharpDX.Direct3D11.ResourceOptionFlags.None; if (renderTarget) desc.BindFlags |= SharpDX.Direct3D11.BindFlags.RenderTarget; _texture = new SharpDX.Direct3D11.Texture2D(graphicsDevice._d3dDevice, desc); #elif PSM _texture2D = new Sce.PlayStation.Core.Graphics.Texture2D(width, height, mipmap, PSSHelper.ToFormat(format)); #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, 8) * Math.Max(this.height, 8) * 2 + 7) / 8; break; case SurfaceFormat.RgbPvrtc4Bpp: case SurfaceFormat.RgbaPvrtc4Bpp: imageSize = (Math.Max(this.width, 16) * Math.Max(this.height, 8) * 4 + 7) / 8; break; case SurfaceFormat.Dxt1: imageSize = ((this.width + 3) / 4) * ((this.height + 3) / 4) * 8 * 1; break; case SurfaceFormat.Dxt3: case SurfaceFormat.Dxt5: imageSize = ((this.width + 3) / 4) * ((this.height + 3) / 4) * 16 * 1; break; default: throw new NotImplementedException(); } 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 }
private void PlatformConstruct( int width, int height, bool mipmap, SurfaceFormat format, SurfaceType type, bool shared) { _glTarget = TextureTarget.Texture2D; format.GetGLFormat(GraphicsDevice, out _glInternalFormat, out _glFormat, out _glType); GenerateGLTextureIfRequired(); int level = 0; while (true) { if (_glFormat == GLPixelFormat.CompressedTextureFormats) { // PVRTC has explicit calculations for imageSize // https://www.khronos.org/registry/OpenGL/extensions/IMG/IMG_texture_compression_pvrtc.txt int imageSize; switch (format) { case SurfaceFormat.RgbPvrtc2Bpp: case SurfaceFormat.RgbaPvrtc2Bpp: imageSize = (Math.Max(width, 16) * Math.Max(height, 8) * 2 + 7) / 8; break; case SurfaceFormat.RgbPvrtc4Bpp: case SurfaceFormat.RgbaPvrtc4Bpp: imageSize = (Math.Max(width, 8) * Math.Max(height, 8) * 4 + 7) / 8; break; default: { format.GetBlockSize(out int blockWidth, out int blockHeight); int wBlocks = (width + (blockWidth - 1)) / blockWidth; int hBlocks = (height + (blockHeight - 1)) / blockHeight; imageSize = wBlocks * hBlocks * format.GetSize(); break; } } GL.CompressedTexImage2D( TextureTarget.Texture2D, level, _glInternalFormat, width, height, 0, imageSize, IntPtr.Zero); GL.CheckError(); } else { GL.TexImage2D( TextureTarget.Texture2D, level, _glInternalFormat, width, height, 0, _glFormat, _glType, IntPtr.Zero); GL.CheckError(); } if ((width == 1 && height == 1) || !mipmap) { break; } if (width > 1) { width /= 2; } if (height > 1) { height /= 2; } level++; } }