Beispiel #1
0
 private static void RemoveBufferFromDict(LW_VertexBuffer buffer)
 {
     foreach (KeyValuePair <Material, LW_MaterialBuffer> kvp in s_MaterialDict)
     {
         LW_MaterialBuffer materialBuffer = kvp.Value;
         if (materialBuffer.vertexBuffers.Contains(buffer))
         {
             int index = materialBuffer.vertexBuffers.IndexOf(buffer);
             if (!materialBuffer.emptyIndices.Contains(index))
             {
                 materialBuffer.emptyIndices.Push(index);
             }
         }
     }
 }
Beispiel #2
0
 private static void RemoveGraphicFromDict(LW_Graphic graphic)
 {
     foreach (KeyValuePair <Material, LW_MaterialBuffer> kvp in s_MaterialDict)
     {
         LW_MaterialBuffer materialBuffer = kvp.Value;
         for (int i = 0; i < materialBuffer.vertexBuffers.Count; i++)
         {
             LW_VertexBuffer buffer = materialBuffer.vertexBuffers[i];
             if (buffer.graphic == graphic)
             {
                 if (!materialBuffer.emptyIndices.Contains(i))
                 {
                     materialBuffer.emptyIndices.Push(i);
                 }
             }
         }
     }
 }
Beispiel #3
0
        public static void Clean()
        {
            s_LastMaterial = null;

            if (s_DirtyTextures.Count > 0)
            {
                while (s_DirtyTextures.Count > 0)
                {
                    s_DirtyTextures.Pop().Apply();
                }
            }

            if (s_MaterialPoolDirty)
            {
                                #if UNITY_EDITOR || DEVELOPMENT
                if (s_DebugMaterialPool)
                {
                    Debug.Log("Clean MaterialPool");
                }
                                #endif

                s_ToRemoveFromDict.Clear();

                foreach (KeyValuePair <Material, LW_MaterialBuffer> kvp in s_MaterialDict)
                {
                    Material               poolMat        = kvp.Key;
                    LW_MaterialBuffer      materialBuffer = kvp.Value;
                    List <LW_VertexBuffer> vertexBuffers  = materialBuffer.vertexBuffers;
                    Stack <int>            emptyIndices   = materialBuffer.emptyIndices;

                    if (poolMat == null || vertexBuffers.Count == 0 || emptyIndices.Count == vertexBuffers.Count)
                    {
                        s_ToRemoveFromDict.Add(poolMat);
                    }
                    else
                    {
                        bool removeMaterialFromDict = true;

                        for (int i = 0; i < vertexBuffers.Count; i++)
                        {
                            if (emptyIndices.Contains(i))
                            {
                                continue;
                            }

                            LW_VertexBuffer buffer = vertexBuffers[i];
                            if (buffer.isValid && MaterialMatchesBuffer(poolMat, buffer) && poolMat.renderQueue == buffer.renderQueue)
                            {
                                removeMaterialFromDict = false;
                            }
                            else
                            {
                                                                #if UNITY_EDITOR || DEVELOPMENT
                                if (s_DebugMaterialPool)
                                {
                                    Debug.Log("Cleaning MaterialPool: vBuffer: " + i);
                                }
                                                                #endif

                                emptyIndices.Push(i);
                            }
                        }

                        if (removeMaterialFromDict)
                        {
                            s_ToRemoveFromDict.Add(poolMat);
                        }
                    }
                }

                for (int i = 0; i < s_ToRemoveFromDict.Count; i++)
                {
                    if (s_MaterialDict.ContainsKey(s_ToRemoveFromDict[i]))
                    {
                        s_MaterialDict.Remove(s_ToRemoveFromDict[i]);
                    }
                }

                s_MaterialPoolDirty = false;
            }
        }
