(一)Graphics基本应用

本文详细介绍了如何在Unity3D中利用Graphics类进行Texture和Mesh的绘制。在DrawTexture时,需要考虑坐标转换,例如使用GL.LoadPixelMatrix进行像素空间转换。DrawTexture可以在OnGUI或OnPostRender中调用,但不能在Update中。如果要绘制到RenderTexture,需在Update中调用并使用GL.LoadPixelMatrix适应目标尺寸。DrawMesh方法可用于Update和OnPostRender,后者需要立即执行。文章还提到了DrawMeshNow在渲染阶段的使用情况。

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

1、 KTV点歌系统单双屏自由选择。   2、 MPEG-4歌曲自由选择,DVD歌曲可付费拷贝。   3、 软解压与硬解压自由选择。   4、 歌库里的歌曲全部采用DVD或LD经业设备与业技师转录而成,几乎全部原人原唱。   5、 欧凯KTV采用了大缓存硬盘预读技术,通过此技术,平均读盘次数比传统的电脑点歌     系统少了100多倍,从而有效地保护了点歌系统中最脆弱的部份-硬盘。大大减少了     系统出错的机会,减低维护成本。   6、 直接支持VCD、SVCD、DVD等格式歌曲,歌源更丰富加歌更简单。   7、 系统稳定可靠:经过多年的实际应用,并且不断完善,是一套经得起考验的产品。   8、 画面清晰漂亮:图文并茂,大字显示 ,可视距离远。   9 、查找方便快捷:电脑自动对歌曲库进行分类、排序,客人可以迅速找到所要点的歌曲   10 、实时跟踪热门:电脑自动生成热门歌曲排行榜, 当今最热门歌曲随时展现眼前,使      点歌更加快捷!   11、 多功能控制:通过电脑可以控制原唱、停唱、音量。   12、大众实用界面:使用中文遥控器点歌,直观方便,不需门训练,不需电脑知识,只     要识字即懂操作。   13、随心所欲点歌:可随时显示已点的歌名,并可随时插播或删除歌曲,十分直观。   14、图像精细流畅:高清晰DVD画质,高保真音质,播放流畅,无马赛克。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值