コード例 #1
0
        static void WriteRawFloat4Packed(RawTexture dest, float f0, float f1, float f2, float f3, int destX, int destY)
        {
            byte r      = (byte)(f0 * 255.0f + 0.5f);
            byte g      = (byte)(f1 * 255.0f + 0.5f);
            byte b      = (byte)(f2 * 255.0f + 0.5f);
            byte a      = (byte)(f3 * 255.0f + 0.5f);
            int  offset = destY * dest.Width + destX;

            dest.Rgba[offset] = new Color32(r, g, b, a);
        }
コード例 #2
0
        internal static void WriteRawInt2Packed(RawTexture dest, int v0, int v1, int destX, int destY)
        {
            byte r      = (byte)(v0 / 255);
            byte g      = (byte)(v0 - r * 255);
            byte b      = (byte)(v1 / 255);
            byte a      = (byte)(v1 - b * 255);
            int  offset = destY * dest.Width + destX;

            dest.Rgba[offset] = new Color32(r, g, b, a);
        }
コード例 #3
0
        public void Reset()
        {
            if (disposed)
            {
                DisposeHelper.NotifyDisposedUsed(this);
                return;
            }

            m_Allocator = new BestFitAllocator((uint)m_Length);
            UIRUtility.Destroy(m_Atlas);
            m_RawAtlas = new RawTexture();
            MustCommit = false;
        }
コード例 #4
0
        private BitmapSource DecodeTexture(RawTexture model)
        {
            BitmapSource bmp;

            switch (model.Format)
            {
            default:
            case RawTexture.DataFormat.Invalid:
            {
                return(null);
            }

            case RawTexture.DataFormat.Bgr888:
            case RawTexture.DataFormat.Bgr565:
            {
                var rgb888 = model.Decode();
                bmp = BitmapSource.Create(model.Width,
                                          model.Height,
                                          96,
                                          96,
                                          PixelFormats.Bgr24,
                                          null,
                                          rgb888,
                                          model.Width * 3);
                break;
            }

            case RawTexture.DataFormat.A8:
            {
                var rgb888 = model.Decode();
                var alpha  = GscToAlpha(rgb888);
                bmp = BitmapSource.Create(model.Width,
                                          model.Height,
                                          96,
                                          96,
                                          PixelFormats.Bgra32,
                                          null,
                                          alpha,
                                          model.Width * 4);
                break;
            }
            }
            bmp.Freeze();
            return(bmp);
        }
コード例 #5
0
ファイル: SliderBody.cs プロジェクト: vbe0201/osu
        private void reloadTexture()
        {
            var texture = new Texture(textureWidth, 1);

            //initialise background
            var raw   = new RawTexture(textureWidth, 1);
            var bytes = raw.Data;

            const float aa_portion       = 0.02f;
            const float border_portion   = 0.128f;
            const float gradient_portion = 1 - border_portion;

            const float opacity_at_centre = 0.3f;
            const float opacity_at_edge   = 0.8f;

            for (int i = 0; i < textureWidth; i++)
            {
                float progress = (float)i / (textureWidth - 1);

                if (progress <= border_portion)
                {
                    bytes[i * 4]     = (byte)(BorderColour.R * 255);
                    bytes[i * 4 + 1] = (byte)(BorderColour.G * 255);
                    bytes[i * 4 + 2] = (byte)(BorderColour.B * 255);
                    bytes[i * 4 + 3] = (byte)(Math.Min(progress / aa_portion, 1) * (BorderColour.A * 255));
                }
                else
                {
                    progress -= border_portion;

                    bytes[i * 4]     = (byte)(AccentColour.R * 255);
                    bytes[i * 4 + 1] = (byte)(AccentColour.G * 255);
                    bytes[i * 4 + 2] = (byte)(AccentColour.B * 255);
                    bytes[i * 4 + 3] = (byte)((opacity_at_edge - (opacity_at_edge - opacity_at_centre) * progress / gradient_portion) * (AccentColour.A * 255));
                }
            }

            texture.SetData(new TextureUpload(raw));
            path.Texture = texture;

            container.ForceRedraw();
        }
コード例 #6
0
 static void BlitRawTexture(RawTexture src, RawTexture dest, int destX, int destY, bool rotate)
 {
     if (rotate)
     {
         for (int y = 0; y < src.Height; y++)
         {
             int srcRowIndex     = y * src.Width;
             int destColumnIndex = destY * dest.Width + destX + y;
             for (int x = 0; x < src.Width; x++)
             {
                 int srcIndex  = srcRowIndex + x;
                 int destIndex = destColumnIndex + x * dest.Width;
                 dest.Rgba[destIndex] = src.Rgba[srcIndex];
             }
         }
     }
     else
     {
         for (int y = 0; y < src.Height; y++)
         {
             Array.Copy(src.Rgba, y * src.Width, dest.Rgba, (destY + y) * dest.Width + destX, src.Width);
         }
     }
 }
