arturoWhere ofApp is the main app as we've always had, GuiApp is a second ofBaseApp class and each of them is run on a different window with:
Once we've created both app objects and windows and told OF in which window want each app object to run we start the main loop by calling:
There's several types of window settings classes depending on the platform and the type of window we want to use, this new object allows to specify things like the position and size of the window, GL version and others depending on the type of window. Each window class has it's own settings object which specifies different settings. For example, with ofGLFWWindowSettings we can specify if the window starts as an icon, has decorations, or in which monitor it should be created.
There's more details about how to use this new features in examples/events/multiWindowExample and examples/events/multiWindowOneAppExample
Multi threaded applications are more and more common given that computers but also even phones and other small devices nowadays have almost always more than one CPU.
The traditional way of communicating threads in OF has been through some kind of lock before accessing shared memory between the main thread and a thread that does some kind of auxiliary work.
This is really error prone since it's really easy to do not lock in the right places and create a segmentation fault that will crash the application.
OF 0.9.0 comes with a new class, ofThreadChannel, that makes inter thread communication much easier without having to use mutexes or similar. You can think of a channel as a way to send information from one thread to another.
The usual case where we use threads is when we need some job that would take too long to do in the main thread to happen in a different thread so we can keep drawing at 60 fps while that job happens in the background. That work usually needs some kind of data that it'll process and once it's done will have a result that needs to be accessed from the main thread.
Instead of sharing both the data that needs to be processed and the result between the 2 threads and acessing it using mutexes to avoid race conditons, now we'll send the data that needs to be processed from the main thread to an auxiliary or worker thread through a channel and the result back to the main thread through a different channel.
Channels are thread safe so all this happens without having to lock at all. Additionally the worker thread can sleep until there's data to be processed by calling ofThreadChannel::receive which will use 0% CPU while there's no data to process and only wake up when there's something to do.
And others, all languages, with multi-threading as a central part of their design.
There's some examples showing how to use ofThreadChannel in examples/utils/threadChannelExample or examples/gl/threadedPixelBufferExample which shows how to download pixels from the GPU using a buffer object in a different thread. ofxThreadedImageLoader's code is also a good example of how to use ofThreadChannel to send jobs to a worker thread and get the result back in the main thread. In all this examples there's no explicit locking any more which makes multi threading programming way easier and less error prone.
One of the most interesting features in C++11 is how it simplifies syntax among others with Range-based for loops. This kind of for loops avoid any indices to iterate over a collection with a syntax that is really clean and friendly.
Most collection objects in OF 0.9.0 have been adapted to work with iterators. For example this is how you would go through every line and every pixel in an image in OF 0.8.4 and before and in OF 0.9.0:
The new version, by not using indices, makes the syntax clearer and less error prone. Also in the new version if we change for example the number of channels in the ofPixels, the for loop keeps working the same, since we are not iterating any more over bytes in an array but over pixels in an image no matter how many channels each pixel has.
A similar syntax can be used with every collection in OF now like ofBuffer to iterate over lines in a text buffer, ofDirectory to iterate over every entry in a directory, ofxSvg to iterate over every path in an svg...
Even if by default is not completely singleton free you can optionally have a completely singleton free graphics engine if you explicitly use the renderers instead of using global calls, i've explained it in the text.
OF until 0.8.4 had several static variables related to the graphics engine among other things to make things faster by reusing certain objects. As part of the re factoring to get multi-window working for 0.9.0, we removed every static variable and singleton and moved the control that before happened between the window object and ofAppRunner in a new class: ofMainLoop.
ofMainLoop takes care now of holding every window in the system and of the loop logic unless the underlying system provides that already (like is the case with Android and iOS).
By default there's an ofMainLoop singleton, which is the only singleton or static variable in the whole graphics engine and holds every window which in turn hold a renderer each.
Optionally and right now only as a experimental API one can avoid completely any singleton, event the main loop, by creating explicitly one or more ofMainLoop and windows in main, each main loop can potentially even run in different threads as long as no global calls are made. The global calls are everything in ofGraphics, of3dGraphics and every object draw and bind.
Instead draw calls like
Where gl is a renderer usually hold by a window and drawing and binding objects would be done through a that same renderer like: