/// <summary> /// Creates a texture from bytes laid out in BGRA format, row major. /// </summary> /// <param name="data">The raw bytes containing the texture in BGRA format, row major.</param> /// <param name="width">Width of the texture in pixels.</param> /// <param name="height">Height of the texture in pixels.</param> /// <param name="atlas">The atlas to add the texture to.</param> /// <returns>The created texture.</returns> public static Texture FromRawBytes(byte[] data, int width, int height, TextureAtlas atlas = null, PixelFormat format = PixelFormat.Rgba) { if (data == null) { return(null); } Texture tex = atlas == null ? new Texture(width, height) : atlas.Add(width, height); var upload = new TextureUpload(data); upload.Format = format; tex.SetData(upload); return(tex); }
public unsafe void SetData(Bitmap bitmap, int level = 0) { if (TextureGL == null) { return; } int width = Math.Min(bitmap.Width, Width); int height = Math.Min(bitmap.Height, Height); BitmapData bData = bitmap.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); TextureUpload upload = new TextureUpload(width * height * 4) { Level = level, Bounds = new Rectangle(0, 0, width, height) }; byte[] data = upload.Data; int bytesPerPixel = 4; byte *bDataPointer = (byte *)bData.Scan0; for (var y = 0; y < height; y++) { // This is why real scan-width is important to have! IntPtr row = new IntPtr(bDataPointer + y * bData.Stride); Marshal.Copy(row, data, width * bytesPerPixel * y, width * bytesPerPixel); } bitmap.UnlockBits(bData); bool isTransparent = bgraToRgba(data, width * height * 4); TextureGL.IsTransparent = isTransparent; if (!isTransparent) { SetData(upload); } else { upload.Dispose(); } }
/// <summary> /// Creates a texture from a data stream representing a bitmap. /// </summary> /// <param name="stream">The data stream containing the texture data.</param> /// <param name="atlas">The atlas to add the texture to.</param> /// <returns>The created texture.</returns> public static Texture FromStream(Stream stream, TextureAtlas atlas = null) { if (stream == null || stream.Length == 0) { return(null); } try { var data = new TextureUpload(stream); Texture tex = atlas == null ? new Texture(data.Width, data.Height) : new Texture(atlas.Add(data.Width, data.Height)); tex.SetData(data); return(tex); } catch (ArgumentException) { return(null); } }
public void SetData(TextureUpload upload) { TextureGL?.SetData(upload); }
/// <summary> /// Retrieves a texture from the store and adds it to the atlas. /// </summary> /// <param name="name">The name of the texture.</param> /// <returns>The texture.</returns> public new virtual Texture Get(string name) { Texture tex = null; try { if (textureCache.TryGetValue(name, out tex)) { //use existing TextureGL (but provide a new texture instance). tex = tex != null ? new Texture(tex.TextureGL) : null; return(tex); } Stream s = base.GetStream($@"{name}"); if (s == null) { return(null); } using (MagickImage mainImage = new MagickImage(s)) { tex = atlas != null?atlas.Add(mainImage.Width, mainImage.Height) : new Texture(mainImage.Width, mainImage.Height); TextureUpload upload = new TextureUpload(mainImage.Width * mainImage.Height * 4); mainImage.Write(new MemoryStream(upload.Data), MagickFormat.Rgba); tex.SetData(upload); } //load available mipmaps //int level = 1; //int div = 2; //while (tex.Width / div > 0) //{ // s = base.GetStream($@"{name}/{div}"); // if (s == null) break; // int w = tex.Width / div; // int h = tex.Height / div; // TextureUpload upload = new TextureUpload(w * h * 4) // { // Level = level // }; // using (MagickImage image = new MagickImage(s)) // { // if (image.Width != w || image.Height != h) // { // image.Resize(new MagickGeometry($"{w}x{h}!")); // } // image.Write(new MemoryStream(upload.Data), MagickFormat.Rgba); // } // tex.SetData(upload); // level++; // div *= 2; //} textureCache[name] = tex; return(tex); } finally { if (tex != null && ScaleAdjust != 1) { tex.DpiScale = 1 / ScaleAdjust; } } }