qtopengl_render.cpp
Go to the documentation of this file.
1 
7 #include "qtopengl_render.h"
8 #include "qtopengl_application.h"
9 
10 #include <argos3/core/utility/logging/argos_log.h>
11 #include <argos3/core/utility/string_utilities.h>
12 #include <cstring>
13 
14 #include <QPixmap>
15 #include <QSplashScreen>
16 
17 namespace argos {
18 
19  /****************************************/
20  /****************************************/
21 
23  /* Parse options from the XML */
24 #ifdef ARGOS_WITH_LUA
25  GetNodeAttributeOrDefault(t_tree, "lua_editor", m_bLuaEditor, m_bLuaEditor);
26 #endif
27  /* Save the configuration for later */
28  m_tConfTree = t_tree;
29  /* Set up dummy arguments for QApplication */
30  m_nOptionNum = 1;
31  m_ppcOptions = new char*[m_nOptionNum];
32  m_ppcOptions[0] = new char[7];
33  ::strcpy(m_ppcOptions[0], "argos3");
34  /* Create the QT application */
35  m_pcApplication = new CQTOpenGLApplication(m_nOptionNum, m_ppcOptions);
36  /* Set some data about the application */
37  m_pcApplication->setApplicationName("ARGoS");
38  m_pcApplication->setApplicationVersion("3.0");
39  m_pcApplication->setOrganizationName("ARGoS");
40  m_pcApplication->setOrganizationDomain("argos-sim.info");
41  /* Draw the main window */
42  m_pcMainWindow = new CQTOpenGLMainWindow(m_tConfTree);
43 #ifdef ARGOS_WITH_LUA
44  /* Create Lua editor if required */
45  if(m_bLuaEditor) {
46  m_pcQTOpenGLLuaMainWindow = new CQTOpenGLLuaMainWindow(m_pcMainWindow);
47  }
48 #endif
49  LOG.Flush();
50  LOGERR.Flush();
51  }
52 
53  /****************************************/
54  /****************************************/
55 
57  try {
58  /* This effectively starts the experiment */
59  m_pcMainWindow->show();
60 #ifdef ARGOS_WITH_LUA
61  if(m_bLuaEditor) {
62  m_pcQTOpenGLLuaMainWindow->show();
63  }
64 #endif
65  m_pcApplication->exec();
66  }
67  catch(CARGoSException& ex) {
68  THROW_ARGOSEXCEPTION_NESTED("Error while executing the experiment.", ex);
69  }
70  }
71 
72  /****************************************/
73  /****************************************/
74 
76 #ifdef ARGOS_WITH_LUA
77  /* Destroy the Lua editor */
78  if(m_bLuaEditor) {
79  delete m_pcQTOpenGLLuaMainWindow;
80  }
81 #endif
82  /* Destroy the main window */
83  delete m_pcMainWindow;
84  /* Destroy the QT application */
85  delete m_pcApplication;
86  /* Get rid of the factory */
88  }
89 
90  /****************************************/
91  /****************************************/
92 
94  if(m_pcMainWindow == nullptr) {
95  THROW_ARGOSEXCEPTION("CQTOpenGLRender::GetMainWindow(): no main window created");
96  }
97  return *m_pcMainWindow;
98  }
99 
100  /****************************************/
101  /****************************************/
102 
103 #ifdef ARGOS_WITH_LUA
104  CQTOpenGLLuaMainWindow& CQTOpenGLRender::GetLuaMainWindow() {
105  if(m_pcQTOpenGLLuaMainWindow == NULL) {
106  THROW_ARGOSEXCEPTION("CQTOpenGLRender::GetLuaMainWindow(): no Lua main window created");
107  }
108  return *m_pcQTOpenGLLuaMainWindow;
109  }
110 #endif
111 
112  /****************************************/
113  /****************************************/
114 
116  "qt-opengl",
117  "Carlo Pinciroli [ilpincy@gmail.com]",
118  "1.0",
119  "An interactive graphical renderer based on Qt and OpenGL.",
120  "The QT-OpenGL renderer is a graphical renderer based on Qt >= 4.5 and OpenGL.\n"
121  "It allows the user to watch and modify the simulation as it's running in an\n"
122  "intuitive way.\n\n"
123  "REQUIRED XML CONFIGURATION\n\n"
124  " <visualization>\n"
125  " <qt-opengl />\n"
126  " </visualization>\n\n"
127  "OPTIONAL XML CONFIGURATION\n\n"
128  "You can auto-play the simulation at startup by specifying the 'autoplay'\n"
129  "attribute as follows:\n\n"
130  " <visualization>\n"
131  " <qt-opengl autoplay=\"true\" />\n"
132  " </visualization>\n\n"
133  "It is also possible to set the camera parameters. There are 12 available slots\n"
134  "in which cameras can be configured. These cameras can be selected in the user\n"
135  "interface by pressing F1-F12 or by clicking on the corresponding camera icon.\n"
136  "By default, and if no configuration is given, each of these slots defaults to a\n"
137  "camera position calculated from the size of the arena and the arena's center.\n"
138  "The following example demonstrates overriding four of these camera\n"
139  "configurations:\n\n"
140  " <visualization>\n"
141  " <qt-opengl>\n"
142  " <camera>\n"
143  " <placements>\n"
144  " <placement index=\"0\" position=\"2,2,2\" look_at=\"1,1,1\" />\n"
145  " <placement index=\"1\" position=\"1,0,7\" look_at=\"1,0,0\" />\n"
146  " <placement index=\"2\" position=\"3,3,4\" look_at=\"1,6,0\" />\n"
147  " <placement index=\"3\" position=\"2,3,2\" look_at=\"0,1,0\" />\n"
148  " </placements>\n"
149  " </camera>\n"
150  " </qt-opengl>\n"
151  " </visualization>\n\n"
152  "The 'index' attribute specifies the camera to override, with the zeroth index\n"
153  "corresponding to the camera bound to the F1 key and so on.\n"
154  "The 'position' attribute contains the position of the camera in the arena.\n"
155  "The 'look_at' attribute sets the point the camera is looking at.\n"
156  "Sometimes, specifying a camera positioning with only 'position' and 'look_at'\n"
157  "generates ambiguous configurations, which ARGoS resolves in a default way after\n"
158  "printing a warning message. To place the camera without ambiguities, specify\n"
159  "also the 'up' vector of the camera. If the camera is your head, imagine this\n"
160  "vector as an arrow that stems from the center of your head and extends upwards\n."
161  "The 'up' vector must be perpendicular to the difference between the 'look_at'\n"
162  "and the 'position' vectors.\n"
163  "You can also set the focal length of the camera. For example:\n\n"
164  " <visualization>\n"
165  " <qt-opengl>\n"
166  " <camera>\n"
167  " <placements>\n"
168  " ...\n"
169  " <placement index=\"4\"\n"
170  " position=\"4,1,4\"\n"
171  " look_at=\"2,1,0\"\n"
172  " lens_focal_length=\"50\" />\n"
173  " ...\n"
174  " <placements>\n"
175  " </camera>\n"
176  " </qt-opengl>\n"
177  " </visualization>\n\n"
178  "The 'lens_focal_length' attribute controls the focal length of the lens of the\n"
179  "simulated camera. The value is in millimeters and defaults to 20 mm, if it is\n"
180  "not set from the XML.\n"
181  "You can also configure the camera to switch placement automatically according\n"
182  "to a timeline and even interpolate between different placements as shown below:\n"
183  " <visualization>\n"
184  " <qt-opengl>\n"
185  " <camera>\n"
186  " <placements>\n"
187  " ...\n"
188  " <placement index=\"0\" ... />\n"
189  " <placement index=\"1\" ... />\n"
190  " <placement index=\"2\" ... />\n"
191  " ...\n"
192  " </placements>\n"
193  " <timeline loop=\"400\">\n"
194  " <keyframe placement=\"0\" step=\"0\" />\n"
195  " <interpolate />\n"
196  " <keyframe placement=\"1\" step=\"100\" />\n"
197  " <keyframe placement=\"2\" step=\"200\" />\n"
198  " <keyframe placement=\"1\" step=\"300\" />\n"
199  " <interpolate />\n"
200  " </timeline>\n"
201  " </camera>\n"
202  " </qt-opengl>\n"
203  " </visualization>\n\n"
204  "This feature is enabled by adding a <timeline> node which consists of\n"
205  "<keyframe> nodes. These keyframe nodes indicate the step number on which a\n"
206  "given camera placement will be used. It is possible to interpolate between two\n"
207  "keyframes by adding a <interpolate> node between them. The keyframes must be\n"
208  "specified in order. The timeline can be set to loop by setting the loop\n"
209  "attribute on the timeline node to the value at which the timeline should start\n"
210  "over from the beginning.\n"
211  "This visualization also allows for user customization. In a similar fashion to\n"
212  "the loop functions, you can set a plug-in that derives from the\n"
213  "CQTOpenGLUserFunctions class. To load it in the system, follow this example:\n\n"
214  " <visualization>\n"
215  " <qt-opengl>\n"
216  " <user_functions library=\"/path/to/libmyuserfunctions.so\"\n"
217  " label=\"my_user_functions\" />\n"
218  " </qt-opengl>\n"
219  " </visualization>\n\n"
220  "The 'library' attribute points to the library where the user functions are\n"
221  "stored. This library can be the same as the loop functions, or a new one.\n"
222  "There is no limitation to where the code is to be found.\n"
223  "The 'label' attribute identifies the user function class to use. In this way,\n"
224  "in a single library you can have multiple user function implementations, if\n"
225  "you wish.\n"
226  "You can also grab frames and store them into image files, for example to create\n"
227  "videos in a fast way. This can be done from within the ARGoS window and when\n"
228  "running ARGoS without visualizations (headless). To do it from within the ARGoS\n"
229  "window, you just need to press the red capture button and frame grabbing will be\n"
230  "on.\n"
231  "You can also grab frames when running without visualizations by running ARGoS\n"
232  "under Xvfb to give it a virtual framebuffer to render into. The command\n\n"
233  " xvfb-run -s \"-screen 0 1600x1200x24\" argos3 -c example.argos\n\n"
234  "will run spawn a new Xvfb server with a virtual window size of 1600x1200, 8-bit\n"
235  "color per channel and run ARGoS under it (ARGoS can also be made to attach to an\n"
236  "existing Xvfb server via the DISPLAY environment variable). Refer to the\n"
237  "documentation on Xvfb for the precise meaning of the arguments.\n"
238  "By default, the frames are named 'frame_NNNNNNNNNN.png' and are stored in the current\n"
239  "directory, i.e. the directory where you run the 'argos' command. If you want to\n"
240  "override these defaults, you can add the optional 'frame_grabbing' section as\n"
241  "follows:\n\n"
242  " <visualization>\n"
243  " <qt-opengl>\n"
244  " <frame_grabbing directory=\"frames\"\n"
245  " base_name=\"myframe_\"\n"
246  " format=\"png\"\n"
247  " quality=\"100\"\n"
248  " headless_grabbing=\"false\"\n"
249  " headless_frame_size=\"1600x1200\"\n"
250  " headless_frame_rate=\"1\"/>\n"
251  " </qt-opengl>\n"
252  " </visualization>\n\n"
253  "All the attributes in this section are optional. If you don't specify one of\n"
254  "them, the default is taken.\n"
255  "The 'directory' attribute stores the directory where the frames are saved. If\n"
256  "the directory does not exist, a fatal error occurs. The directory must exist\n"
257  "and be writable. Both absolute and relative paths are allowed. The default\n"
258  "value is '.'\n"
259  "The 'base_name' attribute is the string to prepend to the file name. After this\n"
260  "string, the frame number (padded to 10 digits) is added. The default value is\n"
261  "'frame_', so a typical resulting name is 'frame_0000000165'.\n"
262  "The 'format' attribute specifies the format. The default value is 'png' but you\n"
263  "can put any format supported by Qt>=4.5. Refer to the Qt documentation for the\n"
264  "complete list of supported formats.\n"
265  "The 'quality' attribute dictates the quality of the image. Its value is in the\n"
266  "range [0:100] where 0 means maximum compression and minimum quality, and 100\n"
267  "means maximum quality and no compression at all. The default value is '-1',\n"
268  "which means to use Qt's default quality. For videos, it's best to use 100 to\n"
269  "avoid artifacts due to compression. For a normal screenshot, the default is the\n"
270  "safest choice.\n"
271  "The 'headless_grabbing' attribute defaults to 'false'.\n"
272  "The 'headless_frame_size' attribute is the size of the main QTWidget in ARGoS,\n"
273  "*not* the size of the converted frames (actual images will be somewhat smaller).\n"
274  "The 'headless_frame_rate' attribute specifes the frame skip rate (i.e. grab\n"
275  "every n-th frame). The default value is '1'.\n",
276  "Usable"
277  );
278 
279 }
#define THROW_ARGOSEXCEPTION_NESTED(message, nested)
This macro throws an ARGoS exception with the passed message and nesting the passed exception.
#define THROW_ARGOSEXCEPTION(message)
This macro throws an ARGoS exception with the passed message.
The namespace containing all the ARGoS related code.
Definition: ci_actuator.h:12
REGISTER_VISUALIZATION(CQTOpenGLRender, "qt-opengl", "Carlo Pinciroli [ilpincy@gmail.com]", "1.0", "An interactive graphical renderer based on Qt and OpenGL.", "The QT-OpenGL renderer is a graphical renderer based on Qt >= 4.5 and OpenGL.\n" "It allows the user to watch and modify the simulation as it's running in an\n" "intuitive way.\n\n" "REQUIRED XML CONFIGURATION\n\n" " <visualization>\n" " <qt-opengl />\n" " </visualization>\n\n" "OPTIONAL XML CONFIGURATION\n\n" "You can auto-play the simulation at startup by specifying the 'autoplay'\n" "attribute as follows:\n\n" " <visualization>\n" " <qt-opengl autoplay=\"true\" />\n" " </visualization>\n\n" "It is also possible to set the camera parameters. There are 12 available slots\n" "in which cameras can be configured. These cameras can be selected in the user\n" "interface by pressing F1-F12 or by clicking on the corresponding camera icon.\n" "By default, and if no configuration is given, each of these slots defaults to a\n" "camera position calculated from the size of the arena and the arena's center.\n" "The following example demonstrates overriding four of these camera\n" "configurations:\n\n" " <visualization>\n" " <qt-opengl>\n" " <camera>\n" " <placements>\n" " <placement index=\"0\" position=\"2,2,2\" look_at=\"1,1,1\" />\n" " <placement index=\"1\" position=\"1,0,7\" look_at=\"1,0,0\" />\n" " <placement index=\"2\" position=\"3,3,4\" look_at=\"1,6,0\" />\n" " <placement index=\"3\" position=\"2,3,2\" look_at=\"0,1,0\" />\n" " </placements>\n" " </camera>\n" " </qt-opengl>\n" " </visualization>\n\n" "The 'index' attribute specifies the camera to override, with the zeroth index\n" "corresponding to the camera bound to the F1 key and so on.\n" "The 'position' attribute contains the position of the camera in the arena.\n" "The 'look_at' attribute sets the point the camera is looking at.\n" "Sometimes, specifying a camera positioning with only 'position' and 'look_at'\n" "generates ambiguous configurations, which ARGoS resolves in a default way after\n" "printing a warning message. To place the camera without ambiguities, specify\n" "also the 'up' vector of the camera. If the camera is your head, imagine this\n" "vector as an arrow that stems from the center of your head and extends upwards\n." "The 'up' vector must be perpendicular to the difference between the 'look_at'\n" "and the 'position' vectors.\n" "You can also set the focal length of the camera. For example:\n\n" " <visualization>\n" " <qt-opengl>\n" " <camera>\n" " <placements>\n" " ...\n" " <placement index=\"4\"\n" " position=\"4,1,4\"\n" " look_at=\"2,1,0\"\n" " lens_focal_length=\"50\" />\n" " ...\n" " <placements>\n" " </camera>\n" " </qt-opengl>\n" " </visualization>\n\n" "The 'lens_focal_length' attribute controls the focal length of the lens of the\n" "simulated camera. The value is in millimeters and defaults to 20 mm, if it is\n" "not set from the XML.\n" "You can also configure the camera to switch placement automatically according\n" "to a timeline and even interpolate between different placements as shown below:\n" " <visualization>\n" " <qt-opengl>\n" " <camera>\n" " <placements>\n" " ...\n" " <placement index=\"0\" ... />\n" " <placement index=\"1\" ... />\n" " <placement index=\"2\" ... />\n" " ...\n" " </placements>\n" " <timeline loop=\"400\">\n" " <keyframe placement=\"0\" step=\"0\" />\n" " <interpolate />\n" " <keyframe placement=\"1\" step=\"100\" />\n" " <keyframe placement=\"2\" step=\"200\" />\n" " <keyframe placement=\"1\" step=\"300\" />\n" " <interpolate />\n" " </timeline>\n" " </camera>\n" " </qt-opengl>\n" " </visualization>\n\n" "This feature is enabled by adding a <timeline> node which consists of\n" "<keyframe> nodes. These keyframe nodes indicate the step number on which a\n" "given camera placement will be used. It is possible to interpolate between two\n" "keyframes by adding a <interpolate> node between them. The keyframes must be\n" "specified in order. The timeline can be set to loop by setting the loop\n" "attribute on the timeline node to the value at which the timeline should start\n" "over from the beginning.\n" "This visualization also allows for user customization. In a similar fashion to\n" "the loop functions, you can set a plug-in that derives from the\n" "CQTOpenGLUserFunctions class. To load it in the system, follow this example:\n\n" " <visualization>\n" " <qt-opengl>\n" " <user_functions library=\"/path/to/libmyuserfunctions.so\"\n" " label=\"my_user_functions\" />\n" " </qt-opengl>\n" " </visualization>\n\n" "The 'library' attribute points to the library where the user functions are\n" "stored. This library can be the same as the loop functions, or a new one.\n" "There is no limitation to where the code is to be found.\n" "The 'label' attribute identifies the user function class to use. In this way,\n" "in a single library you can have multiple user function implementations, if\n" "you wish.\n" "You can also grab frames and store them into image files, for example to create\n" "videos in a fast way. This can be done from within the ARGoS window and when\n" "running ARGoS without visualizations (headless). To do it from within the ARGoS\n" "window, you just need to press the red capture button and frame grabbing will be\n" "on.\n" "You can also grab frames when running without visualizations by running ARGoS\n" "under Xvfb to give it a virtual framebuffer to render into. The command\n\n" " xvfb-run -s \"-screen 0 1600x1200x24\" argos3 -c example.argos\n\n" "will run spawn a new Xvfb server with a virtual window size of 1600x1200, 8-bit\n" "color per channel and run ARGoS under it (ARGoS can also be made to attach to an\n" "existing Xvfb server via the DISPLAY environment variable). Refer to the\n" "documentation on Xvfb for the precise meaning of the arguments.\n" "By default, the frames are named 'frame_NNNNNNNNNN.png' and are stored in the current\n" "directory, i.e. the directory where you run the 'argos' command. If you want to\n" "override these defaults, you can add the optional 'frame_grabbing' section as\n" "follows:\n\n" " <visualization>\n" " <qt-opengl>\n" " <frame_grabbing directory=\"frames\"\n" " base_name=\"myframe_\"\n" " format=\"png\"\n" " quality=\"100\"\n" " headless_grabbing=\"false\"\n" " headless_frame_size=\"1600x1200\"\n" " headless_frame_rate=\"1\"/>\n" " </qt-opengl>\n" " </visualization>\n\n" "All the attributes in this section are optional. If you don't specify one of\n" "them, the default is taken.\n" "The 'directory' attribute stores the directory where the frames are saved. If\n" "the directory does not exist, a fatal error occurs. The directory must exist\n" "and be writable. Both absolute and relative paths are allowed. The default\n" "value is '.'\n" "The 'base_name' attribute is the string to prepend to the file name. After this\n" "string, the frame number (padded to 10 digits) is added. The default value is\n" "'frame_', so a typical resulting name is 'frame_0000000165'.\n" "The 'format' attribute specifies the format. The default value is 'png' but you\n" "can put any format supported by Qt>=4.5. Refer to the Qt documentation for the\n" "complete list of supported formats.\n" "The 'quality' attribute dictates the quality of the image. Its value is in the\n" "range [0:100] where 0 means maximum compression and minimum quality, and 100\n" "means maximum quality and no compression at all. The default value is '-1',\n" "which means to use Qt's default quality. For videos, it's best to use 100 to\n" "avoid artifacts due to compression. For a normal screenshot, the default is the\n" "safest choice.\n" "The 'headless_grabbing' attribute defaults to 'false'.\n" "The 'headless_frame_size' attribute is the size of the main QTWidget in ARGoS,\n" "*not* the size of the converted frames (actual images will be somewhat smaller).\n" "The 'headless_frame_rate' attribute specifes the frame skip rate (i.e. grab\n" "every n-th frame). The default value is '1'.\n", "Usable")
CARGoSLog LOGERR(std::cerr, SLogColor(ARGOS_LOG_ATTRIBUTE_BRIGHT, ARGOS_LOG_COLOR_RED))
Definition: argos_log.h:180
void GetNodeAttributeOrDefault(TConfigurationNode &t_node, const std::string &str_attribute, T &t_buffer, const T &t_default)
Returns the value of a node's attribute, or the passed default value.
ticpp::Element TConfigurationNode
The ARGoS configuration XML node.
CARGoSLog LOG(std::cout, SLogColor(ARGOS_LOG_ATTRIBUTE_BRIGHT, ARGOS_LOG_COLOR_GREEN))
Definition: argos_log.h:179
The exception that wraps all errors in ARGoS.
static void Destroy()
Frees up all used memory.
Definition: factory_impl.h:85
virtual void Init(TConfigurationNode &t_tree)
Initializes the resource.
CQTOpenGLMainWindow & GetMainWindow()
virtual void Destroy()
Undoes whatever was done by Init().