(一)Graphics基本应用

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上稍微麻烦一点,还涉及到贴图等问题,所以单独在下一节中讲解分析。

猜你喜欢

转载自blog.csdn.net/ttod/article/details/130300185