internal int GetPitch(int width) { Debug.Assert(width > 0, "The width is negative!"); int pitch; switch (_format) { case SurfaceFormat.Dxt1: case SurfaceFormat.Dxt1SRgb: case SurfaceFormat.Dxt1a: case SurfaceFormat.RgbPvrtc2Bpp: case SurfaceFormat.RgbaPvrtc2Bpp: case SurfaceFormat.RgbEtc1: case SurfaceFormat.Dxt3: case SurfaceFormat.Dxt3SRgb: case SurfaceFormat.Dxt5: case SurfaceFormat.Dxt5SRgb: case SurfaceFormat.RgbPvrtc4Bpp: case SurfaceFormat.RgbaPvrtc4Bpp: pitch = ((width + 3) / 4) * _format.GetSize(); break; default: pitch = width * _format.GetSize(); break; } ; return(pitch); }
private static int GetBitmapSize(SurfaceFormat format, int width, int height) { // It is recommended that the dwPitchOrLinearSize field is ignored and we calculate it ourselves // https://msdn.microsoft.com/en-us/library/bb943991.aspx int pitch; int rows; switch (format) { case SurfaceFormat.Rgba32: case SurfaceFormat.Bgra4444: case SurfaceFormat.Bgra5551: case SurfaceFormat.Bgr565: case SurfaceFormat.Vector4: pitch = width * format.GetSize(); rows = height; break; case SurfaceFormat.Dxt1: case SurfaceFormat.Dxt3: case SurfaceFormat.Dxt5: pitch = (width + 3) / 4 * format.GetSize(); rows = (height + 3) / 4; break; default: throw new ContentLoadException("Unsupported SurfaceFormat " + format); } return(pitch * rows); }
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); } } }
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; } }); }
public override byte[] GetPixelData() { var formatSize = _format.GetSize(); var dataSize = Width * Height * formatSize; var outputData = new byte[dataSize]; for (var x = 0; x < Height; x++) { var dataHandle = GCHandle.Alloc(_pixelData[x], GCHandleType.Pinned); var dataPtr = (IntPtr)(dataHandle.AddrOfPinnedObject().ToInt64()); Marshal.Copy(dataPtr, outputData, (formatSize * x * Width), (Width * formatSize)); dataHandle.Free(); } return(outputData); }
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 PixelBitmapContent(int width, int height) { if (!TryGetFormat(out _format)) { throw new InvalidOperationException($"Color format \"{typeof(TPixel)}\" is not supported"); } Height = height; Width = width; _pixelData = new byte[Width * Height * _format.GetSize()]; }
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); }
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(); } }); }
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(); } }
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++; } }