Unity自带GL详解

转载自: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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值