Tutorial 3D Scenes
If you prefer directly jumping to example code, see:
2. Relevant C++ classes
The main class behind 3D scenes is
mrpt::opengl::COpenGLScene, which allows the user to create, load, save, and render 3D scenes using OpenGL primitives. The class can be understood as a program to be run on the OpenGL system, containing a sequence of viewport definitions, primitive objects, etc…
An “OpenGL scene” contains from 1 up to any number of “Viewports“, each one associated a set of OpenGL objects and, optionally, a preferred camera position. Both orthogonal (2D/3D) and projection camera models can be used for each viewport independently, greatly increasing the possibilities of rendered scenes. An object of COpenGLScene always contains at least one viewport (
"main" (if you don’t provide a viewport name, “main” will be used always as default, so don’t worry on remembering that name). Optionally, any number of other viewports may exist.
Viewports are referenced by their names, case-sensitive strings. Each viewport contains a different 3D scene (i.e. they render different objects), though a mechanism exists to share the same 3D scene by a number of viewports so memory is not wasted replicating the same smart pointers (see
The main rendering method,
COpenGLScene::render(), assumes that a viewport has been set-up for the entire target window. That method will internally make the required calls to opengl for creating the additional viewports. Note that only the depth buffer is cleared by default for each (non-main) viewport, to allow transparencies. This can be disabled by the approppriate member in COpenGLViewport.
Users will never normally need to invoke
COpenGLScene::render() manually, but use instead:
- the 3D standalone viewer (
- the runtime 3D display windows (
- or a component to be integrated in a custom GUI (see
An object COpenGLScene can be saved to a “.3Dscene” file using
COpenGLScene::saveToFile(), for posterior visualization from the standalone application SceneViewer.
3. Creating, populating and updating a
Since 3D rendering is performed in a detached thread, especial care must be taken when updating the 3D scene to be rendered. Updating here means either (i) inserting/removing new primitives to the
COpenGLScene object associated with a CDisplayWindow3D, or (ii) modifying the pose, color, contents, etc. of any of the primitives previously inserted into such
To work flawlessly, the process of updating a 3D scene contents must make use of a mechanism that locks/unlocks an internal critical section, and it comprises these steps:
// Create the GUI window object.
// This will lock until the detached MRPT GUI thread creates
// the window successfully.
mrpt::gui::CDisplayWindow3D win("My window", 1024, 800);
// Lock the 3D scene (**Enter critical section**)
// get3DSceneAndLock() must be called to prevent the rendering
// thread accessing the OpenGLScene while we are manipulating its contents.
// This function returns a reference to a smart pointer which may be used for:
// a) Create mrpt::opengl primitives and insert them into the scene. This is
// the typical first use of get3DSceneAndLock().
// b) Just ignore it. In subsequent calls, if the scene was already populated
// and you don't need to search for any primitive object (e.g. because you
// kept a copy of all mrpt::opengl::XXXPtr pointers for direct access),
// just ignore the return value.
// c) Replace the entire 3D scene (read below after the code snippet)
mrpt::opengl::COpenGLScenePtr &ptrScene = win.get3DSceneAndLock();
// Modify the scene or the primitives therein:
// Unlock the 3D scene (**Exit critical section**).
// Required for the window to be able to be redrawn.
// Force a window update, if required:
4. Existing primitives
Below follows a table with the preview of most rendering primitive classes (the most up-to-date version should be always found here):
Each scene can comprise of any number of viewports, as described above. The following snapshot shows a scene with two viewports: The “main” viewport, whose extension is the whole window. A second, smaller one, in the bottom-left corner. In this example, this viewport clones the contents of the main one, but this behavior is optional.
Another example of the usage of viewports is this program.
6. Text messages
GUI windows offer the possibility of displaying any number of text labels on top of the rendered scene. Refer to examples at the top of this page, and to the API reference for details: