$search
00001 /* 00002 * Copyright (c) 2011, Willow Garage, Inc. 00003 * All rights reserved. 00004 * 00005 * Redistribution and use in source and binary forms, with or without 00006 * modification, are permitted provided that the following conditions are met: 00007 * 00008 * * Redistributions of source code must retain the above copyright 00009 * notice, this list of conditions and the following disclaimer. 00010 * * Redistributions in binary form must reproduce the above copyright 00011 * notice, this list of conditions and the following disclaimer in the 00012 * documentation and/or other materials provided with the distribution. 00013 * * Neither the name of the Willow Garage, Inc. nor the names of its 00014 * contributors may be used to endorse or promote products derived from 00015 * this software without specific prior written permission. 00016 * 00017 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00018 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00019 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00020 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 00021 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 00022 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 00023 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00024 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 00025 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 00026 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00027 * POSSIBILITY OF SUCH DAMAGE. 00028 */ 00029 00030 // This is required for QT_MAC_USE_COCOA to be set 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> // This dependency should be moved out of here, it is just used for a search path. 00040 00041 #include <OGRE/OgreRenderWindow.h> 00042 00043 #include "render_system.h" 00044 00045 namespace ogre_tools 00046 { 00047 00048 RenderSystem* RenderSystem::instance_ = 0; 00049 00050 RenderSystem* RenderSystem::get() 00051 { 00052 if( instance_ == 0 ) 00053 { 00054 instance_ = new RenderSystem(); 00055 } 00056 return instance_; 00057 } 00058 00059 RenderSystem::RenderSystem() 00060 { 00061 setupDummyWindowId(); 00062 ogre_root_ = new Ogre::Root(); 00063 loadOgrePlugins(); 00064 setupRenderSystem(); 00065 ogre_root_->initialise(false); 00066 setupResources(); 00067 makeRenderWindow( dummy_window_id_, 1, 1 ); 00068 Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups(); 00069 } 00070 00071 void RenderSystem::setupDummyWindowId() 00072 { 00073 #ifdef Q_OS_MAC 00074 dummy_window_id_ = 0; 00075 #else 00076 Display *display = XOpenDisplay(0); 00077 assert( display ); 00078 00079 int screen = DefaultScreen( display ); 00080 00081 int attribList[] = { GLX_RGBA, GLX_DOUBLEBUFFER, GLX_DEPTH_SIZE, 16, 00082 GLX_STENCIL_SIZE, 8, None }; 00083 00084 XVisualInfo *visual = glXChooseVisual( display, screen, (int*)attribList ); 00085 00086 dummy_window_id_ = XCreateSimpleWindow( display, 00087 RootWindow( display, screen ), 00088 0, 0, 1, 1, 0, 0, 0 ); 00089 00090 GLXContext context = glXCreateContext( display, visual, NULL, 1 ); 00091 00092 glXMakeCurrent( display, dummy_window_id_, context ); 00093 #endif 00094 } 00095 00096 void RenderSystem::loadOgrePlugins() 00097 { 00098 std::string suffix = ""; 00099 00100 std::string plugin_prefix; 00101 #ifdef OGRE_PLUGIN_PATH 00102 // OGRE_PLUGIN_PATH is defined in package "ogre"'s manifest.xml in 00103 // the <export><cpp> entry for OSX. 00104 plugin_prefix = OGRE_PLUGIN_PATH + std::string("/"); 00105 #endif 00106 00107 ogre_root_->loadPlugin( plugin_prefix + "RenderSystem_GL" + suffix ); 00108 ogre_root_->loadPlugin( plugin_prefix + "Plugin_OctreeSceneManager" + suffix ); 00109 ogre_root_->loadPlugin( plugin_prefix + "Plugin_ParticleFX" + suffix ); 00110 ogre_root_->loadPlugin( plugin_prefix + "Plugin_CgProgramManager" + suffix ); 00111 } 00112 00113 void RenderSystem::setupRenderSystem() 00114 { 00115 Ogre::RenderSystem *renderSys; 00116 const Ogre::RenderSystemList *rsList; 00117 00118 // Get the list of available renderers. 00119 #if OGRE_VERSION_MAJOR == 1 && OGRE_VERSION_MINOR == 6 00120 rsList = ogre_root_->getAvailableRenderers(); 00121 #else 00122 rsList = &(ogre_root_->getAvailableRenderers()); 00123 #endif 00124 00125 // Look for the OpenGL one, which we require. 00126 renderSys = NULL; 00127 for( unsigned int i = 0; i < rsList->size(); i++ ) 00128 { 00129 renderSys = rsList->at( i ); 00130 if( renderSys->getName().compare("OpenGL Rendering Subsystem")== 0 ) 00131 { 00132 break; 00133 } 00134 } 00135 00136 if( renderSys == NULL ) 00137 { 00138 throw std::runtime_error( "Could not find the opengl rendering subsystem!\n" ); 00139 } 00140 00141 // We operate in windowed mode 00142 renderSys->setConfigOption("Full Screen","No"); 00143 00149 renderSys->setConfigOption("RTT Preferred Mode", "FBO"); 00150 00151 // What is this? 00152 renderSys->setConfigOption("FSAA", "2"); 00153 00154 ogre_root_->setRenderSystem(renderSys); 00155 } 00156 00157 void RenderSystem::setupResources() 00158 { 00159 std::string ogre_tools_path = ros::package::getPath(ROS_PACKAGE_NAME); 00160 Ogre::ResourceGroupManager::getSingleton().addResourceLocation( ogre_tools_path + "/media", "FileSystem", ROS_PACKAGE_NAME ); 00161 Ogre::ResourceGroupManager::getSingleton().addResourceLocation( ogre_tools_path + "/media/fonts", "FileSystem", ROS_PACKAGE_NAME ); 00162 Ogre::ResourceGroupManager::getSingleton().addResourceLocation( ogre_tools_path + "/media/models", "FileSystem", ROS_PACKAGE_NAME ); 00163 Ogre::ResourceGroupManager::getSingleton().addResourceLocation( ogre_tools_path + "/media/materials", "FileSystem", ROS_PACKAGE_NAME ); 00164 Ogre::ResourceGroupManager::getSingleton().addResourceLocation( ogre_tools_path + "/media/materials/scripts", "FileSystem", ROS_PACKAGE_NAME ); 00165 Ogre::ResourceGroupManager::getSingleton().addResourceLocation( ogre_tools_path + "/media/materials/programs", "FileSystem", ROS_PACKAGE_NAME ); 00166 } 00167 00168 Ogre::RenderWindow* RenderSystem::makeRenderWindow( intptr_t window_id, unsigned int width, unsigned int height ) 00169 { 00170 static int windowCounter = 0; // Every RenderWindow needs a unique name, oy. 00171 00172 Ogre::NameValuePairList params; 00173 Ogre::RenderWindow *window = NULL; 00174 00175 std::stringstream window_handle_stream; 00176 window_handle_stream << window_id; 00177 00178 #ifdef Q_OS_MAC 00179 params["externalWindowHandle"] = window_handle_stream.str(); 00180 #else 00181 params["parentWindowHandle"] = window_handle_stream.str(); 00182 #endif 00183 00184 params["externalGLControl"] = true; 00185 00186 // Set the macAPI for Ogre based on the Qt implementation 00187 #ifdef QT_MAC_USE_COCOA 00188 params["macAPI"] = "cocoa"; 00189 params["macAPICocoaUseNSView"] = "true"; 00190 #else 00191 params["macAPI"] = "carbon"; 00192 #endif 00193 00194 std::ostringstream stream; 00195 stream << "OgreWindow(" << windowCounter++ << ")"; 00196 00197 int attempts = 0; 00198 while (window == NULL && (attempts++) < 10) 00199 { 00200 try 00201 { 00202 window = ogre_root_->createRenderWindow( stream.str(), width, height, false, ¶ms ); 00203 } 00204 catch (...) 00205 { 00206 std::cerr << "Unable to create the rendering window" << std::endl; 00207 window = NULL; 00208 } 00209 } 00210 00211 if (attempts >= 10) 00212 { 00213 std::cerr << "Unable to create the rendering window after 10 tries." << std::endl; 00214 assert(false); 00215 } 00216 00217 if (window) 00218 { 00219 window->setActive(true); 00220 //window->setVisible(true); 00221 window->setAutoUpdated(false); 00222 } 00223 00224 return window; 00225 } 00226 00227 } // end namespace ogre_tools