10_RenderToTexture.cs 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  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 scene;
  30. Scene rttScene;
  31. Node rttCameraNode;
  32. public RenderToTextureSample() : base() { }
  33. public override void Start()
  34. {
  35. base.Start();
  36. CreateScene();
  37. SimpleCreateInstructionsWithWasd();
  38. SetupViewport();
  39. }
  40. protected override void Update(float timeStep)
  41. {
  42. base.Update(timeStep);
  43. SimpleMoveCamera3D(timeStep);
  44. }
  45. void SetupViewport()
  46. {
  47. var renderer = GetSubsystem<Renderer>();
  48. renderer.SetViewport(0, new Viewport( scene, CameraNode.GetComponent<Camera>()));
  49. }
  50. void CreateScene()
  51. {
  52. var cache = GetSubsystem<ResourceCache>();
  53. {
  54. rttScene = new Scene();
  55. // Create octree, use default volume (-1000, -1000, -1000) to (1000, 1000, 1000)
  56. rttScene.CreateComponent<Octree>();
  57. // Create a Zone for ambient light & fog control
  58. Node zoneNode = rttScene.CreateChild("Zone");
  59. Zone zone = zoneNode.CreateComponent<Zone>();
  60. // Set same volume as the Octree, set a close bluish fog and some ambient light
  61. zone.SetBoundingBox(new BoundingBox(-1000.0f, 1000.0f));
  62. zone.AmbientColor = new Color(0.05f, 0.1f, 0.15f);
  63. zone.FogColor = new Color(0.1f, 0.2f, 0.3f);
  64. zone.FogStart = 10.0f;
  65. zone.FogEnd = 100.0f;
  66. // Create randomly positioned and oriented box StaticModels in the scene
  67. const uint numObjects = 2000;
  68. for (uint i = 0; i < numObjects; ++i)
  69. {
  70. Node boxNode = rttScene.CreateChild("Box");
  71. boxNode.Position = new Vector3(NextRandom(200.0f) - 100.0f, NextRandom(200.0f) - 100.0f,
  72. NextRandom(200.0f) - 100.0f);
  73. // Orient using random pitch, yaw and roll Euler angles
  74. boxNode.Rotation = new Quaternion(NextRandom(360.0f), NextRandom(360.0f), NextRandom(360.0f));
  75. StaticModel boxObject = boxNode.CreateComponent<StaticModel>();
  76. boxObject.Model = cache.Get<Model>("Models/Box.mdl");
  77. boxObject.SetMaterial(cache.Get<Material>("Materials/Stone.xml"));
  78. // Add our custom Rotator component which will rotate the scene node each frame, when the scene sends its update event.
  79. // Simply set same rotation speed for all objects
  80. Rotator rotator = new Rotator();
  81. boxNode.AddComponent(rotator);
  82. rotator.SetRotationSpeed(new Vector3(10.0f, 20.0f, 30.0f));
  83. }
  84. // Create a camera for the render-to-texture scene. Simply leave it at the world origin and let it observe the scene
  85. rttCameraNode = rttScene.CreateChild("Camera");
  86. Camera camera = rttCameraNode.CreateComponent<Camera>();
  87. camera.FarClip = 100.0f;
  88. // Create a point light to the camera scene node
  89. Light light = rttCameraNode.CreateComponent<Light>();
  90. light.LightType = LightType.LIGHT_POINT;
  91. light.Range = 30.0f;
  92. }
  93. {
  94. // Create the scene in which we move around
  95. scene = new Scene();
  96. // Create octree, use also default volume (-1000, -1000, -1000) to (1000, 1000, 1000)
  97. scene.CreateComponent<Octree>();
  98. // Create a Zone component for ambient lighting & fog control
  99. Node zoneNode = scene.CreateChild("Zone");
  100. Zone zone = zoneNode.CreateComponent<Zone>();
  101. zone.SetBoundingBox(new BoundingBox(-1000.0f, 1000.0f));
  102. zone.AmbientColor = new Color(0.1f, 0.1f, 0.1f);
  103. zone.FogStart = 100.0f;
  104. zone.FogEnd = 300.0f;
  105. // Create a directional light without shadows
  106. Node lightNode = scene.CreateChild("DirectionalLight");
  107. lightNode.SetDirection(new Vector3(0.5f, -1.0f, 0.5f));
  108. Light light = lightNode.CreateComponent<Light>();
  109. light.LightType = LightType.LIGHT_DIRECTIONAL;
  110. light.Color = new Color(0.2f, 0.2f, 0.2f);
  111. light.SpecularIntensity = 1.0f;
  112. // Create a "floor" consisting of several tiles
  113. for (int y = -5; y <= 5; ++y)
  114. {
  115. for (int x = -5; x <= 5; ++x)
  116. {
  117. Node floorNode = scene.CreateChild("FloorTile");
  118. floorNode.Position = new Vector3(x*20.5f, -0.5f, y*20.5f);
  119. floorNode.Scale = new Vector3(20.0f, 1.0f, 20.0f);
  120. StaticModel floorObject = floorNode.CreateComponent<StaticModel>();
  121. floorObject.Model = cache.Get<Model>("Models/Box.mdl");
  122. floorObject.SetMaterial(cache.Get<Material>("Materials/Stone.xml"));
  123. }
  124. }
  125. // Create a "screen" like object for viewing the second scene. Construct it from two StaticModels, a box for the frame
  126. // and a plane for the actual view
  127. {
  128. Node boxNode = scene.CreateChild("ScreenBox");
  129. boxNode.Position = new Vector3(0.0f, 10.0f, 0.0f);
  130. boxNode.Scale = new Vector3(21.0f, 16.0f, 0.5f);
  131. StaticModel boxObject = boxNode.CreateComponent<StaticModel>();
  132. boxObject.Model = cache.Get<Model>("Models/Box.mdl");
  133. boxObject.SetMaterial(cache.Get<Material>("Materials/Stone.xml"));
  134. Node screenNode = scene.CreateChild("Screen");
  135. screenNode.Position = new Vector3(0.0f, 10.0f, -0.27f);
  136. screenNode.Rotation = new Quaternion(-90.0f, 0.0f, 0.0f);
  137. screenNode.Scale = new Vector3(20.0f, 0.0f, 15.0f);
  138. StaticModel screenObject = screenNode.CreateComponent<StaticModel>();
  139. screenObject.Model = cache.Get<Model>("Models/Plane.mdl");
  140. // Create a renderable texture (1024x768, RGB format), enable bilinear filtering on it
  141. Texture2D renderTexture = new Texture2D();
  142. renderTexture.SetSize(1024, 768, Graphics.GetRGBFormat(), TextureUsage.TEXTURE_RENDERTARGET);
  143. renderTexture.FilterMode = TextureFilterMode.FILTER_BILINEAR;
  144. // Create a new material from scratch, use the diffuse unlit technique, assign the render texture
  145. // as its diffuse texture, then assign the material to the screen plane object
  146. Material renderMaterial = new Material();
  147. renderMaterial.SetTechnique(0, cache.Get<Technique>("Techniques/DiffUnlit.xml"), 0, 0);
  148. renderMaterial.SetTexture(TextureUnit.TU_DIFFUSE, renderTexture);
  149. screenObject.SetMaterial(renderMaterial);
  150. // Get the texture's RenderSurface object (exists when the texture has been created in rendertarget mode)
  151. // and define the viewport for rendering the second scene, similarly as how backbuffer viewports are defined
  152. // to the Renderer subsystem. By default the texture viewport will be updated when the texture is visible
  153. // in the main view
  154. RenderSurface surface = renderTexture.RenderSurface;
  155. Viewport rttViewport = new Viewport(rttScene, rttCameraNode.GetComponent<Camera>());
  156. surface.SetViewport(0, rttViewport);
  157. }
  158. // Create the camera. Limit far clip distance to match the fog
  159. CameraNode = scene.CreateChild("Camera");
  160. var camera = CameraNode.CreateComponent<Camera>();
  161. camera.FarClip = 300.0f;
  162. // Set an initial position for the camera scene node above the plane
  163. CameraNode.Position = new Vector3(0.0f, 7.0f, -30.0f);
  164. }
  165. }
  166. public class Rotator : CSComponent
  167. {
  168. Vector3 rotationSpeed;
  169. public void SetRotationSpeed(Vector3 vector)
  170. {
  171. rotationSpeed = vector;
  172. }
  173. void Update(float timeStep)
  174. {
  175. Node.Rotate(new Quaternion(rotationSpeed.X * timeStep, rotationSpeed.Y * timeStep, rotationSpeed.Z * timeStep), TransformSpace.TS_LOCAL);
  176. }
  177. }
  178. }
  179. }