A game about forced loneliness, made by TACStudios
at master 129 lines 4.5 kB view raw
1using System; 2using UnityEngine; 3using UnityEngine.Rendering.LookDev; 4using IDataProvider = UnityEngine.Rendering.LookDev.IDataProvider; 5 6namespace UnityEditor.Rendering.LookDev 7{ 8 /// <summary>Data container to be used with Renderer class</summary> 9 class RenderingData : IDisposable 10 { 11 /// <summary> 12 /// Internally set to true when the given RenderTexture <see cref="output"/> was not the good size regarding <see cref="viewPort"/> and needed to be recreated 13 /// </summary> 14 public bool sizeMissmatched; 15 /// <summary>The stage that possess every object in your view</summary> 16 public Stage stage; 17 /// <summary>Callback to update the Camera position. Only done in First phase.</summary> 18 public ICameraUpdater updater; 19 /// <summary>Viewport size</summary> 20 public Rect viewPort; 21 /// <summary>Render texture handling captured image</summary> 22 public RenderTexture output; 23 24 private bool disposed = false; 25 26 /// <summary>Dispose pattern</summary> 27 public void Dispose() 28 { 29 if (disposed) 30 return; 31 disposed = true; 32 33 stage = null; 34 updater = null; 35 output?.Release(); 36 output = null; 37 } 38 } 39 40 /// <summary>Basic renderer to draw scene in texture</summary> 41 class Renderer 42 { 43 /// <summary>Use pixel perfect</summary> 44 public bool pixelPerfect { get; set; } 45 46 /// <summary>Constructor</summary> 47 /// <param name="pixelPerfect">[Optional] Use pixel perfect</param> 48 public Renderer(bool pixelPerfect = false) 49 => this.pixelPerfect = pixelPerfect; 50 51 /// <summary>Init for rendering</summary> 52 /// <param name="data">The data to use</param> 53 public void BeginRendering(RenderingData data, IDataProvider dataProvider) 54 { 55 data.stage.OnBeginRendering(dataProvider); 56 data.updater?.UpdateCamera(data.stage.camera); 57 data.stage.camera.enabled = true; 58 } 59 60 /// <summary>Finish to render</summary> 61 /// <param name="data">The data to use</param> 62 public void EndRendering(RenderingData data, IDataProvider dataProvider) 63 { 64 data.stage.camera.enabled = false; 65 data.stage.OnEndRendering(dataProvider); 66 } 67 68 bool CheckWrongSizeOutput(RenderingData data) 69 { 70 if (data.viewPort.IsNullOrInverted() 71 || data.viewPort.width != data.output.width 72 || data.viewPort.height != data.viewPort.height) 73 { 74 data.output = null; 75 data.sizeMissmatched = true; 76 return true; 77 } 78 79 data.sizeMissmatched = false; 80 return false; 81 } 82 83 /// <summary> 84 /// Capture image of the scene. 85 /// </summary> 86 /// <param name="data">Datas required to compute the capture</param> 87 /// [Optional] When drawing several time the scene, you can remove First and/or Last to not initialize objects. 88 /// Be careful though to always start your frame with a First and always end with a Last. 89 /// </param> 90 public void Acquire(RenderingData data) 91 { 92 if (CheckWrongSizeOutput(data)) 93 return; 94 95 data.stage.camera.targetTexture = data.output; 96 data.stage.camera.Render(); 97 } 98 99 internal static void DrawFullScreenQuad(Rect rect) 100 { 101 GL.PushMatrix(); 102 GL.LoadOrtho(); 103 GL.Viewport(rect); 104 105 GL.Begin(GL.QUADS); 106 GL.TexCoord2(0, 0); 107 GL.Vertex3(0f, 0f, 0); 108 GL.TexCoord2(0, 1); 109 GL.Vertex3(0f, 1f, 0); 110 GL.TexCoord2(1, 1); 111 GL.Vertex3(1f, 1f, 0); 112 GL.TexCoord2(1, 0); 113 GL.Vertex3(1f, 0f, 0); 114 GL.End(); 115 GL.PopMatrix(); 116 } 117 } 118 119 /// <summary>Rect extension</summary> 120 public static partial class RectExtension 121 { 122 /// <summary>Return true if the <see cref="Rect"/> is null sized or inverted.</summary> 123 /// <param name="r">The rect</param> 124 /// <returns>True: null or inverted area</returns> 125 public static bool IsNullOrInverted(this Rect r) 126 => r.width <= 0f || r.height <= 0f 127 || float.IsNaN(r.width) || float.IsNaN(r.height); 128 } 129}