GettingStarted.dox 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717
  1. namespace Urho3D
  2. {
  3. /**
  4. \page Building Building Urho3D
  5. \section Building_Prerequisites Building prerequisites
  6. Although all required third-party libraries are included as source code, there are system-level dependencies that must be satisfied before Urho3D can be built successfully:
  7. - For Windows, the June 2010 DirectX SDK needs to be installed and its include and library directories set as Visual Studio global directories (Tools -> Options -> Projects and Solutions -> VC++ Directories in VS2008.)
  8. - For Linux, the following development packages need to be installed: libx11-dev, libxrandr-dev, libasound2-dev. Also install the package libgl1-mesa-dev if your GPU driver does not include OpenGL headers & libs.
  9. - For Mac OS X, the Xcode developer tools package should include everything necessary.
  10. - For Android, the Android SDK and Android NDK need to be installed.
  11. To run Urho3D, the minimum system requirements are:
  12. - Windows: CPU with SSE instructions support, Windows XP or newer, DirectX 9.0c, GPU with %Shader %Model 2 support (%Shader %Model 3 recommended.)
  13. - Linux & Mac OS X: CPU with SSE instructions support, GPU with OpenGL 2.0 support, EXT_framebuffer_object and EXT_packed_depth_stencil extensions.
  14. - Android: OS version 2.2 or newer, OpenGL ES 2.0 capable GPU.
  15. - iOS: OpenGL ES 2.0 capable GPU.
  16. SSE requirement can be eliminated by commenting out lines that enable it from the root CMakeLists.txt.
  17. \section Building_Desktop Desktop build process
  18. Urho3D uses CMake (http://www.cmake.org) to build. The process has two steps:
  19. 1) Run CMake in the root directory with your preferred toolchain specified to generate the build files. You can use the batch files or shell scripts provided: cmake_vs2008.bat, cmake_vs2010.bat or cmake_vs2012.bat on Windows, and cmake_gcc.sh on Linux and Mac OS X.
  20. 2) For Visual Studio, open Urho3D.sln and build the configuration(s) you like. For gcc, execute make (by default, cmake_gcc.sh specifies to make a RelWithDebInfo build.)
  21. On Windows, using other compilers than Visual Studio is not officially supported. MinGW may work (cmake -G "MinGW Makefiles"), but may lack required DirectX headers. They can be copied to a MinGW installation from the following package: http://www.libsdl.org/extras/win32/common/directx-devel.tar.gz
  22. When using Xcode on Mac OS X, select the i386 architecture before building (CMake should already select this when generating the Xcode project). Compiling Urho3D as 64-bit is not supported.
  23. After the build is complete, the programs can be run from the Bin directory.
  24. To run from the Visual Studio debugger, set the Urho3D project as the startup project and enter its relative path and filename into Properties -> Debugging -> Command: ..\\Bin\\Urho3D.exe. Additionally, entering -w into Debugging -> Command Arguments is highly recommended. This enables startup in windowed mode: without it running into an exception or breakpoint will be obnoxious as the mouse cursor will likely be hidden.
  25. To actually make Urho3D.exe do something useful, it must be supplied with the name of the script file it should load and run. You can try for example the following arguments: Scripts/NinjaSnowWar.as -w
  26. To make the Urho3D examples start faster on Windows & Direct3D9 mode, run CompileAllShaders.bat from the Bin directory first.
  27. \section Building_Android Android build process
  28. First copy Bin/Data and Bin/CoreData directories to the Android/assets directory (you can use the provided batch file CopyData.bat.) Next, execute the following commands in the Android directory:
  29. - android update project -p . (only needed on the first time)
  30. - ndk-build
  31. - ant debug
  32. Note that ndk-build builds Urho3D twice, once without hardware floating point instructions, and once with them. After the commands finish successfully, the APK should have been generated to the Android/bin directory, from where it can be installed on a device or an emulator.
  33. For a release build, use the "ant release" command instead of "ant debug" and follow the Android SDK instructions on how to sign your APK properly.
  34. By default the Android package for Urho3D is com.googlecode.urho3d. For a real application you must replace this with your own package name. Unfortunately the name has to be replaced in several files:
  35. - Android/AndroidManifest.xml
  36. - Android/src/com/googlecode/urho3d/SDLActivity.java (rename directories also)
  37. - ThirdParty/SDL/include/SDL_config_android.h, look for the NATIVE_FUNCTION macro
  38. \section Building_Ios iOS build process
  39. Run cmake_ios.sh. This generates an Xcode project named Urho3D.xcodeproj.
  40. Open the Xcode project and check the properties for the Urho3D project (topmost in the Project Navigator.) In Architectures -> Base SDK, choose your iOS SDK (CMake would automatically select latest iOS when generating the Xcode project). In Code Signing, enter your developer identity as necessary.
  41. The Urho3D target will actually build the application bundle and copy resources from Bin/Data and Bin/CoreData directories. Edit its build scheme to choose debug or release mode.
  42. \page Running Running Urho3D
  43. The main executable Urho3D.exe in the Bin directory contains all the engine runtime functionality. However, it does not contain any inbuilt logic or application, and therefore must be supplied with the name of the application script file it should run:
  44. Urho3D.exe <scriptfilename> [options]
  45. The scripting language used is AngelScript (http://www.angelcode.com/angelscript); the script files have .as extension and need to be placed under either the Bin/Data or Bin/CoreData subdirectories so that Urho3D.exe can find them. An application script is required to have the function void Start(), which will be executed before starting the engine main loop. It is this function's responsibility to initialize the application and to hook up to any necessary \ref Events "events", such as the update that happens every frame.
  46. On Android and iOS there are no command line options, so running the NinjaSnowWar example is hardcoded. This can be changed from the file Urho3D/Urho3D.cpp.
  47. Currently eight example application scripts exist:
  48. \section Running_NinjaSnowWar NinjaSnowWar
  49. A third-person action game. To start, run NinjaSnowWar.bat in the Bin directory, or use the command Urho3D.exe Scripts/NinjaSnowWar.as
  50. Key and mouse controls:
  51. \verbatim
  52. WSAD Move
  53. Left mouse Attack
  54. Space Jump
  55. F1 Toggle AngelScript console
  56. F2 Toggle physics debug geometry
  57. F3 Toggle profiling display
  58. F4 Toggle octree debug geometry
  59. \endverbatim
  60. If a joystick is connected, it can also be used for controlling the player character.
  61. NinjaSnowWar also supports client/server multiplayer. To start the server, run the command NinjaSnowWar.bat server (-headless switch can optionally given so that the server will not open a graphics window.) To connect to a server, specify the server address on the command line, for example NinjaSnowWar.bat 127.0.0.1
  62. \section Running_TestScene TestScene
  63. Rendering, physics and serialization test. To start, run TestScene.bat in the Bin directory, or use the command Urho3D.exe Scripts/TestScene.as
  64. Key and mouse controls:
  65. \verbatim
  66. WSAD Move
  67. Left mouse Create a new physics object; characters will ragdoll when hit
  68. Right mouse Hold and move mouse to rotate view
  69. Shift+LMB Paint a decal into the mouse cursor hit location
  70. Space Toggle debug geometry
  71. F1 Toggle AngelScript console
  72. F5 Save scene
  73. F7 Load scene
  74. 1 to 8 Toggle rendering options
  75. T Toggle profiling display
  76. O Toggle orthographic camera
  77. F Toggle FXAA edge filter
  78. B Toggle bloom post-process
  79. \endverbatim
  80. TestScene also includes a network replication test, where clients can connect, move around as invisible cameras, and create new physics objects. For this, a server needs to be started with the command TestScene.bat server (-headless switch can optionally given so that the server will not open a graphics window) and clients can connect by specifying the server address on the command line, for example TestScene.bat 127.0.0.1
  81. \section Running_Editor Editor
  82. %Scene editor application written in script. To start, run Editor.bat, or use the command Urho3D.exe Scripts/Editor.as
  83. For details on how to use the editor, see \ref EditorInstructions "Editor instructions."
  84. \section Running_Terrain Terrain
  85. %Terrain rendering example. To start, run Terrain.bat, or use the command Urho3D.exe Scripts/Terrain.as. %Controls are the same as in TestScene, and additionally:
  86. \verbatim
  87. L Toggle buoyant liquid volume
  88. \endverbatim
  89. \section Running_Physics Physics
  90. A stress test of 1000 moving physics objects, which also showcases the performance difference instancing can make. Run with Physics.bat, or use the command Urho3D.exe Scripts/Physics.as. %Controls as in TestScene.
  91. \section Running_TestSceneOld TestSceneOld
  92. A variation of TestScene ported from Urho3D 1.0. It lacks networking features, but is provided for examining backward compatibility and performance. Run with TestSceneOld.bat or by using the command Urho3D.exe Scripts/TestSceneOld.as. %Controls are like in TestScene, and additionally:
  93. \verbatim
  94. P Toggle scene animation
  95. L Toggle camera light detached/attached
  96. \endverbatim
  97. \section Running_LightTest LightTest
  98. %Light rendering performance test. To start, run LightTest.bat in the Bin directory, or use the command Urho3D.exe Scripts\LightTest.as
  99. Key and mouse controls:
  100. \verbatim
  101. WSAD Move
  102. ZX Select model to use
  103. Arrows Add or remove lights and objects
  104. Pageup/down Add or remove 10 lights
  105. Right mouse Hold and move mouse to rotate view
  106. F1 Toggle AngelScript console
  107. 1 to 8 Toggle rendering options
  108. T Toggle profiling display
  109. O Toggle orthographic camera
  110. V Toggle vertex lighting
  111. F Toggle FXAA edge filter
  112. R Re-randomize light and object positions
  113. \endverbatim
  114. \section Running_Chat Chat
  115. Simple client-server chat test application. To start, run Chat.bat or ChatServer.bat in the Bin directory, or use the command Urho3D.exe Scripts/Chat.as
  116. On the client, first type the server address to the text edit box and click "Connect." After connecting successfully you can start typing messages;
  117. either press return or click "Send" to send them. Press ESC to exit.
  118. To connect automatically, the server address can also be given on the command line, for example Chat.bat 127.0.0.1
  119. \section Running_Commandline Command line options
  120. Urho3D.exe understands the following command line options:
  121. \verbatim
  122. -x<res> Horizontal resolution
  123. -y<res> Vertical resolution
  124. -m<level> Enable hardware multisampling
  125. -v Enable vertical sync
  126. -t Enable triple buffering
  127. -w Start in windowed mode
  128. -b<length> Sound buffer length in milliseconds
  129. -r<freq> Sound mixing frequency in Hz
  130. -headless Headless mode. No application window will be created
  131. -logdebug Display debug level log messages also in release mode
  132. -prepass Use light pre-pass rendering
  133. -deferred Use deferred rendering
  134. -lqshadows Use low-quality (1-sample) shadow filtering
  135. -noshadows Disable shadow rendering
  136. -nolimit Disable frame limiter
  137. -nothreads Disable worker threads
  138. -nosound Disable sound output
  139. -noip Disable sound mixing interpolation
  140. -sm2 Force SM2.0 rendering
  141. \endverbatim
  142. \page Structure Overall structure
  143. Urho3D consists of several static libraries that are independent where possible: for example the Graphics library could be used without the Engine library, if only rendering capabilities were desired.
  144. The libraries are the following:
  145. - Container. Provides STL replacement classes and shared pointers.
  146. - Math. Provides vector & quaternion types and geometric shapes used in intersection tests.
  147. - Core. Provides the execution Context, the base class Object for typed objects, object factories, \ref Event "event handling", threading and profiling.
  148. - IO. Provides file system access, stream input/output and logging.
  149. - %Resource. Provides the ResourceCache and the base resource types, including XML documents.
  150. - %Scene. Provides Node and Component classes, from which Urho3D scenes are built.
  151. - %Graphics. Provides application window handling and 3D rendering capabilities.
  152. - %Input. Provides mouse & keyboard input in both polled and event-based mode.
  153. - %Network. Provides client-server networking functionality.
  154. - %Audio. Provides the audio subsystem and playback of .wav & .ogg sounds in either 2D or 3D.
  155. - %UI. Provides a 2D graphical user interface.
  156. - Physics. Provides physics simulation.
  157. - %Script. Provides scripting support using the AngelScript language.
  158. - %Engine. Instantiates the subsystems from the libraries above, and manages the main loop iteration.
  159. Urho3D.exe uses the Engine & Script libraries to start up the subsystems and to load the script file specified on the command line; however all of the libraries above get automatically linked as Engine library depends on all of them.
  160. Although Urho3D.exe itself is geared towards running a scripted application, it is also possible to use the engine through C++ only. When the scripting subsystem initialization is completely skipped, the resulting executable will also be significantly smaller.
  161. The third-party libraries are used for the following functionality:
  162. - AngelScript: scripting language implementation
  163. - Bullet: physics simulation implementation
  164. - FreeType: font rendering
  165. - GLee: OpenGL extensions handling
  166. - kNet: UDP networking
  167. - libcpuid: CPU properties detection
  168. - MojoShader: parsing HLSL bytecode after shader compilation
  169. - Open Asset Import Library: reading various 3D file formats
  170. - pugixml: parsing XML files
  171. - SDL: window and OpenGL context creation, input and sound output
  172. - StanHull: convex hull generation from triangle meshes, used for physics collision shapes
  173. - stb_image: image loading
  174. - stb_vorbis: Ogg Vorbis decoding
  175. \page Conventions Conventions
  176. Urho3D uses the following conventions and principles:
  177. - Left-handed coordinates. Positive X, Y & Z axes point to the right, up, and forward, and positive rotation is clockwise.
  178. - Degrees are used for angles.
  179. - Clockwise vertices define a front face.
  180. - %Audio volume is specified from 0.0 (silence) to 1.0 (full volume)
  181. - Path names use slash instead of backslash. Paths will be converted internally into the necessary format when calling into the operating system.
  182. - In the script API, properties are used whenever appropriate instead of %Set... and Get... functions. If the setter and getter require index parameters, the property will use array-style indexing, and its name will be in plural. For example model->SetMaterial(0, myMaterial) in C++ would become model.materials[0] = myMaterial in script.
  183. - Raw pointers are used whenever possible in the classes' public API. This simplifies exposing functions & classes to script, and is relatively safe, because SharedPtr & WeakPtr use intrusive reference counting.
  184. - No C++ exceptions. Error return values (false / null pointer / dummy reference) are used instead. %Script exceptions are used when there is no other sensible way, such as with out of bounds array access.
  185. - Feeding illegal data to public API functions, such as out of bounds indices or null pointers, should not cause crashes or corruption. Instead errors are logged as appropriate.
  186. - For threading and multi-instance safety, no mutable static data (including singletons) or function-static data is allowed.
  187. - Third party libraries are included as source code for the build process. They are however hidden from the public API as completely as possible.
  188. For more details related to the C++ coding style, see also \ref CodingConventions "Coding conventions".
  189. \page ScriptQuickstart Quickstart in script
  190. In the following example, a minimal "Hello World" application with both 3D and user interface content will be built.
  191. We start by defining the Start() function required in all Urho3D script applications. When Urho3D.exe executes it, all the engine subsystems are already in place, so any initialization that needs to be done is specific to the application itself.
  192. \code
  193. Scene@ helloScene;
  194. void Start()
  195. {
  196. helloScene = Scene();
  197. CreateObjects();
  198. CreateText();
  199. SubscribeToEvents();
  200. }
  201. \endcode
  202. Even before Start(), we define the object handle for the 3D scene we are going to create. This must be outside the function so that the Scene will remain after the function execution ends. Angelscript uses the @ symbol for object handles, which correspond to SharedPtr's on C++ side (ie. they keep alive the object pointed to.)
  203. In the Start() function itself, first of all we create the 3D scene. Note the lack of "new" keyword. Then we branch off to further initialization functions that will be defined below.
  204. Note that Urho3D has modified AngelScript to allow object handle assignment without the @ symbol, if the object in question does not support value assignment. None of the Urho3D reference-counted objects, such as Scene, support value assignment. In unmodified AngelScript the first line of Start() would have to read "@helloScene = Scene()".
  205. In CreateObjects(), which we define next, the scene will be filled with some content. The Urho3D scene model is basically a scene graph; the Scene object serves also as the root node.
  206. \code
  207. void CreateObjects()
  208. {
  209. helloScene.CreateComponent("Octree");
  210. Node@ objectNode = helloScene.CreateChild();
  211. Node@ lightNode = helloScene.CreateChild();
  212. Node@ cameraNode = helloScene.CreateChild();
  213. StaticModel@ object = objectNode.CreateComponent("StaticModel");
  214. object.model = cache.GetResource("Model", "Models/Mushroom.mdl");
  215. object.material = cache.GetResource("Material", "Materials/Mushroom.xml");
  216. Light@ light = lightNode.CreateComponent("Light");
  217. light.lightType = LIGHT_DIRECTIONAL;
  218. lightNode.direction = Vector3(-1, -1, -1);
  219. Camera@ camera = cameraNode.CreateComponent("Camera");
  220. cameraNode.position = Vector3(0, 0.3, -3);
  221. renderer.viewports[0] = Viewport(helloScene, camera);
  222. }
  223. \endcode
  224. First of all we need to create an Octree component into the root node. This is used for accelerated visibility queries to check what the camera "sees", and without it nothing would be visible.
  225. Three child nodes are then created: one for a 3D model object, one for a directional light, and one for the camera. The scene nodes themselves display nothing in the 3D world; components need to be created into them for the actual visible content.
  226. Child nodes can be created with or without names; uniqueness of names is not enforced. In this case we opt to not use names, as we do not need to find the nodes later after creation.
  227. As animation is not needed, we use a StaticModel component for the 3D model. Its scene node remains at the origin (default position of each scene node.) The ResourceCache subsystem is used to load the needed Model & Material resources.
  228. The light scene node also remains at the origin. Position does not matter for directional lights, but the node's forward direction is adjusted so that the light will shine down diagonally.
  229. The camera's scene node is pulled back along the Z-axis to be able to see the object.
  230. Finally we define a fullscreen Viewport into the Renderer subsystem so that the scene can be shown. The viewport needs Scene and Camera object handles. Note the indexing; multiple viewports could be defined (for example to use split screen rendering) if necessary.
  231. The 3D content is now finished. Next, we create the user interface content in CreateText().
  232. \code
  233. void CreateText()
  234. {
  235. Text@ helloText = Text();
  236. helloText.SetFont(cache.GetResource("Font", "Fonts/Anonymous Pro.ttf"), 30);
  237. helloText.text = "Hello World from Urho3D";
  238. helloText.color = Color(0, 1, 0);
  239. helloText.horizontalAlignment = HA_CENTER;
  240. helloText.verticalAlignment = VA_CENTER;
  241. ui.root.AddChild(helloText);
  242. }
  243. \endcode
  244. We display a "Hello World" message on the screen with the help of a Text user interface element. We use the included Anonymous Pro font with point size 30. For the text to actually become visible, it needs to be added as a child of the user interface root element (the UI can be thought of as a 2D scene graph.) It is also centered both horizontally and vertically in relation to the parent element.
  245. Finally we subscribe to necessary Urho3D events in the SubscribeToEvents() function.
  246. \code
  247. void SubscribeToEvents()
  248. {
  249. SubscribeToEvent("Update", "HandleUpdate");
  250. }
  251. \endcode
  252. If no events would be responded to, the application would just be left running with no possibility to interact with it, until it was forcibly exited with Alt-F4. In this case, we are interested of the frame update event, which will be sent on each iteration of the main loop. When subscribing, we need to give the name of the event, and the name of the event handler function. We could also require the event to be sent by a specific sender, but in this case that is unnecessary.
  253. The event handler function needs to have a specific signature. If event type and parameters are not needed, "void HandleEvent()", or if they are, "void HandleEvent(StringHash eventType, VariantMap& eventData)". We might want to expand the application later, so we use the latter form.
  254. \code
  255. void HandleUpdate(StringHash eventType, VariantMap& eventData)
  256. {
  257. float timeStep = eventData["TimeStep"].GetFloat();
  258. if (input.keyPress[KEY_ESC])
  259. engine.Exit();
  260. }
  261. \endcode
  262. The current frame's delta time is sent in the update event's parameters, and that will be useful when animating the scene. For now the event handler simply checks from the Input subsystem if the ESC key has been pressed; if it is, it calls the Engine subsystem's \ref Engine::Exit "Exit()" function. This closes the application window and causes Urho3D.exe to exit after the current main loop iteration finishes.
  263. Note that to get the ESC keypress without having to poll it for each frame, we could also subscribe to the "KeyDown" event sent by the Input subsystem.
  264. The example application is now complete. To try it out, save it as HelloWorld.as in the Bin/Data/Scripts directory, then run Urho3D.exe Scripts/HelloWorld.as
  265. \section Xcode_AngleScript_Info Mac OS X specific - How to view/edit AngelScript within Xcode
  266. By default Mac OS X recognizes file having extension .as as 'AppleSingle Archive'. So, even after associating this file type to always open with Xcode, Xcode is still not able to view/edit the content of the file correctly. In order to view/edit the scripts, after launching the Urho3D project in Xcode, select the .as file(s) in the Project Navigator and then in the %File Inspector (right panel) change the file type from 'Default - AppleSingle archive' to 'C++ Source' in the %File Type drop down list. The current editor view usually does not refresh its content after this change. Selecting another file in the Project Navigator then reselecting the .as file should force the editor to reload and show the .as file correctly afterwards.
  267. The drawback of the above approach is, Xcode does not remember it. The steps needs to be carried out each time Xcode is relaunched.
  268. To solve this permanently, we need to 'hack' the system a little bit to 'fool' Xcode to always treat .as file as one of the C++ source files. Execute the following commands in a terminal as normal user. These commands have been verified on Lion.
  269. \code
  270. $ cd /System/Library/CoreServices/CoreTypes.bundle/Contents
  271. $ plutil -convert xml1 Info.plist -o /tmp/Info.plist.xml
  272. $ sed -i.bak "s/<string>cxx<\/string>/<string>cxx<\/string>\\`echo -e '\n\r'`<string>as<\/string>/g" /tmp/Info.plist.xml
  273. $ sudo cp -p Info.plist{,.ori}
  274. $ sudo plutil -convert binary1 /tmp/Info.plist.xml -o Info.plist
  275. $ find /System/Library/Frameworks -type f -name lsregister -exec {} -kill -r -domain local -domain system -domain user -domain network \;
  276. \endcode
  277. The last command resets the launch service database and rebuilds it, so the changes should take effect immediately when Xcode restarts.
  278. \page CppQuickstart Quickstart in C++
  279. This example shows how to create an Urho3D C++ application from the ground up. The actual functionality will be the same as in \ref ScriptQuickstart "Quickstart in script"; it is strongly recommended that you familiarize yourself with it first.
  280. For simplicity, the application is assumed to be compiled on Windows and therefore defines the WinMain() function; look at the file Urho3D.cpp in the Urho3D subdirectory on how to handle cross-platform startup using a macro defined in Main.h in the Core library.
  281. To start with, create a subdirectory "HelloWorld" into the Urho3D root directory, and add the following line to the end of the root directory's CMakeLists.txt %file:
  282. \code
  283. add_subdirectory (HelloWorld)
  284. \endcode
  285. Then, create the following CMakeLists.txt file into the HelloWorld directory (mostly copied from CMakeLists.txt of Urho3D.exe):
  286. \code
  287. # Define target name
  288. set (TARGET_NAME HelloWorld)
  289. # Define source files
  290. file (GLOB CPP_FILES *.cpp)
  291. file (GLOB H_FILES *.h)
  292. set (SOURCE_FILES ${CPP_FILES} ${H_FILES})
  293. # Define dependency libs
  294. set (LIBS ../Engine/Container ../Engine/Core ../Engine/Engine ../Engine/Graphics ../Engine/Input ../Engine/IO ../Engine/Math ../Engine/Resource ../Engine/Scene ../Engine/UI)
  295. # Setup target
  296. if (WIN32)
  297. set (EXE_TYPE WIN32)
  298. endif ()
  299. setup_executable ()
  300. \endcode
  301. Before recreating the build files with CMake, create an empty HelloWorld.cpp into the HelloWorld directory. Now you can re-run CMake. If using Visual Studio, the HelloWorld project should now appear in the Urho3D solution, and you can start writing the actual application into HelloWorld.cpp.
  302. To start with, we need the include files for all the engine classes we are going to use, plus Windows.h for the WinMain function:
  303. \code
  304. #include "Camera.h"
  305. #include "Context.h"
  306. #include "CoreEvents.h"
  307. #include "Engine.h"
  308. #include "Font.h"
  309. #include "Input.h"
  310. #include "Light.h"
  311. #include "Material.h"
  312. #include "Model.h"
  313. #include "Octree.h"
  314. #include "ProcessUtils.h"
  315. #include "Renderer.h"
  316. #include "ResourceCache.h"
  317. #include "Scene.h"
  318. #include "StaticModel.h"
  319. #include "Text.h"
  320. #include "UI.h"
  321. #include <Windows.h>
  322. \endcode
  323. All Urho3D classes reside inside the namespace Urho3D, so a using directive is convenient:
  324. \code
  325. using namespace Urho3D;
  326. \endcode
  327. To be able to subscribe to events, we need to subclass Object (if we did not use events, we could do everything procedurally, for example directly in WinMain, but that would be somewhat ugly.) We name the class HelloWorld, with functions that match the script version, plus a constructor. Note the shared pointers to the scene that we will create, and to the ResourceCache, which is perhaps the most often used subsystem, and therefore convenient to store here. Also note the OBJECT(className) macro, which inserts code for object type identification:
  328. \code
  329. class HelloWorld : public Object
  330. {
  331. OBJECT(HelloWorld);
  332. public:
  333. HelloWorld(Context* context);
  334. void Start();
  335. void CreateObjects();
  336. void CreateText();
  337. void SubscribeToEvents();
  338. void HandleUpdate(StringHash eventType, VariantMap& eventData);
  339. SharedPtr<Scene> helloScene_;
  340. SharedPtr<ResourceCache> cache_;
  341. };
  342. \endcode
  343. Before the actual HelloWorld implementation, we define WinMain.
  344. \code
  345. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE prevInstance, PSTR cmdLine, int showCmd)
  346. {
  347. SharedPtr<Context> context(new Context());
  348. SharedPtr<Engine> engine(new Engine(context));
  349. engine->Initialize("HelloWorld", "HelloWorld.log", ParseArguments(GetCommandLineW()));
  350. SharedPtr<HelloWorld> helloWorld(new HelloWorld(context));
  351. helloWorld->Start();
  352. while (!engine->IsExiting())
  353. engine->RunFrame();
  354. return 0;
  355. }
  356. \endcode
  357. First, we create the Context object, which holds all subsystems and object factories, and keeps track of event senders and receivers. All Object subclasses need to be supplied a pointer to that context. When using an object factory (such as when creating components) that is automatic, but when creating objects manually, the pointer also needs to be passed manually.
  358. With the context at hand, we create the Engine and initialize it. The arguments for the \ref Engine::Initialize "Initialize()" function are the initial window title, the log file name, and command line parameters, which are parsed using the ParseArguments() helper function.
  359. After this, we instantiate the HelloWorld object, call its Start() function, and run the main loop until Engine tells that we should exit. The shared pointers will take care of deleting the objects in the correct order; the Context will be the last to be destroyed.
  360. Now we can start implementing HelloWorld.
  361. \code
  362. OBJECTTYPESTATIC(HelloWorld);
  363. HelloWorld::HelloWorld(Context* context) :
  364. Object(context),
  365. cache_(GetSubsystem<ResourceCache>())
  366. {
  367. }
  368. \endcode
  369. Note the OBJECTTYPESTATIC(className) macro, which creates the static type name and type name hash for object type identification. For each OBJECT macro, a matching OBJECTTYPESTATIC must appear in a .cpp file.
  370. During construction, we only store the ResourceCache subsystem pointer for later access.
  371. In the Start() function the Scene will be created:
  372. \code
  373. void HelloWorld::Start()
  374. {
  375. helloScene_ = new Scene(context_);
  376. CreateObjects();
  377. CreateText();
  378. SubscribeToEvents();
  379. }
  380. \endcode
  381. Like in the script example, CreateObjects() does the actual scene object creation and defines the viewport.
  382. \code
  383. void HelloWorld::CreateObjects()
  384. {
  385. helloScene_->CreateComponent<Octree>();
  386. Node* objectNode = helloScene_->CreateChild();
  387. Node* lightNode = helloScene_->CreateChild();
  388. Node* cameraNode = helloScene_->CreateChild();
  389. StaticModel* object = objectNode->CreateComponent<StaticModel>();
  390. object->SetModel(cache_->GetResource<Model>("Models/Mushroom.mdl"));
  391. object->SetMaterial(cache_->GetResource<Material>("Materials/Mushroom.xml"));
  392. Light* light = lightNode->CreateComponent<Light>();
  393. light->SetLightType(LIGHT_DIRECTIONAL);
  394. lightNode->SetDirection(Vector3(-1.0f, -1.0f, -1.0f));
  395. Camera* camera = cameraNode->CreateComponent<Camera>();
  396. cameraNode->SetPosition(Vector3(0.0f, 0.3f, -3.0f));
  397. GetSubsystem<Renderer>()->SetViewport(0, new Viewport(context_, helloScene_, camera));
  398. }
  399. \endcode
  400. Unlike in script, where properties were used to set the component values and scene node transforms, here we must use setter functions instead. Also, whereas strings were used in script to identify the components to create, here it is most convenient to use the template form of \ref Node::CreateComponent "CreateComponent()":
  401. The text overlay creation is next. Again, setters are used throughout:
  402. \code
  403. void HelloWorld::CreateText()
  404. {
  405. SharedPtr<Text> helloText(new Text(context_));
  406. helloText->SetFont(cache_->GetResource<Font>("Fonts/Anonymous Pro.ttf"), 30);
  407. helloText->SetText("Hello World from Urho3D");
  408. helloText->SetColor(Color(0.0f, 1.0f, 0.0f));
  409. helloText->SetHorizontalAlignment(HA_CENTER);
  410. helloText->SetVerticalAlignment(VA_CENTER);
  411. GetSubsystem<UI>()->GetRoot()->AddChild(helloText);
  412. }
  413. \endcode
  414. Finally we get to event subscribing and handling.
  415. \code
  416. void HelloWorld::SubscribeToEvents()
  417. {
  418. SubscribeToEvent(E_UPDATE, HANDLER(HelloWorld, HandleUpdate));
  419. }
  420. \endcode
  421. The helper macro HANDLER is used to create pointers to the event handler member functions: it takes the class name followed by the function name. Note also that unlike script, where events and event parameters are identified with strings, in C++ precalculated hash constants are used instead. The frame update event is defined in CoreEvents.h.
  422. In C++ the event handler function must always have the signature "void HandleEvent(StringHash eventType, VariantMap& eventData)". Note that when accessing event parameters, the event's name is used as a namespace to prevent name clashes:
  423. \code
  424. void HelloWorld::HandleUpdate(StringHash eventType, VariantMap& eventData)
  425. {
  426. float timeStep = eventData[Update::P_TIMESTEP].GetFloat();
  427. if (GetSubsystem<Input>()->GetKeyDown(KEY_ESC))
  428. GetSubsystem<Engine>()->Exit();
  429. }
  430. \endcode
  431. Now you should be ready to compile HelloWorld.cpp. The resulting executable will be placed in the Bin directory. It should be substantially smaller than Urho3D.exe due to leaving out the scripting functionality.
  432. \page EditorInstructions Editor instructions
  433. The Urho3D scene editor is a script application that can be run with the Urho3D main executable. To start, execute either of these commands: (in the Bin directory) Editor.bat or Urho3D.exe Scripts/Editor.as
  434. Hint: to get some content to look at, run the TestScene example, and press F5. This saves a scene file called TestScene.xml into the Data/Scenes subdirectory, which can be loaded in the editor. The NinjaSnowWar scene also exists in the Data/Scenes subdirectory, and the NinjaSnowWar object "prefabs" are in the Data/Objects subdirectory.
  435. \section EditorInstructions_Controls Controls
  436. \verbatim
  437. Left mouse - Select nodes or drag the node transform gizmo. Hold Shift to
  438. select components instead. Hold Ctrl to multiselect.
  439. Right mouse - Hold down and move mouse to rotate camera
  440. WSAD or arrows - Move
  441. Shift+WSAD - Move faster
  442. Ctrl+1,2,3 - Select manipulation mode: move/rotate/scale
  443. Ctrl+4 - Toggle between world and local axes manipulation
  444. Ctrl+5,6 - Cycle through components to pick: geometries, lights, zones,
  445. collision shapes
  446. Ctrl+7 - Cycle through solid, wireframe and point rendering
  447. Ctrl+arrows - Manipulate node in X & Z directions
  448. Ctrl+pgup/pgdn - Manipulate node in Y direction
  449. Ctrl+plus/minus - Scale node uniformly (scale mode only)
  450. Ctrl+O - Open scene
  451. Ctrl+S - Save scene
  452. Ctrl+Shift+S - Save scene as
  453. Ctrl+A - Select/deselect all root level nodes
  454. Ctrl+X,C,V - Cut/copy/paste node or component
  455. Ctrl+U - Unparent scene node
  456. Ctrl+H - Open the scene hierarchy window
  457. Ctrl+N - Open the node / component edit window
  458. Ctrl+P - Toggle scene update on/off
  459. Ctrl+R - Reload scene resources
  460. ESC - Close the file selector or editor settings window
  461. DEL - Delete node or component
  462. F1 - Toggle console
  463. F2 - Toggle rendering debug geometry
  464. F3 - Toggle physics debug geometry
  465. F4 - Toggle octree debug geometry
  466. \endverbatim
  467. Press right mouse button in the 3D view if you want to defocus the active window without changing the object selection.
  468. \section EditorInstructions_Workflow Workflow
  469. When you start with an empty scene, set the resource path first (%File -> %Set resource path). This is the base directory, under which the subdirectories Models, Materials & Textures will be created as you import assets.
  470. Scenes should be saved either into this base directory, or into its immediate subdirectory, named for example Scenes or Levels. When loading a scene, the resource path will be set automatically.
  471. Check the Editor settings window so that the camera parameters match the size of the objects you are using.
  472. The editor settings will be saved on exit to a file Urho3D\Editor\Config.xml in the My Documents directory. Delete this file if you want to revert the settings to defaults.
  473. \section EditorInstructions_Editing Editing
  474. New scene nodes and components are created with the buttons at the bottom of the hierarchy window. Their attributes can then be edited in the node / component edit window. Note that the node transform shown is the local transform (offset from parent.)
  475. %Scene nodes can also be moved/rotated/scaled by Ctrl + arrow keys and Page Up / Page Down. Press Ctrl+1,2,3 to change the manipulation mode, and Ctrl+4 to toggle between world relative and scene node relative movement.
  476. To reparent scene nodes, drag and drop them onto the new parent scene node in the scene hierarchy window. Reparenting should retain the effective world transform, so check afterwards from the component window that the local transform is what you expect it to be. Components can not be dragged between nodes, but can be duplicated with cut/copy/paste operations.
  477. Though Urho3D supports setting a non-identity transform on the root node (scene), it is still best to leave it at identity (position 0, 0, 0, rotation 0, 0, 0, scale 1, 1, 1.)
  478. To create a user variable into the current node, or delete it, type the variable name into the edit field below the node attributes, and press New or Del buttons next to it. The New button will prompt to choose the variable type.
  479. While editing, you can execute script files using the "Run script" item in the %File menu. These are AngelScript files that are executed in immediate mode ie. you do not need to define a function. The editor's scene will be accessible to the script as the global property "scene."
  480. Automatic resource reloading when changed (for example editing a texture in a paint program while the scene editor is running) is currently supported on Windows only. On other platforms you need to manually reload scene resources (Ctrl+R) after editing to make the changes visible.
  481. Components of same type can be multi-edited. Where attribute values differ, the attribute field will be left blank, but editing the attribute will apply the change to all components.
  482. In addition to whole scenes, single scene nodes including all their components and child nodes can be loaded and saved (%File -> Load node, %File -> Save node as.) These can act as "prefabs" for speeding up scene construction. To save a node, it needs first to be selected in the hierarchy window.
  483. Primitive geometries (boxes, spheres, cylinders) can be instantiated from the Create menu. Note that these are just ordinary model files in the Bin/Data/Models directory; their Blender format source files are in the SourceAssets directory.
  484. \section EditorInstructions_Importing Importing
  485. The editor can import models or scenes from all the formats that the Open Asset Import Library supports, see http://assimp.sourceforge.net/main_features_formats.html
  486. %Model and scene import work differently: model import will take everything in the source file (for example a Collada scene), and combine it into a single model, with possibly many subgeometries. %Scene import on the other hand will export each source scene node separately, creating multiple models as necessary.
  487. When a model is imported, it will also be instantiated into the scene as a new scene node with a StaticModel component.
  488. To do the actual importing, the editor will invoke AssetImporter.exe from the same directory as where Urho3D.exe resides, so be sure both are built.
  489. Importing lights is not properly supported yet. Instead, when a scene is imported, a zone for ambient lighting and a single directional light are created, so that you can at least see something.
  490. */
  491. }