Main.cpp 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. // Framework includes
  2. #include "BsApplication.h"
  3. #include "Resources/BsResources.h"
  4. #include "Audio/BsAudioClip.h"
  5. #include "Audio/BsAudioClipImportOptions.h"
  6. #include "Audio/BsAudio.h"
  7. #include "Material/BsMaterial.h"
  8. #include "Components/BsCCamera.h"
  9. #include "Components/BsCAudioSource.h"
  10. #include "Components/BsCAudioListener.h"
  11. #include "RenderAPI/BsRenderAPI.h"
  12. #include "RenderAPI/BsRenderWindow.h"
  13. #include "Scene/BsSceneObject.h"
  14. #include "Importer/BsImporter.h"
  15. #include "Utility/BsTime.h"
  16. #include "Input/BsInput.h"
  17. #include "GUI/BsCGUIWidget.h"
  18. #include "GUI/BsGUIPanel.h"
  19. #include "GUI/BsGUILayoutY.h"
  20. #include "GUI/BsGUILabel.h"
  21. // Example headers
  22. #include "BsExampleConfig.h"
  23. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  24. // This example demonstrates how to import audio clips and then play them back using a variety of settings.
  25. //
  26. // The example starts off by import the relevant audio clips, demonstrating various settings for streaming, compression and
  27. // 2D/3D audio. It then sets up a camera that will be used for GUI rendering, unrelated to audio. It proceeds to
  28. // add an AudioListener component which is required to play back 3D sounds (it determines what are sounds relative to). It
  29. // then creates a couple of AudioSources - one that is static and used for music playback (2D audio), and another that
  30. // moves around the listener and demonstrates 3D audio playback. Follow that, input is hooked up that lets the user switch
  31. // between the playback of the two audio sources. It also demonstrates how to play one-shot audio clips without the
  32. // AudioSource component. Finally, GUI is set up that lets the user know which input controls are available.
  33. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  34. namespace bs
  35. {
  36. UINT32 windowResWidth = 1280;
  37. UINT32 windowResHeight = 720;
  38. /** Create a helper component that causes its scene object to move around in a circle around the world origin. */
  39. class ObjectFlyer : public Component
  40. {
  41. public:
  42. ObjectFlyer(const HSceneObject& parent)
  43. :Component(parent)
  44. { }
  45. /** Triggered once per frame. */
  46. void update() override
  47. {
  48. const float time = gTime().getTime();
  49. const float x = cos(time);
  50. const float z = sin(time);
  51. SO()->setPosition(Vector3(x, 0.0f, z));
  52. }
  53. };
  54. /** Import audio clips and set up the audio sources and listeners. */
  55. void setUpScene()
  56. {
  57. /************************************************************************/
  58. /* ASSETS */
  59. /************************************************************************/
  60. // First import any audio clips we plan on using
  61. // Set up paths to the audio file resources
  62. const Path exampleDataPath = EXAMPLE_DATA_PATH;
  63. const Path musicClipPath = exampleDataPath + "Audio/BrokeForFree-NightOwl.ogg";
  64. const Path environmentClipPath = exampleDataPath + "Audio/FilteredPianoAmbient.ogg";
  65. const Path cueClipPath = exampleDataPath + "Audio/GunShot.wav";
  66. // Import the music audio clip. Compress the imported data to Vorbis format to save space, at the cost of decoding
  67. // performance. Also since it's a longer audio clip, use streaming to avoid loading the entire clip into memory,
  68. // at the additional cost of performance and IO overhead.
  69. SPtr<AudioClipImportOptions> musicImportOptions = AudioClipImportOptions::create();
  70. musicImportOptions->setFormat(AudioFormat::VORBIS);
  71. musicImportOptions->setReadMode(AudioReadMode::Stream);
  72. musicImportOptions->setIs3D(false);
  73. HAudioClip musicClip = gImporter().import<AudioClip>(musicClipPath, musicImportOptions);
  74. // Import a loopable environment ambient sound. Compress the imported data to Vorbis format to save space, at the
  75. // cost of decoding performance. Same as the music clip, this is also a longer clip, but instead of streaming we
  76. // load the compressed data and just uncompress on the fly. This saves on IO overhead at the cost of little
  77. // extra memory.
  78. SPtr<AudioClipImportOptions> environmentImportOptions = AudioClipImportOptions::create();
  79. environmentImportOptions->setFormat(AudioFormat::VORBIS);
  80. environmentImportOptions->setReadMode(AudioReadMode::LoadCompressed);
  81. environmentImportOptions->setIs3D(true);
  82. HAudioClip environmentClip = gImporter().import<AudioClip>(environmentClipPath, environmentImportOptions);
  83. // Import a short audio cue. Use the uncompressed PCM audio format for fast playback, at the cost of memory.
  84. SPtr<AudioClipImportOptions> cueImportOptions = AudioClipImportOptions::create();
  85. cueImportOptions->setFormat(AudioFormat::PCM);
  86. cueImportOptions->setIs3D(true);
  87. HAudioClip cueClip = gImporter().import<AudioClip>(cueClipPath, cueImportOptions);
  88. /************************************************************************/
  89. /* CAMERA */
  90. /************************************************************************/
  91. // Add a camera that will be used for rendering out GUI elements
  92. // Like before, we create a new scene object at (0, 0, 0).
  93. HSceneObject sceneCameraSO = SceneObject::create("SceneCamera");
  94. // Get the primary render window we need for creating the camera.
  95. SPtr<RenderWindow> window = gApplication().getPrimaryWindow();
  96. // Add a Camera component that will output whatever it sees into that window
  97. // (You could also use a render texture or another window you created).
  98. HCamera sceneCamera = sceneCameraSO->addComponent<CCamera>();
  99. sceneCamera->getViewport()->setTarget(window);
  100. // Set background color
  101. sceneCamera->getViewport()->setClearColorValue(Color::Black);
  102. /************************************************************************/
  103. /* AUDIO */
  104. /************************************************************************/
  105. // Set up an audio listener. Every sound will be played relative to this listener. We'll add it to the same
  106. // scene object as our main camera.
  107. HAudioListener listener = sceneCameraSO->addComponent<CAudioListener>();
  108. // Add an audio source for playing back the music. Position of the audio source is not important as it is not
  109. // a 3D sound.
  110. HSceneObject musicSourceSO = SceneObject::create("Music");
  111. HAudioSource musicSource = musicSourceSO->addComponent<CAudioSource>();
  112. // Assign the clip we want to use for the audio source
  113. musicSource->setClip(musicClip);
  114. // Start playing the audio clip immediately
  115. musicSource->play();
  116. // Add an audio source for playing back an environment sound. This sound is played back on a scene object that
  117. // orbits the viewer.
  118. HSceneObject environmentSourceSO = SceneObject::create("Environment");
  119. HAudioSource environmentSource = environmentSourceSO->addComponent<CAudioSource>();
  120. // Assign the clip we want to use for the audio source
  121. environmentSource->setClip(environmentClip);
  122. // Make sure the sound keeps looping if it reaches the end
  123. environmentSource->setIsLooping(true);
  124. // Make the audio source orbit the listener, by attaching an ObjectFlyer component
  125. environmentSourceSO->addComponent<ObjectFlyer>();
  126. /************************************************************************/
  127. /* INPUT */
  128. /************************************************************************/
  129. // Hook up input commands that toggle between the different audio sources.
  130. gInput().onButtonUp.connect([=](const ButtonEvent& event)
  131. {
  132. switch(event.buttonCode)
  133. {
  134. case BC_1:
  135. // Start or resume playing music, if not already playing. Stop the ambient sound playback.
  136. environmentSource->stop();
  137. musicSource->play();
  138. break;
  139. case BC_2:
  140. // Start playing ambient sound, if not already playing. Pause music playback.
  141. musicSource->pause();
  142. environmentSource->play();
  143. break;
  144. case BC_MOUSE_LEFT:
  145. // Play a one-shot sound at origin. We don't use an AudioSource component because it's a short sound cue
  146. // that we don't require additional control over.
  147. gAudio().play(cueClip, Vector3::ZERO);
  148. break;
  149. default:
  150. break;
  151. }
  152. });
  153. /************************************************************************/
  154. /* GUI */
  155. /************************************************************************/
  156. // Display GUI elements indicating to the user which input keys are available
  157. // Add a GUIWidget component we will use for rendering the GUI
  158. HSceneObject guiSO = SceneObject::create("GUI");
  159. HGUIWidget gui = guiSO->addComponent<CGUIWidget>(sceneCamera);
  160. // Grab the main panel onto which to attach the GUI elements to
  161. GUIPanel* mainPanel = gui->getPanel();
  162. // Create a vertical GUI layout to align the labels one below each other
  163. GUILayoutY* vertLayout = GUILayoutY::create();
  164. // Create the GUI labels displaying the available input commands
  165. HString musicString(u8"Press 1 to play music");
  166. HString environmentString(u8"Press 2 to play 3D ambient sound");
  167. HString cueString(u8"Press left mouse button to play a gun shot sound");
  168. vertLayout->addNewElement<GUILabel>(musicString);
  169. vertLayout->addNewElement<GUILabel>(environmentString);
  170. vertLayout->addNewElement<GUILabel>(cueString);
  171. // Register the layout with the main GUI panel, placing the layout in top left corner of the screen by default
  172. mainPanel->addElement(vertLayout);
  173. }
  174. }
  175. /** Main entry point into the application. */
  176. #if BS_PLATFORM == BS_PLATFORM_WIN32
  177. #include <windows.h>
  178. int CALLBACK WinMain(
  179. _In_ HINSTANCE hInstance,
  180. _In_ HINSTANCE hPrevInstance,
  181. _In_ LPSTR lpCmdLine,
  182. _In_ int nCmdShow
  183. )
  184. #else
  185. int main()
  186. #endif
  187. {
  188. using namespace bs;
  189. // Initializes the application and creates a window with the specified properties
  190. VideoMode videoMode(windowResWidth, windowResHeight);
  191. Application::startUp(videoMode, "Example", false);
  192. // Custom example code goes here
  193. setUpScene();
  194. // Runs the main loop that does most of the work. This method will exit when user closes the main
  195. // window or exits in some other way.
  196. Application::instance().runMainLoop();
  197. // When done, clean up
  198. Application::shutDown();
  199. return 0;
  200. }