Unity3D OpenGL实现画符功能

发表于2018-07-09
评论0 2.5k浏览
本篇文章主要和大家分享Unity3D用OpenGL实现画符的功能,仅供参考。

一、实现一笔画符
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class DrawFu : MonoBehaviour {
    //第一步 屏幕写东西
    //1.记录屏幕上画的点  List 存储 鼠标输入点
    //1.1 视图坐标系  以屏幕分辨率大小为参考物(1024*768) 右上角(1,1) 左下角(0,0) UV坐标系
    //1.2 屏幕坐标系  以屏幕分辨率大小为参考物(1024*768) 右上角(1024,768,0) 左下角(0,0,0)
    //1.3 世界坐标系  以(0,0,0) 为起点
    //1.4 物体坐标系  以 父类 为参考物
    //2.显示点    输入点 链接起来
    //2.1  放一个image 当做画布
    //第二步 屏幕上写的东西映射到旗上 
    //1.在图片上生成对应的像素点
    //2.将 图片放到旗上
    private Image testImage;
    //存储所有点
    private List<Vector2> allPoints;
    //
    private Material targetMaterial;
    private void Start()
    {
        testImage = transform.GetComponent<Image>();
        allPoints = new List<Vector2>();
        targetMaterial = transform.GetComponent<Renderer>().material;
    }
    private void Update()
    {
        if (Input.GetMouseButton(0))
        {
            //获得鼠标的视图坐标系坐标
            Vector2 viewPoint = Camera.main.ScreenToViewportPoint(Input.mousePosition);
            allPoints.Add(viewPoint);
        }
        if (Input.GetMouseButtonUp(0))
        {
            GenerateTexture();
        }
    }
    public void GenerateTexture()
    {
        Texture2D temTexture = new Texture2D(300, 400);
        for (int i = 1; i < allPoints.Count; i++)
        {
            //前一个点
            Vector2 temPos = allPoints[i - 1];
            //后一个点
            Vector2 temBack = allPoints[i];
            //插值100次
            for (int j = 0; j < 100; j++)
            {
                //插值的比例
                float temxx = Mathf.Lerp(temPos.x, temBack.x, j / 100.0f);
                //插值的比例
                float temyy = Mathf.Lerp(temPos.y, temBack.y, j / 100.0f);
                //得到所有的比例点
                int xx = (int)(temTexture.width * temxx);
                int yy = (int)(temTexture.width * temyy);
                //赋值 画出点
                temTexture.SetPixel(xx, yy, Color.red);
            }
        }
        temTexture.Apply();
        targetMaterial.SetTexture("_MainTex", temTexture);
        allPoints.Clear();
    }
    static Material lineMaterial;
    static void CreateLineMaterial()
    {
        if (!lineMaterial)
        {
            // Unity has a built-in shader that is useful for drawing
            // simple colored things.
            Shader shader = Shader.Find("Hidden/Internal-Colored");
            lineMaterial = new Material(shader);
            lineMaterial.hideFlags = HideFlags.HideAndDontSave;
            // Turn on alpha blending
            lineMaterial.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
            lineMaterial.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
            // Turn backface culling off
            lineMaterial.SetInt("_Cull", (int)UnityEngine.Rendering.CullMode.Off);
            // Turn off depth writes
            lineMaterial.SetInt("_ZWrite", 0);
        }
    }
    // Will be called after all regular rendering is done
    public void OnRenderObject()
    {
        CreateLineMaterial();
        // Apply the line material
        lineMaterial.SetPass(0);
        GL.PushMatrix();
        //将透视投影改为正交投影
        GL.LoadOrtho();
        // 划线开始
        GL.Begin(GL.LINES);
        //划线颜色
        GL.Color(Color.red);
        for (int i  = 1; i  < allPoints.Count; i ++)
        {
            //前一个点
            Vector2 temPos = allPoints[i - 1];
            //后一个点
            Vector2 temBack = allPoints[i];
            //起点
            GL.Vertex3(temPos.x, temPos.y, 0);
            //终点
            GL.Vertex3(temBack.x, temBack.y, 0);
        }
        //划线结束
        GL.End();
        GL.PopMatrix();
    }
}