コード例 #7
0
        /// <summary>Generates a Texture2D atlas containing the textures and gradients for the vector geometry.</summary>
        /// <param name="geoms">The list of Geometry objects, probably created with TessellateNodeHierarchy</param>
        /// <param name="rasterSize">Maximum size of the generated texture</param>
        /// <returns>The generated texture atlas</returns>
        public static TextureAtlas GenerateAtlas(IEnumerable <Geometry> geoms, uint rasterSize)
        {
            UnityEngine.Profiling.Profiler.BeginSample("GenerateAtlas");

            var fills             = new Dictionary <IFill, AtlasEntry>();
            int texturedGeomCount = 0;

            foreach (var g in geoms)
            {
                RawTexture tex;
                if (g.Fill is GradientFill)
                {
                    tex = new RawTexture()
                    {
                        Width = (int)rasterSize, Height = 1, Rgba = RasterizeGradientStripe((GradientFill)g.Fill, (int)rasterSize)
                    };
                    ++texturedGeomCount;
                }
                else if (g.Fill is TextureFill)
                {
                    var fillTex = ((TextureFill)g.Fill).Texture;
                    tex = new RawTexture()
                    {
                        Rgba = fillTex.GetPixels32(), Width = fillTex.width, Height = fillTex.height
                    };
                    ++texturedGeomCount;
                }
                else
                {
                    continue;
                }
                fills[g.Fill] = new AtlasEntry()
                {
                    Texture = tex
                };
            }

            if (fills.Count == 0)
            {
                return(null);
            }

            Vector2 atlasSize;
            var     rectsToPack = fills.Select(x => new KeyValuePair <IFill, Vector2>(x.Key, new Vector2(x.Value.Texture.Width, x.Value.Texture.Height))).ToList();

            rectsToPack.Add(new KeyValuePair <IFill, Vector2>(null, new Vector2(2, 2))); // White fill
            var pack = PackRects(rectsToPack, out atlasSize);

            // The first row of the atlas is reserved for the gradient settings
            for (int packIndex = 0; packIndex < pack.Count; ++packIndex)
            {
                var item = pack[packIndex];
                item.Position.y += 1;
                pack[packIndex]  = item;
            }
            atlasSize.y += 1;

            // Need enough space on first row for texture settings
            int maxSettingIndex = 0;

            foreach (var item in pack)
            {
                maxSettingIndex = Math.Max(maxSettingIndex, item.SettingIndex);
            }
            int minWidth = (maxSettingIndex + 1) * 3;

            atlasSize.x = Math.Max(minWidth, (int)atlasSize.x);

            int atlasWidth  = NextPOT((int)atlasSize.x);
            int atlasHeight = NextPOT((int)atlasSize.y);
            var atlasColors = new Color32[atlasWidth * atlasHeight];

            for (int k = 0; k < atlasWidth * atlasHeight; ++k)
            {
                atlasColors[k] = Color.black;
            }
            Vector2 atlasInvSize         = new Vector2(1.0f / (float)atlasWidth, 1.0f / (float)atlasHeight);
            Vector2 whiteTexelsScreenPos = pack[pack.Count - 1].Position;

            int        i           = 0;
            RawTexture rawAtlasTex = new RawTexture()
            {
                Rgba = atlasColors, Width = atlasWidth, Height = atlasHeight
            };

            foreach (var entry in fills.Values)
            {
                var packItem = pack[i++];
                entry.AtlasLocation = packItem;
                BlitRawTexture(entry.Texture, rawAtlasTex, (int)packItem.Position.x, (int)packItem.Position.y, packItem.Rotated);
            }

            RawTexture whiteTex = new RawTexture()
            {
                Width = 2, Height = 2, Rgba = new Color32[4]
            };

            for (i = 0; i < whiteTex.Rgba.Length; i++)
            {
                whiteTex.Rgba[i] = new Color32(0xFF, 0xFF, 0xFF, 0xFF);
            }
            BlitRawTexture(whiteTex, rawAtlasTex, (int)whiteTexelsScreenPos.x, (int)whiteTexelsScreenPos.y, false);

            // Setting 0 is reserved for the white texel
            WriteRawFloat4Packed(rawAtlasTex, 0.0f, 0.0f, 0.0f, 0.0f, 0, 0);
            WriteRawInt2Packed(rawAtlasTex, (int)whiteTexelsScreenPos.x + 1, (int)whiteTexelsScreenPos.y + 1, 1, 0);
            WriteRawInt2Packed(rawAtlasTex, 0, 0, 2, 0);

            var writtenSettings = new HashSet <int>();

            writtenSettings.Add(0);

            foreach (var g in geoms)
            {
                AtlasEntry entry;
                int        vertsCount = g.Vertices.Length;
                if ((g.Fill != null) && fills.TryGetValue(g.Fill, out entry))
                {
                    int setting = entry.AtlasLocation.SettingIndex;
                    if (writtenSettings.Contains(setting))
                    {
                        continue;
                    }

                    writtenSettings.Add(setting);

                    // There are 3 consecutive pixels to store the settings
                    int destX = setting * 3;

                    var gradientFill = g.Fill as GradientFill;
                    if (gradientFill != null)
                    {
                        var focus = gradientFill.RadialFocus;
                        focus  += Vector2.one;
                        focus  /= 2.0f;
                        focus.y = 1.0f - focus.y;
                        WriteRawFloat4Packed(rawAtlasTex, ((float)gradientFill.Type) / 255, ((float)gradientFill.Addressing) / 255, focus.x, focus.y, destX++, 0);
                    }

                    var textureFill = g.Fill as TextureFill;
                    if (textureFill != null)
                    {
                        WriteRawFloat4Packed(rawAtlasTex, 0.0f, ((float)textureFill.Addressing) / 255, 0.0f, 0.0f, destX++, 0);
                    }

                    var pos  = entry.AtlasLocation.Position;
                    var size = new Vector2(entry.Texture.Width - 1, entry.Texture.Height - 1);
                    WriteRawInt2Packed(rawAtlasTex, (int)pos.x, (int)pos.y, destX++, 0);
                    WriteRawInt2Packed(rawAtlasTex, (int)size.x, (int)size.y, destX++, 0);
                }
            }

            var atlasTex = new Texture2D(atlasWidth, atlasHeight, TextureFormat.ARGB32, false, true);

            atlasTex.wrapModeU = TextureWrapMode.Clamp;
            atlasTex.wrapModeV = TextureWrapMode.Clamp;
            atlasTex.wrapModeW = TextureWrapMode.Clamp;
            atlasTex.SetPixels32(atlasColors);
            atlasTex.Apply();

            UnityEngine.Profiling.Profiler.EndSample();

            return(new TextureAtlas()
            {
                Texture = atlasTex, Entries = pack
            });
        }
