internal override void CopyPropertiesFrom(LW_Element element) { LW_Stroke stroke = element as LW_Stroke; if (stroke != null) { m_GlobalWidth = stroke.m_GlobalWidth; if (stroke.m_VariableWidths != null) { m_VariableWidths = new List <LW_WidthStop>(stroke.m_VariableWidths); } else { m_VariableWidths = null; } m_SpaceWidthsEvenly = stroke.m_SpaceWidthsEvenly; m_SpaceColorsEvenly = stroke.m_SpaceColorsEvenly; m_ScreenSpace = stroke.m_ScreenSpace; m_Linecap = stroke.m_Linecap; m_Linejoin = stroke.m_Linejoin; m_MiterLimit = stroke.m_MiterLimit; m_Justification = stroke.m_Justification; m_Angle = stroke.m_Angle; } base.CopyPropertiesFrom(element); }
public static LW_Stroke Create(Color color = default(Color), float width = 1f) { LW_Stroke instance = CreateInstance <LW_Stroke>(); instance.Set(color, width); return(instance); }
internal override void CopyPropertiesFrom(LW_Element element) { LW_Marker marker = element as LW_Marker; if (marker != null) { m_Graphic = marker.m_Graphic; m_Position = marker.m_Position; m_EulerRotation = marker.m_EulerRotation; m_Scale = marker.m_Scale; m_ScaleWithStroke = marker.m_ScaleWithStroke; m_Stroke = marker.m_Stroke; m_VariableScales = marker.m_VariableScales; m_AtStart = marker.m_AtStart; m_AtMiddle = marker.m_AtMiddle; m_AtEnd = marker.m_AtEnd; m_FlipEnd = marker.m_FlipEnd; m_FaceForward = marker.m_FaceForward; m_PlacementMode = marker.m_PlacementMode; m_FixedSpacingLength = marker.m_FixedSpacingLength; m_FixedJustification = marker.m_FixedJustification; m_NumberOfMarkers = marker.m_NumberOfMarkers; } base.CopyPropertiesFrom(element); }
public override void SetElementDirty() { if (m_ScaleWithStroke && m_Stroke == null && m_OnElementDirtyCallback != null) { LW_Styles styles = m_OnElementDirtyCallback.Target as LW_Styles; if (styles != null) { for (int i = 0; i < styles.Count; i++) { if (styles[i] is LW_Stroke) { m_Stroke = styles[i] as LW_Stroke; } } } } base.SetElementDirty(); }
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]); }