| [5] | 1 | /* | 
|---|
 | 2 | ----------------------------------------------------------------------------- | 
|---|
 | 3 | This source file is part of OGRE | 
|---|
 | 4 | (Object-oriented Graphics Rendering Engine) | 
|---|
 | 5 | For the latest info, see http://www.ogre3d.org | 
|---|
 | 6 |  | 
|---|
 | 7 | Copyright (c) 2000-2006 Torus Knot Software Ltd | 
|---|
 | 8 | Also see acknowledgements in Readme.html | 
|---|
 | 9 |  | 
|---|
 | 10 | This program is free software; you can redistribute it and/or modify it under | 
|---|
 | 11 | the terms of the GNU Lesser General Public License as published by the Free Software | 
|---|
 | 12 | Foundation; either version 2 of the License, or (at your option) any later | 
|---|
 | 13 | version. | 
|---|
 | 14 |  | 
|---|
 | 15 | This program is distributed in the hope that it will be useful, but WITHOUT | 
|---|
 | 16 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS | 
|---|
 | 17 | FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. | 
|---|
 | 18 |  | 
|---|
 | 19 | You should have received a copy of the GNU Lesser General Public License along with | 
|---|
 | 20 | this program; if not, write to the Free Software Foundation, Inc., 59 Temple | 
|---|
 | 21 | Place - Suite 330, Boston, MA 02111-1307, USA, or go to | 
|---|
 | 22 | http://www.gnu.org/copyleft/lesser.txt. | 
|---|
 | 23 |  | 
|---|
 | 24 | You may alternatively use this source under the terms of a specific version of | 
|---|
 | 25 | the OGRE Unrestricted License provided you have obtained such a license from | 
|---|
 | 26 | Torus Knot Software Ltd. | 
|---|
 | 27 | ----------------------------------------------------------------------------- | 
|---|
 | 28 | */ | 
|---|
 | 29 |  | 
|---|
 | 30 | #include "OgreGTKGLSupport.h" | 
|---|
 | 31 | #include "OgreGTKWindow.h" | 
|---|
 | 32 |  | 
|---|
 | 33 | #include "OgreLogManager.h" | 
|---|
 | 34 | #include "OgreException.h" | 
|---|
 | 35 | #include "OgreStringConverter.h" | 
|---|
 | 36 |  | 
|---|
 | 37 |  | 
|---|
 | 38 |  | 
|---|
 | 39 | using namespace Ogre; | 
|---|
 | 40 |  | 
|---|
 | 41 | template<> GTKGLSupport* Singleton<GTKGLSupport>::ms_Singleton = 0; | 
|---|
 | 42 | GTKGLSupport* GTKGLSupport::getSingletonPtr(void) | 
|---|
 | 43 | { | 
|---|
 | 44 |     return ms_Singleton; | 
|---|
 | 45 | } | 
|---|
 | 46 | GTKGLSupport& GTKGLSupport::getSingleton(void) | 
|---|
 | 47 | {   | 
|---|
 | 48 |     assert( ms_Singleton );  return ( *ms_Singleton );   | 
|---|
 | 49 | } | 
|---|
 | 50 |  | 
|---|
 | 51 | GTKGLSupport::GTKGLSupport() :  | 
|---|
 | 52 |     _kit(0, NULL), | 
|---|
 | 53 |     _context_ref(0) | 
|---|
 | 54 | { | 
|---|
 | 55 |     Gtk::GL::init(0, NULL); | 
|---|
 | 56 |     _main_context = 0; | 
|---|
 | 57 |     _main_window = 0; | 
|---|
 | 58 |     //_ogre_widget = 0; | 
|---|
 | 59 | } | 
|---|
 | 60 |  | 
|---|
 | 61 | void GTKGLSupport::addConfig() | 
|---|
 | 62 | { | 
|---|
 | 63 |     ConfigOption optFullScreen; | 
|---|
 | 64 |     ConfigOption optVideoMode; | 
|---|
 | 65 |  | 
|---|
 | 66 |      // FS setting possiblities | 
|---|
 | 67 |     optFullScreen.name = "Full Screen"; | 
|---|
 | 68 |     optFullScreen.possibleValues.push_back("Yes"); | 
|---|
 | 69 |     optFullScreen.possibleValues.push_back("No"); | 
|---|
 | 70 |     optFullScreen.currentValue = "No"; | 
|---|
 | 71 |     optFullScreen.immutable = false; | 
|---|
 | 72 |   | 
|---|
 | 73 |     // Video mode possiblities | 
|---|
 | 74 |     // XXX Actually do this | 
|---|
 | 75 |     optVideoMode.name = "Video Mode"; | 
|---|
 | 76 |     optVideoMode.immutable = false; | 
|---|
 | 77 |     optVideoMode.possibleValues.push_back("640 x 480"); | 
|---|
 | 78 |     optVideoMode.possibleValues.push_back("800 x 600"); | 
|---|
 | 79 |     optVideoMode.possibleValues.push_back("1024 x 768"); | 
|---|
 | 80 |     optVideoMode.possibleValues.push_back("1280 x 1024"); | 
|---|
 | 81 |  | 
|---|
 | 82 |     optVideoMode.currentValue = "800 x 600"; | 
|---|
 | 83 |  | 
|---|
 | 84 |     mOptions[optFullScreen.name] = optFullScreen; | 
|---|
 | 85 |     mOptions[optVideoMode.name] = optVideoMode; | 
|---|
 | 86 | } | 
|---|
 | 87 |      | 
|---|
 | 88 | String GTKGLSupport::validateConfig() | 
|---|
 | 89 | { | 
|---|
 | 90 |     return String(""); | 
|---|
 | 91 | } | 
|---|
 | 92 |  | 
|---|
 | 93 | RenderWindow* GTKGLSupport::createWindow(bool autoCreateWindow,  | 
|---|
 | 94 |                                          GLRenderSystem* renderSystem,  | 
|---|
 | 95 |                                          const String& windowTitle) | 
|---|
 | 96 | { | 
|---|
 | 97 |     if (autoCreateWindow) | 
|---|
 | 98 |     { | 
|---|
 | 99 |         ConfigOptionMap::iterator opt = mOptions.find("Full Screen"); | 
|---|
 | 100 |         if (opt == mOptions.end()) | 
|---|
 | 101 |             OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Can't find full screen options!", "GTKGLSupport::createWindow"); | 
|---|
 | 102 |         bool fullscreen = (opt->second.currentValue == "Yes"); | 
|---|
 | 103 |   | 
|---|
 | 104 |         opt = mOptions.find("Video Mode"); | 
|---|
 | 105 |         if (opt == mOptions.end()) | 
|---|
 | 106 |             OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Can't find video mode options!", "GTKGLSupport::createWindow"); | 
|---|
 | 107 |         String val = opt->second.currentValue; | 
|---|
 | 108 |         String::size_type pos = val.find('x'); | 
|---|
 | 109 |         if (pos == String::npos) | 
|---|
 | 110 |             OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Invalid Video Mode provided", "GTKGLSupport::createWindow"); | 
|---|
 | 111 |   | 
|---|
 | 112 |         unsigned int w = StringConverter::parseUnsignedInt(val.substr(0, pos)); | 
|---|
 | 113 |         unsigned int h = StringConverter::parseUnsignedInt(val.substr(pos + 1)); | 
|---|
 | 114 |   | 
|---|
 | 115 |         return renderSystem->createRenderWindow(windowTitle, w, h, 32, | 
|---|
 | 116 | fullscreen); | 
|---|
 | 117 |     } | 
|---|
 | 118 |     else | 
|---|
 | 119 |     { | 
|---|
 | 120 |         // XXX What is the else? | 
|---|
 | 121 |                 return NULL; | 
|---|
 | 122 |     } | 
|---|
 | 123 | } | 
|---|
 | 124 |  | 
|---|
 | 125 | RenderWindow* GTKGLSupport::newWindow(const String& name, unsigned int width,  | 
|---|
 | 126 |         unsigned int height, unsigned int colourDepth, bool fullScreen, int left, int top, | 
|---|
 | 127 |         bool depthBuffer, RenderWindow* parentWindowHandle, bool vsync) | 
|---|
 | 128 | { | 
|---|
 | 129 |     GTKWindow* window = new GTKWindow(); | 
|---|
 | 130 |     window->create(name, width, height, colourDepth, fullScreen, left, top, | 
|---|
 | 131 |                    depthBuffer, parentWindowHandle); | 
|---|
 | 132 |  | 
|---|
 | 133 |     //if(!_ogre_widget) | 
|---|
 | 134 |     //  _ogre_widget = window->get_ogre_widget(); | 
|---|
 | 135 |  | 
|---|
 | 136 |     // Copy some important information for future reference, for example | 
|---|
 | 137 |     // for when the context is needed | 
|---|
 | 138 |     if(!_main_context) | 
|---|
 | 139 |         _main_context = window->get_ogre_widget()->get_gl_context(); | 
|---|
 | 140 |     if(!_main_window) | 
|---|
 | 141 |         _main_window = window->get_ogre_widget()->get_gl_window(); | 
|---|
 | 142 |  | 
|---|
 | 143 |     return window; | 
|---|
 | 144 | } | 
|---|
 | 145 |  | 
|---|
 | 146 | void GTKGLSupport::start() | 
|---|
 | 147 | { | 
|---|
 | 148 |     LogManager::getSingleton().logMessage( | 
|---|
 | 149 |         "******************************\n" | 
|---|
 | 150 |         "*** Starting GTK Subsystem ***\n" | 
|---|
 | 151 |         "******************************"); | 
|---|
 | 152 |  | 
|---|
 | 153 | } | 
