GameWindow.cs 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. using BansheeEngine;
  2. namespace BansheeEditor
  3. {
  4. /// <summary>
  5. /// Displays in-game viewport in the editor.
  6. /// </summary>
  7. public class GameWindow : EditorWindow
  8. {
  9. private const int HeaderHeight = 20;
  10. private readonly AspectRatio[] aspectRatios =
  11. {
  12. new AspectRatio(16, 9),
  13. new AspectRatio(16, 10),
  14. new AspectRatio(5, 4),
  15. new AspectRatio(4, 3),
  16. new AspectRatio(3, 2)
  17. };
  18. private int selectedAspectRatio = 0;
  19. private GUIRenderTexture renderTextureGUI;
  20. /// <summary>
  21. /// Opens the game window.
  22. /// </summary>
  23. [MenuItem("Windows/Game", ButtonModifier.CtrlAlt, ButtonCode.G, 6000)]
  24. private static void OpenGameWindow()
  25. {
  26. OpenWindow<GameWindow>();
  27. }
  28. /// <summary>
  29. /// Starts execution of the game in the game window.
  30. /// </summary>
  31. [MenuItem("Tools/Play", 9300)]
  32. [ToolbarItem("Play", ToolbarIcon.Play, "", 1800, true)]
  33. private static void Play()
  34. {
  35. if (EditorApplication.IsPaused)
  36. EditorApplication.IsPaused = false;
  37. else
  38. EditorApplication.IsPlaying = !EditorApplication.IsPlaying;
  39. }
  40. /// <summary>
  41. /// Pauses the execution of the game on the current frame.
  42. /// </summary>
  43. [MenuItem("Tools/Pause", 9299)]
  44. [ToolbarItem("Pause", ToolbarIcon.Pause, "", 1799)]
  45. private static void Pause()
  46. {
  47. EditorApplication.IsPaused = !EditorApplication.IsPaused;
  48. }
  49. /// <summary>
  50. /// Moves the execution of the game by one frame forward.
  51. /// </summary>
  52. [MenuItem("Tools/Step", 9298)]
  53. [ToolbarItem("Step", ToolbarIcon.Step, "", 1798)]
  54. private static void Step()
  55. {
  56. EditorApplication.FrameStep();
  57. }
  58. /// <inheritdoc/>
  59. protected override LocString GetDisplayName()
  60. {
  61. return new LocEdString("Game");
  62. }
  63. private void OnInitialize()
  64. {
  65. GUILayoutY mainLayout = GUI.AddLayoutY();
  66. string[] aspectRatioTitles = new string[aspectRatios.Length + 1];
  67. aspectRatioTitles[0] = "Free";
  68. for (int i = 0; i < aspectRatios.Length; i++)
  69. aspectRatioTitles[i + 1] = aspectRatios[i].width + ":" + aspectRatios[i].height;
  70. GUIListBoxField aspectField = new GUIListBoxField(aspectRatioTitles, new LocEdString("Aspect ratio"));
  71. aspectField.OnSelectionChanged += OnAspectRatioChanged;
  72. GUILayout buttonLayout = mainLayout.AddLayoutX();
  73. buttonLayout.AddElement(aspectField);
  74. buttonLayout.AddFlexibleSpace();
  75. renderTextureGUI = new GUIRenderTexture(null);
  76. GUILayoutY alignLayoutY = mainLayout.AddLayoutY();
  77. alignLayoutY.AddFlexibleSpace();
  78. GUILayoutX alignLayoutX = alignLayoutY.AddLayoutX();
  79. alignLayoutX.AddFlexibleSpace();
  80. alignLayoutX.AddElement(renderTextureGUI);
  81. alignLayoutX.AddFlexibleSpace();
  82. alignLayoutY.AddFlexibleSpace();
  83. UpdateRenderTexture(Width, Height);
  84. }
  85. private void OnDestroy()
  86. {
  87. EditorApplication.MainRenderTarget = null;
  88. }
  89. /// <summary>
  90. /// Creates or rebuilds the main render texture. Should be called at least once before using the
  91. /// game window. Should be called whenever the window is resized.
  92. /// </summary>
  93. /// <param name="width">Width of the scene render target, in pixels.</param>
  94. /// <param name="height">Height of the scene render target, in pixels.</param>
  95. private void UpdateRenderTexture(int width, int height)
  96. {
  97. width = MathEx.Max(20, width);
  98. height = MathEx.Max(20, height - HeaderHeight);
  99. if (selectedAspectRatio != 0) // 0 is free aspect
  100. {
  101. AspectRatio aspectRatio = aspectRatios[selectedAspectRatio - 1];
  102. float aspectInv = aspectRatio.height/(float)aspectRatio.width;
  103. height = MathEx.RoundToInt(width*aspectInv);
  104. }
  105. RenderTexture2D renderTexture = new RenderTexture2D(PixelFormat.R8G8B8A8, width, height) {Priority = 1};
  106. EditorApplication.MainRenderTarget = renderTexture;
  107. renderTextureGUI.RenderTexture = renderTexture;
  108. }
  109. /// <summary>
  110. /// Triggered when the user selects a new aspect ratio from the drop down box.
  111. /// </summary>
  112. /// <param name="idx">Index of the aspect ratio the user selected.</param>
  113. private void OnAspectRatioChanged(int idx)
  114. {
  115. selectedAspectRatio = idx;
  116. UpdateRenderTexture(Width, Height);
  117. }
  118. /// <inheritdoc/>
  119. protected override void WindowResized(int width, int height)
  120. {
  121. UpdateRenderTexture(width, height - HeaderHeight);
  122. base.WindowResized(width, height);
  123. }
  124. /// <summary>
  125. /// Camera aspect ratio as numerator and denominator.
  126. /// </summary>
  127. struct AspectRatio
  128. {
  129. /// <summary>
  130. /// Creates a new object that holds the aspect ratio.
  131. /// </summary>
  132. /// <param name="width">Numerator of the aspect ratio.</param>
  133. /// <param name="height">Denominator of the aspect ratio.</param>
  134. public AspectRatio(int width, int height)
  135. {
  136. this.width = width;
  137. this.height = height;
  138. }
  139. public int width;
  140. public int height;
  141. }
  142. }
  143. }