Beispiel #4
0
        private static void RebuildStyleData(Material material, LW_MaterialBuffer materialBuffer, bool forceRebuild = false)
        {
            //Debug.Log("RebuildStyleData material: " + material.name);

            if (!(material != null && materialBuffer != null && materialBuffer.vertexBuffers != null && materialBuffer.isAdvancedShader && (forceRebuild || materialBuffer.isDirty)))
            {
                return;
            }

            List <LW_VertexBuffer> vertexBuffers = materialBuffer.vertexBuffers;
            Stack <int>            emptyIndices  = materialBuffer.emptyIndices;

            // Setup
            int       width          = s_GradientDataLength + s_GradientPrecision;
            int       height         = vertexBuffers.Count;
            bool      hasChanged     = false;
            bool      rebuildAllRows = forceRebuild;
            Texture2D styleData      = material.GetTexture("_StyleData") as Texture2D;

            // Resizing StyleData
            if (styleData != null)
            {
                if (styleData.height < height)
                {
                    int     oldHeight = styleData.height;
                    int     oldWidth  = styleData.width;
                    Color[] pixels    = styleData.GetPixels();
                    styleData.Resize(width, height, TextureFormat.RGBAFloat, false);
                    styleData.SetPixels(0, 0, oldWidth, oldHeight, pixels, 0);
                    material.SetVector("_StyleDataSize", new Vector4(width, height, s_GradientDataLength, s_GradientPrecision));
                    hasChanged = true;
                }
                else if (styleData.height > height)
                {
                    styleData = null;
                }
            }

            // Creating StyleData
            if (styleData == null)
            {
                styleData            = new Texture2D(width, height, TextureFormat.RGBAFloat, false);
                styleData.hideFlags  = HideFlags.DontSave;
                styleData.filterMode = FilterMode.Bilinear;
                styleData.wrapMode   = TextureWrapMode.Clamp;
                styleData.anisoLevel = 0;
                material.SetTexture("_StyleData", styleData);
                material.SetVector("_StyleDataSize", new Vector4(width, height, s_GradientDataLength, s_GradientPrecision));
                hasChanged     = true;
                rebuildAllRows = true;
            }

            // Updating StyleData
            for (int i = 0; i < vertexBuffers.Count; i++)
            {
                int index = i;

                LW_VertexBuffer buffer = vertexBuffers[i];


                if (buffer.isEmpty || emptyIndices.Contains(i) || (buffer.styleDataIndex == index && !buffer.style.isDirty && !rebuildAllRows))
                {
                    continue;
                }

                //Debug.Log("buffer.styleDataIndex = " + index);

                hasChanged            = true;
                buffer.styleDataIndex = index;

                //LW_Graphic graphic = buffer.graphic;
                //LW_Canvas canvas = buffer.canvas;
                LW_PaintStyle style = buffer.style as LW_PaintStyle;

                float boundsMin = Mathf.Min(buffer.bounds.min.x, buffer.bounds.min.y);
                float boundsMax = Mathf.Max(buffer.bounds.max.x, buffer.bounds.max.y);

                float strokeJustification   = -1;
                float strokeWidth           = 0;
                float strokeLength          = 0;
                float screenSpaceMiterLimit = 0;
                float caps  = -1;
                float joins = -1;

                // Vertex Data
                if (style is LW_Stroke)
                {
                    LW_Stroke stroke = style as LW_Stroke;
                    strokeJustification   = ((int)stroke.justification - 1);
                    strokeWidth           = stroke.MaxWidth();
                    strokeLength          = buffer.totalLength;
                    screenSpaceMiterLimit = stroke.screenSpace ? stroke.miterLimit : -stroke.miterLimit;
                    caps  = (int)stroke.linecap;
                    joins = (int)stroke.linejoin;
                }

                if (style is LW_Fill)
                {
                    strokeWidth  = buffer.bounds.size.y;
                    strokeLength = buffer.bounds.size.x;
                    caps         = (int)Linecap.Round;
                    joins        = (int)Linejoin.Round;
                }

                // Fragment Data
                Matrix4x4 gradTransform = style.gradientUnits == GradientUnits.objectBoundingBox ?
                                          style.BoundsToLocalMatrix(buffer.bounds) * style.gradientTransform * style.LocalToBoundsMatrix(buffer.bounds) :
                                          style.gradientTransform;
                Vector2 start             = gradTransform.MultiplyPoint(style.gradientStart);
                Vector2 end               = gradTransform.MultiplyPoint(style.gradientEnd);
                Vector2 gradientDirection = end - start;
                float   gradAngle         = Mathf.Atan2(gradientDirection.x, gradientDirection.y);
                float   gradScale         = gradientDirection.magnitude;

                styleData.SetPixel(0, index, new Color(screenSpaceMiterLimit, strokeJustification, strokeWidth, strokeLength));
                styleData.SetPixel(1, index, new Color((int)style.uvMode, (int)style.gradientUnits, boundsMin, boundsMax));
                styleData.SetPixel(2, index, new Color(start.x, start.y, (int)style.gradientSpreadMethod, (int)style.paintMode));
                styleData.SetPixel(3, index, new Color(gradAngle, gradScale, caps, joins));

                for (int p = 0; p < s_GradientPrecision + 1; p++)
                {
                    float percentage = (float)p / (float)s_GradientPrecision;
                    Color color      = style.ColorAtPercentage(percentage);
                    styleData.SetPixel(s_GradientDataLength + p, i, color);
                }
            }

            if (hasChanged)
            {
                if (!s_DirtyTextures.Contains(styleData))
                {
                    s_DirtyTextures.Push(styleData);
                }
            }

            materialBuffer.isDirty = false;
        }
