(C)GL空間変換

1.はじめに

GL Graphicsクラスのカテゴリを使用してグラフィックスを描画する場合、必要が座標変換を使用します。ドローとグラフィックス・インターフェースを使用している場合も同様です。ボールを使って、たとえば、あなたは座標、球の中心に座標の原点で描く場合は0です。異なる位置にプロットされた場合、球の中心座標が0でない場合、頂点の球座標を再計算する必要があります。行列変換(座標変換)は、球の中心の位置座標原点が配置されているに移動した場合、依然として球体の中心の元の位置に、球面座標は不変のままです。だから我々は最初の座標変換をして、描画した後、元の座標系の描画終了に戻る(すなわち、ワールド座標系)、その後、他のグラフィックスは、座標変換した後、ワールド座標系に戻す描画、グラフを描画するとき。

座標変換2.GL

このセクションは次のようLoadPixelMatrix、MultMatrixとして説明する座標系GLいくつかのクラスをロードするための方法に焦点を当てています。

2.1世界座標系

デフォルトでは、世界座標系で正多角形を描画するためのシステムは、次のコードをワールド座標です。この場合、モバイルカメラでは、画像が移動します。画像の座標とカメラ座標無関係ため。

    public int circleRadius = 3;
    public int circleCount = 6; public int zValue = 0; private void DrawCircleSurface() { float angleDelta = 2 * Mathf.PI / circleCount; GL.Begin(GL.TRIANGLES); GL.Color(Color.yellow); for (int i = 0; i < circleCount; i++) { float angle = angleDelta * i; float angleNext = angle + angleDelta; GL.Vertex3(0, 0, zValue); GL.Vertex3(Mathf.Cos(angle) * circleRadius, Mathf.Sin(angle) * circleRadius, zValue); GL.Vertex3(Mathf.Cos(angleNext) * circleRadius, Mathf.Sin(angleNext) * circleRadius, zValue); } GL.End(); }`在这里插入代码片` 

2.2ローカル座標系

我々は画像が(カメラなど)ゲームオブジェクトの子オブジェクトになりたい場合は、GL.MultMatrix法を用いることができます。最初transform.localToWorldMatrixは、ローカルワールド座標に座標変換行列を、次いでGL.MultMatrixを通してロード取得通過することができます。私たちが描くこのとき、ローカル座標の座標を計算するために、次のように最終的な結果のデータは、ワールド座標系の座標に変換されます。カメラは再び移動した場合、この時点では、カメラの画像は、動きに追従します。

   private void DrawCircleSurfaceLocal()
    {
        GL.PushMatrix(); GL.MultMatrix(transform.localToWorldMatrix); DrawCircleSurface(); GL.PopMatrix(); } 

2.3スクリーン座標

GL.LoadPixelMatrix直接スクリーン上に画像を描画することによって、この方法は、二つの画面へとピクセルレンダリングのサイズを指定する引き出された電流に対応する、オーバーロードしています。あなたが同じことを、画面の各画素のサイズを指定した場合、現在の画面サイズに作成しなければなりません。しかし、この場合は、画素サイズの画像座標であり、zは、値0を座標.. そして画面座標負ではない、それは、位置の原点0ので、画面の唯一四分の一例として、本実施形態では正多角形です。

    private void DrawCircleSurfaceScreen()
    {
        //circleRadius = 1000; 以像素为单位 GL.PushMatrix(); //GL.LoadPixelMatrix(); GL.LoadPixelMatrix(0,screenSize.x,0,screenSize.y); DrawCircleSurface(); GL.PopMatrix(); } 

場合GL.LoadPixelMatrix効果()と一致する画面サイズxとyの値と同一の画面解像度、。

2.4直交座標系

この場合、直交視野において、画面上に直接画像を描くことができるGL.LoadOrtho()メソッドを使用して、大きさが1で、座標値未満であるか、または1に等しいです.. 同じ座標値が負ではありません。

    private void DrawCircleSurfaceOrtho()
    {
        //circleRadius = 1; 最大值为1 GL.PushMatrix(); GL.LoadOrtho(); DrawCircleSurface(); GL.PopMatrix(); } 

2.5分離ビューポート

以下の方法は、ローカルビューポート内に描画GL.Viewportによって実現されてもよいです。

    private void DrawCircleSurfaceViewport()
    {
        GL.PushMatrix(); GL.LoadPixelMatrix(); GL.Viewport(new Rect(0, 0, Screen.width / 2, Screen.height / 2)); DrawCircleSurface(); GL.PopMatrix(); } 

注:直交座標系、すなわちGL.LoadOrtho()メソッドを使用して、ビューポートの最大値が1である場合、GL.Viewport(新規のRect(0、0、1.0F / 2、1.0Fを使用する場合、座標系/ 2))。

3.完全なコード

using System.Collections;
using System.Collections.Generic; using UnityEngine; public class Graphics03GLMatrix : MonoBehaviour { public enum SpaceType { WORLD, LOCAL, SCREEN_NORMAL, SCREEN, VIEWPORT } public SpaceType type = SpaceType.WORLD; public int circleRadius = 3; public int circleCount = 6; public int zValue = 0; public Vector2 screenSize = Vector2.zero; private void OnRenderObject() { SetMaterialPass(); switch (type) { case SpaceType.WORLD: DrawCircleSurface(); break; case SpaceType.LOCAL: DrawCircleSurfaceLocal(); break; case SpaceType.SCREEN_NORMAL: DrawCircleSurfaceOrtho(); break; case SpaceType.SCREEN: DrawCircleSurfaceScreen(); break; case SpaceType.VIEWPORT: DrawCircleSurfaceViewport(); break; } } private Material glMat; private void SetMaterialPass() { if (glMat == null) { glMat = new Material(Shader.Find("Hidden/Internal-Colored")); } glMat.SetPass(0); } private void DrawCircleSurface() { float angleDelta = 2 * Mathf.PI / circleCount; GL.Begin(GL.TRIANGLES); GL.Color(Color.yellow); for (int i = 0; i < circleCount; i++) { float angle = angleDelta * i; float angleNext = angle + angleDelta; GL.Vertex3(0, 0, zValue); GL.Vertex3(Mathf.Cos(angle) * circleRadius, Mathf.Sin(angle) * circleRadius, zValue); GL.Vertex3(Mathf.Cos(angleNext) * circleRadius, Mathf.Sin(angleNext) * circleRadius, zValue); } GL.End(); } private void DrawCircleSurfaceLocal() { GL.PushMatrix(); GL.MultMatrix(transform.localToWorldMatrix); DrawCircleSurface(); GL.PopMatrix(); } private void DrawCircleSurfaceOrtho() { //circleRadius = 1; 最大值为1 GL.PushMatrix(); GL.LoadOrtho(); DrawCircleSurface(); GL.PopMatrix(); } private void DrawCircleSurfaceScreen() { //circleRadius = 1000; 以像素为单位 GL.PushMatrix(); //GL.LoadPixelMatrix(); GL.LoadPixelMatrix(0,screenSize.x,0,screenSize.y); DrawCircleSurface(); GL.PopMatrix(); } private void DrawCircleSurfaceViewport() { GL.PushMatrix(); GL.LoadPixelMatrix(); GL.Viewport(new Rect(0, 0, Screen.width / 2, Screen.height / 2)); DrawCircleSurface(); GL.PopMatrix(); } } 

おすすめ

転載: www.cnblogs.com/llstart-new0201/p/12315711.html