Unity3D OpenGL实现画符功能
发表于2018-07-09
本篇文章主要和大家分享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