|---|
 | 154 |   | 
|---|
 | 155 | void GTKGLSupport::stop() | 
|---|
 | 156 | { | 
|---|
 | 157 |     LogManager::getSingleton().logMessage( | 
|---|
 | 158 |         "******************************\n" | 
|---|
 | 159 |         "*** Stopping GTK Subsystem ***\n" | 
|---|
 | 160 |         "******************************"); | 
|---|
 | 161 | } | 
|---|
 | 162 |  | 
|---|
 | 163 | void GTKGLSupport::begin_context(RenderTarget *_target) | 
|---|
 | 164 | { | 
|---|
 | 165 |         // Support nested contexts, in which case.. nothing happens | 
|---|
 | 166 |         ++_context_ref; | 
|---|
 | 167 |         if (_context_ref == 1) { | 
|---|
 | 168 |                 if(_target) { | 
|---|
 | 169 |                         // Begin a specific context | 
|---|
 | 170 |                         OGREWidget *_ogre_widget = static_cast<GTKWindow*>(_target)->get_ogre_widget(); | 
|---|
 | 171 |  | 
|---|
 | 172 |                         _ogre_widget->get_gl_window()->gl_begin(_ogre_widget->get_gl_context()); | 
|---|
 | 173 |                 } else { | 
|---|
 | 174 |                         // Begin a generic main context | 
|---|
 | 175 |                         _main_window->gl_begin(_main_context); | 
|---|
 | 176 |                 } | 
|---|
 | 177 |         } | 
|---|
 | 178 | } | 
|---|
 | 179 |  | 
|---|
 | 180 | void GTKGLSupport::end_context() | 
|---|
 | 181 | { | 
|---|
 | 182 |         --_context_ref; | 
|---|
 | 183 |         if(_context_ref < 0) | 
|---|
 | 184 |                 OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Too many contexts destroyed!", "GTKGLSupport::end_context"); | 
|---|
 | 185 |         if (_context_ref == 0) | 
|---|
 | 186 |         { | 
|---|
 | 187 |                 // XX is this enough? (_main_window might not be the current window, | 
|---|
 | 188 |                 // but we can never be sure the previous rendering window  | 
|---|
 | 189 |                 // even still exists) | 
|---|
 | 190 |                 _main_window->gl_end(); | 
|---|
 | 191 |         } | 
|---|
 | 192 | } | 
|---|
 | 193 |   | 
|---|
 | 194 | void GTKGLSupport::initialiseExtensions(void) | 
|---|
 | 195 | { | 
|---|
 | 196 |     // XXX anythign to actually do here? | 
|---|
 | 197 | } | 
|---|
 | 198 |  | 
|---|
 | 199 | bool GTKGLSupport::checkMinGLVersion(const String& v) const | 
|---|
 | 200 | { | 
|---|
 | 201 |     int major, minor; | 
|---|
 | 202 |     Gdk::GL::query_version(major, minor); | 
|---|
 | 203 |  | 
|---|
 | 204 |     std::string::size_type pos = v.find("."); | 
|---|
 | 205 |     int cmaj = atoi(v.substr(0, pos).c_str()); | 
|---|
 | 206 |     int cmin = atoi(v.substr(pos + 1).c_str()); | 
|---|
 | 207 |  | 
|---|
 | 208 |     return ( (major >= cmaj) && (minor >= cmin) ); | 
|---|
 | 209 | } | 
|---|
 | 210 |  | 
|---|
 | 211 | bool GTKGLSupport::checkExtension(const String& ext) const | 
|---|
 | 212 | { | 
|---|
 | 213 |         // query_gl_extension needs an active context, doesn't matter which one | 
|---|
 | 214 |         if (_context_ref == 0) | 
|---|
 | 215 |                 _main_window->gl_begin(_main_context); | 
|---|
 | 216 |  | 
|---|
 | 217 |         bool result = Gdk::GL::query_gl_extension(ext.c_str()); | 
|---|
 | 218 |  | 
|---|
 | 219 |         if (_context_ref == 0) | 
|---|
 | 220 |                 _main_window->gl_end(); | 
|---|
 | 221 | } | 
|---|
 | 222 |  | 
|---|
 | 223 | void* GTKGLSupport::getProcAddress(const String& procname) | 
|---|
 | 224 | { | 
|---|
 | 225 |     return (void*)Gdk::GL::get_proc_address(procname.c_str()); | 
|---|
 | 226 | } | 
|---|
 | 227 |  | 
|---|
 | 228 | Glib::RefPtr<const Gdk::GL::Context> GTKGLSupport::getMainContext() const { | 
|---|
 | 229 |         return _main_context; | 
|---|
 | 230 | } | 
|---|
 | 231 |  | 
|---|