Unity画线之GL

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/n_moling/article/details/88546672

上一篇中,SetPixel的方法,卡顿严重,暂未解决,又去看了原来的GL画线,自己画图思考了一下适配UI的问题,最终解决。

特此说明,GL画线功能,及Shader均为借鉴,自己做了优化。

程序代码如下:

(MouseOverController.GetOverUI(UIManager.GetInstance().GetCanvas().gameObject) == null   这句为UI判断)

using UnityEngine;
using UnityEngine.UI;

namespace LastZero.Utility
{
    public class Painting: MonoBehaviour {

        public Texture brushTexture;//画笔
        private float brushScale = 0.1f;//画笔大小
        private Color mColor = Color.black;//画笔颜色
        private RenderTexture texRender;//接收图的RenderTexture
        private Material mat;//材质球
        private RawImage rImage;//RawImage,自身
        private RectTransform rTransform;//RectTransform

        private Vector3 startPosition = Vector3.zero;
        private Vector3 endPosition = Vector3.zero;

        private Vector2 posOffset;

        private void Start()
        {
            SetPainting();
            posOffset.Set((Screen.width - rTransform.sizeDelta.x) / 2 + transform.position.x - transform.root.position.x , (Screen.height - rTransform.sizeDelta.y) / 2 + transform.position.y - transform.root.position.y );
        }

        void Update()
        {
            if (MouseOverController.GetOverUI(UIManager.GetInstance().GetCanvas().gameObject) == null)
            {
                EndPainting();
                return;
            }

            if (Input.GetMouseButton(0))
            {
                StartPainting(new Vector3(Input.mousePosition.x -posOffset.x, Input.mousePosition.y - posOffset.y, 0));
            }
            if (Input.GetMouseButtonUp(0))
            {
                EndPainting();
            }
        }

        /// <summary>
        /// 初始化设置
        /// </summary>
        public void SetPainting()
        {
            rTransform = GetComponent<RectTransform>();
            mat = new Material(Shader.Find("Custom/Painting"));
            texRender = new RenderTexture((int)rTransform.sizeDelta.x, (int)rTransform.sizeDelta.y, 24, RenderTextureFormat.ARGB32);
            Clear(texRender);
            rImage = GetComponent<RawImage>();
            rImage.texture = texRender;
        }

        /// <summary>
        /// 开始画线
        /// </summary>
        /// <param name="pos"></param>
        public void StartPainting(Vector3 pos)
        {
            endPosition = pos;

            if (startPosition.Equals(Vector3.zero))
            {
                startPosition = endPosition;
                return;
            }

            float distance = Vector3.Distance(startPosition, endPosition);
            if (distance > 1)
            {
                int d = (int)distance;
                for (int i = 0; i < d; i++)
                {
                    float difx = endPosition.x - startPosition.x;
                    float dify = endPosition.y - startPosition.y;
                    float delta = (float)i / distance;
                    DrawBrush(texRender, new Vector2(startPosition.x + (difx * delta), startPosition.y + (dify * delta)), brushTexture, mColor, brushScale);
                }
            }
            startPosition = endPosition;
        }
        
        /// <summary>
        /// 结束画线
        /// </summary>
        public void EndPainting()
        {
            startPosition = Vector3.zero;
        }
       
        private void DrawBrush(RenderTexture destTexture, Vector2 pos, Texture sourceTexture, Color color, float scale)
        {
            DrawBrush(destTexture, (int)pos.x, (int)pos.y, sourceTexture, color, scale);
        }

        private void DrawBrush(RenderTexture destTexture, int x, int y, Texture sourceTexture, Color color, float scale)
        {
            DrawBrush(destTexture, new Rect(x, y, sourceTexture.width, sourceTexture.height), sourceTexture, color, scale);
        }

        private void DrawBrush(RenderTexture destTexture, Rect destRect, Texture sourceTexture, Color color, float scale)
        {
            float left = destRect.xMin - destRect.width * scale / 2.0f;
            float right = destRect.xMin + destRect.width * scale / 2.0f;
            float top = destRect.yMin - destRect.height * scale / 2.0f;
            float bottom = destRect.yMin + destRect.height * scale / 2.0f;

            GL.PushMatrix();
            GL.LoadOrtho();

            mat.SetTexture("_MainTex", brushTexture);
            mat.SetColor("_Color", color);
            mat.SetPass(0);

            GL.Begin(GL.QUADS);

            GL.TexCoord2(0.0f, 0.0f); GL.Vertex3(left / (int)rTransform.sizeDelta.x, top / (int)rTransform.sizeDelta.y, 0);
            GL.TexCoord2(1.0f, 0.0f); GL.Vertex3(right / (int)rTransform.sizeDelta.x, top / (int)rTransform.sizeDelta.y, 0);
            GL.TexCoord2(1.0f, 1.0f); GL.Vertex3(right / (int)rTransform.sizeDelta.x, bottom / (int)rTransform.sizeDelta.y, 0);
            GL.TexCoord2(0.0f, 1.0f); GL.Vertex3(left / (int)rTransform.sizeDelta.x, bottom / (int)rTransform.sizeDelta.y, 0);

            GL.End();
            GL.PopMatrix();
        }

        /// <summary>
        /// 重置RenderTexture
        /// </summary>
        /// <param name="destTexture"></param>
        private void Clear(RenderTexture destTexture)
        {
            Graphics.SetRenderTarget(destTexture);
            GL.PushMatrix();
            GL.Clear(true, true, Color.white);
            GL.PopMatrix();
        }

        /// <summary>
        /// 外部可以调用的重置修改的RenderTexture
        /// </summary>
        public void ClearAll()
        {
            Clear(texRender);
        }
    }
}

Shader:

Shader "Custom/Painting"
{
	Properties
	{
		_MainTex("MainTex (RGB) Trans (A)", 2D) = "white" {}
	_Color("Color", Color) = (1,1,1,1)
	}

		SubShader
	{
		Tags
	{
		"Queue" = "Transparent"
		"IgnoreProjector" = "True"
		"RenderType" = "Transparent"
		"PreviewType" = "Plane"
		"CanUseSpriteAtlas" = "True"
	}

		Cull Off
		Lighting Off
		ZWrite Off
		Fog{ Mode Off }
		Blend One OneMinusSrcAlpha

		Pass
	{
		CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"

		struct v2f
	{
		float4 vertex : SV_POSITION;
		half2 texcoord : TEXCOORD0;
	};

	fixed4 _Color;

	v2f vert(appdata_base IN)
	{
		v2f OUT;
		OUT.vertex = mul(UNITY_MATRIX_MVP, IN.vertex);
		OUT.texcoord = IN.texcoord;
		return OUT;
	}

	sampler2D _MainTex;

	fixed4 frag(v2f IN) : SV_Target
	{
		float4 col = _Color * tex2D(_MainTex, IN.texcoord);
		col.rgb *= col.a;
		return col;
	}
		ENDCG
	}
	}
}

猜你喜欢

转载自blog.csdn.net/n_moling/article/details/88546672
今日推荐