Skip to content

Instantly share code, notes, and snippets.

@radiatoryang
Created March 9, 2013 08:02
Show Gist options
  • Save radiatoryang/5123407 to your computer and use it in GitHub Desktop.
Save radiatoryang/5123407 to your computer and use it in GitHub Desktop.
The start of an all-purpose GLShape thing. MIT license. Tabs are all messed up. Oh well.
/* copyright Robert Yang 2013
use at your own risk
*/
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class GLShape : MonoBehaviour { // all-purpose interface for drawing stuff, PUT THIS ON YOUR CAMERA OBJECT
static Material lineMaterial; // init in Start()
static Material lineMaterialAlwaysRender; // init in Start()
static List<GLLine> worldLines = new List<GLLine>();
static List<GLLine> screenLines = new List<GLLine>();
static List<GLQuad> worldWireQuad = new List<GLQuad>();
static List<GLQuad> screenWireQuad = new List<GLQuad>();
// Use this for initialization
void Start () {
lineMaterial = CreateLineMaterial(false);
lineMaterialAlwaysRender = CreateLineMaterial(true);
}
public static void DrawScreenLine(Vector3 start, Vector3 end, Color color) { // coords are normalized (0-1)
screenLines.Add(new GLLine(start, end, color) );
}
public static void DrawWorldLine(Vector3 start, Vector3 end, Color color) {
worldLines.Add(new GLLine(start, end, color) );
}
// TODO: in the future, implement as DrawScreenWireShape(int sides)
public static void DrawScreenWireQuad (Vector3 center, float width, float height, Color color) { // coords are normalized (0-1)
screenWireQuad.Add( new GLQuad(center, Vector3.zero, width, height, color) );
}
public static void DrawWorldWireQuad (Vector3 center, Vector3 normal, float width, float height, Color color) {
worldWireQuad.Add( new GLQuad(center, normal, width, height, color) );
}
void Update () {
// test
// DrawWorldLine(Vector3.zero, new Vector3 (100f, 100f, 100f), Color.white);
DrawScreenWireQuad( Vector3.one * 0.5f, 0.5f, 0.5f, Color.white );
}
void OnPostRender() {
if (GLShape.screenLines.Count > 0) {
GL.PushMatrix();
lineMaterial.SetPass(0);
GL.LoadOrtho();
GL.Begin(GL.LINES);
foreach (GLLine line in GLShape.screenLines) {
GL.Color(line.color);
GL.Vertex(line.start);
GL.Vertex(line.end);
}
GL.End();
GL.PopMatrix();
GLShape.screenLines.Clear();
}
if (GLShape.worldLines.Count > 0) {
GL.PushMatrix();
lineMaterial.SetPass(0);
GL.LoadProjectionMatrix(camera.projectionMatrix);
GL.Begin(GL.LINES);
foreach (GLLine line in GLShape.worldLines) {
GL.Color(line.color);
GL.Vertex(line.start);
GL.Vertex(line.end);
}
GL.End();
GL.PopMatrix();
GLShape.worldLines.Clear();
}
if (GLShape.screenWireQuad.Count > 0) {
GL.PushMatrix();
lineMaterial.SetPass(0);
GL.LoadOrtho();
GL.Begin(GL.LINES);
foreach (GLQuad quad in GLShape.screenWireQuad) {
GL.Color(quad.color);
quad.width /= camera.aspect;
Vector3[] vertices = quad.GetVertices();
foreach (Vector3 vertex in vertices) {
GL.Vertex(vertex);
}
}
GL.End();
GL.PopMatrix();
GLShape.screenWireQuad.Clear();
}
if (GLShape.worldWireQuad.Count > 0) {
GL.PushMatrix();
lineMaterial.SetPass(0);
GL.LoadProjectionMatrix(camera.projectionMatrix);
GL.Begin(GL.LINES);
foreach (GLQuad quad in GLShape.worldWireQuad) {
GL.Color(quad.color);
Vector3[] vertices = quad.GetVertices();
foreach (Vector3 vertex in vertices) {
GL.Vertex(vertex);
}
}
GL.End();
GL.PopMatrix();
GLShape.worldWireQuad.Clear();
}
}
static Material CreateLineMaterial(bool alwaysRender) {
string ztest = "";
if (alwaysRender)
ztest = "ZTest Always ";
Material mat = new Material( "Shader \"Lines/Colored Blended\" {" +
"SubShader { Pass { " +
" BindChannels { Bind \"Color\",color } " +
" Blend SrcAlpha OneMinusSrcAlpha " +
" " + ztest + "ZWrite Off Cull Off Fog { Mode Off } " +
"} } }" );
mat.hideFlags = HideFlags.HideAndDontSave;
mat.shader.hideFlags = HideFlags.HideAndDontSave;
return mat;
}
}
[System.Serializable]
public class GLLine {
public Vector3 start = Vector3.zero;
public Vector3 end = Vector3.one;
public Color color = Color.white;
public GLLine () {}
public GLLine (Vector3 start, Vector3 end, Color color) {
this.start = start;
this.end = end;
this.color = color;
}
}
[System.Serializable]
public class GLQuad {
public Vector3 center = Vector3.zero;
public Vector3 normal = Vector3.zero;
public float width = 1f;
public float height = 1f;
public Color color = Color.white;
public Vector3[] vertices { get { return GetVertices(); } }
public GLQuad () {}
public GLQuad (Vector3 center, Vector3 normal, float width, float height, Color color) {
this.center = center;
this.normal = normal;
this.width = width;
this.height = height;
this.color = color;
}
public Vector3[] GetVertices () {
Vector3[] _vertices = new Vector3[8];
Quaternion _normal = Quaternion.LookRotation(this.normal); // if no normal, then no rotation, nothing to worry about for screen quads?
_vertices[0] = _normal * (center + new Vector3(-width/2f, height/2f, 0f) );
_vertices[1] = _normal * (center + new Vector3(width/2f, height/2f, 0f) );
_vertices[2] = _normal * (center + new Vector3(width/2f, height/2f, 0f) );
_vertices[3] = _normal * (center + new Vector3(width/2f, -height/2f, 0f) );
_vertices[4] = _normal * (center + new Vector3(width/2f, -height/2f, 0f) );
_vertices[5] = _normal * (center + new Vector3(-width/2f, -height/2f, 0f) );
_vertices[6] = _normal * (center + new Vector3(-width/2f, -height/2f, 0f) );
_vertices[7] = _normal * (center + new Vector3(-width/2f, height/2f, 0f) );
return _vertices;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment