10_RenderToTexture.cs 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. //
  2. // Copyright (c) 2008-2015 the Urho3D project.
  3. // Copyright (c) 2015 Xamarin Inc
  4. // Copyright (c) 2016 THUNDERBEAST GAMES LLC
  5. //
  6. // Permission is hereby granted, free of charge, to any person obtaining a copy
  7. // of this software and associated documentation files (the "Software"), to deal
  8. // in the Software without restriction, including without limitation the rights
  9. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10. // copies of the Software, and to permit persons to whom the Software is
  11. // furnished to do so, subject to the following conditions:
  12. //
  13. // The above copyright notice and this permission notice shall be included in
  14. // all copies or substantial portions of the Software.
  15. //
  16. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  19. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22. // THE SOFTWARE.
  23. //
  24. using AtomicEngine;
  25. namespace FeatureExamples
  26. {
  27. public class RenderToTextureSample : Sample
  28. {
  29. Scene rttScene;
  30. Node rttCameraNode;
  31. public RenderToTextureSample() : base() { }
  32. public override void Start()
  33. {
  34. base.Start();
  35. CreateScene();
  36. SimpleCreateInstructionsWithWasd();
  37. SetupViewport();
  38. }
  39. override protected void Stop()
  40. {
  41. if (rttScene != null)
  42. rttScene.Dispose();
  43. }
  44. protected override void Update(float timeStep)
  45. {
  46. base.Update(timeStep);
  47. SimpleMoveCamera3D(timeStep);
  48. }
  49. void SetupViewport()
  50. {
  51. var renderer = GetSubsystem<Renderer>();
  52. renderer.SetViewport(0, new Viewport( scene, CameraNode.GetComponent<Camera>()));
  53. }
  54. void CreateScene()
  55. {
  56. var cache = GetSubsystem<ResourceCache>();
  57. {
  58. rttScene = new Scene();
  59. // Create octree, use default volume (-1000, -1000, -1000) to (1000, 1000, 1000)
  60. rttScene.CreateComponent<Octree>();
  61. // Create a Zone for ambient light & fog control
  62. Node zoneNode = rttScene.CreateChild("Zone");
  63. Zone zone = zoneNode.CreateComponent<Zone>();
  64. // Set same volume as the Octree, set a close bluish fog and some ambient light
  65. zone.SetBoundingBox(new BoundingBox(-1000.0f, 1000.0f));
  66. zone.AmbientColor = new Color(0.05f, 0.1f, 0.15f);
  67. zone.FogColor = new Color(0.1f, 0.2f, 0.3f);
  68. zone.FogStart = 10.0f;
  69. zone.FogEnd = 100.0f;
  70. // Create randomly positioned and oriented box StaticModels in the scene
  71. const uint numObjects = 2000;
  72. for (uint i = 0; i < numObjects; ++i)
  73. {
  74. Node boxNode = rttScene.CreateChild("Box");
  75. boxNode.Position = new Vector3(NextRandom(200.0f) - 100.0f, NextRandom(200.0f) - 100.0f,
  76. NextRandom(200.0f) - 100.0f);
  77. // Orient using random pitch, yaw and roll Euler angles
  78. boxNode.Rotation = new Quaternion(NextRandom(360.0f), NextRandom(360.0f), NextRandom(360.0f));
  79. StaticModel boxObject = boxNode.CreateComponent<StaticModel>();
  80. boxObject.Model = cache.Get<Model>("Models/Box.mdl");
  81. boxObject.SetMaterial(cache.Get<Material>("Materials/Stone.xml"));
  82. // Add our custom Rotator component which will rotate the scene node each frame, when the scene sends its update event.
  83. // Simply set same rotation speed for all objects
  84. Rotator rotator = new Rotator();
  85. boxNode.AddComponent(rotator);
  86. rotator.SetRotationSpeed(new Vector3(10.0f, 20.0f, 30.0f));
  87. }
  88. // Create a camera for the render-to-texture scene. Simply leave it at the world origin and let it observe the scene
  89. rttCameraNode = rttScene.CreateChild("Camera");
  90. Camera camera = rttCameraNode.CreateComponent<Camera>();
  91. camera.FarClip = 100.0f;
  92. // Create a point light to the camera scene node
  93. Light light = rttCameraNode.CreateComponent<Light>();
  94. light.LightType = LightType.LIGHT_POINT;
  95. light.Range = 30.0f;
  96. }
  97. {
  98. // Create the scene in which we move around
  99. scene = new Scene();
  100. // Create octree, use also default volume (-1000, -1000, -1000) to (1000, 1000, 1000)
  101. scene.CreateComponent<Octree>();
  102. // Create a Zone component for ambient lighting & fog control
  103. Node zoneNode = scene.CreateChild("Zone");
  104. Zone zone = zoneNode.CreateComponent<Zone>();
  105. zone.SetBoundingBox(new BoundingBox(-1000.0f, 1000.0f));
  106. zone.AmbientColor = new Color(0.1f, 0.1f, 0.1f);
  107. zone.FogStart = 100.0f;
  108. zone.FogEnd = 300.0f;
  109. // Create a directional light without shadows
  110. Node lightNode = scene.CreateChild("DirectionalLight");
  111. lightNode.SetDirection(new Vector3(0.5f, -1.0f, 0.5f));
  112. Light light = lightNode.CreateComponent<Light>();
  113. light.LightType = LightType.LIGHT_DIRECTIONAL;
  114. light.Color = new Color(0.2f, 0.2f, 0.2f);
  115. light.SpecularIntensity = 1.0f;
  116. // Create a "floor" consisting of several tiles
  117. for (int y = -5; y <= 5; ++y)
  118. {
  119. for (int x = -5; x <= 5; ++x)
  120. {
  121. Node floorNode = scene.CreateChild("FloorTile");
  122. floorNode.Position = new Vector3(x*20.5f, -0.5f, y*20.5f);
  123. floorNode.Scale = new Vector3(20.0f, 1.0f, 20.0f);
  124. StaticModel floorObject = floorNode.CreateComponent<StaticModel>();
  125. floorObject.Model = cache.Get<Model>("Models/Box.mdl");
  126. floorObject.SetMaterial(cache.Get<Material>("Materials/Stone.xml"));
  127. }
  128. }
  129. // Create a "screen" like object for viewing the second scene. Construct it from two StaticModels, a box for the frame
  130. // and a plane for the actual view
  131. {
  132. Node boxNode = scene.CreateChild("ScreenBox");
  133. boxNode.Position = new Vector3(0.0f, 10.0f, 0.0f);
  134. boxNode.Scale = new Vector3(21.0f, 16.0f, 0.5f);
  135. StaticModel boxObject = boxNode.CreateComponent<StaticModel>();
  136. boxObject.Model = cache.Get<Model>("Models/Box.mdl");
  137. boxObject.SetMaterial(cache.Get<Material>("Materials/Stone.xml"));
  138. Node screenNode = scene.CreateChild("Screen");
  139. screenNode.Position = new Vector3(0.0f, 10.0f, -0.27f);
  140. screenNode.Rotation = new Quaternion(-90.0f, 0.0f, 0.0f);
  141. screenNode.Scale = new Vector3(20.0f, 0.0f, 15.0f);
  142. StaticModel screenObject = screenNode.CreateComponent<StaticModel>();
  143. screenObject.Model = cache.Get<Model>("Models/Plane.mdl");
  144. // Create a renderable texture (1024x768, RGB format), enable bilinear filtering on it
  145. Texture2D renderTexture = new Texture2D();
  146. renderTexture.SetSize(1024, 768, Graphics.GetRGBFormat(), TextureUsage.TEXTURE_RENDERTARGET);
  147. renderTexture.FilterMode = TextureFilterMode.FILTER_BILINEAR;
  148. // Create a new material from scratch, use the diffuse unlit technique, assign the render texture
  149. // as its diffuse texture, then assign the material to the screen plane object
  150. Material renderMaterial = new Material();
  151. renderMaterial.SetTechnique(0, cache.Get<Technique>("Techniques/DiffUnlit.xml"), 0, 0);
  152. renderMaterial.SetTexture(TextureUnit.TU_DIFFUSE, renderTexture);
  153. screenObject.SetMaterial(renderMaterial);
  154. // Get the texture's RenderSurface object (exists when the texture has been created in rendertarget mode)
  155. // and define the viewport for rendering the second scene, similarly as how backbuffer viewports are defined
  156. // to the Renderer subsystem. By default the texture viewport will be updated when the texture is visible
  157. // in the main view
  158. RenderSurface surface = renderTexture.RenderSurface;
  159. Viewport rttViewport = new Viewport(rttScene, rttCameraNode.GetComponent<Camera>());
  160. surface.SetViewport(0, rttViewport);
  161. }
  162. // Create the camera. Limit far clip distance to match the fog
  163. CameraNode = scene.CreateChild("Camera");
  164. var camera = CameraNode.CreateComponent<Camera>();
  165. camera.FarClip = 300.0f;
  166. // Set an initial position for the camera scene node above the plane
  167. CameraNode.Position = new Vector3(0.0f, 7.0f, -30.0f);
  168. }
  169. }
  170. public class Rotator : CSComponent
  171. {
  172. Vector3 rotationSpeed;
  173. public void SetRotationSpeed(Vector3 vector)
  174. {
  175. rotationSpeed = vector;
  176. }
  177. void Update(float timeStep)
  178. {
  179. Node.Rotate(new Quaternion(rotationSpeed.X * timeStep, rotationSpeed.Y * timeStep, rotationSpeed.Z * timeStep), TransformSpace.TS_LOCAL);
  180. }
  181. }
  182. }
  183. }