コード例 #8
0
        private static void EncodeSettings(IEnumerable <Geometry> geoms, Dictionary <IFill, AtlasEntry> fills, RawTexture rawAtlasTex, Vector2 whiteTexelsScreenPos)
        {
            // Setting 0 is reserved for the white texel
            WriteRawFloat4Packed(rawAtlasTex, 0.0f, 0.0f, 0.0f, 0.0f, 0, 0);
            WriteRawInt2Packed(rawAtlasTex, (int)whiteTexelsScreenPos.x + 1, (int)whiteTexelsScreenPos.y + 1, 1, 0);
            WriteRawInt2Packed(rawAtlasTex, 0, 0, 2, 0);

            var writtenSettings = new HashSet <int>();

            writtenSettings.Add(0);

            foreach (var g in geoms)
            {
                AtlasEntry entry;
                int        vertsCount = g.Vertices.Length;
                if ((g.Fill != null) && fills.TryGetValue(g.Fill, out entry))
                {
                    int setting = entry.AtlasLocation.SettingIndex;
                    if (writtenSettings.Contains(setting))
                    {
                        continue;
                    }

                    writtenSettings.Add(setting);

                    // There are 3 consecutive pixels to store the settings
                    int destX = 0;
                    int destY = setting;

                    var gradientFill = g.Fill as GradientFill;
                    if (gradientFill != null)
                    {
                        var focus = gradientFill.RadialFocus;
                        focus  += Vector2.one;
                        focus  /= 2.0f;
                        focus.y = 1.0f - focus.y;

                        WriteRawFloat4Packed(rawAtlasTex, ((float)gradientFill.Type) / 255, ((float)gradientFill.Addressing) / 255, focus.x, focus.y, destX++, destY);
                    }

                    var textureFill = g.Fill as TextureFill;
                    if (textureFill != null)
                    {
                        WriteRawFloat4Packed(rawAtlasTex, 0.0f, ((float)textureFill.Addressing) / 255, 0.0f, 0.0f, destX++, destY);
                    }

                    var pos  = entry.AtlasLocation.Position;
                    var size = new Vector2(entry.Texture.Width - 1, entry.Texture.Height - 1);
                    WriteRawInt2Packed(rawAtlasTex, (int)pos.x, (int)pos.y, destX++, destY);
                    WriteRawInt2Packed(rawAtlasTex, (int)size.x, (int)size.y, destX++, destY);
                }
            }
        }
