Unity使用OpenGL绘制经纬线圈

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class LatLonGridGL : MonoBehaviour {
    /// <summary>
    /// 地球半径
    /// </summary>
    public float R = 1;
    /// <summary>
    /// 纬线圈数(不包括南极点和北极点)
    /// </summary>
    public int latNum = 9;
    /// <summary>
    /// 经线数
    /// </summary>
    public int lonNum = 18;
    /// <summary>
    /// 一条纬线圈分段
    /// </summary>
    public int latSegment = 36;
    /// <summary>
    /// 一条经线(半圆)分段
    /// </summary>
    public int lonSegment = 36;
    /// <summary>
    /// 网格颜色
    /// </summary>
    public Color color = Color.white;
    /// <summary>
    /// 显示度数
    /// </summary>
    private Object latlonText3D;
    private List<List<Vector3>> latLines = new List<List<Vector3>>();
    private List<List<Vector3>> lonLines = new List<List<Vector3>>();
    /// <summary>
    /// 里面包含了shader
    /// </summary>
    static Material lineMaterial;

    void Start()
    {
        float latSpan = Mathf.PI / (latNum + 1);//纬线间隔度数
        float lonSpan = Mathf.PI * 2 / lonNum;//经线间隔度数
        float anglePerLatSeg = Mathf.PI * 2 / latSegment;//一条纬线每一段对应的度数
        float anglePerLonSeg = Mathf.PI / lonSegment;//一条经线每一段对应的度数
        latlonText3D = Resources.Load("LatLonText3D", typeof(GameObject));
        // 纬度度数
        for (int r = 0; r < latNum + 2; r++)
        {
            GameObject obj = Instantiate(latlonText3D, this.transform) as GameObject;
            obj.transform.position = new Vector3(R * Mathf.Sin(latSpan * r), R * Mathf.Cos(latSpan * r), 0);
            obj.GetComponent<TextMesh>().text = (int)(Mathf.Rad2Deg * (latSpan * r)) - 90 + "°";
            obj.GetComponent<TextMesh>().fontSize = 100;
            obj.transform.localScale = new Vector3(0.01f, 0.01f, 0.01f);
            obj.GetComponent<TextMesh>().color = Color.red;
        }
        //经度度数
        for (int c = 0; c < lonNum; c++)
        {
            GameObject obj = Instantiate(latlonText3D, this.transform) as GameObject;
            obj.transform.position = new Vector3(R * Mathf.Cos(lonSpan * c), 0, R * Mathf.Sin(lonSpan * c));
            obj.GetComponent<TextMesh>().text = (int)(Mathf.Rad2Deg * (lonSpan * c)) + "°";
            obj.GetComponent<TextMesh>().fontSize = 100;
            obj.transform.localScale = new Vector3(0.01f, 0.01f, 0.01f);
            obj.GetComponent<TextMesh>().color = Color.yellow;
        }

        // 绘制纬线圈
        for (int r = 0; r < latNum; r++)
        {
            //顶点
            List<Vector3> vertices = new List<Vector3>();
            for (int n = 0; n < latSegment+1; n++)
            {
                Vector3 v;
                v.x = R * Mathf.Sin(latSpan * (r + 1)) * Mathf.Cos(anglePerLatSeg * n);
                v.y = R * Mathf.Cos(latSpan * (r + 1));
                v.z = R * Mathf.Sin(latSpan * (r + 1)) * Mathf.Sin(anglePerLatSeg * n);
                vertices.Add(v);
            }
            latLines.Add(vertices);
        }

        // 绘制经线圈
        for (int c = 0; c < lonNum; c++)
        {
            //顶点
            List<Vector3> vertices = new List<Vector3>();
            for (int n = 0; n < lonSegment+1; n++)
            {
                Vector3 v;
                v.x = R * Mathf.Sin(anglePerLonSeg * n) * Mathf.Cos(lonSpan * c);
                v.y = R * Mathf.Cos(anglePerLonSeg * n);
                v.z = R * Mathf.Sin(anglePerLonSeg * n) * Mathf.Sin(lonSpan * c);
                vertices.Add(v);
            }
            lonLines.Add(vertices);
        }

    }

    public void OnRenderObject()
    {
        CreateLineMaterial();
        // Apply the line material
        lineMaterial.SetPass(0);

        GL.PushMatrix();
        // Set transformation matrix for drawing to
        // match our transform
        GL.MultMatrix(transform.localToWorldMatrix);
        // Draw lines
        foreach (List<Vector3> vertices in latLines)
        {
            GL.Begin(GL.LINE_STRIP);
            GL.Color(color);
            //GL.Color(new Color(0, 0.5f, 1, 0.5F));
            foreach (Vector3 ver in vertices)
            {
                GL.Vertex3(ver.x, ver.y, ver.z);
            }
            GL.End();
        }
        foreach (List<Vector3> vertices in lonLines)
        {
            GL.Begin(GL.LINE_STRIP);
            GL.Color(color);
            //GL.Color(new Color(0, 0.5f, 1, 1.0F));
            foreach (Vector3 ver in vertices)
            {
                GL.Vertex3(ver.x, ver.y, ver.z);
            }
            GL.End();
        }
        /*for (int i = 0; i < lineCount; ++i)
        {
            float a = i / (float)lineCount;
            float angle = a * Mathf.PI * 2;
            // Vertex colors change from red to green
            GL.Color(new Color(a, 1 - a, 0, 0.8F));
            // One vertex at transform position
            //GL.Vertex3(0, 0, 0);
            // Another vertex at edge of circle
            GL.Vertex3(Mathf.Cos(angle) * radius, Mathf.Sin(angle) * radius, 0);
        }*/
        GL.PopMatrix();
    }


    void OnPostRender()
    {
        // Set your materials
        GL.PushMatrix();
        // yourMaterial.SetPass( );
        // Draw your stuff
        GL.PopMatrix();

    }

    static void CreateLineMaterial()
    {
        if (!lineMaterial)
        {
            // Unity has a built-in shader that is useful for drawing
            // simple colored things.
            Shader shader = Shader.Find("Hidden/Internal-Colored");
            lineMaterial = new Material(shader);
            lineMaterial.hideFlags = HideFlags.HideAndDontSave;
            // Turn on alpha blending
            lineMaterial.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
            lineMaterial.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
            // Turn backface culling off
            lineMaterial.SetInt("_Cull", (int)UnityEngine.Rendering.CullMode.Off);
            // Turn off depth writes
            lineMaterial.SetInt("_ZWrite", 0);
        }
    }

}

 

posted @ 2018-03-30 14:48  酷熊  阅读(1443)  评论(0编辑  收藏  举报