成都匠心互动

利用unity3D Gl图形库绘制鼠标轨迹

2017-04-25  本文已影响45人  爱喝粥的西瓜

初心

一开始的时候是想在一张图上进行涂鸦,经过寻找,在unity中,可以通过GL图形库,来绘制线条,以达到涂鸦的效果。

代码实现

简单的添加了改变线条颜色和线条粗细的功能,在一定程度上可以撤销操作和断点绘制
ps:装13的英文注释请忽略

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class DrawLineByCursor: MonoBehaviour
{
    //  the line's Material
    private Material m_LineMaterial;
    public Material LineMaterial
    {
        get { return m_LineMaterial; }
    }
    //  MousePosition Data
    private List<List<Vector3>> m_LineInfo;
    //  the line's Width
    public int m_Width = 1;

    public Color LineColor = Color.black;

    //  MouseButtonUp Count
    private int currentID;

    // Use this for initialization
    void Start ()
    {
        currentID = 0;
        //  Create List
        m_LineInfo = new List<List<Vector3>>();
    }
    
    // Update is called once per frame
    void Update ()
    {
        //  the Left mouseButton Up stop recording the mousePosition to this list
        if (Input.GetMouseButtonUp(0))
        {
            currentID += 1;
        }
        // the left mouseButton Down create new mousePosition list
        if (Input.GetMouseButtonDown(0))
        {
            List<Vector3> tmp = new List<Vector3>();
            m_LineInfo.Add(tmp);
        }
        if (Input.GetMouseButton(0))
        {
            m_LineInfo[currentID].Add(Input.mousePosition);
        }

        if (Input.GetKeyDown(KeyCode.C))
            ClearAll();
        if (Input.GetKeyDown(KeyCode.Z))
            Undo();
    }

    //  Draw Line by system
    void OnPostRender()
    {
        //  create the line's shader
        if (m_LineMaterial == null)
            CreateLineShader();
        //  set the Ortho
        GL.LoadOrtho();
        //  filtration the material
        m_LineMaterial.SetPass(0);
        //  strat Draw line
        GL.Begin(GL.LINES);
        //  Get the need draw line Count
        int size = m_LineInfo.Count;
        if (size != 0)
        {
            //  draw line one by one
            for (int i = 0; i < size; ++i)
            {
                for (int j = 0; j < m_LineInfo[i].Count - 1; ++j)
                {
                    Vector3 start = m_LineInfo[i][j];
                    Vector3 end = m_LineInfo[i][j + 1];
                    GL.Color(LineColor);
                    DrawLine(start.x, start.y, start.z, end.x, end.y, end.z, m_Width);
                }
            }
        }
        GL.End();
        
    }

    //  DrawLine procedure
    void DrawLine(float x1, float y1, float z1, float x2, float y2, float z2, int width)
    {
        for (int i = 0; i < width; ++i)
        {
            int iTmp = width / 2;
            // Draw current line
            GL.Vertex3(x1 / Screen.width, y1 / Screen.height, z1);
            GL.Vertex3(x2 / Screen.width, y2 / Screen.height, z2);
            //  Draw Left
            if (i % 2 == 0)
            {
                for (int j = -iTmp; j < iTmp; ++j)
                {
                    GL.Vertex3((x1 - (i / 2)) / Screen.width, (y1 + j) / Screen.height, z1);
                    GL.Vertex3((x2 - (i / 2)) / Screen.width, (y2 + j) / Screen.height, z2);
                }
            }
            //  Draw Right
            else
            {
                for (int j = -iTmp; j < iTmp; ++j)
                {
                    GL.Vertex3((x1 + (i / 2)) / Screen.width, (y1 + j) / Screen.height, z1);
                    GL.Vertex3((x2 + (i / 2)) / Screen.width, (y2 + j) / Screen.height, z2);
                }
            }
        }
    }


    //  Create LineShader
    private  void CreateLineShader()
    {
        Shader shader = Shader.Find("Hidden/Internal-Colored");
        m_LineMaterial = new Material(shader);
        m_LineMaterial.hideFlags = HideFlags.HideAndDontSave;

        m_LineMaterial.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
        m_LineMaterial.SetInt("_DstBlend",(int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);

        m_LineMaterial.SetInt("_Cull",(int)UnityEngine.Rendering.CullMode.Off);

        m_LineMaterial.SetInt("_ZWrite", 0);
    }

    // ClearAll
    public void ClearAll()
    {
        m_LineInfo.Clear();
        currentID = 0;
    }

    // Undo
    public void Undo()
    {
        if (currentID > 0)
            currentID--;
        m_LineInfo.RemoveAt(currentID);
    }
}

附注
在使用过程中,尝试使用unity创建完成的材质球,发现无法改变线条的颜色,所以动态创建了材质,如果有大神知道如何使用通过unity创建的材质球,烦请指点

上一篇 下一篇

猜你喜欢

热点阅读