转载自:http://blog.sina.com.cn/s/blog_471132920101gxzf.html
GL即Graphics Library。Low-Level Graphics Library。计算matrices,发出类似OpenGL的immediate模式的渲染指令,和其它低级图像任务。Graphic.DrawMesh()比GL更高效。
GL立即绘制函数,只用当前material的设置,除非你显示指定mat。否则mat可以是任何材质。并且GL可能会改变材质。
GL立即执行的,如果你在Update()里调用,它们将在相机渲染前执行,相机渲染将会清空屏幕,GL效果将无法看到。
通常GL用法是,在camera上贴脚本,并在OnPostRender()里执行。
注意:
1、GL的线等基本图元并没有UV,所以没有贴图纹理映射的,shader里仅仅做的是单色计算或者对之前的影像加以处理。
2、GL所使用的shader里必须有cull off指令,否则显示会变成如下。(如何???)
3、如果是线,颜色是GL.Color( new Color(1,1,1,0.5f)设置颜色。如果是GL.TRIANGLES或者GL.QUADS,则颜色是shader里的颜色。
方法说明:
1、GL.PushMatrix():保存Matrices至matrix stack上
GL.PopMatrix():从matrix stack上读取matrices。
2、GL.LoadPixeMatrix():改变MVP矩阵,使得transform里的xy直接对应像素,(0,0)表示屏幕ViewPort的左下角,z的范围是(-1,1),该函数改变camera的参数,所以需要GL.PushMatrix()保存和GL.PopMatrix()读取。
GL.Vertex3()的取值范围从左下角的(0,0,0)到右上角的(Screen.width,Screen.height, 0)。
使用GL.LoadPixeMatrix时,Vertex3的xy值不需要除上Screen.width和Screen.height
3、GL.LoadOrtho():设置ortho perspective,即水平视角。GL.Vertex3()取值范围从左下角的(0,0,0)到右上角的(1,1,0)即需要除上Screen.width和Screen.height。
4、OnPostRender():只有物体上有激活的相机时,才会调用该函数。当摄像机完成渲染场景后,绘制了所有物体再调用该方法。OnPostRender可以使用coroutine,加yield使用
WaitForEndOfFrame():等待至所有绘制之后,在展示frame到屏幕之前,可以做截图。可以在任务物体上使用该函数。
例子1:屏幕划线
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class Line : MonoBehaviour
{
public float z;
private Material mat;
private Vector3 vBeg;
private Vector3 vEnd;
private static IList<Vector3> _posList = new List<Vector3>();
private static bool _isReady = false;
public static bool isReady
{
set{ _isReady = value; }
}
void Start()
{
mat = 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 }" +
"} } }");//生成画线的材质
mat.hideFlags = HideFlags.HideAndDontSave;
mat.color = Color.green;
mat.shader.hideFlags = HideFlags.HideAndDontSave;
}
public static void setPosList( ref IList<Vector3> posList )
{
if( _isReady )
{
return;
}
_posList = posList;
if( _posList.Count > 1 )
{
_isReady = true;
}
}
void OnPostRender()
{
if( _isReady )
{
vBeg = camera.WorldToScreenPoint( panelFullMap.instance.mainPlayer.position );
vEnd = camera.WorldToScreenPoint( _posList[0] );
GL.PushMatrix(); //保存当前Matirx
mat.SetPass(0); //刷新当前材质
GL.LoadOrtho();//设置pixelMatrix
GL.Color(Color.yellow);
GL.Begin(GL.LINES);
GL.Vertex3( vBeg.x/Screen.width, vBeg.y/Screen.height, z );
GL.Vertex3( vEnd.x/Screen.width, vEnd.y/Screen.height, z );
GL.End();
GL.PopMatrix();//读取之前的Matrix
for( int i = 0; i < _posList.Count - 1; ++i )
{
vBeg = camera.WorldToScreenPoint( _posList[i] );
vEnd = camera.WorldToScreenPoint( _posList[i+1] );
GL.PushMatrix();
mat.SetPass(0);
GL.LoadOrtho();
// GL.LoadPixelMatrix();
GL.Begin(GL.LINES);
GL.Color(Color.green);
GL.Vertex3( vBeg.x/Screen.width, vBeg.y/Screen.height, z );
GL.Vertex3( vEnd.x/Screen.width, vEnd.y/Screen.height, z );
// GL.Vertex3( vBeg.x, vBeg.y, 0 );
// GL.Vertex3( vEnd.x, vEnd.y, 0 );
GL.End();
GL.PopMatrix();
}
}
}
}
例子2:截图
using System.IO;
using UnityEngine;
using System.Collections;
public class ScreenShot : MonoBehaviour
{
void Start()
{
StartCoroutine(UploadPNG() );
}
IEnumerator UploadPNG()
{
yield return new WaitForEndOfFrame();
print ("yuuuuu");
int width = Screen.width;
int height = Screen.height;
Texture2D tex = new Texture2D(width, height, TextureFormat.RGB24, false);
tex.ReadPixels(new Rect(0, 0, width, height), 0, 0);
tex.Apply();
byte[] bytes = tex.EncodeToPNG();
File.WriteAllBytes(Application.dataPath+"/ss.png",bytes);
UnityEditor.AssetDatabase.Refresh();
}
}
例子3:展示Alpha
using UnityEngine;
using System.Collections;
public class GLTest : MonoBehaviour
{
public Shader shader;
public Texture2D t2d;
private Material mat;
void Start()
{
mat = new Material(shader);
mat.mainTexture = t2d;
}
void OnPostRender()
{
if (!mat)
{
Debug.LogError("Please Assign a material on the inspector");
return;
}
GL.PushMatrix();
mat.SetPass(0);
GL.LoadOrtho();
GL.Begin(GL.QUADS);
GL.Vertex3(0, 0, 0.1F);
GL.Vertex3(1f, 0, 0.1F);
GL.Vertex3(1f, 1, 0.1F);
GL.Vertex3(0, 1, 0.1F);
GL.End();
GL.PopMatrix();
}
}
Shader "Custom/GLDrawLine"
{
Properties {
_MainTex ("Base (RGB)", 2D) = "white" {}
}
SubShader
{
Pass
{
Cull off
Blend DstAlpha zero
Color(1,1,1,1)
}
}
}
一个完整的例子:
转载自:http://www.omuying.com/article/65.aspx