在Unity3D中绘制一个平面图形可不容易,可别惯性思维觉得,嗯,这引擎3D的事情都能解决了,2D的不叫事情。其实除去布置UI,在Unity3D中绘制一个2D平面图形是很蛋疼的一件事情。不然的话,也不会有大量的平面图形绘制插件出现。如果不用插件的话,需要利用的GL去绘制平面图形,而在屏幕中动态放置文本则需要用的GUI。

GL是Unity3D直接调用底层的OpenGL图形库来进行图形绘制,GUI估计大家是有印象的,在Helloworld中,用脚本动态创建文本用到这个对象。下面用一个例子说明GL的使用与更进一步说明GUI如何布置文本。

如下图,十足一个苏格兰的国旗:

则需要对主摄像机挂载如下的脚本:

using UnityEngine;
using System.Collections;public class GLLine : MonoBehaviour
{private static Material lineMaterial;static void CreateLineMaterial(){lineMaterial = new Material("Shader \"Lines/Colored Blended\" {" +"SubShader { Pass { " +"    Blend SrcAlpha OneMinusSrcAlpha " +"    ZWrite Off Cull Off Fog { Mode Off } " +"    BindChannels {" +"      Bind \"vertex\", vertex Bind \"color\", color }" +"} } }");//不同的Unity3D的版本,这段可能不同,具体只能从Unity3D的API抄下来,这是Unity4.x的设置lineMaterial.hideFlags = HideFlags.HideAndDontSave;lineMaterial.shader.hideFlags = HideFlags.HideAndDontSave;lineMaterial.SetPass(0);//只能这样设置材质,不能设置为其它材质,同时还是设置通道}void OnPostRender()//所有GL的绘制只能写在这个方法里面,并将此脚本赋予给主摄像机{CreateLineMaterial();GL.LoadOrtho();//设置绘制2D图像        //画从左下到右上的线GL.Begin(GL.LINES);GL.Color(Color.white);GL.Vertex(new Vector2(0, 0));GL.Vertex(new Vector2(1, 1));GL.End();//画从左上到右下的线GL.Begin(GL.LINES);GL.Color(Color.white);GL.Vertex(new Vector2(0, 1));GL.Vertex(new Vector2(1, 0));GL.End();}void OnGUI()//所有关于GUI的绘制只能写在这个方法里面,不过可以将此脚本赋予给其它物体,不一定是主摄像机{string string_content = "线";GUIStyle fontStyle = new GUIStyle();fontStyle.normal.background = null;//设置背景填充  fontStyle.normal.textColor = Color.white;//设置字体颜色  fontStyle.fontSize = 24;//字体大小  Vector2 string_size = fontStyle.CalcSize(new GUIContent(string_content));//根据设置的样式求得字体具体的尺寸GUI.Label(new Rect(0, 0, string_size.x, string_size.y), string_content, fontStyle);}
}

大家可以看到,虽然只是设置两条线和设置一个左上角的文字,但需要的编程的代码绝不少功夫。

首先只能赋予GL画笔一个Lines/Colored Blended的固定材质,这个材质还不是Unity3D的普通材质,所以不能用Shader.Find还代替这种冗长的用Shader字符串新建材质的方法。如果不这样设置材质,后面的GL.Color是没有效果的。其次,GL.Begin(GL.LINES);意为画一个不填充的多边形,而不是画一条线,对应OpenGL的glBegin(GL_LINE_LOOP);如果后面GL.Vertex打的点数多于3个,含本数的话,那么则会形成一个没有填充色的三角形,具体可以见下面的例子。GL.Vertex打的点中的二维坐标new Vector2(x,y)中的x与y直接就表示(屏幕的横向宽百分之几,屏幕的纵向高百分之几)。

GUI设置文本,如果需要给这个文本设置字体什么的需要用到GUIStyle,具体的设置如上所示。设置完毕,一般再用CalcSize求得这个字体的具体尺寸。所以不用设置这个字体的对齐方式,并且,可以不用考虑GUI.Label所需要设置的矩形的大小了,直接就是CalcSize的返回的Vector2的x与y。倒是矩形的坐标需要注意一下,GUI的(0,0)是屏幕的左上角,GL的(0,0)则在左下角。

如下图:

则需要对主摄像机挂载如下的脚本:

using UnityEngine;
using System.Collections;public class GLCircle_Rectangle : MonoBehaviour
{private static Material lineMaterial;static void CreateLineMaterial(){lineMaterial = new Material("Shader \"Lines/Colored Blended\" {" +"SubShader { Pass { " +"    Blend SrcAlpha OneMinusSrcAlpha " +"    ZWrite Off Cull Off Fog { Mode Off } " +"    BindChannels {" +"      Bind \"vertex\", vertex Bind \"color\", color }" +"} } }");lineMaterial.hideFlags = HideFlags.HideAndDontSave;lineMaterial.shader.hideFlags = HideFlags.HideAndDontSave;lineMaterial.SetPass(0);}void OnPostRender(){CreateLineMaterial();GL.LoadOrtho();//设置绘制2D图像        //画填充多边形GL.Begin(GL.QUADS);GL.Color(Color.white);GL.Vertex(new Vector2(0.1f, 0.1f));GL.Vertex(new Vector2(0.1f, 0.2f));GL.Vertex(new Vector2(0.2f, 0.2f));GL.Vertex(new Vector2(0.2f, 0.1f));GL.End();//画圆GL.Begin(GL.LINES);//如果是填充圆则用GL.Begin(GL.QUADS);GL.Color(Color.yellow); Vector2 Circle_center_point = new Vector2(0.75f, 0.75f);float Circle_r_x = 0.1f;float Circle_r_y = Circle_r_x * Screen.width / Screen.height;int n = 1000;//实质是绘制一个正1000边形for (int i = 0; i < n; ++i)//割圆术画圆{GL.Vertex(new Vector2(Circle_center_point.x + Circle_r_x * Mathf.Cos(2 * Mathf.PI / n * i), Circle_center_point.y + Circle_r_y * Mathf.Sin(2 * Mathf.PI / n * i)));}GL.End();}void OnGUI(){string string_content = "矩形和圆形";GUIStyle fontStyle = new GUIStyle();fontStyle.normal.background = null;//设置背景填充  fontStyle.normal.textColor = Color.white;//设置字体颜色  fontStyle.fontSize = 24;//字体大小  Vector2 string_size = fontStyle.CalcSize(new GUIContent(string_content));GUI.Label(new Rect(Screen.width - string_size.x, Screen.height - string_size.y, string_size.x, string_size.y), string_content, fontStyle);}
}

这里说明了Unity3D中如何用GL画圆和矩形。脚本中对GL与GUI和上面的脚本类似的,同时表达了,如何用GL画一个填充的矩形,也表明了GL.Begin(GL.QUADS);与GL.Begin(GL.LINES);的区别,GL的Begin也只有这2种初始化,GL.Begin(GL.QUADS);则对应于OpenGL的glBegin(GL_POLYGON);。

画矩形没什么所说的,就是打四个点。GL会自己连起来的。画圆这里实则是画一个正1000边形,如果你觉得不够圆还可以画成100000边形。此算法是OpenGL的公认画圆算法,甚至是计算机图形学公认的画圆算法,比起经典算法《【win32】计算机图形学——中点法画线和八分法画圆》(点击打开链接)效率高得不知道哪里去了。

至此,整个程序的说明就结束了。

这个画圆算法以后自己换换参数就行,因为其思想实在深奥,难以弄懂,不过可以说说这里的典故。

实质上这和求圆周率算法,求正多边形的中心至边角距离与正多边形周长之比,从正方形(正4边形),逼近到正6边形,到逼近到无穷的正无穷边形的正多边形的中心至边角距离与正多边形周长之比,可以概括如下公式来求圆周率:

由于从正方形不停在砍角,求新的正多边形,所以也叫割圆术。

这个公式最早的思想是由南北朝的刘徽提出的,后来祖冲之直接转化为应用,求出正96边形的中心与正多边形周长之比,3.1415926的比率用了很久很久,实际上这个比率对于平常应用也足够了。后来,西欧文艺复兴和大航海时期,甚至到了近代,极限和微积分的计算方法发明之后,也是用直接用这中国的古典思想在求圆周率。而今天,在计算机上打点画圆,发现也是画正N变形,通过对N的迭代来画圆是最快的。实质上就是在割圆。可见,刘徽与祖冲之的历史地位!

【Unity3D】平面绘图——GL与GUI相关推荐

  1. matlab平面绘图命令

    基本xy平面绘图命令 MATLAB不但擅长於矩阵相关的数值运算,也适合用在各种科学目视表示(Scientific visualization).本节将介绍MATLAB基本xy平面及xyz空间的各项绘图 ...

  2. 学习Unity3D(1)之GUI游戏界面

    前言: 本学习笔记仅供参考,有问题可以留言! 至于Unity游戏引擎的安装破解之类的问题请自行百度. 基本的Unity界面也可以随意百度的到,所以不做阐述. 一.GUI高级控件 圣典百科GUI界面纲要 ...

  3. Unity3D单击物体弹出GUI窗口

    功能: 1.显示视窗及关闭视窗功能 2.单击物体弹出GUI窗口 [javascript] view plain copy static var WindowSwitch : boolean = fal ...

  4. 【GraphMaker】Unity3D图表——柱状图、折线图、饼图

    http://blog.csdn.net/yongh701/article/details/71637090?utm_source=itdadao&utm_medium=referral 版权 ...

  5. Unity3D 实践学习1 GUI井字棋的实现

    这是我学Unity3D的第一个小游戏,挺简单的,代码量也不多,参考博客是 UNITY3D学习(1)之GUI井字棋.对于Unity3D,想必大家都比较熟悉了的,我就不多作介绍了.需要了解Unity3D的 ...

  6. GUI程序中的Matplotlib绘图

    1.示例程序和运行效果 一般的书上介绍Matplotlib的绘图功能都主要是介绍matplotlib.pyplot模块中的指令式绘图功能,因为这种方式与MATLAB很相似,使用过MATLAB的人转而使 ...

  7. matlab 3D绘图详解

    <pre code_snippet_id="1628801" snippet_file_name="blog_20160330_1_8408168" na ...

  8. qpython怎么用matplotlib_将matplotlib绘图嵌入pyqt的方法示例

    我的终极整理,供参考 # coding:utf-8 import matplotlib # 使用 matplotlib中的FigureCanvas (在使用 Qt5 Backends中 FigureC ...

  9. 计算机绘图c2是什么,Cad里c2表示(cad中C1(C2)这样的符号是什么意思)

    CAD倒角标注里面的C1 C2是表示是什么? C1表示1 X 45°倒角:C2表示 1 X 45°倒角. CAD全称计算机辅助设计指利用计算机及其图形设备帮助设计人员进行设计工作. 在设计中通常要用计 ...

最新文章

  1. VS code 插件配置手册
  2. 655. Print Binary Tree 解题报告(树)
  3. 最小栈的实现(设计一个支持 push,pop,top 操作,并能在常数时间内检索到最小元素的栈。)
  4. LintCode 137. 克隆图
  5. 【个人想法】个人关于数据库字段类型选择的想法
  6. java interface泛型_JAVA的接口泛型
  7. Git 基础之远程仓库-2.5
  8. PS 前端技能一 白色背景图片变为透明的图片
  9. ArcGIS小知识(八)——坡降、流动方向、剖面线、弯曲系数、河系密度、补给长度比
  10. AD实用操作(三)- 原理图器件配置参数批量修改
  11. Egencia smartmix航班排名模型背后的运营研究
  12. 【历史上的今天】5 月 6 日:第一台实际运行程序的计算机;Adobe 转型云端;首个非拉丁文网址出现
  13. android7.1 jack-admin 报错
  14. 各阶段产品经理突破自身瓶颈总结(建议收藏)
  15. 帖子浏览定位展开、收起标签js部分思路及代码
  16. 【PC】通过BAT批处理来更改IE代理设置
  17. 滴滴在招聘,以及司乘防疫口罩识别技术的系统框架、原理和方法展
  18. 安装 Cartographer问题记录汇总
  19. 元宇宙是个什么样的概念?
  20. MAE同期工作!MSRA新作SimMIM收录CVPR 2022!高达87.1%准确率!掩码图像建模新框架...

热门文章

  1. 人人都是产品经理2.0-02章摘要总结
  2. GIS与地质灾害评价
  3. 成都java到底怎么样?发展前景如何?
  4. 解决笔记本电脑win10系统指纹间歇性无法识别(失灵)的问题
  5. java斗地主代码_基于java实现斗地主代码实例解析
  6. python中find是什么意思啊_python中str的find()
  7. ios分屏_苹果分屏功能怎么用?教你一键开启iPad分屏
  8. 亚马逊被关联?别怕有救
  9. 随笔-能够让我们感觉美好的只是回忆而已
  10. 自学java的网站,怎样自学java