Game and Simulation development with Qt
CC Attribution 2.0 Belgium:
You are free to use, adapt and copy, distribute and transmit the work or content in adapted or unchanged form for any legal purpose as long as the work is attributed to the author in the manner specified by the author or licensor.
The Qt toolkit offers a huge amount of cross-platform functionality. Qt can be used in a lot of different ways for game programming, from quickly creating throw-away external debug tools to providing core game infrastructure. This talk will highlight different ways that Qt can make the lives of game developers easier. Qt contains a huge number of well-tested and cross-platform modules that can be used for game development purposes. Of course, Qt is great for creating level editors and other tools with a nice cross-platform GUI. But Qt can also be helpful in building the game itself, even when the Qt GUI parts are not used. The QObject system provides ways to give generic access to properties and methods of C++ objects. This can be used for introspection and live manipulation of game objects. With the generic QVariant data type it is easy to make game objects serializable and to give scripting languages like JavaScript access to the game. Other useful parts are the multithreading support, the QML markup language and OpenGL integration. This talk gives an overview of these different techniques and also discusses issues like performance, memory management, ways of implementing the game loop and integrating various render engines like OSG or Ogre3D.
 And I'm going to talk about game and simulation development with Qt. And I'd first like to mention that I'm not a Qt contributor or anything. I'm only a user. And so these are only my experiences working with Qt. And they may or may not apply to the stuff you are doing. Okay. So I'm going to talk a little about simulation programming, because that's what I do. And the difference to the normal game programming. Then I'm going to focus on some topics in Qt Core. And mention some of the Qt widgets that are applicable to game programming. I'm going to talk about Qt Quick, which is the 2D scene graph that is in newer versions of Qt. And I'm going to skip through some other game-related features of Qt that may be useful. Okay. I'm from Bremen, Germany. As I just mentioned, I'm a simulation developer. And my interests are, of course, Qt, then Linux game development, open scene graph, and different game engines. And I studied at the Bauhaus Universität Weimar, where I worked with virtual reality setups and multi-user collaboration, where people share virtual spaces. After university, I did some game development. And now I'm working at Rheinmetallagie in Bremen in the simulation department, where I work on simulators and visualization tools of various kinds. And with simulations, I mean this kind of simulation, oh, it's a little dark, right? This is a ship security simulator over there where people run around a ship and put out fires and communicate and stuff. Then this is a ship simulator, a different one. And so it's about simulating vehicles or persons running around. And it's mainly training exercises for preparing for real-life situations. And these simulations have to be realistic, at least on the level that is being simulated. So it can be good to have an immersive graphics. And simulations have a lot of data. You have terrain data if you want to simulate real terrain. You have building blueprints where people run around. You have artificial intelligence data and, of course, physics data for engine simulation or whatever you want to simulate, right? And one of the differences to game development is that it's less iterative. And in games, you can do it over and over until it starts to become fun. That's not the focus of simulations. You know from the start what you want to simulate and what to achieve. And you also have dedicated hardware. You don't have to optimize for 10-year-old laptops. You can just say we are buying machines for $5,000 a piece. And if it runs on them, it's OK. And some of these simulations run for a very long time, maybe a decade or two. So at the end, they look really, really old. But as long as the simulation goal is achieved, that's OK. So when I'm building simulation tools, I want to have handled a lot of different data formats. You have XML or Rust or formats for satellite imagery or, yeah, a thousand other parts. So it's good to have tools to read in these data. If you build a tool, you want to have some stuff that is supported for a long time. So if you have really small open source projects where the developer may lose interest in a few weeks, then you don't really want to use that. In my opinion, it's a good thing to have cross-platform software, just that you can move it from Linux to Windows or back, because some of the systems that you're integrating with may be on various platforms. Also, the other parts of the simulation, you're never running alone there. You always have a lot of machines, and you have to integrate with changing parts over the time. Even the whole render engine may change because all 3D graphics doesn't look very good, so from time to time you may want to change that part. So it's a good thing to have that modularized so you can exchange it. OK, now why would I use Qt? Of course, Qt has very good user interface parts. I mean, that's the main part that Qt does. Qt or Qt, I think it's both OK. Qt is also written and usable in C++, which is a good thing if you are integrating with other middleware from game engines or something. So you could want to integrate artificial intelligence or physics engine, then it's a good thing if your own stuff is in Qt in C++, so you don't have any problems there. Then Qt has a stable API and API, so if you are programming for Qt version 5.0, you can be sure that it runs with 5.1,000 or whatever. It doesn't change, it only adds parts. Qt has a type system for dynamic type handling, and it has introspection support, so that's one thing that's always missing when you are doing C++ game development. I think these are the parts that every game engine or game system needs, so it's good if you can reuse that, and it's very nicely done. Qt, of course, has support for XML, JSON, SVG graphics, database binding, networking, multi-threading and... Sorry, but what is the difference between the types of Qt authors and the basic C++ types? I will show that in a minute. You can also use JavaScript or other scripting languages that are bound to Qt, and there you can also use the introspection system just to have script access. I'll just start reading here. My screen is too small. Of course, it's cross-platform. It runs on Windows, Linux, Mac, Android, iOS now, although I don't think there are any of the new consoles supported, but maybe that will change now that they are more 3.86-based. Qt also has a 2D scene graph that I will show, so if you are doing 2D games, that may be something interesting in and of itself. Okay, now the type system. Up there you have a custom class, MyClass. It's empty because that's not interesting here, and in the header you have to call this Qt declare meta type, and this adds the class to the Qt type system. You can use this to fetch type ID for the MyClass with a templated method, Qmeta type ID, and you can use that ID to fetch the class name during runtime, which is of course a problem in C++ if you don't add it on, and also you can use it to create objects of the class during runtime, so you can just create objects from a class if you know its name or its type ID. So that's good if you want to do a factory class or something, and create objects from a file or something. Is that good? Okay. I would say it's the same ID if you're... No, I think it's just counting up. Yeah, you should maybe use the class name or maybe there's some other method. If you use the base types like float or something, that won't change. It's just your custom class inside. Maybe there's some way to make it static, I don't know. I didn't look it up. Now, the whole user interface path that you see in Qt, like the checkboxes or textboxes or whatever, they are all derived from the class Q object, and if you want to do QObject yourself, you have to simply derive from class QObject and then call the macro QRU underscore object. Now, if you want to use programming Qt, you always have to run a pre-processor for your code. That's something many people don't like, but I think it only adds a little complexity to your build step. This pre-processor called MOC. Is there a close sign there? Sorry, that's also... Now... Oh man. Okay, so this QObject macro declares it as a QObject and MOC automatically adds some stuff to the class to make it more dynamic. For example, you can use the QProperty macro to add properties. I think I'll use the mouse, right? Yes, the mouse. So, this property is called velocity and it's type of type QVector2D. And these are the getters and setters that are used by Qt if you access this property. So you can read and write this property. You can also declare them as read only and there are some other flexes I don't remember. And now if during runtime you analyze a QObject instance and you can see it has these properties and you can set them during runtime or from a configuration file or whatever. Now down here is another nice thing, QInvocable. This adds the speed method to the runtime system. Now if you pass a moving object to a JavaScript then you can call this speed method from JavaScript and this is a very simple way to add script bindings to objects. And this all works by magic from the compiler. Okay, another thing I won't go into this very deep. It's a signal-slot connections. It's basically like an observer pattern. Each QObject can have a number of signals and it's a number of slots and you can connect signals to slots. Slots are just basically object methods. Now if object1 emits signal1 then all connected slots are called. The slot1 method is called and the signal-slot connections can also have a number of parameters. So maybe object1 has a signal value changed with an in-parameter then all connected methods with an in-parameter are called and that parameter has passed to that. And the nice thing about that is that it works across threads. This is possible because in Qt, Qt expects to have a Q thread which is a custom thread object and each Q thread has its own event loop. Now if you have two Q objects, they can live in different threads and if a signal-slot connection exists then this is basically copied across threads and in the next event iteration the slots are called. So this is a very simple way of doing complex cross thread communication. In C++11 you can even connect lambdas to signals so you can just say if object1 emits the signal then do this in X++1 or something. Okay, the Q thread object I just mentioned, it holds an event loop and each Q object is assigned to one Q thread. If you start without creating Q threads then you have one main user interface thread where the objects live. Qt also has some other high-level thread support. You have a Q thread pool class which can be used to assign tasks to a specific number of threads. Maybe you want to convert 1,000 images, then you create for worker threads for each CPU core or something and you just post these 1,000 conversion tasks to the thread pool and it will feed it to the different threads. There's also support for futures and continuations which you can use to do asynchronous programming. Just mention that I won't go into that. One basic Qt object is the Q variant which is the same as in boost variant. This is a class where you can put values of different types. For example float or string. You can also put in pointers and even the objects directly which only works if you register them with the few meta type system I just mentioned. You can later identify which type of value is in the variant and convert them back. This is very useful if you do script communication, if you're working with scripts or parsing that to files or stuff. One nice thing of the Q variant object is you also have a Q variant map which is just a map from string to Q variant. Q variant map itself is a Q variant which means you can nest these and you can very easily build trees of data that you can pass during runtime and do pretty complex stuff with that. It's good for language binding as I just mentioned. You can also serialize Q variant to files. You can build up a very complex data structure and just write it to a disk and later convert it back. You can also stream it across a network. It's not very performant of course. Every time you put something into a Q variant that is bigger than a float or something, then that object is created on the heap or the free space. You may fragment your memory and it's not very cache friendly and everything, but if you want to build some stuff quickly, then I think it's a nice thing to have. If you have custom types, you can also register conversion functions. If you have a class MyClass, then you maybe want to add a two string method to the variant so that it can be converted to a string. We can do that now in Qt 5.2 with the registerConverter function. This is improving. Now you want to integrate Qt with your game. First thing you have to do is create an object of class QApplication or QQApplication if you want to do user interfaces. You have to run the Qt loop. The simplest way to do that is to just give Qt the control. Just run the Q application as a method runner and that starts the loop. Then you can register a slot that is called by Qt for each game tick. You can just set a timer 60 times a second. I want to call my update and render functions or whatever. That's the easy way, but of course if you have an existing game, you maybe don't want to give Qt add-on control of your game. Instead you can instantiate the QApplication object and then call QCoreApplication process events which does all the signals, lots of stuff and timer and whatever Qt does. You can run that in the background. It's a little more complicated of course like it always is, but this should work most times. You probably want to run your game and user interface if you want to do one in separate threads. Because if your user interface is blocked somehow, then you don't want your game to stop and the other way around. So you run those in two separate threads. I would suggest having all communication with signal slots so that no blocking and no deadlocks or whatever can happen. Can you merge Qt with Sdl? Merge? Yeah. You mean use together? Yeah, we already used single direct media layer and we have homegrown GUI systems too. So those are bugged. So it would be nice to replace them, but we can't get rid of the Sdl. I'm pretty sure that you can. I mean it's both C++ so I don't know about the main loop issues there. But I'm pretty sure that's possible. So maybe you can pick the important parts of Sdl, whatever you do and leave. So for event events, mouse events, keyboard events, how do you decide when to do this? Yeah, I mean if you only want to do secure variants stuff from Qt, then you don't have to start any event loops or something. So you can pick the parts that you need and then you have to look at how you are integrating the two. So of course it's some work, but I think it's possible to integrate it with about everything. So our argument against existing libraries was always don't look as nice as homegrown. Okay, if you are a really good programmer, sure. But I think Qt is very nicely constructed and it's very hard to......try to play games outside the US. Do you have an example game? Yeah, I'll mention that at the end, right? No. Oh, did I skip something? No. Okay, so one useful thing to have in a game if you are developing is to have a list of all your game objects. Now you can use the Qt table widget from Qt, which is just a list of stuff. And now you can do that by... you can communicate with signal slots. Maybe every time an object is created, emit entity created with the name of the object, every time it is removed, emit entity removed, then add that to that list. And I think that's already a very useful thing to have just for analyzing and debugging. And another nice part of Qt, which is actually not part of the Qt main distribution, is Qt property browser. If you ever use the Qt designer, user interface designer, then you already know that. It's a property browser. You have all these name properties here and they have different kinds of editors. And you can simply feed that with Q variants. So if you want to make your object visible in the Qt property browser, you simply send a Q variant map with all the properties of the object through the threads to the Qt property browser and feed that with various properties. And if you have a float value, it will display a spin box. And if you have a color value, you get a nice color picker. You can even do, I think there's a font picker somewhere here. And you can also do custom editors for your own classes if you add them. For example, there's no 3D vector in Qt, at least not a 3D double vector that I needed. And so I had to build my own editor for that. And that's a little bit of work, but it's possible. And you can also add configuration to the various editors. If you have a float value, you can add a max value, a min value, a stepping range and stuff like that. Excuse me. Is this built into Qt or is this an example? Yeah, this is part of the Qt solutions archive which you can look up on the internet. And it is actually not distributed with a Qt API. It's a separate project. I also have a question. Does it mean that I can define an object using the whole Qt or QtI system? And just to say it displays that object and it will use the QtI version to... Yeah, that's the next slide. Now, if you have a game object, then you have to convert that to a Qvaryon map. So you have to know about your object and pick out your properties somehow, named properties and their values. And yeah, if you have that as a Qvaryon map, you can send that across your signal slot connection to the Qpropriety browser. There's some code around it, of course, so it doesn't really accept Qvaryon maps, but it's very easy to do. And then, yeah, it displays all your values. So Q objects, doesn't work automatically? I think it does, yeah. I think that's an example, just to be clear. So you can just make all your game objects Q objects? Yeah, but you shouldn't pass Q objects across threads. So if your Q object is living in the game thread and you want to show that in the user interface thread, then you should have to copy it anyway. So I guess this is an easier way, I think. And now if the user changes something in the Qpropriety browser, you can connect to that signal and pass the changed values back to your game and apply them somehow to your game. Okay, so as I just mentioned, Qvaryon does heap allocations. So if you are doing an editor or something, that's probably okay. If you are doing a game with 60 hertz and you're allocating stuff on the heap all the time and deleting it again, then that could cause performance trouble. So that's probably not a good idea. Also, if you have a lot of game objects, then probably you don't want to use the Q object class, because it's quite heavyweight. Each Q object instantiation creates a private implementation object on the heap. Also, there's a lot of stuff going in the background, so it's probably not a good idea. If you have 10,000 objects or something, then you shouldn't use Q object for your game object. Okay, now time to pimp my project. This is the stuff I just talked about and I have it as an open source library. So here's the game object list. Here are the properties with nice color pickers. This is actually an example of a working application that I programmed for an in-house customer, where he wanted to place sensors on a car, which is very abstract here, just a cube, and he wanted to see where the sensors overlap. So I actually added another functionality to the Q object browser to have lists of stuff. So here, the sensor-placer object has a list of sensor objects, and you can add and remove from that list, and it just edits its Q-variant map and sends it back to the game. So if you are removing a sensor here, the whole list is passed again, and all the unused sensors are removed. What's happening now? Qt entity is a component entity system, which some of you may have heard of. Each game object is composed of a loose collection of components with no central intelligence. Here, the components are not Q objects. They are because I wanted to have them in consecutive memory space, which is not possible with heap-allocated objects. So I did my custom class, and for each component, I have a conversion function from and to Q-variant map. This is another example, a little more gamey. Here you can have an enum editor. What's happening with the projector? And here are these emitters. There are particle system emitters where you can add emitters as many as you want. The graphics part here is done in Qt Quick, which is a lot nicer looking if it's not so dark. These are SVG graphics, spectrographics directly passed from Qt, and displayed in a 2D scene graph. Now, next part, Qt Quick. Qt Quick is quite new. It started in, I don't know, 4.7 or something, or 4.8. It's a hardware-accelerated 2D scene graph, and it's supposed to have become really fast now in Qt 5.2. They do a lot of optimizing for render, bunching, and whatever. Qt Quick uses a declarative syntax, declarative, called QML, which we just talked about in the previous talk. I think I have some examples here. You see the Qt Creator editor, so you have a visual editor for stuff like that. I think it doesn't work with every functionality yet, but I think it's coming towards flash territory somehow with all the editing methodology. This is a syntax example. I think it looks a little like JSON notation, and you have nested objects and properties and values. These actually use the QObject property system that I just talked about, so you can pass in QObjects here and set their properties with a QML syntax. Qt Quick uses a syntax to do 2D graphics. You can also embed JavaScript here, and you can also somehow connect values. If one property value is changed, then all the dependent values are updated. The nice thing about this for Qt Quick is that you only need a text editor. You don't have to recompile for the different platforms. I think it's great if you want to do mobile phone games and stuff like that. This is a new thing, Qt Quick components, so all the Qt widgets are now ported to Qt Quick. These are really hardware accelerated and scriptable and skinnable and everything, and you can do very complex user interfaces with that. I didn't really do any work on this, but of course that's my next goal to have Qt Quick overlays. You have a 3D game and you have a Qt interface for that. If you're having complex user interfaces for your game with lots of heads-up displays and stuff, then you could use Qt for that. Qt Quick renders to OpenGL, I think OpenGL ES2 or something, and you can combine that. On the bottom right corner, this is OpenSceneRaf, someone did that, and this is custom OpenGL from Qt example. I think this is not even Qt Quick, I think that's normal Qt. I think that would be a nice thing if you're having a complex user interface that you can use all this signal-slot goodness and compose that in an editor. Do you mention it in reference to OpenGL ES? I think so, I think you can change it, I don't know. It's OpenGL 2 on desktop, R2 and higher, and ES2 or embedded. On Windows, there's even an abstraction layer so that renders to DirectX to get a little more performance. We have the option to use angle on Windows. I just talked about that, what's the reason? Is it for performance reason or compatibility? It's a limitation for GL, since we require OpenGL 2 and higher, the Windows only guarantees 1.4 as a minimum. So to get the tune support, we're just using angle. We have packages that contain angle. We can also use regular desktop GL machines that have a proper graphic control. Thank you, Nestico. Now if you want to distribute a game, then you want to keep it slim, especially if it's over the network. So this is something I don't really care about because I'm doing simulations, but I guess if you want to ship your game, then Qt has 40 megabytes now. Of course, there's a 20 megabyte DL for translation stuff, so you can get that a lot slimmer if you do static compilation. Although maybe if someone is interested in that, you should contact Qt because there are licensing issues. Qt is licensed under LGPL, which allows linking, but I don't know if you're allowed to do static stuff. I think the opinions differ. But I just tried it out. I got it to around 7 megabytes, the Qt part, which includes the user interface stuff. That was the sensor application I just showed you with the car and the sensors. So that took about 9.5 megabytes in all. So if you're doing a professional game, then maybe you should think about that. What else is there in Qt? Just to mention those, Qt Multimedia, which you can use to play video and audio stuff. And you have Qt camera to access the webcam. On mobile phones, you can access the sensors, I think, and the GPS stuff. Then Qt has some OpenGL stuff, which is pretty low-level support, I think. It's not really a lot of high-level stuff. It's just to access the extensions and abstract away some stuff. Then there's the Qt Quick 3D project, which does some declarative 3D programming. I don't know about the current status of that. I think it's asleep as of now. Then, of course, Qt has support for internationalization, which is great if you want to ship your game to a large audience. I don't think there is any game control access, which I don't think is so great. Maybe for that you want to fall back to STL or something, or create it and use another library. Because it's all C++, it's not that big of an issue. There's even a commercial game engine replay, which is targeted to mobile phones. You see a box 2D physics demo. That's the stuff I know about game programming and Qt. To conclude, I think it's great if you are doing tools and editors and stuff where you don't really have to look towards accessing the last 10% of performance for everything. The introspection is very helpful if you are doing dynamic and data-driven stuff. It's good if you want to do complex user interfaces, of course. It's just a big load of stuff that you can use for your game. You don't have to grab it from everywhere you can. You just have one central part of stuff where you can get your game functionality. Yes, thank you very much. I guess I don't know. Sorry. I have a question about reception handling. Does Qt actually do anything related to that? No, I think you can compile it without. I think they try to not use exceptions. We can live it out. I actually have a second question about the whole hardware accelerator. How abstract is the rendering part? If I wanted to have X render not to open up some other API, how big of an effort would that be to import it? No idea, sorry. If you could be quite an effort, the implementation details of the Qt Quick 2 same graph are very open-nil-specific right now. It's not impossible, but much harder than I thought. Maybe you could do that at the angle part, right? You can do angle to another system or something. I don't know. You mentioned the merging of the main loop and the GUI loop, but if you're using OpenGL or hardware accelerator, how would you keep it safe? You should keep them separate. You shouldn't merge them. If you have only signal-slot communication, then that's all asynchronous message passing. You don't have shared data, so there shouldn't be that much of an issue. But then you're saying the game loop is not drawing anything? No, the game loop is drawing to the OpenGL window or something, and the user interface is drawing to the user interface. You have to do that on the window manager layer, I think. You can't use the user interface. If you're using Qt Quick or something to draw over your 3D scene, then you can't separate it, I think. Then you have to merge. But if you have separate windows for your property editor or something, then you can keep them separate. Yeah, the demo I just showed is exactly that with the spaceships. Oh, come on. The user interface stuff is just using C++, and the game is using QML, and I think I just use it for rendering. I have a method to create shape with a texture area and draw that to the stuff, and then all the rest is done in C++. So I tried to somehow read the QML properties and use that to directly display them in the property window, but I didn't get that to work yet. But maybe that would be very useful. Then you can declare your properties in QML and have them in the interface. But yeah, I don't know if that will work. Yeah, it's a declaration of user interface stuff. It's text file. I think there are some tools if you want to do a mobile game, then you can just use the Qt mobile application for displaying QML and feed your QML to that application thing. So that's a very easy way to do cross-platform stuff without doing any compiling or anything. Okay, no more questions. Thank you very much.
 And I'm going to talk about game and simulation development with Qt.  And I'd first like to mention that I'm not a Qt contributor or anything.  I'm only a user. And so these are only my experiences working with Qt.  And they may or may not apply to the stuff you are doing.  Okay. So I'm going to talk a little about simulation programming,  because that's what I do. And the difference to the normal game programming.  Then I'm going to focus on some topics in Qt Core.  And mention some of the Qt widgets that are applicable to game programming.  I'm going to talk about Qt Quick, which is the 2D scene graph that is in newer versions of Qt.  And I'm going to skip through some other game-related features of Qt that may be useful.  Okay. I'm from Bremen, Germany. As I just mentioned, I'm a simulation developer.  And my interests are, of course, Qt, then Linux game development, open scene graph,  and different game engines.  And I studied at the Bauhaus Universität Weimar, where I worked with virtual reality setups  and multi-user collaboration, where people share virtual spaces.  After university, I did some game development.  And now I'm working at Rheinmetallagie in Bremen in the simulation department,  where I work on simulators and visualization tools of various kinds.  And with simulations, I mean this kind of simulation, oh, it's a little dark, right?  This is a ship security simulator over there where people run around a ship  and put out fires and communicate and stuff.  Then this is a ship simulator, a different one.  And so it's about simulating vehicles or persons running around.  And it's mainly training exercises for preparing for real-life situations.  And these simulations have to be realistic, at least on the level that is being simulated.  So it can be good to have an immersive graphics.  And simulations have a lot of data.  You have terrain data if you want to simulate real terrain.  You have building blueprints where people run around.  You have artificial intelligence data and, of course, physics data for engine simulation  or whatever you want to simulate, right?  And one of the differences to game development is that it's less iterative.  And in games, you can do it over and over until it starts to become fun.  That's not the focus of simulations.  You know from the start what you want to simulate and what to achieve.  And you also have dedicated hardware.  You don't have to optimize for 10-year-old laptops.  You can just say we are buying machines for $5,000 a piece.  And if it runs on them, it's OK.  And some of these simulations run for a very long time, maybe a decade or two.  So at the end, they look really, really old.  But as long as the simulation goal is achieved, that's OK.  So when I'm building simulation tools, I want to have handled a lot of different data formats.  You have XML or Rust or formats for satellite imagery or, yeah, a thousand other parts.  So it's good to have tools to read in these data.  If you build a tool, you want to have some stuff that is supported for a long time.  So if you have really small open source projects where the developer may lose interest in a few weeks,  then you don't really want to use that.  In my opinion, it's a good thing to have cross-platform software,  just that you can move it from Linux to Windows or back,  because some of the systems that you're integrating with may be on various platforms.  Also, the other parts of the simulation, you're never running alone there.  You always have a lot of machines, and you have to integrate with changing parts over the time.  Even the whole render engine may change because all 3D graphics doesn't look very good,  so from time to time you may want to change that part.  So it's a good thing to have that modularized so you can exchange it.  OK, now why would I use Qt?  Of course, Qt has very good user interface parts.  I mean, that's the main part that Qt does. Qt or Qt, I think it's both OK.  Qt is also written and usable in C++, which is a good thing if you are integrating with other middleware from game engines or something.  So you could want to integrate artificial intelligence or physics engine,  then it's a good thing if your own stuff is in Qt in C++, so you don't have any problems there.  Then Qt has a stable API and API, so if you are programming for Qt version 5.0,  you can be sure that it runs with 5.1,000 or whatever. It doesn't change, it only adds parts.  Qt has a type system for dynamic type handling, and it has introspection support,  so that's one thing that's always missing when you are doing C++ game development.  I think these are the parts that every game engine or game system needs,  so it's good if you can reuse that, and it's very nicely done.  Qt, of course, has support for XML, JSON, SVG graphics, database binding, networking, multi-threading and...  Sorry, but what is the difference between the types of Qt authors and the basic C++ types?  I will show that in a minute.  You can also use JavaScript or other scripting languages that are bound to Qt,  and there you can also use the introspection system just to have script access.  I'll just start reading here. My screen is too small.  Of course, it's cross-platform. It runs on Windows, Linux, Mac, Android, iOS now,  although I don't think there are any of the new consoles supported,  but maybe that will change now that they are more 3.86-based.  Qt also has a 2D scene graph that I will show,  so if you are doing 2D games, that may be something interesting in and of itself.  Okay, now the type system.  Up there you have a custom class, MyClass.  It's empty because that's not interesting here,  and in the header you have to call this Qt declare meta type,  and this adds the class to the Qt type system.  You can use this to fetch type ID for the MyClass with a templated method, Qmeta type ID,  and you can use that ID to fetch the class name during runtime,  which is of course a problem in C++ if you don't add it on,  and also you can use it to create objects of the class during runtime,  so you can just create objects from a class if you know its name or its type ID.  So that's good if you want to do a factory class or something,  and create objects from a file or something.  Is that good? Okay.  I would say it's the same ID if you're...  No, I think it's just counting up.  Yeah, you should maybe use the class name or maybe there's some other method.  If you use the base types like float or something, that won't change.  It's just your custom class inside.  Maybe there's some way to make it static, I don't know.  I didn't look it up.  Now, the whole user interface path that you see in Qt,  like the checkboxes or textboxes or whatever,  they are all derived from the class Q object,  and if you want to do QObject yourself,  you have to simply derive from class QObject  and then call the macro QRU underscore object.  Now, if you want to use programming Qt,  you always have to run a pre-processor for your code.  That's something many people don't like,  but I think it only adds a little complexity to your build step.  This pre-processor called MOC.  Is there a close sign there?  Sorry, that's also...  Now...  Oh man.  Okay, so this QObject macro declares it as a QObject  and MOC automatically adds some stuff to the class to make it more dynamic.  For example, you can use the QProperty macro to add properties.  I think I'll use the mouse, right?  Yes, the mouse.  So, this property is called velocity and it's type of type QVector2D.  And these are the getters and setters that are used by Qt  if you access this property.  So you can read and write this property.  You can also declare them as read only  and there are some other flexes I don't remember.  And now if during runtime you analyze a QObject instance  and you can see it has these properties  and you can set them during runtime  or from a configuration file or whatever.  Now down here is another nice thing, QInvocable.  This adds the speed method to the runtime system.  Now if you pass a moving object to a JavaScript  then you can call this speed method from JavaScript  and this is a very simple way to add script bindings to objects.  And this all works by magic from the compiler.  Okay, another thing I won't go into this very deep.  It's a signal-slot connections.  It's basically like an observer pattern.  Each QObject can have a number of signals  and it's a number of slots and you can connect signals to slots.  Slots are just basically object methods.  Now if object1 emits signal1 then all connected slots are called.  The slot1 method is called  and the signal-slot connections can also have a number of parameters.  So maybe object1 has a signal value changed with an in-parameter  then all connected methods with an in-parameter are called  and that parameter has passed to that.  And the nice thing about that is that it works across threads.  This is possible because in Qt,  Qt expects to have a Q thread which is a custom thread object  and each Q thread has its own event loop.  Now if you have two Q objects, they can live in different threads  and if a signal-slot connection exists  then this is basically copied across threads  and in the next event iteration the slots are called.  So this is a very simple way of doing complex cross thread communication.  In C++11 you can even connect lambdas to signals  so you can just say if object1 emits the signal then do this in X++1 or something.  Okay, the Q thread object I just mentioned,  it holds an event loop and each Q object is assigned to one Q thread.  If you start without creating Q threads then you have one main user interface thread  where the objects live.  Qt also has some other high-level thread support.  You have a Q thread pool class which can be used to assign tasks to a specific number of threads.  Maybe you want to convert 1,000 images, then you create for worker threads for each CPU core or something  and you just post these 1,000 conversion tasks to the thread pool and it will feed it to the different threads.  There's also support for futures and continuations which you can use to do asynchronous programming.  Just mention that I won't go into that.  One basic Qt object is the Q variant which is the same as in boost variant.  This is a class where you can put values of different types.  For example float or string.  You can also put in pointers and even the objects directly which only works if you register them with the few meta type system I just mentioned.  You can later identify which type of value is in the variant and convert them back.  This is very useful if you do script communication, if you're working with scripts or parsing that to files or stuff.  One nice thing of the Q variant object is you also have a Q variant map which is just a map from string to Q variant.  Q variant map itself is a Q variant which means you can nest these and you can very easily build trees of data that you can pass during runtime and do pretty complex stuff with that.  It's good for language binding as I just mentioned.  You can also serialize Q variant to files.  You can build up a very complex data structure and just write it to a disk and later convert it back.  You can also stream it across a network.  It's not very performant of course.  Every time you put something into a Q variant that is bigger than a float or something, then that object is created on the heap or the free space.  You may fragment your memory and it's not very cache friendly and everything, but if you want to build some stuff quickly, then I think it's a nice thing to have.  If you have custom types, you can also register conversion functions.  If you have a class MyClass, then you maybe want to add a two string method to the variant so that it can be converted to a string.  We can do that now in Qt 5.2 with the registerConverter function.  This is improving.  Now you want to integrate Qt with your game.  First thing you have to do is create an object of class QApplication or QQApplication if you want to do user interfaces.  You have to run the Qt loop.  The simplest way to do that is to just give Qt the control.  Just run the Q application as a method runner and that starts the loop.  Then you can register a slot that is called by Qt for each game tick.  You can just set a timer 60 times a second.  I want to call my update and render functions or whatever.  That's the easy way, but of course if you have an existing game, you maybe don't want to give Qt add-on control of your game.  Instead you can instantiate the QApplication object and then call QCoreApplication process events which does all the signals, lots of stuff and timer and whatever Qt does.  You can run that in the background.  It's a little more complicated of course like it always is, but this should work most times.  You probably want to run your game and user interface if you want to do one in separate threads.  Because if your user interface is blocked somehow, then you don't want your game to stop and the other way around.  So you run those in two separate threads.  I would suggest having all communication with signal slots so that no blocking and no deadlocks or whatever can happen.  Can you merge Qt with Sdl?  Merge?  Yeah.  You mean use together?  Yeah, we already used single direct media layer and we have homegrown GUI systems too.  So those are bugged. So it would be nice to replace them, but we can't get rid of the Sdl.  I'm pretty sure that you can. I mean it's both C++ so I don't know about the main loop issues there.  But I'm pretty sure that's possible.  So maybe you can pick the important parts of Sdl, whatever you do and leave.  So for event events, mouse events, keyboard events, how do you decide when to do this?  Yeah, I mean if you only want to do secure variants stuff from Qt, then you don't have to start any event loops or something.  So you can pick the parts that you need and then you have to look at how you are integrating the two.  So of course it's some work, but I think it's possible to integrate it with about everything.  So our argument against existing libraries was always don't look as nice as homegrown.  Okay, if you are a really good programmer, sure.  But I think Qt is very nicely constructed and it's very hard to... ...try to play games outside the US. Do you have an example game?  Yeah, I'll mention that at the end, right?  No. Oh, did I skip something? No.  Okay, so one useful thing to have in a game if you are developing is to have a list of all your game objects.  Now you can use the Qt table widget from Qt, which is just a list of stuff.  And now you can do that by... you can communicate with signal slots.  Maybe every time an object is created, emit entity created with the name of the object,  every time it is removed, emit entity removed, then add that to that list.  And I think that's already a very useful thing to have just for analyzing and debugging.  And another nice part of Qt, which is actually not part of the Qt main distribution,  is Qt property browser.  If you ever use the Qt designer, user interface designer, then you already know that.  It's a property browser.  You have all these name properties here and they have different kinds of editors.  And you can simply feed that with Q variants.  So if you want to make your object visible in the Qt property browser,  you simply send a Q variant map with all the properties of the object through the threads to the Qt property browser  and feed that with various properties.  And if you have a float value, it will display a spin box.  And if you have a color value, you get a nice color picker.  You can even do, I think there's a font picker somewhere here.  And you can also do custom editors for your own classes if you add them.  For example, there's no 3D vector in Qt, at least not a 3D double vector that I needed.  And so I had to build my own editor for that.  And that's a little bit of work, but it's possible.  And you can also add configuration to the various editors.  If you have a float value, you can add a max value, a min value, a stepping range and stuff like that.  Excuse me.  Is this built into Qt or is this an example?  Yeah, this is part of the Qt solutions archive which you can look up on the internet.  And it is actually not distributed with a Qt API. It's a separate project.  I also have a question.  Does it mean that I can define an object using the whole Qt or QtI system?  And just to say it displays that object and it will use the QtI version to...  Yeah, that's the next slide.  Now, if you have a game object, then you have to convert that to a Qvaryon map.  So you have to know about your object and pick out your properties somehow, named properties and their values.  And yeah, if you have that as a Qvaryon map, you can send that across your signal slot connection to the Qpropriety browser.  There's some code around it, of course, so it doesn't really accept Qvaryon maps, but it's very easy to do.  And then, yeah, it displays all your values.  So Q objects, doesn't work automatically?  I think it does, yeah. I think that's an example, just to be clear.  So you can just make all your game objects Q objects?  Yeah, but you shouldn't pass Q objects across threads.  So if your Q object is living in the game thread and you want to show that in the user interface thread,  then you should have to copy it anyway.  So I guess this is an easier way, I think.  And now if the user changes something in the Qpropriety browser,  you can connect to that signal and pass the changed values back to your game and apply them somehow to your game.  Okay, so as I just mentioned, Qvaryon does heap allocations.  So if you are doing an editor or something, that's probably okay.  If you are doing a game with 60 hertz and you're allocating stuff on the heap all the time and deleting it again,  then that could cause performance trouble.  So that's probably not a good idea.  Also, if you have a lot of game objects, then probably you don't want to use the Q object class,  because it's quite heavyweight.  Each Q object instantiation creates a private implementation object on the heap.  Also, there's a lot of stuff going in the background, so it's probably not a good idea.  If you have 10,000 objects or something, then you shouldn't use Q object for your game object.  Okay, now time to pimp my project.  This is the stuff I just talked about and I have it as an open source library.  So here's the game object list.  Here are the properties with nice color pickers.  This is actually an example of a working application that I programmed for an in-house customer,  where he wanted to place sensors on a car, which is very abstract here, just a cube,  and he wanted to see where the sensors overlap.  So I actually added another functionality to the Q object browser to have lists of stuff.  So here, the sensor-placer object has a list of sensor objects,  and you can add and remove from that list, and it just edits its Q-variant map and sends it back to the game.  So if you are removing a sensor here, the whole list is passed again,  and all the unused sensors are removed.  What's happening now?  Qt entity is a component entity system, which some of you may have heard of.  Each game object is composed of a loose collection of components with no central intelligence.  Here, the components are not Q objects.  They are because I wanted to have them in consecutive memory space,  which is not possible with heap-allocated objects.  So I did my custom class, and for each component, I have a conversion function from and to Q-variant map.  This is another example, a little more gamey.  Here you can have an enum editor.  What's happening with the projector?  And here are these emitters.  There are particle system emitters where you can add emitters as many as you want.  The graphics part here is done in Qt Quick, which is a lot nicer looking if it's not so dark.  These are SVG graphics, spectrographics directly passed from Qt, and displayed in a 2D scene graph.  Now, next part, Qt Quick.  Qt Quick is quite new. It started in, I don't know, 4.7 or something, or 4.8.  It's a hardware-accelerated 2D scene graph, and it's supposed to have become really fast now in Qt 5.2.  They do a lot of optimizing for render, bunching, and whatever.  Qt Quick uses a declarative syntax, declarative, called QML, which we just talked about in the previous talk.  I think I have some examples here.  You see the Qt Creator editor, so you have a visual editor for stuff like that.  I think it doesn't work with every functionality yet, but I think it's coming towards flash territory somehow with all the editing methodology.  This is a syntax example.  I think it looks a little like JSON notation, and you have nested objects and properties and values.  These actually use the QObject property system that I just talked about, so you can pass in QObjects here and set their properties with a QML syntax.  Qt Quick uses a syntax to do 2D graphics.  You can also embed JavaScript here, and you can also somehow connect values.  If one property value is changed, then all the dependent values are updated.  The nice thing about this for Qt Quick is that you only need a text editor.  You don't have to recompile for the different platforms.  I think it's great if you want to do mobile phone games and stuff like that.  This is a new thing, Qt Quick components, so all the Qt widgets are now ported to Qt Quick.  These are really hardware accelerated and scriptable and skinnable and everything, and you can do very complex user interfaces with that.  I didn't really do any work on this, but of course that's my next goal to have Qt Quick overlays.  You have a 3D game and you have a Qt interface for that.  If you're having complex user interfaces for your game with lots of heads-up displays and stuff, then you could use Qt for that.  Qt Quick renders to OpenGL, I think OpenGL ES2 or something, and you can combine that.  On the bottom right corner, this is OpenSceneRaf, someone did that, and this is custom OpenGL from Qt example.  I think this is not even Qt Quick, I think that's normal Qt.  I think that would be a nice thing if you're having a complex user interface that you can use all this signal-slot goodness and compose that in an editor.  Do you mention it in reference to OpenGL ES?  I think so, I think you can change it, I don't know.  It's OpenGL 2 on desktop, R2 and higher, and ES2 or embedded.  On Windows, there's even an abstraction layer so that renders to DirectX to get a little more performance.  We have the option to use angle on Windows.  I just talked about that, what's the reason? Is it for performance reason or compatibility?  It's a limitation for GL, since we require OpenGL 2 and higher, the Windows only guarantees 1.4 as a minimum.  So to get the tune support, we're just using angle.  We have packages that contain angle.  We can also use regular desktop GL machines that have a proper graphic control.  Thank you, Nestico.  Now if you want to distribute a game, then you want to keep it slim, especially if it's over the network.  So this is something I don't really care about because I'm doing simulations, but I guess if you want to ship your game, then Qt has 40 megabytes now.  Of course, there's a 20 megabyte DL for translation stuff, so you can get that a lot slimmer if you do static compilation.  Although maybe if someone is interested in that, you should contact Qt because there are licensing issues.  Qt is licensed under LGPL, which allows linking, but I don't know if you're allowed to do static stuff.  I think the opinions differ.  But I just tried it out.  I got it to around 7 megabytes, the Qt part, which includes the user interface stuff.  That was the sensor application I just showed you with the car and the sensors.  So that took about 9.5 megabytes in all.  So if you're doing a professional game, then maybe you should think about that.  What else is there in Qt? Just to mention those, Qt Multimedia, which you can use to play video and audio stuff.  And you have Qt camera to access the webcam.  On mobile phones, you can access the sensors, I think, and the GPS stuff.  Then Qt has some OpenGL stuff, which is pretty low-level support, I think.  It's not really a lot of high-level stuff. It's just to access the extensions and abstract away some stuff.  Then there's the Qt Quick 3D project, which does some declarative 3D programming.  I don't know about the current status of that. I think it's asleep as of now.  Then, of course, Qt has support for internationalization, which is great if you want to ship your game to a large audience.  I don't think there is any game control access, which I don't think is so great.  Maybe for that you want to fall back to STL or something, or create it and use another library.  Because it's all C++, it's not that big of an issue.  There's even a commercial game engine replay, which is targeted to mobile phones.  You see a box 2D physics demo.  That's the stuff I know about game programming and Qt.  To conclude, I think it's great if you are doing tools and editors and stuff where you don't really have to look towards accessing the last 10% of performance for everything.  The introspection is very helpful if you are doing dynamic and data-driven stuff.  It's good if you want to do complex user interfaces, of course.  It's just a big load of stuff that you can use for your game.  You don't have to grab it from everywhere you can.  You just have one central part of stuff where you can get your game functionality.  Yes, thank you very much.  I guess I don't know.  Sorry.  I have a question about reception handling.  Does Qt actually do anything related to that?  No, I think you can compile it without.  I think they try to not use exceptions.  We can live it out.  I actually have a second question about the whole hardware accelerator.  How abstract is the rendering part?  If I wanted to have X render not to open up some other API, how big of an effort would that be to import it?  No idea, sorry.  If you could be quite an effort, the implementation details of the Qt Quick 2 same graph are very open-nil-specific right now.  It's not impossible, but much harder than I thought.  Maybe you could do that at the angle part, right?  You can do angle to another system or something.  I don't know.  You mentioned the merging of the main loop and the GUI loop, but if you're using OpenGL or hardware accelerator, how would you keep it safe?  You should keep them separate.  You shouldn't merge them.  If you have only signal-slot communication, then that's all asynchronous message passing.  You don't have shared data, so there shouldn't be that much of an issue.  But then you're saying the game loop is not drawing anything?  No, the game loop is drawing to the OpenGL window or something, and the user interface is drawing to the user interface.  You have to do that on the window manager layer, I think.  You can't use the user interface.  If you're using Qt Quick or something to draw over your 3D scene, then you can't separate it, I think.  Then you have to merge.  But if you have separate windows for your property editor or something, then you can keep them separate.  Yeah, the demo I just showed is exactly that with the spaceships.  Oh, come on.  The user interface stuff is just using C++, and the game is using QML, and I think I just use it for rendering.  I have a method to create shape with a texture area and draw that to the stuff, and then all the rest is done in C++.  So I tried to somehow read the QML properties and use that to directly display them in the property window,  but I didn't get that to work yet.  But maybe that would be very useful.  Then you can declare your properties in QML and have them in the interface.  But yeah, I don't know if that will work.  Yeah, it's a declaration of user interface stuff.  It's text file.  I think there are some tools if you want to do a mobile game, then you can just use the Qt mobile application for displaying QML  and feed your QML to that application thing.  So that's a very easy way to do cross-platform stuff without doing any compiling or anything.  Okay, no more questions.  Thank you very much.