二、实现多笔画符 存在问题 暂时不对
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class DrawFu : MonoBehaviour {
    //第一步 屏幕写东西
    //1.记录屏幕上画的点  List 存储 鼠标输入点
    //1.1 视图坐标系  以屏幕分辨率大小为参考物(1024*768) 右上角(1,1) 左下角(0,0) UV坐标系
    //1.2 屏幕坐标系  以屏幕分辨率大小为参考物(1024*768) 右上角(1024,768,0) 左下角(0,0,0)
    //1.3 世界坐标系  以(0,0,0) 为起点
    //1.4 物体坐标系  以 父类 为参考物
    //2.显示点    输入点 链接起来
    //2.1  放一个image 当做画布
    //第二步 屏幕上写的东西映射到旗上 
    //1.在图片上生成对应的像素点
    //2.将 图片放到旗上
    private Image testImage;
    //存储所有点
    private List<Vector2> allPoints;
    //
    private Material targetMaterial;
    //笔画数
    public int count = 2;
    //记录已画笔数
    private int temCount = 0;
    private void Start()
    {
        testImage = transform.GetComponent<Image>();
        allPoints = new List<Vector2>();
        targetMaterial = transform.GetComponent<Renderer>().material;
    }
    private void Update()
    {
        if (Input.GetMouseButton(0))
        {
            //获得鼠标的视图坐标系坐标
            Vector2 viewPoint = Camera.main.ScreenToViewportPoint(Input.mousePosition);
            allPoints.Add(viewPoint);
        }
        if (Input.GetMouseButtonUp(0))
        {
            temCount++;
            if (temCount == count)
            {
                GenerateTexture();
            }
        }
    }
    public void GenerateTexture()
    {
        Texture2D temTexture = new Texture2D(300, 400);
        for (int i = 1; i < allPoints.Count; i++)
        {
            //前一个点
            Vector2 temPos = allPoints[i - 1];
            //后一个点
            Vector2 temBack = allPoints[i];
            //插值100次
            for (int j = 0; j < 100; j++)
            {
                //插值的比例
                float temxx = Mathf.Lerp(temPos.x, temBack.x, j / 100.0f);
                //插值的比例
                float temyy = Mathf.Lerp(temPos.y, temBack.y, j / 100.0f);
                //得到所有的比例点
                int xx = (int)(temTexture.width * temxx);
                int yy = (int)(temTexture.width * temyy);
                //赋值 画出点
                temTexture.SetPixel(xx, yy, Color.red);
            }
        }
        temTexture.Apply();
        targetMaterial.SetTexture("_MainTex", temTexture);
        allPoints.Clear();
    }
    static Material lineMaterial;
    static void CreateLineMaterial()
    {
        if (!lineMaterial)
        {
            // Unity has a built-in shader that is useful for drawing
            // simple colored things.
            Shader shader = Shader.Find("Hidden/Internal-Colored");
            lineMaterial = new Material(shader);
            lineMaterial.hideFlags = HideFlags.HideAndDontSave;
            // Turn on alpha blending
            lineMaterial.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
            lineMaterial.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
            // Turn backface culling off
            lineMaterial.SetInt("_Cull", (int)UnityEngine.Rendering.CullMode.Off);
            // Turn off depth writes
            lineMaterial.SetInt("_ZWrite", 0);
        }
    }
    // Will be called after all regular rendering is done
    public void OnRenderObject()
    {
        CreateLineMaterial();
        // Apply the line material
        lineMaterial.SetPass(0);
        GL.PushMatrix();
        //将透视投影改为正交投影
        GL.LoadOrtho();
        // 划线开始
        GL.Begin(GL.LINES);
        //划线颜色
        GL.Color(Color.red);
        for (int i  = 1; i  < allPoints.Count; i ++)
        {
            //前一个点
            Vector2 temPos = allPoints[i - 1];
            //后一个点
            Vector2 temBack = allPoints[i];
            //起点
            GL.Vertex3(temPos.x, temPos.y, 0);
            //终点
            GL.Vertex3(temBack.x, temBack.y, 0);
        }
        //划线结束
        GL.End();
        GL.PopMatrix();
    }
}
来自:https://blog.csdn.net/battletiger/article/details/77868111

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引