コード例 #9
0
        /// <summary>Generates a Texture2D atlas containing the textures and gradients for the vector geometry.</summary>
        /// <param name="geoms">The list of Geometry objects, probably created with TessellateNodeHierarchy</param>
        /// <param name="rasterSize">Maximum size of the generated texture</param>
        /// <param name="generatePOTTexture">Resize the texture to the next power-of-two</param>
        /// <param name="encodeSettings">Encode the gradient settings inside the texture</param>
        /// <returns>The generated texture atlas</returns>
        public static TextureAtlas GenerateAtlas(IEnumerable <Geometry> geoms, uint rasterSize, bool generatePOTTexture = true, bool encodeSettings = true)
        {
            var fills             = new Dictionary <IFill, AtlasEntry>();
            int texturedGeomCount = 0;

            foreach (var g in geoms)
            {
                RawTexture tex;
                if (g.Fill is GradientFill)
                {
                    tex = new RawTexture()
                    {
                        Width = (int)rasterSize, Height = 1, Rgba = RasterizeGradientStripe((GradientFill)g.Fill, (int)rasterSize)
                    };
                    ++texturedGeomCount;
                }
                else if (g.Fill is TextureFill)
                {
                    var fillTex = ((TextureFill)g.Fill).Texture;
                    tex = new RawTexture()
                    {
                        Rgba = fillTex.GetPixels32(), Width = fillTex.width, Height = fillTex.height
                    };
                    ++texturedGeomCount;
                }
                else
                {
                    continue;
                }
                fills[g.Fill] = new AtlasEntry()
                {
                    Texture = tex
                };
            }

            if (fills.Count == 0)
            {
                return(null);
            }

            UnityEngine.Profiling.Profiler.BeginSample("GenerateAtlas");

            Vector2 atlasSize;
            var     rectsToPack = fills.Select(x => new KeyValuePair <IFill, Vector2>(x.Key, new Vector2(x.Value.Texture.Width, x.Value.Texture.Height))).ToList();

            rectsToPack.Add(new KeyValuePair <IFill, Vector2>(null, new Vector2(2, 2))); // White fill
            var pack = PackRects(rectsToPack, out atlasSize);

            if (encodeSettings)
            {
                // The first row/cols of the atlas is reserved for the gradient settings
                for (int packIndex = 0; packIndex < pack.Count; ++packIndex)
                {
                    var item = pack[packIndex];
                    item.Position.x += 3;
                    pack[packIndex]  = item;
                }
                atlasSize.x += 3;
            }

            // Need enough space on first 3 columns for texture settings
            int maxSettingIndex = 0;

            foreach (var item in pack)
            {
                maxSettingIndex = Math.Max(maxSettingIndex, item.SettingIndex);
            }
            int minWidth  = encodeSettings ? 3 : 0;
            int minHeight = encodeSettings ? (maxSettingIndex + 1) : maxSettingIndex;

            atlasSize.x = Math.Max(minWidth, (int)atlasSize.x);
            atlasSize.y = Math.Max(minHeight, (int)atlasSize.y);

            int atlasWidth  = (int)atlasSize.x;
            int atlasHeight = (int)atlasSize.y;

            if (generatePOTTexture)
            {
                atlasWidth  = NextPOT(atlasWidth);
                atlasHeight = NextPOT(atlasHeight);
            }

            var atlasColors = new Color32[atlasWidth * atlasHeight];

            for (int k = 0; k < atlasWidth * atlasHeight; ++k)
            {
                atlasColors[k] = Color.black;
            }
            Vector2 atlasInvSize         = new Vector2(1.0f / (float)atlasWidth, 1.0f / (float)atlasHeight);
            Vector2 whiteTexelsScreenPos = pack[pack.Count - 1].Position;

            int        i           = 0;
            RawTexture rawAtlasTex = new RawTexture()
            {
                Rgba = atlasColors, Width = atlasWidth, Height = atlasHeight
            };

            foreach (var entry in fills.Values)
            {
                var packItem = pack[i++];
                entry.AtlasLocation = packItem;
                BlitRawTexture(entry.Texture, rawAtlasTex, (int)packItem.Position.x, (int)packItem.Position.y, packItem.Rotated);
            }

            RawTexture whiteTex = new RawTexture()
            {
                Width = 2, Height = 2, Rgba = new Color32[4]
            };

            for (i = 0; i < whiteTex.Rgba.Length; i++)
            {
                whiteTex.Rgba[i] = new Color32(0xFF, 0xFF, 0xFF, 0xFF);
            }
            BlitRawTexture(whiteTex, rawAtlasTex, (int)whiteTexelsScreenPos.x, (int)whiteTexelsScreenPos.y, false);

            if (encodeSettings)
            {
                EncodeSettings(geoms, fills, rawAtlasTex, whiteTexelsScreenPos);
            }

            var atlasTex = new Texture2D(atlasWidth, atlasHeight, TextureFormat.ARGB32, false, true);

            atlasTex.wrapModeU = TextureWrapMode.Clamp;
            atlasTex.wrapModeV = TextureWrapMode.Clamp;
            atlasTex.wrapModeW = TextureWrapMode.Clamp;
            atlasTex.SetPixels32(atlasColors);
            atlasTex.Apply(false, true);

            UnityEngine.Profiling.Profiler.EndSample();

            return(new TextureAtlas()
            {
                Texture = atlasTex, Entries = pack
            });
        }
