LookDevRenderer.cs 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  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?.Dispose();
  30. stage = null;
  31. updater = null;
  32. output?.Release();
  33. output = null;
  34. }
  35. }
  36. /// <summary>Basic renderer to draw scene in texture</summary>
  37. class Renderer
  38. {
  39. /// <summary>Use pixel perfect</summary>
  40. public bool pixelPerfect { get; set; }
  41. /// <summary>Constructor</summary>
  42. /// <param name="pixelPerfect">[Optional] Use pixel perfect</param>
  43. public Renderer(bool pixelPerfect = false)
  44. => this.pixelPerfect = pixelPerfect;
  45. /// <summary>Init for rendering</summary>
  46. /// <param name="data">The data to use</param>
  47. public void BeginRendering(RenderingData data, IDataProvider dataProvider)
  48. {
  49. data.stage.OnBeginRendering(dataProvider);
  50. data.updater?.UpdateCamera(data.stage.camera);
  51. data.stage.camera.enabled = true;
  52. }
  53. /// <summary>Finish to render</summary>
  54. /// <param name="data">The data to use</param>
  55. public void EndRendering(RenderingData data, IDataProvider dataProvider)
  56. {
  57. data.stage.camera.enabled = false;
  58. data.stage.OnEndRendering(dataProvider);
  59. }
  60. bool CheckWrongSizeOutput(RenderingData data)
  61. {
  62. if (data.viewPort.IsNullOrInverted()
  63. || data.viewPort.width != data.output.width
  64. || data.viewPort.height != data.viewPort.height)
  65. {
  66. data.output = null;
  67. data.sizeMissmatched = true;
  68. return true;
  69. }
  70. data.sizeMissmatched = false;
  71. return false;
  72. }
  73. /// <summary>
  74. /// Capture image of the scene.
  75. /// </summary>
  76. /// <param name="data">Datas required to compute the capture</param>
  77. /// [Optional] When drawing several time the scene, you can remove First and/or Last to not initialize objects.
  78. /// Be careful though to always start your frame with a First and always end with a Last.
  79. /// </param>
  80. public void Acquire(RenderingData data)
  81. {
  82. if (CheckWrongSizeOutput(data))
  83. return;
  84. data.stage.camera.targetTexture = data.output;
  85. data.stage.camera.Render();
  86. }
  87. internal static void DrawFullScreenQuad(Rect rect)
  88. {
  89. GL.PushMatrix();
  90. GL.LoadOrtho();
  91. GL.Viewport(rect);
  92. GL.Begin(GL.QUADS);
  93. GL.TexCoord2(0, 0);
  94. GL.Vertex3(0f, 0f, 0);
  95. GL.TexCoord2(0, 1);
  96. GL.Vertex3(0f, 1f, 0);
  97. GL.TexCoord2(1, 1);
  98. GL.Vertex3(1f, 1f, 0);
  99. GL.TexCoord2(1, 0);
  100. GL.Vertex3(1f, 0f, 0);
  101. GL.End();
  102. GL.PopMatrix();
  103. }
  104. }
  105. /// <summary>Rect extension</summary>
  106. public static partial class RectExtension
  107. {
  108. /// <summary>Return true if the <see cref="Rect"/> is null sized or inverted.</summary>
  109. /// <param name="r">The rect</param>
  110. /// <returns>True: null or inverted area</returns>
  111. public static bool IsNullOrInverted(this Rect r)
  112. => r.width <= 0f || r.height <= 0f
  113. || float.IsNaN(r.width) || float.IsNaN(r.height);
  114. }
  115. }