internal override void CopyPropertiesFrom(LW_Element element) { LW_PaintStyle style = element as LW_PaintStyle; if (style != null) { m_Material = style.m_Material; m_MainTexture = style.m_MainTexture; m_PaintMode = style.m_PaintMode; m_UvMode = style.m_UvMode; m_UvTiling = style.m_UvTiling; m_UvOffset = style.m_UvOffset; if (style.m_GradientColors != null) { m_GradientColors = new List <LW_ColorStop>(style.m_GradientColors); } else { m_GradientColors = null; } m_GradientPosition = style.m_GradientPosition; m_GradientRotation = style.m_GradientRotation; m_GradientScale = style.m_GradientScale; m_GradientSpreadMethod = style.m_GradientSpreadMethod; m_GradientUnits = style.m_GradientUnits; m_GradientStart = style.m_GradientStart; m_GradientEnd = style.m_GradientEnd; m_Opacity = style.m_Opacity; } base.CopyPropertiesFrom(element); }
private static bool MaterialMatchesBuffer(Material material, LW_VertexBuffer buffer) { LW_PaintStyle style = buffer.style as LW_PaintStyle; LW_Canvas canvas = buffer.canvas; // Get Custom Material Material customMaterial = style.material != null ? style.material : (canvas.material != null ? canvas.material : null); bool isLineWorksShader = customMaterial == null || customMaterial.shader.name.StartsWith("LineWorks"); // Get Buffer Textures Texture bufferTexture = style.mainTexture != null ? style.mainTexture : canvas.mainTexture != null ? canvas.mainTexture : null; Vector2 bufferUvOffset = style.mainTexture != null ? style.uvOffset : Vector2.zero; Vector2 bufferUvTiling = style.mainTexture != null ? style.uvTiling : Vector2.one; // Get Material Textures Texture materialTexture = isLineWorksShader ? material.GetTexture("_MainTex") : null; Vector2 materialUvOffset = isLineWorksShader ? material.GetTextureOffset("_MainTex") : Vector2.zero; Vector2 materialUvTiling = isLineWorksShader ? material.GetTextureScale("_MainTex") : Vector2.one; Texture bufferCapTexture = null; Texture bufferJoinTexture = null; if (style is LW_Stroke) { LW_Stroke stroke = style as LW_Stroke; bufferCapTexture = stroke.linecap == Linecap.Texture ? stroke.capTexture : null; bufferJoinTexture = stroke.linejoin == Linejoin.Texture ? stroke.joinTexture : null; } Texture materialCapTexture = isLineWorksShader && material.HasProperty("_CapTex") ? material.GetTexture("_CapTex") : null; Texture materialJoinTexture = isLineWorksShader && material.HasProperty("_JoinTex") ? material.GetTexture("_JoinTex") : null; // Check for Match bool isMatch = customMaterial != null && customMaterial == material || ( customMaterial == null && bufferCapTexture == materialCapTexture && bufferJoinTexture == materialJoinTexture && bufferTexture == materialTexture && bufferUvOffset == materialUvOffset && bufferUvTiling == materialUvTiling && ( (canvas.blendMode == BlendMode.Opaque && !material.IsKeywordEnabled("_BLEND_ALPHATEST") && !material.IsKeywordEnabled("_BLEND_ALPHABLEND") && !material.IsKeywordEnabled("_BLEND_UI") && !material.IsKeywordEnabled("_BLEND_ADDITIVESOFT")) || (canvas.blendMode == BlendMode.AlphaTest && material.IsKeywordEnabled("_BLEND_ALPHATEST")) || (canvas.blendMode == BlendMode.AlphaBlend && material.IsKeywordEnabled("_BLEND_ALPHABLEND")) || (canvas.blendMode == BlendMode.UI && material.IsKeywordEnabled("_BLEND_UI")) || (canvas.blendMode == BlendMode.AdditiveSoft && material.IsKeywordEnabled("_BLEND_ADDITIVESOFT")) ) && ( ( (canvas.featureMode == FeatureMode.Advanced && material.IsKeywordEnabled("_ADVANCED_ON")) || (canvas.featureMode == FeatureMode.Simple && !material.IsKeywordEnabled("_ADVANCED_ON")) ) && ( (canvas.strokeDrawMode == StrokeDrawMode.Draw3D && material.IsKeywordEnabled("_STROKE_3D")) || ((canvas.featureMode == FeatureMode.Simple || canvas.strokeDrawMode == StrokeDrawMode.Draw2D) && !material.IsKeywordEnabled("_STROKE_3D")) ) && ( ((canvas.featureMode == FeatureMode.Simple || canvas.strokeScaleMode == StrokeScaleMode.Scaled) && !material.IsKeywordEnabled("_STROKE_UNSCALED") && !material.IsKeywordEnabled("_STROKE_SCREENSPACE")) || (canvas.strokeScaleMode == StrokeScaleMode.Unscaled && material.IsKeywordEnabled("_STROKE_UNSCALED")) || (canvas.strokeScaleMode == StrokeScaleMode.ScreenSpace && material.IsKeywordEnabled("_STROKE_SCREENSPACE")) ) && ( (canvas.joinsAndCapsMode == JoinsAndCapsMode.Shader && material.IsKeywordEnabled("_JOINSCAPS_ON")) || ((canvas.featureMode == FeatureMode.Simple || canvas.joinsAndCapsMode != JoinsAndCapsMode.Shader) && !material.IsKeywordEnabled("_JOINSCAPS_ON")) ) && ( (canvas.gradientsMode == GradientsMode.Shader && material.IsKeywordEnabled("_GRADIENTS_ON")) || ((canvas.featureMode == FeatureMode.Simple || canvas.gradientsMode != GradientsMode.Shader) && !material.IsKeywordEnabled("_GRADIENTS_ON")) ) && ( (canvas.antiAliasingMode == AntiAliasingMode.On && material.IsKeywordEnabled("_ANTIALIAS_ON")) || ((canvas.featureMode == FeatureMode.Simple || canvas.antiAliasingMode != AntiAliasingMode.On) && !material.IsKeywordEnabled("_ANTIALIAS_ON")) ) ) ); /* * Debug.Log(material.name + " == " + buffer.style.name + * "(" + (customMaterial != null) + " && " + (customMaterial == material) + ")" + " || (" + (customMaterial == null) + " && " + (bufferTexture == materialTexture) + " && " + (bufferUvOffset == materialUvOffset) + " && " + (bufferUvTiling == materialUvTiling) + " && (" + (canvas.blendMode == BlendMode.Opaque && !material.IsKeywordEnabled("_BLEND_ALPHATEST") && !material.IsKeywordEnabled("_BLEND_ALPHABLEND") && !material.IsKeywordEnabled("_BLEND_UI") && !material.IsKeywordEnabled("_BLEND_ADDITIVESOFT")) + " || " + (canvas.blendMode == BlendMode.AlphaTest && material.IsKeywordEnabled("_BLEND_ALPHATEST")) + " || " + (canvas.blendMode == BlendMode.AlphaBlend && material.IsKeywordEnabled("_BLEND_ALPHABLEND")) + " || " + (canvas.blendMode == BlendMode.UI && material.IsKeywordEnabled("_BLEND_UI")) + " || " + (canvas.blendMode == BlendMode.AdditiveSoft && material.IsKeywordEnabled("_BLEND_ADDITIVESOFT")) + ") && (" + //+ !isAdvancedShader + //+ " || ((" + (canvas.featureMode == FeatureMode.Advanced && material.IsKeywordEnabled("_ADVANCED_ON")) + " || " + (canvas.featureMode == FeatureMode.Simple && !material.IsKeywordEnabled("_ADVANCED_ON")) + ") && (" + (canvas.strokeDrawMode == StrokeDrawMode.Draw3D && material.IsKeywordEnabled("_STROKE_3D")) + " || " + ((canvas.featureMode == FeatureMode.Simple || canvas.strokeDrawMode == StrokeDrawMode.Draw2D) && !material.IsKeywordEnabled("_STROKE_3D")) + ") && (" + ((canvas.featureMode == FeatureMode.Simple || canvas.strokeScaleMode == StrokeScaleMode.Scaled) && !material.IsKeywordEnabled("_STROKE_UNSCALED") && !material.IsKeywordEnabled("_STROKE_SCREENSPACE")) + " || " + (canvas.strokeScaleMode == StrokeScaleMode.Unscaled && material.IsKeywordEnabled("_STROKE_UNSCALED")) + " || " + (canvas.strokeScaleMode == StrokeScaleMode.ScreenSpace && material.IsKeywordEnabled("_STROKE_SCREENSPACE")) + ") && (" + (canvas.joinsAndCapsMode == JoinsAndCapsMode.Shader && material.IsKeywordEnabled("_JOINSCAPS_ON")) + " || " + ((canvas.featureMode == FeatureMode.Simple || canvas.joinsAndCapsMode != JoinsAndCapsMode.Shader) && !material.IsKeywordEnabled("_JOINSCAPS_ON")) + ") && (" + (canvas.gradientsMode == GradientsMode.Shader && material.IsKeywordEnabled("_GRADIENTS_ON")) + " || " + ((canvas.featureMode == FeatureMode.Simple || canvas.gradientsMode != GradientsMode.Shader) && !material.IsKeywordEnabled("_GRADIENTS_ON")) + ") && (" + (canvas.antiAliasingMode == AntiAliasingMode.On && material.IsKeywordEnabled("_ANTIALIAS_ON")) + " || " + ((canvas.featureMode == FeatureMode.Simple || canvas.antiAliasingMode != AntiAliasingMode.On) && !material.IsKeywordEnabled("_ANTIALIAS_ON")) + ")))" + ); */ return(isMatch); }
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; }
private static void MatchMaterialToBuffer(Material material, LW_VertexBuffer buffer) { // Setup LW_PaintStyle style = buffer.style as LW_PaintStyle; LW_Canvas canvas = buffer.canvas; Material customMaterial = style.material != null ? style.material : (canvas.material != null ? canvas.material : null); bool isLineWorksShader = customMaterial == null || customMaterial.shader.name.StartsWith("LineWorks"); bool isCustomMaterial = customMaterial != null; // Update LineWorks Material to Match Buffer if (isLineWorksShader && !isCustomMaterial) { Shader shader = defaultShader; if (material.shader != shader) { material.shader = shader; } // this was from a previous version where the width and color property were directly applied to the material. //if (style is LW_Stroke) { // LW_Stroke stroke = style as LW_Stroke; // if (material.GetFloat("_Width") != stroke.widthMultiplier) material.SetFloat("_Width", stroke.widthMultiplier); //} //if (material.GetColor("_Color") != style.color) material.SetColor("_Color", style.color); Texture2D texture = style.mainTexture != null ? style.mainTexture : canvas.mainTexture != null ? canvas.mainTexture : null; Vector2 uvOffset = style.mainTexture != null ? style.uvOffset : Vector2.zero; Vector2 uvTiling = style.mainTexture != null ? style.uvTiling : Vector2.one; if (material.GetTexture("_MainTex") != texture) { material.SetTexture("_MainTex", texture); } if (material.GetTextureOffset("_MainTex") != uvOffset) { material.SetTextureOffset("_MainTex", uvOffset); } if (material.GetTextureScale("_MainTex") != uvTiling) { material.SetTextureScale("_MainTex", uvTiling); } if (style is LW_Stroke) { LW_Stroke stroke = style as LW_Stroke; if (stroke.linecap == Linecap.Texture && stroke.capTexture != null && material.GetTexture("_CapTex") != stroke.capTexture) { material.SetTexture("_CapTex", stroke.capTexture); } if (stroke.linejoin == Linejoin.Texture && stroke.joinTexture != null && material.GetTexture("_JoinTex") != stroke.joinTexture) { material.SetTexture("_JoinTex", stroke.joinTexture); } } SetMaterialPopups(material, buffer); SetMaterialKeywords(material); } material.renderQueue = buffer.renderQueue; //if (isAdvancedShader) RebuildStyleData(material, s_MaterialDict[material]); }
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); }