00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #include <QtCore/qglobal.h>
00032
00033 #ifndef Q_OS_MAC
00034 #include <X11/Xlib.h>
00035 #include <X11/Xutil.h>
00036 #include <GL/glx.h>
00037 #endif
00038
00039 #include <ros/package.h>
00040 #include <ros/console.h>
00041
00042 #include <OGRE/OgreRenderWindow.h>
00043
00044 #include "render_system.h"
00045
00046 namespace rviz
00047 {
00048
00049 RenderSystem* RenderSystem::instance_ = 0;
00050
00051 RenderSystem* RenderSystem::get()
00052 {
00053 if( instance_ == 0 )
00054 {
00055 instance_ = new RenderSystem();
00056 }
00057 return instance_;
00058 }
00059
00060 RenderSystem::RenderSystem()
00061 {
00062 setupDummyWindowId();
00063 ogre_root_ = new Ogre::Root();
00064 loadOgrePlugins();
00065 setupRenderSystem();
00066 ogre_root_->initialise(false);
00067 setupResources();
00068 makeRenderWindow( dummy_window_id_, 1, 1 );
00069 Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
00070 }
00071
00072 void RenderSystem::setupDummyWindowId()
00073 {
00074 #ifdef Q_OS_MAC
00075 dummy_window_id_ = 0;
00076 #else
00077 Display *display = XOpenDisplay(0);
00078 assert( display );
00079
00080 int screen = DefaultScreen( display );
00081
00082 int attribList[] = { GLX_RGBA, GLX_DOUBLEBUFFER, GLX_DEPTH_SIZE, 16,
00083 GLX_STENCIL_SIZE, 8, None };
00084
00085 XVisualInfo *visual = glXChooseVisual( display, screen, (int*)attribList );
00086
00087 dummy_window_id_ = XCreateSimpleWindow( display,
00088 RootWindow( display, screen ),
00089 0, 0, 1, 1, 0, 0, 0 );
00090
00091 GLXContext context = glXCreateContext( display, visual, NULL, 1 );
00092
00093 glXMakeCurrent( display, dummy_window_id_, context );
00094 #endif
00095 }
00096
00097 void RenderSystem::loadOgrePlugins()
00098 {
00099 std::string suffix = "";
00100
00101 std::string plugin_prefix;
00102 #ifdef OGRE_PLUGIN_PATH
00103
00104
00105 plugin_prefix = OGRE_PLUGIN_PATH + std::string("/");
00106 #endif
00107
00108 ogre_root_->loadPlugin( plugin_prefix + "RenderSystem_GL" + suffix );
00109 ogre_root_->loadPlugin( plugin_prefix + "Plugin_OctreeSceneManager" + suffix );
00110 ogre_root_->loadPlugin( plugin_prefix + "Plugin_ParticleFX" + suffix );
00111 ogre_root_->loadPlugin( plugin_prefix + "Plugin_CgProgramManager" + suffix );
00112 }
00113
00114 void RenderSystem::setupRenderSystem()
00115 {
00116 Ogre::RenderSystem *renderSys;
00117 const Ogre::RenderSystemList *rsList;
00118
00119
00120 #if OGRE_VERSION_MAJOR == 1 && OGRE_VERSION_MINOR == 6
00121 rsList = ogre_root_->getAvailableRenderers();
00122 #else
00123 rsList = &(ogre_root_->getAvailableRenderers());
00124 #endif
00125
00126
00127 renderSys = NULL;
00128 for( unsigned int i = 0; i < rsList->size(); i++ )
00129 {
00130 renderSys = rsList->at( i );
00131 if( renderSys->getName().compare("OpenGL Rendering Subsystem")== 0 )
00132 {
00133 break;
00134 }
00135 }
00136
00137 if( renderSys == NULL )
00138 {
00139 throw std::runtime_error( "Could not find the opengl rendering subsystem!\n" );
00140 }
00141
00142
00143 renderSys->setConfigOption("Full Screen","No");
00144
00150
00151
00152
00153 renderSys->setConfigOption("FSAA", "2");
00154
00155 ogre_root_->setRenderSystem(renderSys);
00156 }
00157
00158 void RenderSystem::setupResources()
00159 {
00160 std::string rviz_path = ros::package::getPath(ROS_PACKAGE_NAME);
00161 Ogre::ResourceGroupManager::getSingleton().addResourceLocation( rviz_path + "/ogre_media", "FileSystem", ROS_PACKAGE_NAME );
00162 Ogre::ResourceGroupManager::getSingleton().addResourceLocation( rviz_path + "/ogre_media/textures", "FileSystem", ROS_PACKAGE_NAME );
00163 Ogre::ResourceGroupManager::getSingleton().addResourceLocation( rviz_path + "/ogre_media/fonts", "FileSystem", ROS_PACKAGE_NAME );
00164 Ogre::ResourceGroupManager::getSingleton().addResourceLocation( rviz_path + "/ogre_media/models", "FileSystem", ROS_PACKAGE_NAME );
00165 Ogre::ResourceGroupManager::getSingleton().addResourceLocation( rviz_path + "/ogre_media/materials", "FileSystem", ROS_PACKAGE_NAME );
00166 Ogre::ResourceGroupManager::getSingleton().addResourceLocation( rviz_path + "/ogre_media/materials/scripts", "FileSystem", ROS_PACKAGE_NAME );
00167 Ogre::ResourceGroupManager::getSingleton().addResourceLocation( rviz_path + "/ogre_media/materials/programs", "FileSystem", ROS_PACKAGE_NAME );
00168 }
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178 static bool x_baddrawable_error = false;
00179 #ifdef Q_WS_X11
00180 static int (*old_error_handler)( Display*, XErrorEvent* );
00181 int checkBadDrawable( Display* display, XErrorEvent* error )
00182 {
00183 if( error->error_code == BadDrawable &&
00184 error->request_code == 136 &&
00185 error->minor_code == 3 )
00186 {
00187 x_baddrawable_error = true;
00188 return 0;
00189 }
00190 else
00191 {
00192
00193
00194 return old_error_handler( display, error );
00195 }
00196 }
00197 #endif // Q_WS_X11
00198
00199 Ogre::RenderWindow* RenderSystem::makeRenderWindow( intptr_t window_id, unsigned int width, unsigned int height )
00200 {
00201 static int windowCounter = 0;
00202
00203 Ogre::NameValuePairList params;
00204 Ogre::RenderWindow *window = NULL;
00205
00206 std::stringstream window_handle_stream;
00207 window_handle_stream << window_id;
00208
00209 #ifdef Q_OS_MAC
00210 params["externalWindowHandle"] = window_handle_stream.str();
00211 #else
00212 params["parentWindowHandle"] = window_handle_stream.str();
00213 #endif
00214
00215 params["externalGLControl"] = true;
00216
00217
00218 #ifdef QT_MAC_USE_COCOA
00219 params["macAPI"] = "cocoa";
00220 params["macAPICocoaUseNSView"] = "true";
00221 #else
00222 params["macAPI"] = "carbon";
00223 #endif
00224
00225 std::ostringstream stream;
00226 stream << "OgreWindow(" << windowCounter++ << ")";
00227
00228 #ifdef Q_WS_X11
00229 old_error_handler = XSetErrorHandler( &checkBadDrawable );
00230 #endif
00231
00232 int attempts = 0;
00233 while (window == NULL && (attempts++) < 100)
00234 {
00235 try
00236 {
00237 window = ogre_root_->createRenderWindow( stream.str(), width, height, false, ¶ms );
00238
00239
00240
00241 if( x_baddrawable_error )
00242 {
00243 ogre_root_->detachRenderTarget( window );
00244 window = NULL;
00245 x_baddrawable_error = false;
00246 }
00247 }
00248 catch( std::exception ex )
00249 {
00250 std::cerr << "rviz::RenderSystem: error creating render window: "
00251 << ex.what() << std::endl;
00252 window = NULL;
00253 }
00254 }
00255
00256 #ifdef Q_WS_X11
00257 XSetErrorHandler( old_error_handler );
00258 #endif
00259
00260 if( window == NULL )
00261 {
00262 ROS_ERROR( "Unable to create the rendering window after 100 tries." );
00263 assert(false);
00264 }
00265
00266 if( attempts > 1 )
00267 {
00268 ROS_INFO( "Created render window after %d attempts.", attempts );
00269 }
00270
00271 if (window)
00272 {
00273 window->setActive(true);
00274
00275 window->setAutoUpdated(false);
00276 }
00277
00278 return window;
00279 }
00280
00281 }