_FOSDEM_2014__Game_and_Simulation_development_with_Qt_XxAVcOedQCg_0_2159.png _FOSDEM_2014__Game_and_Simulation_development_with_Qt_XxAVcOedQCg_2160_5819.png _FOSDEM_2014__Game_and_Simulation_development_with_Qt_XxAVcOedQCg_5820_6503.png _FOSDEM_2014__Game_and_Simulation_development_with_Qt_XxAVcOedQCg_6504_7415.png _FOSDEM_2014__Game_and_Simulation_development_with_Qt_XxAVcOedQCg_7416_7955.png _FOSDEM_2014__Game_and_Simulation_development_with_Qt_XxAVcOedQCg_7956_9167.png _FOSDEM_2014__Game_and_Simulation_development_with_Qt_XxAVcOedQCg_9168_16427.png _FOSDEM_2014__Game_and_Simulation_development_with_Qt_XxAVcOedQCg_16428_19127.png _FOSDEM_2014__Game_and_Simulation_development_with_Qt_XxAVcOedQCg_19128_20519.png _FOSDEM_2014__Game_and_Simulation_development_with_Qt_XxAVcOedQCg_20520_21971.png _FOSDEM_2014__Game_and_Simulation_development_with_Qt_XxAVcOedQCg_21972_22391.png _FOSDEM_2014__Game_and_Simulation_development_with_Qt_XxAVcOedQCg_22392_24143.png _FOSDEM_2014__Game_and_Simulation_development_with_Qt_XxAVcOedQCg_24144_24227.png _FOSDEM_2014__Game_and_Simulation_development_with_Qt_XxAVcOedQCg_24228_24299.png _FOSDEM_2014__Game_and_Simulation_development_with_Qt_XxAVcOedQCg_24300_24431.png _FOSDEM_2014__Game_and_Simulation_development_with_Qt_XxAVcOedQCg_24432_25331.png _FOSDEM_2014__Game_and_Simulation_development_with_Qt_XxAVcOedQCg_25332_26111.png _FOSDEM_2014__Game_and_Simulation_development_with_Qt_XxAVcOedQCg_26112_26243.png _FOSDEM_2014__Game_and_Simulation_development_with_Qt_XxAVcOedQCg_26244_26843.png _FOSDEM_2014__Game_and_Simulation_development_with_Qt_XxAVcOedQCg_26844_31787.png _FOSDEM_2014__Game_and_Simulation_development_with_Qt_XxAVcOedQCg_31788_32135.png _FOSDEM_2014__Game_and_Simulation_development_with_Qt_XxAVcOedQCg_32136_33419.png _FOSDEM_2014__Game_and_Simulation_development_with_Qt_XxAVcOedQCg_33420_33467.png _FOSDEM_2014__Game_and_Simulation_development_with_Qt_XxAVcOedQCg_33468_33647.png _FOSDEM_2014__Game_and_Simulation_development_with_Qt_XxAVcOedQCg_33648_33983.png _FOSDEM_2014__Game_and_Simulation_development_with_Qt_XxAVcOedQCg_33984_34487.png _FOSDEM_2014__Game_and_Simulation_development_with_Qt_XxAVcOedQCg_34488_34991.png _FOSDEM_2014__Game_and_Simulation_development_with_Qt_XxAVcOedQCg_34992_35183.png _FOSDEM_2014__Game_and_Simulation_development_with_Qt_XxAVcOedQCg_35184_35891.png _FOSDEM_2014__Game_and_Simulation_development_with_Qt_XxAVcOedQCg_35892_36491.png _FOSDEM_2014__Game_and_Simulation_development_with_Qt_XxAVcOedQCg_36492_36935.png _FOSDEM_2014__Game_and_Simulation_development_with_Qt_XxAVcOedQCg_36936_37595.png _FOSDEM_2014__Game_and_Simulation_development_with_Qt_XxAVcOedQCg_37596_37643.png _FOSDEM_2014__Game_and_Simulation_development_with_Qt_XxAVcOedQCg_37644_38039.png _FOSDEM_2014__Game_and_Simulation_development_with_Qt_XxAVcOedQCg_38040_38639.png _FOSDEM_2014__Game_and_Simulation_development_with_Qt_XxAVcOedQCg_38640_39047.png _FOSDEM_2014__Game_and_Simulation_development_with_Qt_XxAVcOedQCg_39048_40379.png _FOSDEM_2014__Game_and_Simulation_development_with_Qt_XxAVcOedQCg_40380_40535.png _FOSDEM_2014__Game_and_Simulation_development_with_Qt_XxAVcOedQCg_40536_41471.png _FOSDEM_2014__Game_and_Simulation_development_with_Qt_XxAVcOedQCg_41472_42947.png _FOSDEM_2014__Game_and_Simulation_development_with_Qt_XxAVcOedQCg_42948_43595.png _FOSDEM_2014__Game_and_Simulation_development_with_Qt_XxAVcOedQCg_43596_44903.png _FOSDEM_2014__Game_and_Simulation_development_with_Qt_XxAVcOedQCg_44904_48131.png _FOSDEM_2014__Game_and_Simulation_development_with_Qt_XxAVcOedQCg_48132_50291.png _FOSDEM_2014__Game_and_Simulation_development_with_Qt_XxAVcOedQCg_50292_50399.png _FOSDEM_2014__Game_and_Simulation_development_with_Qt_XxAVcOedQCg_50400_53267.png _FOSDEM_2014__Game_and_Simulation_development_with_Qt_XxAVcOedQCg_53268_55379.png _FOSDEM_2014__Game_and_Simulation_development_with_Qt_XxAVcOedQCg_55380_55511.png _FOSDEM_2014__Game_and_Simulation_development_with_Qt_XxAVcOedQCg_55512_56159.png _FOSDEM_2014__Game_and_Simulation_development_with_Qt_XxAVcOedQCg_56160_57707.png _FOSDEM_2014__Game_and_Simulation_development_with_Qt_XxAVcOedQCg_57708_57743.png