33 #include <QtCore/qglobal.h>
37 #if !defined(Q_OS_MAC) && !defined(Q_OS_WIN)
39 #include <X11/Xutil.h>
44 #include <OpenGL/gl.h>
58 #include <OgreRenderWindow.h>
59 #include <OgreSceneManager.h>
60 #include <Overlay/OgreOverlaySystem.h>
67 #include <QMessageBox>
88 ROS_INFO_STREAM(
"Forcing OpenGl version " << (
float)version / 100.0 <<
".");
110 ogre_root_ =
new Ogre::Root(rviz_path +
"/ogre_media/plugins.cfg");
118 Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
129 #if defined(Q_OS_MAC) || defined(Q_OS_WIN)
132 Display* display = XOpenDisplay(
nullptr);
134 if (display ==
nullptr)
136 ROS_WARN(
"$DISPLAY is invalid, falling back on default :0");
137 display = XOpenDisplay(
":0");
139 if (display ==
nullptr)
141 ROS_FATAL(
"Can't open default or :0 display. Try setting DISPLAY environment variable.");
142 throw std::runtime_error(
"Can't open default or :0 display!\n");
146 int screen = DefaultScreen(display);
148 int attribList[] = {GLX_RGBA, GLX_DOUBLEBUFFER, GLX_DEPTH_SIZE, 16, GLX_STENCIL_SIZE, 8,
None};
150 XVisualInfo* visual = glXChooseVisual(display, screen, (
int*)attribList);
152 dummy_window_id_ = XCreateSimpleWindow(display, RootWindow(display, screen), 0, 0, 1, 1, 0, 0, 0);
154 GLXContext context = glXCreateContext(display, visual,
nullptr, 1);
164 plugin_prefix +=
"lib";
166 ogre_root_->loadPlugin(plugin_prefix +
"RenderSystem_GL");
167 ogre_root_->loadPlugin(plugin_prefix +
"Plugin_OctreeSceneManager");
168 ogre_root_->loadPlugin(plugin_prefix +
"Plugin_ParticleFX");
169 #if OGRE_VERSION >= OGRE_VERSION_CHECK(1, 11, 0)
170 ogre_root_->loadPlugin(plugin_prefix +
"Codec_FreeImage");
176 bool mesa_workaround =
false;
183 Ogre::RenderSystem* renderSys =
ogre_root_->getRenderSystem();
184 const Ogre::RenderSystemCapabilities* caps = renderSys->createRenderSystemCapabilities();
185 ROS_INFO(
"OpenGL device: %s", caps->getDeviceName().c_str());
186 int major = caps->getDriverVersion().major;
187 int minor = caps->getDriverVersion().minor;
191 std::string gl_version_string = (
const char*)glGetString(GL_VERSION);
193 mesa_workaround = gl_version_string.find(
"Mesa 2") != std::string::npos &&
gl_version_ >= 320;
195 mesa_workaround =
false;
229 ROS_INFO(
"OpenGl version: %.1f (GLSL %.1f) limited to GLSL 1.4 on Mesa system.",
241 Ogre::RenderSystem* renderSys;
243 const Ogre::RenderSystemList* rsList = &(
ogre_root_->getAvailableRenderers());
247 for (
unsigned int i = 0; i < rsList->size(); i++)
249 renderSys = rsList->at(i);
250 if (renderSys->getName().compare(
"OpenGL Rendering Subsystem") == 0)
256 if (renderSys ==
nullptr)
258 throw std::runtime_error(
"Could not find the opengl rendering subsystem!\n");
262 renderSys->setConfigOption(
"Full Screen",
"No");
274 renderSys->setConfigOption(
"FSAA",
"4");
283 Ogre::ResourceGroupManager::getSingleton().addResourceLocation(
284 rviz_path +
"/ogre_media",
"FileSystem", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
285 Ogre::ResourceGroupManager::getSingleton().addResourceLocation(
286 rviz_path +
"/ogre_media/textures",
"FileSystem",
287 Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
288 Ogre::ResourceGroupManager::getSingleton().addResourceLocation(
289 rviz_path +
"/ogre_media/fonts",
"FileSystem",
290 Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
true);
291 Ogre::ResourceGroupManager::getSingleton().addResourceLocation(
292 rviz_path +
"/ogre_media/models",
"FileSystem",
293 Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
294 Ogre::ResourceGroupManager::getSingleton().addResourceLocation(
295 rviz_path +
"/ogre_media/materials",
"FileSystem",
296 Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
297 Ogre::ResourceGroupManager::getSingleton().addResourceLocation(
298 rviz_path +
"/ogre_media/materials/scripts",
"FileSystem",
299 Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
300 Ogre::ResourceGroupManager::getSingleton().addResourceLocation(
301 rviz_path +
"/ogre_media/materials/glsl120",
"FileSystem",
302 Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
303 Ogre::ResourceGroupManager::getSingleton().addResourceLocation(
304 rviz_path +
"/ogre_media/materials/glsl120/nogp",
"FileSystem",
305 Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
306 Ogre::ResourceGroupManager::getSingleton().addResourceLocation(
307 rviz_path +
"/ogre_media/materials/glsl120/include",
"FileSystem",
308 Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
314 Ogre::ResourceGroupManager::getSingleton().addResourceLocation(
315 rviz_path +
"/ogre_media/materials/glsl150",
"FileSystem",
316 Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
317 Ogre::ResourceGroupManager::getSingleton().addResourceLocation(
318 rviz_path +
"/ogre_media/materials/scripts150",
"FileSystem",
319 Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
323 Ogre::ResourceGroupManager::getSingleton().addResourceLocation(
324 rviz_path +
"/ogre_media/materials/scripts120",
"FileSystem",
325 Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
329 std::string
s =
"Your graphics driver does not support OpenGL 2.1. Please enable software rendering "
330 "before running RViz (e.g. type 'export LIBGL_ALWAYS_SOFTWARE=1').";
332 msgBox.setText(
s.c_str());
334 throw std::runtime_error(
s);
338 std::vector<std::string> media_paths;
340 std::string delim(
":");
341 for (std::vector<std::string>::iterator iter = media_paths.begin(); iter != media_paths.end(); ++iter)
347 int pos2 = iter->find(delim);
348 while (pos2 != (
int)std::string::npos)
350 path = iter->substr(pos1, pos2 - pos1);
351 ROS_DEBUG(
"adding resource location: '%s'\n", path.c_str());
352 Ogre::ResourceGroupManager::getSingleton().addResourceLocation(
353 path,
"FileSystem", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
355 pos2 = iter->find(delim, pos2 + 1);
357 path = iter->substr(pos1, iter->size() - pos1);
358 ROS_DEBUG(
"adding resource location: '%s'\n", path.c_str());
359 Ogre::ResourceGroupManager::getSingleton().addResourceLocation(
360 path,
"FileSystem", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
375 static int (*old_error_handler)(
Display*, XErrorEvent*);
376 int checkBadDrawable(
Display* display, XErrorEvent* error)
378 if (error->error_code == BadDrawable && error->request_code == 136 && error->minor_code == 3)
387 return old_error_handler(display, error);
397 static int windowCounter = 0;
399 Ogre::NameValuePairList params;
400 Ogre::RenderWindow* window =
nullptr;
402 params[
"externalWindowHandle"] = Ogre::StringConverter::toString(window_id);
403 params[
"parentWindowHandle"] = Ogre::StringConverter::toString(window_id);
405 params[
"externalGLControl"] =
true;
410 params[
"FSAA"] =
"4";
414 #if defined(Q_OS_MAC)
415 params[
"macAPI"] =
"cocoa";
416 params[
"macAPICocoaUseNSView"] =
"true";
418 params[
"contentScalingFactor"] = std::to_string(pixel_ratio);
420 std::ostringstream stream;
421 stream <<
"OgreWindow(" << windowCounter++ <<
")";
425 #if !OGRE_STEREO_ENABLE
430 bool is_stereo =
false;
433 params[
"stereoMode"] =
"Frame Sequential";
435 params.erase(
"stereoMode");
439 #if OGRE_STEREO_ENABLE
440 is_stereo = window->isStereoEnabled();
455 if (window ==
nullptr)
460 if (window ==
nullptr)
462 ROS_ERROR(
"Unable to create the rendering window after 100 tries.");
468 window->setActive(
true);
470 window->setAutoUpdated(
false);
483 const Ogre::NameValuePairList* params,
486 Ogre::RenderWindow* window =
nullptr;
490 old_error_handler = XSetErrorHandler(&checkBadDrawable);
493 while (window ==
nullptr && (attempts++) < max_attempts)
497 window =
ogre_root_->createRenderWindow(name, width, height,
false, params);
508 catch (
const std::exception& ex)
510 std::cerr <<
"rviz::RenderSystem: error creating render window: " << ex.what() << std::endl;
516 XSetErrorHandler(old_error_handler);
519 if (window && attempts > 1)
521 ROS_INFO(
"Created render window after %d attempts.", attempts);