コード例 #10
0
 protected SMDH(bool inter)
 {
     AppTitles = new AppTitle[16];
     SmallIcon = new RawTexture(24, 24, RawTexture.DataFormat.Bgr565);
     LargeIcon = new RawTexture(48, 48, RawTexture.DataFormat.Bgr565);
 }
コード例 #11
0
        public void Write(Alloc alloc, GradientSettings[] settings, GradientRemap remap)
        {
            if (disposed)
            {
                DisposeHelper.NotifyDisposedUsed(this);
                return;
            }

            if (m_RawAtlas.rgba == null)
            {
                m_RawAtlas = new RawTexture
                {
                    rgba   = new Color32[m_ElemWidth * m_Length],
                    width  = m_ElemWidth,
                    height = m_Length
                };

                int size = m_ElemWidth * m_Length;
                for (int i = 0; i < size; ++i)
                {
                    m_RawAtlas.rgba[i] = Color.black;
                }
            }

            s_MarkerWrite.Begin();

            int destY = (int)alloc.start;

            for (int i = 0, settingsCount = settings.Length; i < settingsCount; ++i)
            {
                int destX = 0;
                GradientSettings entry = settings[i];
                Debug.Assert(remap == null || destY == remap.destIndex);
                if (entry.gradientType == GradientType.Radial)
                {
                    var focus = entry.radialFocus;
                    focus  += Vector2.one;
                    focus  /= 2.0f;
                    focus.y = 1.0f - focus.y;
                    m_RawAtlas.WriteRawFloat4Packed((float)GradientType.Radial / 255, (float)entry.addressMode / 255, focus.x, focus.y, destX++, destY);
                }
                else if (entry.gradientType == GradientType.Linear)
                {
                    m_RawAtlas.WriteRawFloat4Packed(0.0f, (float)entry.addressMode / 255, 0.0f, 0.0f, destX++, destY);
                }

                Vector2Int pos  = new Vector2Int(entry.location.x, entry.location.y);
                var        size = new Vector2(entry.location.width - 1, entry.location.height - 1);
                if (remap != null)
                {
                    pos  = new Vector2Int(remap.location.x, remap.location.y);
                    size = new Vector2(remap.location.width - 1, remap.location.height - 1);
                }
                m_RawAtlas.WriteRawInt2Packed(pos.x, pos.y, destX++, destY);
                m_RawAtlas.WriteRawInt2Packed((int)size.x, (int)size.y, destX++, destY);

                remap = remap?.next;
                ++destY;
            }

            MustCommit = true;

            s_MarkerWrite.End();
        }
コード例 #12
0
 /// <summary>
 /// Create an upload from a <see cref="RawTexture"/>. This is the preferred method.
 /// </summary>
 /// <param name="texture">The texture to upload.</param>
 public TextureUpload(RawTexture texture)
 {
     this.texture = texture;
     Data         = texture.Data;
 }
コード例 #13
0
 public TextureViewModel(RawTexture model, string tag) : base(model, tag)
 {
 }