LookDevRenderer.cs 4.4 KB

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