| 1 | #include "OgreRoot.h" | 
|---|
| 2 | #include "OgreException.h" | 
|---|
| 3 | #include "OgreLogManager.h" | 
|---|
| 4 | #include "OgreStringConverter.h" | 
|---|
| 5 |  | 
|---|
| 6 | #include <algorithm> | 
|---|
| 7 |  | 
|---|
| 8 | #include "OgreWin32GLSupport.h" | 
|---|
| 9 | #include "OgreGLTexture.h" | 
|---|
| 10 | #include "OgreWin32Window.h" | 
|---|
| 11 | #include <GL/wglext.h> | 
|---|
| 12 | #include "OgreWin32RenderTexture.h" | 
|---|
| 13 |  | 
|---|
| 14 | using namespace Ogre; | 
|---|
| 15 |  | 
|---|
| 16 | GLenum wglewContextInit (Ogre::GLSupport *glSupport); | 
|---|
| 17 |  | 
|---|
| 18 | namespace Ogre { | 
|---|
| 19 |         Win32GLSupport::Win32GLSupport() | 
|---|
| 20 |         : mInitialWindow(0) | 
|---|
| 21 |         , mHasPixelFormatARB(false) | 
|---|
| 22 |         , mHasMultisample(false) | 
|---|
| 23 |     { | 
|---|
| 24 |                 // immediately test WGL_ARB_pixel_format and FSAA support | 
|---|
| 25 |                 // so we can set configuration options appropriately | 
|---|
| 26 |                 initialiseWGL(); | 
|---|
| 27 |     }  | 
|---|
| 28 |  | 
|---|
| 29 |         template<class C> void remove_duplicates(C& c) | 
|---|
| 30 |         { | 
|---|
| 31 |                 std::sort(c.begin(), c.end()); | 
|---|
| 32 |                 typename C::iterator p = std::unique(c.begin(), c.end()); | 
|---|
| 33 |                 c.erase(p, c.end()); | 
|---|
| 34 |         } | 
|---|
| 35 |  | 
|---|
| 36 |         void Win32GLSupport::addConfig() | 
|---|
| 37 |         { | 
|---|
| 38 |                 //TODO: EnumDisplayDevices http://msdn.microsoft.com/library/en-us/gdi/devcons_2303.asp | 
|---|
| 39 |                 /*vector<string> DisplayDevices; | 
|---|
| 40 |                 DISPLAY_DEVICE DisplayDevice; | 
|---|
| 41 |                 DisplayDevice.cb = sizeof(DISPLAY_DEVICE); | 
|---|
| 42 |                 DWORD i=0; | 
|---|
| 43 |                 while (EnumDisplayDevices(NULL, i++, &DisplayDevice, 0) { | 
|---|
| 44 |                         DisplayDevices.push_back(DisplayDevice.DeviceName); | 
|---|
| 45 |                 }*/ | 
|---|
| 46 |                    | 
|---|
| 47 |                 ConfigOption optFullScreen; | 
|---|
| 48 |                 ConfigOption optVideoMode; | 
|---|
| 49 |                 ConfigOption optColourDepth; | 
|---|
| 50 |                 ConfigOption optDisplayFrequency; | 
|---|
| 51 |                 ConfigOption optVSync; | 
|---|
| 52 |                 ConfigOption optFSAA; | 
|---|
| 53 |                 ConfigOption optRTTMode; | 
|---|
| 54 |  | 
|---|
| 55 |                 // FS setting possiblities | 
|---|
| 56 |                 optFullScreen.name = "Full Screen"; | 
|---|
| 57 |                 optFullScreen.possibleValues.push_back("Yes"); | 
|---|
| 58 |                 optFullScreen.possibleValues.push_back("No"); | 
|---|
| 59 |                 optFullScreen.currentValue = "Yes"; | 
|---|
| 60 |                 optFullScreen.immutable = false; | 
|---|
| 61 |  | 
|---|
| 62 |                 // Video mode possiblities | 
|---|
| 63 |                 DEVMODE DevMode; | 
|---|
| 64 |                 DevMode.dmSize = sizeof(DEVMODE); | 
|---|
| 65 |                 optVideoMode.name = "Video Mode"; | 
|---|
| 66 |                 optVideoMode.immutable = false; | 
|---|
| 67 |                 for (DWORD i = 0; EnumDisplaySettings(NULL, i, &DevMode); ++i) | 
|---|
| 68 |                 { | 
|---|
| 69 |                         if (DevMode.dmBitsPerPel < 16 || DevMode.dmPelsHeight < 480) | 
|---|
| 70 |                                 continue; | 
|---|
| 71 |                         mDevModes.push_back(DevMode); | 
|---|
| 72 |                         StringUtil::StrStreamType str; | 
|---|
| 73 |                         str << DevMode.dmPelsWidth << " x " << DevMode.dmPelsHeight; | 
|---|
| 74 |                         optVideoMode.possibleValues.push_back(str.str()); | 
|---|
| 75 |                 } | 
|---|
| 76 |                 remove_duplicates(optVideoMode.possibleValues); | 
|---|
| 77 |                 optVideoMode.currentValue = optVideoMode.possibleValues.front(); | 
|---|
| 78 |  | 
|---|
| 79 |                 optColourDepth.name = "Colour Depth"; | 
|---|
| 80 |                 optColourDepth.immutable = false; | 
|---|
| 81 |                 optColourDepth.currentValue.clear(); | 
|---|
| 82 |  | 
|---|
| 83 |                 optDisplayFrequency.name = "Display Frequency"; | 
|---|
| 84 |                 optDisplayFrequency.immutable = false; | 
|---|
| 85 |         optDisplayFrequency.currentValue.clear(); | 
|---|
| 86 |  | 
|---|
| 87 |                 optVSync.name = "VSync"; | 
|---|
| 88 |                 optVSync.immutable = false; | 
|---|
| 89 |                 optVSync.possibleValues.push_back("No"); | 
|---|
| 90 |                 optVSync.possibleValues.push_back("Yes"); | 
|---|
| 91 |                 optVSync.currentValue = "No"; | 
|---|
| 92 |  | 
|---|
| 93 |                 optFSAA.name = "FSAA"; | 
|---|
| 94 |                 optFSAA.immutable = false; | 
|---|
| 95 |                 optFSAA.possibleValues.push_back("0"); | 
|---|
| 96 |                 for (std::vector<int>::iterator it = mFSAALevels.begin(); it != mFSAALevels.end(); ++it) | 
|---|
| 97 |                         optFSAA.possibleValues.push_back(StringConverter::toString(*it)); | 
|---|
| 98 |                 optFSAA.currentValue = "0"; | 
|---|
| 99 |  | 
|---|
| 100 |                 optRTTMode.name = "RTT Preferred Mode"; | 
|---|
| 101 |                 optRTTMode.possibleValues.push_back("FBO"); | 
|---|
| 102 |                 optRTTMode.possibleValues.push_back("PBuffer"); | 
|---|
| 103 |                 optRTTMode.possibleValues.push_back("Copy"); | 
|---|
| 104 |                 optRTTMode.currentValue = "FBO"; | 
|---|
| 105 |                 optRTTMode.immutable = false; | 
|---|
| 106 |  | 
|---|
| 107 |  | 
|---|
| 108 |                 mOptions[optFullScreen.name] = optFullScreen; | 
|---|
| 109 |                 mOptions[optVideoMode.name] = optVideoMode; | 
|---|
| 110 |                 mOptions[optColourDepth.name] = optColourDepth; | 
|---|
| 111 |                 mOptions[optDisplayFrequency.name] = optDisplayFrequency; | 
|---|
| 112 |                 mOptions[optVSync.name] = optVSync; | 
|---|
| 113 |                 mOptions[optFSAA.name] = optFSAA; | 
|---|
| 114 |                 mOptions[optRTTMode.name] = optRTTMode; | 
|---|
| 115 |  | 
|---|
| 116 |                 refreshConfig(); | 
|---|
| 117 |         } | 
|---|
| 118 |  | 
|---|
| 119 |         void Win32GLSupport::refreshConfig() | 
|---|
| 120 |         { | 
|---|
| 121 |                 ConfigOptionMap::iterator optVideoMode = mOptions.find("Video Mode"); | 
|---|
| 122 |                 ConfigOptionMap::iterator moptColourDepth = mOptions.find("Colour Depth"); | 
|---|
| 123 |                 ConfigOptionMap::iterator moptDisplayFrequency = mOptions.find("Display Frequency"); | 
|---|
| 124 |                 if(optVideoMode == mOptions.end() || moptColourDepth == mOptions.end() || moptDisplayFrequency == mOptions.end()) | 
|---|
| 125 |                         OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Can't find mOptions!", "Win32GLSupport::refreshConfig"); | 
|---|
| 126 |                 ConfigOption* optColourDepth = &moptColourDepth->second; | 
|---|
| 127 |                 ConfigOption* optDisplayFrequency = &moptDisplayFrequency->second; | 
|---|
| 128 |  | 
|---|
| 129 |                 const String& val = optVideoMode->second.currentValue; | 
|---|
| 130 |                 String::size_type pos = val.find('x'); | 
|---|
| 131 |                 if (pos == String::npos) | 
|---|
| 132 |                         OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Invalid Video Mode provided", "Win32GLSupport::refreshConfig"); | 
|---|
| 133 |                 DWORD width = StringConverter::parseUnsignedInt(val.substr(0, pos)); | 
|---|
| 134 |                 DWORD height = StringConverter::parseUnsignedInt(val.substr(pos+1, String::npos)); | 
|---|
| 135 |  | 
|---|
| 136 |                 for(std::vector<DEVMODE>::const_iterator i = mDevModes.begin(); i != mDevModes.end(); ++i) | 
|---|
| 137 |                 { | 
|---|
| 138 |                         if (i->dmPelsWidth != width || i->dmPelsHeight != height) | 
|---|
| 139 |                                 continue; | 
|---|
| 140 |                         optColourDepth->possibleValues.push_back(StringConverter::toString(i->dmBitsPerPel)); | 
|---|
| 141 |                         optDisplayFrequency->possibleValues.push_back(StringConverter::toString(i->dmDisplayFrequency)); | 
|---|
| 142 |                 } | 
|---|
| 143 |                 remove_duplicates(optColourDepth->possibleValues); | 
|---|
| 144 |                 remove_duplicates(optDisplayFrequency->possibleValues); | 
|---|
| 145 |                 optColourDepth->currentValue = optColourDepth->possibleValues.back(); | 
|---|
| 146 |                 if (optDisplayFrequency->currentValue != "N/A") | 
|---|
| 147 |                         optDisplayFrequency->currentValue = optDisplayFrequency->possibleValues.front(); | 
|---|
| 148 |         } | 
|---|
| 149 |  | 
|---|
| 150 |         void Win32GLSupport::setConfigOption(const String &name, const String &value) | 
|---|
| 151 |         { | 
|---|
| 152 |                 ConfigOptionMap::iterator it = mOptions.find(name); | 
|---|
| 153 |  | 
|---|
| 154 |                 // Update | 
|---|
| 155 |                 if(it != mOptions.end()) | 
|---|
| 156 |                         it->second.currentValue = value; | 
|---|
| 157 |                 else | 
|---|
| 158 |                 { | 
|---|
| 159 |             StringUtil::StrStreamType str; | 
|---|
| 160 |             str << "Option named '" << name << "' does not exist."; | 
|---|
| 161 |                         OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS, str.str(), "Win32GLSupport::setConfigOption" ); | 
|---|
| 162 |                 } | 
|---|
| 163 |  | 
|---|
| 164 |                 if( name == "Video Mode" ) | 
|---|
| 165 |                         refreshConfig(); | 
|---|
| 166 |  | 
|---|
| 167 |                 if( name == "Full Screen" ) | 
|---|
| 168 |                 { | 
|---|
| 169 |                         it = mOptions.find( "Display Frequency" ); | 
|---|
| 170 |                         if( value == "No" ) | 
|---|
| 171 |                         { | 
|---|
| 172 |                                 it->second.currentValue = "N/A"; | 
|---|
| 173 |                                 it->second.immutable = true; | 
|---|
| 174 |                         } | 
|---|
| 175 |                         else | 
|---|
| 176 |                         { | 
|---|
| 177 |                                 it->second.currentValue = it->second.possibleValues.front(); | 
|---|
| 178 |                                 it->second.immutable = false; | 
|---|
| 179 |                         } | 
|---|
| 180 |                 } | 
|---|
| 181 |         } | 
|---|
| 182 |  | 
|---|
| 183 |         String Win32GLSupport::validateConfig() | 
|---|
| 184 |         { | 
|---|
| 185 |                 // TODO, DX9 | 
|---|
| 186 |                 return StringUtil::BLANK; | 
|---|
| 187 |         } | 
|---|
| 188 |  | 
|---|
| 189 |         RenderWindow* Win32GLSupport::createWindow(bool autoCreateWindow, GLRenderSystem* renderSystem, const String& windowTitle) | 
|---|
| 190 |         { | 
|---|
| 191 |                 if (autoCreateWindow) | 
|---|
| 192 |         { | 
|---|
| 193 |             ConfigOptionMap::iterator opt = mOptions.find("Full Screen"); | 
|---|
| 194 |             if (opt == mOptions.end()) | 
|---|
| 195 |                 OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Can't find full screen options!", "Win32GLSupport::createWindow"); | 
|---|
| 196 |             bool fullscreen = (opt->second.currentValue == "Yes"); | 
|---|
| 197 |  | 
|---|
| 198 |             opt = mOptions.find("Video Mode"); | 
|---|
| 199 |             if (opt == mOptions.end()) | 
|---|
| 200 |                 OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Can't find video mode options!", "Win32GLSupport::createWindow"); | 
|---|
| 201 |             String val = opt->second.currentValue; | 
|---|
| 202 |             String::size_type pos = val.find('x'); | 
|---|
| 203 |             if (pos == String::npos) | 
|---|
| 204 |                 OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Invalid Video Mode provided", "Win32GLSupport::createWindow"); | 
|---|
| 205 |  | 
|---|
| 206 |                         unsigned int w = StringConverter::parseUnsignedInt(val.substr(0, pos)); | 
|---|
| 207 |             unsigned int h = StringConverter::parseUnsignedInt(val.substr(pos + 1)); | 
|---|
| 208 |  | 
|---|
| 209 |                         // Parse optional parameters | 
|---|
| 210 |                         NameValuePairList winOptions; | 
|---|
| 211 |                         opt = mOptions.find("Colour Depth"); | 
|---|
| 212 |                         if (opt == mOptions.end()) | 
|---|
| 213 |                                 OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Can't find Colour Depth options!", "Win32GLSupport::createWindow"); | 
|---|
| 214 |                         unsigned int colourDepth = | 
|---|
| 215 |                                 StringConverter::parseUnsignedInt(opt->second.currentValue); | 
|---|
| 216 |                         winOptions["colourDepth"] = StringConverter::toString(colourDepth); | 
|---|
| 217 |  | 
|---|
| 218 |                         opt = mOptions.find("VSync"); | 
|---|
| 219 |                         if (opt == mOptions.end()) | 
|---|
| 220 |                                 OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Can't find VSync options!", "Win32GLSupport::createWindow"); | 
|---|
| 221 |                         bool vsync = (opt->second.currentValue == "Yes"); | 
|---|
| 222 |                         winOptions["vsync"] = StringConverter::toString(vsync); | 
|---|
| 223 |                         renderSystem->setWaitForVerticalBlank(vsync); | 
|---|
| 224 |  | 
|---|
| 225 |                         opt = mOptions.find("Display Frequency"); | 
|---|
| 226 |                         if (opt != mOptions.end()) | 
|---|
| 227 |                         { | 
|---|
| 228 |                                 unsigned int displayFrequency = | 
|---|
| 229 |                                         StringConverter::parseUnsignedInt(opt->second.currentValue); | 
|---|
| 230 |                                 winOptions["displayFrequency"] = StringConverter::toString(displayFrequency); | 
|---|
| 231 |                         } | 
|---|
| 232 |  | 
|---|
| 233 |                         opt = mOptions.find("FSAA"); | 
|---|
| 234 |                         if (opt == mOptions.end()) | 
|---|
| 235 |                                 OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Can't find FSAA options!", "Win32GLSupport::createWindow"); | 
|---|
| 236 |                         unsigned int multisample = | 
|---|
| 237 |                                 StringConverter::parseUnsignedInt(opt->second.currentValue); | 
|---|
| 238 |                         winOptions["FSAA"] = StringConverter::toString(multisample); | 
|---|
| 239 |  | 
|---|
| 240 |             return renderSystem->createRenderWindow(windowTitle, w, h, fullscreen, &winOptions); | 
|---|
| 241 |         } | 
|---|
| 242 |         else | 
|---|
| 243 |         { | 
|---|
| 244 |             // XXX What is the else? | 
|---|
| 245 |                         return NULL; | 
|---|
| 246 |         } | 
|---|
| 247 |         } | 
|---|
| 248 |  | 
|---|
| 249 |         RenderWindow* Win32GLSupport::newWindow(const String &name, unsigned int width,  | 
|---|
| 250 |                 unsigned int height, bool fullScreen, const NameValuePairList *miscParams) | 
|---|
| 251 |         { | 
|---|
| 252 |                 ConfigOptionMap::iterator opt = mOptions.find("Display Frequency"); | 
|---|
| 253 |                 if (opt == mOptions.end()) | 
|---|
| 254 |                         OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Can't find Display Frequency options!", "Win32GLSupport::newWindow"); | 
|---|
| 255 |                 unsigned int displayFrequency = StringConverter::parseUnsignedInt(opt->second.currentValue); | 
|---|
| 256 |  | 
|---|
| 257 |                 Win32Window* window = new Win32Window(*this); | 
|---|
| 258 |                 window->create(name, width, height, fullScreen, miscParams); | 
|---|
| 259 |  | 
|---|
| 260 |                 if(!mInitialWindow) | 
|---|
| 261 |                         mInitialWindow = window; | 
|---|
| 262 |                 return window; | 
|---|
| 263 |         } | 
|---|
| 264 |  | 
|---|
| 265 |         void Win32GLSupport::start() | 
|---|
| 266 |         { | 
|---|
| 267 |                 LogManager::getSingleton().logMessage("*** Starting Win32GL Subsystem ***"); | 
|---|
| 268 |         } | 
|---|
| 269 |  | 
|---|
| 270 |         void Win32GLSupport::stop() | 
|---|
| 271 |         { | 
|---|
| 272 |                 LogManager::getSingleton().logMessage("*** Stopping Win32GL Subsystem ***"); | 
|---|
| 273 |                 mInitialWindow = 0; // Since there is no removeWindow, although there should be... | 
|---|
| 274 |         } | 
|---|
| 275 |  | 
|---|
| 276 |         void Win32GLSupport::initialiseExtensions() | 
|---|
| 277 |         { | 
|---|
| 278 |                 assert(mInitialWindow); | 
|---|
| 279 |                 // First, initialise the normal extensions | 
|---|
| 280 |                 GLSupport::initialiseExtensions(); | 
|---|
| 281 |                 // wglew init | 
|---|
| 282 |                 wglewContextInit(this); | 
|---|
| 283 |  | 
|---|
| 284 |                 // Check for W32 specific extensions probe function | 
|---|
| 285 |                 PFNWGLGETEXTENSIONSSTRINGARBPROC _wglGetExtensionsStringARB =  | 
|---|
| 286 |                         (PFNWGLGETEXTENSIONSSTRINGARBPROC)wglGetProcAddress("wglGetExtensionsStringARB"); | 
|---|
| 287 |                 if(!_wglGetExtensionsStringARB) | 
|---|
| 288 |                         return; | 
|---|
| 289 |                 const char *wgl_extensions = _wglGetExtensionsStringARB(mInitialWindow->getHDC()); | 
|---|
| 290 |         StringUtil::StrStreamType str; | 
|---|
| 291 |         str << "Supported WGL extensions: " << wgl_extensions; | 
|---|
| 292 |                 LogManager::getSingleton().logMessage( | 
|---|
| 293 |                         LML_NORMAL, str.str()); | 
|---|
| 294 |                 // Parse them, and add them to the main list | 
|---|
| 295 |                 std::stringstream ext; | 
|---|
| 296 |         String instr; | 
|---|
| 297 |                 ext << wgl_extensions; | 
|---|
| 298 |         while(ext >> instr) | 
|---|
| 299 |         { | 
|---|
| 300 |             extensionList.insert(instr); | 
|---|
| 301 |         } | 
|---|
| 302 |         } | 
|---|
| 303 |  | 
|---|
| 304 |  | 
|---|
| 305 |         void* Win32GLSupport::getProcAddress(const String& procname) | 
|---|
| 306 |         { | 
|---|
| 307 |                 return (void*)wglGetProcAddress( procname.c_str() ); | 
|---|
| 308 |         } | 
|---|
| 309 | /* | 
|---|
| 310 |         RenderTexture * Win32GLSupport::createRenderTexture( const String & name,  | 
|---|
| 311 |                 unsigned int width, unsigned int height, | 
|---|
| 312 |                 TextureType texType, PixelFormat internalFormat,  | 
|---|
| 313 |                 const NameValuePairList *miscParams )  | 
|---|
| 314 |         { | 
|---|
| 315 | #ifdef HW_RTT | 
|---|
| 316 |                 bool useBind = checkExtension("WGL_ARB_render_texture"); | 
|---|
| 317 |  | 
|---|
| 318 |                 if(Root::getSingleton().getRenderSystem()->getCapabilities()->hasCapability(RSC_HWRENDER_TO_TEXTURE)) | 
|---|
| 319 |                         return new Win32RenderTexture(*this, name, width, height, texType,  | 
|---|
| 320 |                                 internalFormat, miscParams, useBind); | 
|---|
| 321 |                 else | 
|---|
| 322 | #endif | 
|---|
| 323 |                         return new GLRenderTexture(name, width, height, texType, internalFormat, miscParams); | 
|---|
| 324 |         } | 
|---|
| 325 |  | 
|---|
| 326 | */ | 
|---|
| 327 |         void Win32GLSupport::initialiseWGL() | 
|---|
| 328 |         { | 
|---|
| 329 |                 // wglGetProcAddress does not work without an active OpenGL context, | 
|---|
| 330 |                 // but we need wglChoosePixelFormatARB's address before we can | 
|---|
| 331 |                 // create our main window.  Thank you very much, Microsoft! | 
|---|
| 332 |                 // | 
|---|
| 333 |                 // The solution is to create a dummy OpenGL window first, and then | 
|---|
| 334 |                 // test for WGL_ARB_pixel_format support.  If it is not supported, | 
|---|
| 335 |                 // we make sure to never call the ARB pixel format functions. | 
|---|
| 336 |                 // | 
|---|
| 337 |                 // If is is supported, we call the pixel format functions at least once | 
|---|
| 338 |                 // to initialise them (pointers are stored by glprocs.h).  We can also | 
|---|
| 339 |                 // take this opportunity to enumerate the valid FSAA modes. | 
|---|
| 340 |                  | 
|---|
| 341 |                 LPCSTR dummyText = "OgreWglDummy"; | 
|---|
| 342 | #ifdef OGRE_STATIC_LIB | 
|---|
| 343 |                 HINSTANCE hinst = GetModuleHandle( NULL ); | 
|---|
| 344 | #else | 
|---|
| 345 |                 HINSTANCE hinst = GetModuleHandle("RenderSystem_GL.dll"); | 
|---|
| 346 | #endif | 
|---|
| 347 |                  | 
|---|
| 348 |                 WNDCLASS dummyClass; | 
|---|
| 349 |                 memset(&dummyClass, 0, sizeof(WNDCLASS)); | 
|---|
| 350 |                 dummyClass.style = CS_OWNDC; | 
|---|
| 351 |                 dummyClass.hInstance = hinst; | 
|---|
| 352 |                 dummyClass.lpfnWndProc = dummyWndProc; | 
|---|
| 353 |                 dummyClass.lpszClassName = dummyText; | 
|---|
| 354 |                 RegisterClass(&dummyClass); | 
|---|
| 355 |  | 
|---|
| 356 |                 HWND hwnd = CreateWindow(dummyText, dummyText, | 
|---|
| 357 |                         WS_POPUP | WS_CLIPCHILDREN, | 
|---|
| 358 |                         0, 0, 32, 32, 0, 0, hinst, 0); | 
|---|
| 359 |  | 
|---|
| 360 |                 // if a simple CreateWindow fails, then boy are we in trouble... | 
|---|
| 361 |                 if (hwnd == NULL) | 
|---|
| 362 |                         OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "CreateWindow() failed", "Win32GLSupport::initializeWGL"); | 
|---|
| 363 |  | 
|---|
| 364 |  | 
|---|
| 365 |                 // no chance of failure and no need to release thanks to CS_OWNDC | 
|---|
| 366 |                 HDC hdc = GetDC(hwnd);  | 
|---|
| 367 |  | 
|---|
| 368 |                 // assign a simple OpenGL pixel format that everyone supports | 
|---|
| 369 |                 PIXELFORMATDESCRIPTOR pfd; | 
|---|
| 370 |                 memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR)); | 
|---|
| 371 |                 pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); | 
|---|
| 372 |                 pfd.nVersion = 1; | 
|---|
| 373 |                 pfd.cColorBits = 16; | 
|---|
| 374 |                 pfd.cDepthBits = 15; | 
|---|
| 375 |                 pfd.dwFlags = PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|PFD_DOUBLEBUFFER; | 
|---|
| 376 |                 pfd.iPixelType = PFD_TYPE_RGBA; | 
|---|
| 377 |                  | 
|---|
| 378 |                 // if these fail, wglCreateContext will also quietly fail | 
|---|
| 379 |                 int format; | 
|---|
| 380 |                 if ((format = ChoosePixelFormat(hdc, &pfd)) != 0) | 
|---|
| 381 |                         SetPixelFormat(hdc, format, &pfd); | 
|---|
| 382 |  | 
|---|
| 383 |                 HGLRC hrc = wglCreateContext(hdc); | 
|---|
| 384 |                 if (hrc) | 
|---|
| 385 |                 { | 
|---|
| 386 |                         HGLRC oldrc = wglGetCurrentContext(); | 
|---|
| 387 |                         HDC oldhdc = wglGetCurrentDC(); | 
|---|
| 388 |                         // if wglMakeCurrent fails, wglGetProcAddress will return null | 
|---|
| 389 |                         wglMakeCurrent(hdc, hrc); | 
|---|
| 390 |                          | 
|---|
| 391 |                         PFNWGLGETEXTENSIONSSTRINGARBPROC _wglGetExtensionsStringARB = | 
|---|
| 392 |                                 (PFNWGLGETEXTENSIONSSTRINGARBPROC) | 
|---|
| 393 |                                 wglGetProcAddress("wglGetExtensionsStringARB"); | 
|---|
| 394 |                          | 
|---|
| 395 |                         // check for pixel format and multisampling support | 
|---|
| 396 |                         if (_wglGetExtensionsStringARB) | 
|---|
| 397 |                         { | 
|---|
| 398 |                                 std::istringstream wglexts(_wglGetExtensionsStringARB(hdc)); | 
|---|
| 399 |                                 std::string ext; | 
|---|
| 400 |                                 while (wglexts >> ext) | 
|---|
| 401 |                                 { | 
|---|
| 402 |                                         if (ext == "WGL_ARB_pixel_format") | 
|---|
| 403 |                                                 mHasPixelFormatARB = true; | 
|---|
| 404 |                                         else if (ext == "WGL_ARB_multisample") | 
|---|
| 405 |                                                 mHasMultisample = true; | 
|---|
| 406 |                                 } | 
|---|
| 407 |                         } | 
|---|
| 408 |  | 
|---|
| 409 |                         if (mHasPixelFormatARB && mHasMultisample) | 
|---|
| 410 |                         { | 
|---|
| 411 |                                 // enumerate all formats w/ multisampling | 
|---|
| 412 |                                 static const int iattr[] = { | 
|---|
| 413 |                                         WGL_DRAW_TO_WINDOW_ARB, GL_TRUE, | 
|---|
| 414 |                                         WGL_SUPPORT_OPENGL_ARB, GL_TRUE, | 
|---|
| 415 |                                         WGL_DOUBLE_BUFFER_ARB, GL_TRUE, | 
|---|
| 416 |                                         WGL_SAMPLE_BUFFERS_ARB, GL_TRUE, | 
|---|
| 417 |                                         WGL_ACCELERATION_ARB, WGL_FULL_ACCELERATION_ARB, | 
|---|
| 418 |                     /* We are no matter about the colour, depth and stencil buffers here | 
|---|
| 419 |                                         WGL_COLOR_BITS_ARB, 24, | 
|---|
| 420 |                                         WGL_ALPHA_BITS_ARB, 8, | 
|---|
| 421 |                                         WGL_DEPTH_BITS_ARB, 24, | 
|---|
| 422 |                                         WGL_STENCIL_BITS_ARB, 8, | 
|---|
| 423 |                     */ | 
|---|
| 424 |                                         WGL_SAMPLES_ARB, 2, | 
|---|
| 425 |                                         0 | 
|---|
| 426 |                                 }; | 
|---|
| 427 |                                 int formats[256]; | 
|---|
| 428 |                                 unsigned int count; | 
|---|
| 429 |                 // cheating here.  wglChoosePixelFormatARB procc address needed later on | 
|---|
| 430 |                 // when a valid GL context does not exist and glew is not initialized yet. | 
|---|
| 431 |                 __wglewChoosePixelFormatARB = | 
|---|
| 432 |                     (PFNWGLCHOOSEPIXELFORMATARBPROC)wglGetProcAddress("wglChoosePixelFormatARB"); | 
|---|
| 433 |                 if (__wglewChoosePixelFormatARB(hdc, iattr, 0, 256, formats, &count)) | 
|---|
| 434 |                 { | 
|---|
| 435 |                     // determine what multisampling levels are offered | 
|---|
| 436 |                     int query = WGL_SAMPLES_ARB, samples; | 
|---|
| 437 |                     for (unsigned int i = 0; i < count; ++i) | 
|---|
| 438 |                     { | 
|---|
| 439 |                         PFNWGLGETPIXELFORMATATTRIBIVARBPROC _wglGetPixelFormatAttribivARB = | 
|---|
| 440 |                             (PFNWGLGETPIXELFORMATATTRIBIVARBPROC) | 
|---|
| 441 |                             wglGetProcAddress("wglGetPixelFormatAttribivARB"); | 
|---|
| 442 |                         if (_wglGetPixelFormatAttribivARB(hdc, formats[i], 0, 1, &query, &samples)) | 
|---|
| 443 |                         { | 
|---|
| 444 |                             mFSAALevels.push_back(samples); | 
|---|
| 445 |                         } | 
|---|
| 446 |                     } | 
|---|
| 447 |                     remove_duplicates(mFSAALevels); | 
|---|
| 448 |                 } | 
|---|
| 449 |                         } | 
|---|
| 450 |                          | 
|---|
| 451 |                         wglMakeCurrent(oldhdc, oldrc); | 
|---|
| 452 |                         wglDeleteContext(hrc); | 
|---|
| 453 |                 } | 
|---|
| 454 |  | 
|---|
| 455 |                 // clean up our dummy window and class | 
|---|
| 456 |                 DestroyWindow(hwnd); | 
|---|
| 457 |                 UnregisterClass(dummyText, hinst); | 
|---|
| 458 |         } | 
|---|
| 459 |  | 
|---|
| 460 |         LRESULT Win32GLSupport::dummyWndProc(HWND hwnd, UINT umsg, WPARAM wp, LPARAM lp) | 
|---|
| 461 |         { | 
|---|
| 462 |                 return DefWindowProc(hwnd, umsg, wp, lp); | 
|---|
| 463 |         } | 
|---|
| 464 |  | 
|---|
| 465 |         bool Win32GLSupport::selectPixelFormat(HDC hdc, int colourDepth, int multisample) | 
|---|
| 466 |         { | 
|---|
| 467 |                 PIXELFORMATDESCRIPTOR pfd; | 
|---|
| 468 |                 memset(&pfd, 0, sizeof(pfd)); | 
|---|
| 469 |                 pfd.nSize = sizeof(pfd); | 
|---|
| 470 |                 pfd.nVersion = 1; | 
|---|
| 471 |                 pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; | 
|---|
| 472 |                 pfd.iPixelType = PFD_TYPE_RGBA; | 
|---|
| 473 |                 pfd.cColorBits = (colourDepth > 16)? 24 : colourDepth; | 
|---|
| 474 |                 pfd.cAlphaBits = (colourDepth > 16)? 8 : 0; | 
|---|
| 475 |                 pfd.cDepthBits = 24; | 
|---|
| 476 |                 pfd.cStencilBits = 8; | 
|---|
| 477 |  | 
|---|
| 478 |                 int format = 0; | 
|---|
| 479 |  | 
|---|
| 480 |                 if (multisample) | 
|---|
| 481 |                 { | 
|---|
| 482 |                         // only available with driver support | 
|---|
| 483 |                         if (!mHasMultisample || !mHasPixelFormatARB) | 
|---|
| 484 |                                 return false; | 
|---|
| 485 |                          | 
|---|
| 486 |                         int iattr[] = { | 
|---|
| 487 |                                 WGL_DRAW_TO_WINDOW_ARB, GL_TRUE, | 
|---|
| 488 |                                 WGL_SUPPORT_OPENGL_ARB, GL_TRUE, | 
|---|
| 489 |                                 WGL_DOUBLE_BUFFER_ARB, GL_TRUE, | 
|---|
| 490 |                                 WGL_SAMPLE_BUFFERS_ARB, GL_TRUE, | 
|---|
| 491 |                                 WGL_ACCELERATION_ARB, WGL_FULL_ACCELERATION_ARB, | 
|---|
| 492 |                                 WGL_COLOR_BITS_ARB, pfd.cColorBits, | 
|---|
| 493 |                                 WGL_ALPHA_BITS_ARB, pfd.cAlphaBits, | 
|---|
| 494 |                                 WGL_DEPTH_BITS_ARB, 24, | 
|---|
| 495 |                                 WGL_STENCIL_BITS_ARB, 8, | 
|---|
| 496 |                                 WGL_SAMPLES_ARB, multisample, | 
|---|
| 497 |                                 0 | 
|---|
| 498 |                         }; | 
|---|
| 499 |  | 
|---|
| 500 |                         UINT nformats; | 
|---|
| 501 |             assert(__wglewChoosePixelFormatARB && "failed to get proc address for ChoosePixelFormatARB"); | 
|---|
| 502 |             // ChoosePixelFormatARB proc address was obtained when setting up a dummy GL context in initialiseWGL() | 
|---|
| 503 |             // since glew hasn't been initialized yet, we have to cheat and use the previously obtained address | 
|---|
| 504 |                         if (!__wglewChoosePixelFormatARB(hdc, iattr, NULL, 1, &format, &nformats) || nformats <= 0) | 
|---|
| 505 |                 return false; | 
|---|
| 506 |                 } | 
|---|
| 507 |                 else | 
|---|
| 508 |                 { | 
|---|
| 509 |                         format = ChoosePixelFormat(hdc, &pfd); | 
|---|
| 510 |                 } | 
|---|
| 511 |  | 
|---|
| 512 |                 return (format != 0 && SetPixelFormat(hdc, format, &pfd)); | 
|---|
| 513 |         } | 
|---|
| 514 |  | 
|---|
| 515 |         bool Win32GLSupport::supportsPBuffers() | 
|---|
| 516 |         { | 
|---|
| 517 |                 return __WGLEW_ARB_pbuffer != GL_FALSE; | 
|---|
| 518 |         } | 
|---|
| 519 |     GLPBuffer *Win32GLSupport::createPBuffer(PixelComponentType format, size_t width, size_t height) | 
|---|
| 520 |         { | 
|---|
| 521 |                 return new Win32PBuffer(format, width, height); | 
|---|
| 522 |         } | 
|---|
| 523 | } | 
|---|