文章目录
1.前言
本文主要针对Graphics类进行texture和mesh的绘制。
2.Draw Texture
使用Graphics类直接进行Texture绘制时,由于属于直接绘制到平面上,所以需要转换到平面像素空间内,所以需要用到LoadPixelMatrix方法。对于空间转换可以参考这一节
2.1 ToScreen
示例代码:
public void Dmainxture()
{
GL.PushMatrix();
//GL.LoadPixelMatrix();
GL.LoadPixelMatrix(0,Screen.width,Screen.height,0);
Graphics.DrawTexture(new Rect(0, 0, 200, 100), mainTexture);
GL.PopMatrix();
}
代码中Graphics.DrawTexture使用的是最基本的方法,即将mainTexture绘制到屏幕new Rect(0, 0, 200, 100)的范围内。此方法有很多重载,可以根据自己的需求选择不同的方法。
使用GL.LoadPixelMatrix()(代码中注释掉的部分)进行坐标转换时,mainTexture会被绘制在屏幕左下角区域,但是像素上下是反的。这是由于不同的图形接口,texture对应的坐标原点不同。OpenGl为左下角,D3d为左上角。如果使用GL.LoadPixelMatrix(0,Screen.width,Screen.height,0)则像素不会反转,但是由于坐标变换矩阵变成从上到下,所以绘制屏幕的左上角。
2.1.1 调用位置
由于是绘制在屏幕上,所以只能在OnGui方法和OnPostRender中调用,在update中则会被camera渲染时会clear掉。但是如果将texture绘制到一个RenderTexture中则可以在update中可以。
2.2 ToTarget
示例代码:
public void DrawTextureToTarget()
{
Graphics.SetRenderTarget(target);
clearBuffer.Clear();
clearBuffer.ClearRenderTarget(true, true, clearColor);
Graphics.ExecuteCommandBuffer(clearBuffer);
GL.PushMatrix();
GL.LoadPixelMatrix(0, target.width, target.height, 0);
//GL.LoadPixelMatrix(0, target.width, 0, target.height);
Graphics.DrawTexture(new Rect(0, 0, target.width, target.height), mainTexture);
GL.PopMatrix();
}
Graphics.SetRenderTarget(target);将绘制结果绘制在一个RenderTexture类型的变量target上,所以屏幕变换需要使用GL.LoadPixelMatrix(0, target.width, target.height, 0);,此时可以在update中调用。
3.Draw Mesh
3.1 Update中调用
示例代码:
public void DrawMesh()
{
Graphics.DrawMesh(Graphics00Mesh.Instance.GetMesh(10, 5), Matrix4x4.identity, material, 0);
//Graphics.DrawMesh(Graphics00Mesh.Instance.GetMesh(10, 5), center,Quaternion.identity, material, 0);
}
Graphics.DrawMesh同样有很多重载,可以满足众多需求,文中只给出了两个示例,一个通过提供矩阵进行坐标变换,另一个(注释掉的方法)则通过提供mesh所在的位置和旋转在进行定位。由于时绘制的模型,所以只能在update中调用。
3.2 OnPostRender中调用
在渲染阶段调用只能使用Graphics.DrawMeshNow方法,让指令立即生效。
4.完整代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering;
public enum DrawLocation
{
ONGUI,
POSTRENDER,
UPDATE
}
public class Graphics06Graphics : MonoBehaviour
{
public DrawLocation location = DrawLocation.ONGUI;
public bool toTarget = false;
public Texture mainTexture;
public RenderTexture target;
public Color clearColor = Color.red;
CommandBuffer clearBuffer;
void Draw()
{
if (toTarget)
{
DrawTextureToTarget();
}
else
{
DrawTexture();
}
}
public void DrawTexture()
{
GL.PushMatrix();
//GL.LoadPixelMatrix();
GL.LoadPixelMatrix(0,Screen.width,Screen.height,0);
Graphics.DrawTexture(new Rect(0, 0, 200, 100), mainTexture);
GL.PopMatrix();
}
public void DrawTextureToTarget()
{
Graphics.SetRenderTarget(target);
clearBuffer.Clear();
clearBuffer.ClearRenderTarget(true, true, clearColor);
Graphics.ExecuteCommandBuffer(clearBuffer);
GL.PushMatrix();
GL.LoadPixelMatrix(0, target.width, target.height, 0);
//GL.LoadPixelMatrix(0, target.width, 0, target.height);
Graphics.DrawTexture(new Rect(0, 0, target.width, target.height), mainTexture);
GL.PopMatrix();
}
private void Start()
{
clearBuffer = new CommandBuffer() { name = "Clear Buffer" };
}
private void OnGUI()
{
if (location != DrawLocation.ONGUI) return;
if (Event.current.type.Equals(EventType.Repaint))
{
Draw();
}
}
private void Update()
{
if (location != DrawLocation.UPDATE) return;
//如果此时绘制到屏幕上,则不会看到绘制的结果
Draw();
}
private void OnPostRender()
{
if (location != DrawLocation.POSTRENDER) return;
Draw();
}
}
5.结语
由于将mesh绘制到RenderTexture上稍微麻烦一点,还涉及到贴图等问题,所以单独在下一节中讲解分析。