Beispiel #5
0
        public static Material Get(LW_VertexBuffer buffer)
        {
            if (!buffer.isValid)
            {
                return(null);
            }

            // Setup
            Material material = null;

            // Check for Custom Materials
            LW_PaintStyle style = buffer.style as LW_PaintStyle;

            if (style.material != null)
            {
                material           = style.material;
                buffer.renderQueue = material.renderQueue;
            }
            else if (buffer.canvas.material != null)
            {
                material           = buffer.canvas.material;
                buffer.renderQueue = material.renderQueue;
            }

            // Check Last Material and Update RenderQue If needed.
            if (material == null)
            {
                buffer.renderQueue = GetRenderQueue(buffer);

                if (s_LastMaterial != null && buffer.renderQueue < s_LastMaterial.renderQueue)
                {
                    buffer.renderQueue = s_LastMaterial.renderQueue + 1;
                }

                if (s_LastMaterial != null && MaterialMatchesBuffer(s_LastMaterial, buffer))
                {
                    material = s_LastMaterial;
                }
            }

            // Check Material Dictionary for Match
            if (material == null)
            {
                foreach (KeyValuePair <Material, LW_MaterialBuffer> kvp in s_MaterialDict)
                {
                    if (kvp.Key == null)
                    {
                        continue;
                    }

                    Material poolMat = kvp.Key;

                    if (MaterialMatchesBuffer(poolMat, buffer) && poolMat.renderQueue == buffer.renderQueue)
                    {
                        material = kvp.Key;
                        break;
                    }
                }
            }

            // Check Material Dictionary for Unused Material
            if (material == null)
            {
                foreach (KeyValuePair <Material, LW_MaterialBuffer> kvp in s_MaterialDict)
                {
                    if (kvp.Key == null)
                    {
                        continue;
                    }

                    Material poolMat = kvp.Key;
                    List <LW_VertexBuffer> bufferList = kvp.Value.vertexBuffers;

                    if (bufferList == null || bufferList.Count == 0 || (bufferList.Count == 1 && bufferList[0] == buffer))
                    {
                        material = poolMat;
                        MatchMaterialToBuffer(material, buffer);
                        break;
                    }
                }
            }

            // Create New Material
            if (material == null)
            {
                Shader shader = defaultShader;
                if (shader == null)
                {
                    Debug.Log("LineWorks Shader: \"LineWorks/Default\" is Missing. Make sure required LineWorks Shader is included in the scene or in a Resources Folder. Using UI/Default shader but Vector Graphics may not display correctly.");
                    shader = Shader.Find("UI/Default");
                }
                material           = new Material(shader);
                material.hideFlags = HideFlags.DontSave;
                material.name      = string.Format("LineWorks Material {0}", s_MaterialNameCount++);
                MatchMaterialToBuffer(material, buffer);
            }

            //MatchMaterialToBuffer(material, buffer);

            // Add Material to Dictionary if needed.
            LW_MaterialBuffer materialBuffer = null;

            if (s_MaterialDict.ContainsKey(material))
            {
                materialBuffer = s_MaterialDict[material];
                List <LW_VertexBuffer> vertexBuffers = materialBuffer.vertexBuffers;
                Stack <int>            emptyIndices  = materialBuffer.emptyIndices;

                if (!vertexBuffers.Contains(buffer))
                {
                    if (emptyIndices.Count > 0)
                    {
                        vertexBuffers[emptyIndices.Pop()] = buffer;
                    }
                    else
                    {
                        vertexBuffers.Add(buffer);
                    }
                    buffer.styleDataIndex = -1;
                }
            }
            else
            {
                materialBuffer = new LW_MaterialBuffer();
                materialBuffer.vertexBuffers.Add(buffer);
                s_MaterialDict.Add(material, materialBuffer);
                buffer.styleDataIndex = -1;
            }

            materialBuffer.isDirty           = !buffer.isValid || buffer.style.isDirty || buffer.styleDataIndex == -1;
            materialBuffer.isLineWorksShader = material.shader.name.StartsWith("LineWorks");
            materialBuffer.isAdvancedShader  = materialBuffer.isLineWorksShader && material.IsKeywordEnabled("_ADVANCED_ON");

            // Finish
            s_LastMaterial = material;

            return(material);
        }