gfxGLDevice.win.cpp
Engine/source/gfx/gl/win32/gfxGLDevice.win.cpp
Public Defines
define
GETHWND(x) static_cast<*>(x)->getHWND()
Public Functions
CreatePixelFormat(PIXELFORMATDESCRIPTOR * pPFD, S32 colorBits, S32 depthBits, S32 stencilBits, bool stereo)
loadGLExtensions(void * context)
Detailed Description
Public Defines
GETHWND(x) static_cast<*>(x)->getHWND()
Public Functions
CreatePixelFormat(PIXELFORMATDESCRIPTOR * pPFD, S32 colorBits, S32 depthBits, S32 stencilBits, bool stereo)
loadGLCore()
loadGLExtensions(void * context)
1 2//----------------------------------------------------------------------------- 3// Copyright (c) 2012 GarageGames, LLC 4// 5// Permission is hereby granted, free of charge, to any person obtaining a copy 6// of this software and associated documentation files (the "Software"), to 7// deal in the Software without restriction, including without limitation the 8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 9// sell copies of the Software, and to permit persons to whom the Software is 10// furnished to do so, subject to the following conditions: 11// 12// The above copyright notice and this permission notice shall be included in 13// all copies or substantial portions of the Software. 14// 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21// IN THE SOFTWARE. 22//----------------------------------------------------------------------------- 23 24#include "platformWin32/platformWin32.h" 25#include "gfx/gfxCubemap.h" 26#include "gfx/screenshot.h" 27 28#include "gfx/GL/gfxGLDevice.h" 29#include "gfx/GL/gfxGLEnumTranslate.h" 30#include "gfx/GL/gfxGLVertexBuffer.h" 31#include "gfx/GL/gfxGLPrimitiveBuffer.h" 32#include "gfx/gl/gfxGLTextureTarget.h" 33#include "gfx/GL/gfxGLWindowTarget.h" 34#include "gfx/GL/gfxGLTextureManager.h" 35#include "gfx/GL/gfxGLTextureObject.h" 36#include "gfx/GL/gfxGLCubemap.h" 37#include "gfx/GL/gfxGLCardProfiler.h" 38#include "windowManager/win32/win32Window.h" 39#include "gfx/gl/tGL/tWGL.h" 40 41#include "postFx/postEffect.h" 42#include "gfx/gl/gfxGLUtils.h" 43 44#define GETHWND(x) static_cast<Win32Window*>(x)->getHWND() 45 46// yonked from winWindow.cc 47void CreatePixelFormat( PIXELFORMATDESCRIPTOR *pPFD, S32 colorBits, S32 depthBits, S32 stencilBits, bool stereo ) 48{ 49 PIXELFORMATDESCRIPTOR src = 50 { 51 sizeof(PIXELFORMATDESCRIPTOR), // size of this pfd 52 1, // version number 53 PFD_DRAW_TO_WINDOW | // support window 54 PFD_SUPPORT_OPENGL | // support OpenGL 55 PFD_DOUBLEBUFFER, // double buffered 56 PFD_TYPE_RGBA, // RGBA type 57 colorBits, // color depth 58 0, 0, 0, 0, 0, 0, // color bits ignored 59 0, // no alpha buffer 60 0, // shift bit ignored 61 0, // no accumulation buffer 62 0, 0, 0, 0, // accum bits ignored 63 depthBits, // z-buffer 64 stencilBits, // stencil buffer 65 0, // no auxiliary buffer 66 PFD_MAIN_PLANE, // main layer 67 0, // reserved 68 0, 0, 0 // layer masks ignored 69 }; 70 71 if ( stereo ) 72 { 73 //ri.Printf( PRINT_ALL, "...attempting to use stereo\n" ); 74 src.dwFlags |= PFD_STEREO; 75 //glConfig.stereoEnabled = true; 76 } 77 else 78 { 79 //glConfig.stereoEnabled = qfalse; 80 } 81 *pPFD = src; 82} 83 84extern void loadGLCore(); 85extern void loadGLExtensions(void* context); 86 87void GFXGLDevice::enumerateAdapters( Vector<GFXAdapter*> &adapterList ) 88{ 89// GL_ERROR_CHECK(); 90 WNDCLASS windowclass; 91 dMemset( &windowclass, 0, sizeof( WNDCLASS ) ); 92 93 windowclass.lpszClassName = L"GFX-OpenGL"; 94 windowclass.style = CS_OWNDC; 95 windowclass.lpfnWndProc = DefWindowProc; 96 windowclass.hInstance = winState.appInstance; 97 98 if( !RegisterClass( &windowclass ) ) 99 AssertFatal( false, "Failed to register the window class for the GL test window." ); 100 101 // Now create a window 102 HWND hwnd = CreateWindow( L"GFX-OpenGL", L"", WS_POPUP, 0, 0, 640, 480, 103 NULL, NULL, winState.appInstance, NULL ); 104 AssertFatal( hwnd != NULL, "Failed to create the window for the GL test window." ); 105 106 // Create a device context 107 HDC tempDC = GetDC( hwnd ); 108 AssertFatal( tempDC != NULL, "Failed to create device context" ); 109 110 // Create pixel format descriptor... 111 PIXELFORMATDESCRIPTOR pfd; 112 CreatePixelFormat( &pfd, 32, 0, 0, false ); 113 if( !SetPixelFormat( tempDC, ChoosePixelFormat( tempDC, &pfd ), &pfd ) ) 114 AssertFatal( false, "I don't know who's responcible for this, but I want caught..." ); 115 116 // Create a rendering context! 117 HGLRC tempGLRC = wglCreateContext( tempDC ); 118 if( !wglMakeCurrent( tempDC, tempGLRC ) ) 119 AssertFatal( false, "I want them caught and killed." ); 120 121 // Add the GL renderer 122 loadGLCore(); 123 loadGLExtensions(tempDC); 124 125 GFXAdapter *toAdd = new GFXAdapter; 126 toAdd->mIndex = 0; 127 128 const char* renderer = (const char*) glGetString( GL_RENDERER ); 129 AssertFatal( renderer != NULL, "GL_RENDERER returned NULL!" ); 130 131 if (renderer) 132 { 133 dStrcpy(toAdd->mName, renderer, GFXAdapter::MaxAdapterNameLen); 134 dStrncat(toAdd->mName, " OpenGL", GFXAdapter::MaxAdapterNameLen); 135 } 136 else 137 dStrcpy(toAdd->mName, "OpenGL", GFXAdapter::MaxAdapterNameLen); 138 139 toAdd->mType = OpenGL; 140 toAdd->mShaderModel = 0.f; 141 toAdd->mCreateDeviceInstanceDelegate = mCreateDeviceInstance; 142 143 // Enumerate all available resolutions: 144 DEVMODE devMode; 145 U32 modeNum = 0; 146 U32 stillGoing = true; 147 while ( stillGoing ) 148 { 149 dMemset( &devMode, 0, sizeof( devMode ) ); 150 devMode.dmSize = sizeof( devMode ); 151 152 stillGoing = EnumDisplaySettings( NULL, modeNum++, &devMode ); 153 154 if (( devMode.dmPelsWidth >= 480) && (devMode.dmPelsHeight >= 360 ) 155 && ( devMode.dmBitsPerPel == 16 || devMode.dmBitsPerPel == 32 )) 156 { 157 GFXVideoMode vmAdd; 158 159 vmAdd.bitDepth = devMode.dmBitsPerPel; 160 vmAdd.fullScreen = true; 161 vmAdd.refreshRate = devMode.dmDisplayFrequency; 162 vmAdd.resolution.x = devMode.dmPelsWidth; 163 vmAdd.resolution.y = devMode.dmPelsHeight; 164 165 // Only add this resolution if it is not already in the list: 166 bool alreadyInList = false; 167 for (Vector<GFXVideoMode>::iterator i = toAdd->mAvailableModes.begin(); i != toAdd->mAvailableModes.end(); i++) 168 { 169 if (vmAdd == *i) 170 { 171 alreadyInList = true; 172 break; 173 } 174 } 175 176 if(alreadyInList) 177 continue; 178 179 toAdd->mAvailableModes.push_back( vmAdd ); 180 } 181 } 182 183 // Add to the list of available adapters. 184 adapterList.push_back(toAdd); 185 186 // Cleanup our window 187 wglMakeCurrent(NULL, NULL); 188 wglDeleteContext(tempGLRC); 189 ReleaseDC(hwnd, tempDC); 190 DestroyWindow(hwnd); 191 UnregisterClass(L"GFX-OpenGL", winState.appInstance); 192} 193 194void GFXGLDevice::enumerateVideoModes() 195{ 196 mVideoModes.clear(); 197 198 // Enumerate all available resolutions: 199 DEVMODE devMode; 200 U32 modeNum = 0; 201 U32 stillGoing = true; 202 while ( stillGoing ) 203 { 204 dMemset( &devMode, 0, sizeof( devMode ) ); 205 devMode.dmSize = sizeof( devMode ); 206 207 stillGoing = EnumDisplaySettings( NULL, modeNum++, &devMode ); 208 209 if (( devMode.dmPelsWidth >= 480) && (devMode.dmPelsHeight >= 360 ) 210 && ( devMode.dmBitsPerPel == 16 || devMode.dmBitsPerPel == 32 )) 211 //( smCanSwitchBitDepth || devMode.dmBitsPerPel == winState.desktopBitsPixel ) ) 212 { 213 GFXVideoMode toAdd; 214 215 toAdd.bitDepth = devMode.dmBitsPerPel; 216 toAdd.fullScreen = false; 217 toAdd.refreshRate = devMode.dmDisplayFrequency; 218 toAdd.resolution.x = devMode.dmPelsWidth; 219 toAdd.resolution.y = devMode.dmPelsHeight; 220 221 // Only add this resolution if it is not already in the list: 222 bool alreadyInList = false; 223 for (Vector<GFXVideoMode>::iterator i = mVideoModes.begin(); i != mVideoModes.end(); i++) 224 { 225 if (toAdd == *i) 226 { 227 alreadyInList = true; 228 break; 229 } 230 } 231 if ( !alreadyInList ) 232 { 233 //Con::printf("Resolution: %dx%d %d bpp %d Refresh rate: %d", toAdd.resolution.x, toAdd.resolution.y, toAdd.bitDepth, toAdd.refreshRate); 234 mVideoModes.push_back( toAdd ); 235 } 236 } 237 } 238} 239 240void GFXGLDevice::init( const GFXVideoMode &mode, PlatformWindow *window ) 241{ 242 AssertFatal(window, "GFXGLDevice::init - no window specified, can't init device without a window!"); 243 AssertFatal(dynamic_cast<Win32Window*>(window), "Invalid window class type!"); 244 HWND hwnd = GETHWND(window); 245 246 mWindowRT = &static_cast<Win32Window*>(window)->mTarget; 247 248 RECT rect; 249 GetClientRect(hwnd, &rect); 250 251 Point2I resolution; 252 resolution.x = rect.right - rect.left; 253 resolution.y = rect.bottom - rect.top; 254 255 // Create a device context 256 HDC hdcGL = GetDC( hwnd ); 257 AssertFatal( hdcGL != NULL, "Failed to create device context" ); 258 259 // Create pixel format descriptor... 260 PIXELFORMATDESCRIPTOR pfd; 261 CreatePixelFormat( &pfd, 32, 0, 0, false ); // 32 bit color... We do not need depth or stencil, OpenGL renders into a FBO and then copy the image to window 262 if( !SetPixelFormat( hdcGL, ChoosePixelFormat( hdcGL, &pfd ), &pfd ) ) 263 { 264 AssertFatal( false, "GFXGLDevice::init - cannot get the one and only pixel format we check for." ); 265 } 266 267 int OGL_MAJOR = 3; 268 int OGL_MINOR = 2; 269 270#if TORQUE_DEBUG 271 int debugFlag = WGL_CONTEXT_DEBUG_BIT_ARB; 272#else 273 int debugFlag = 0; 274#endif 275 276 // Create a temp rendering context, needed a current context to use wglCreateContextAttribsARB 277 HGLRC tempGLRC = wglCreateContext(hdcGL); 278 if (!wglMakeCurrent(hdcGL, tempGLRC)) 279 AssertFatal(false, "Couldn't make temp GL context."); 280 281 if( gglHasWExtension(hdcGL, ARB_create_context) ) 282 { 283 int const create_attribs[] = { 284 WGL_CONTEXT_MAJOR_VERSION_ARB, OGL_MAJOR, 285 WGL_CONTEXT_MINOR_VERSION_ARB, OGL_MINOR, 286 WGL_CONTEXT_FLAGS_ARB, /*WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB |*/ debugFlag, 287 WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB, 288 //WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, 289 0 290 }; 291 292 mContext = wglCreateContextAttribsARB(hdcGL, 0, create_attribs); 293 if(!mContext) 294 { 295 AssertFatal(0,""); 296 } 297 } 298 else 299 mContext = wglCreateContext( hdcGL ); 300 301 // Delete temp rendering context 302 wglMakeCurrent(NULL, NULL); 303 wglDeleteContext(tempGLRC); 304 305 if( !wglMakeCurrent( hdcGL, (HGLRC)mContext ) ) 306 AssertFatal( false , "GFXGLDevice::init - cannot make our context current. Or maybe we can't create it." ); 307 308 loadGLCore(); 309 loadGLExtensions(hdcGL); 310 311 // It is very important that extensions be loaded 312 // before we call initGLState() 313 initGLState(); 314 315 mProjectionMatrix.identity(); 316 317 mInitialized = true; 318 deviceInited(); 319} 320 321bool GFXGLDevice::beginSceneInternal() 322{ 323 mCanCurrentlyRender = true; 324 return true; 325} 326 327U32 GFXGLDevice::getTotalVideoMemory() 328{ 329 return getTotalVideoMemory_GL_EXT(); 330} 331 332//------------------------------------------------------------------------------ 333 334GFXWindowTarget *GFXGLDevice::allocWindowTarget( PlatformWindow *window ) 335{ 336 AssertFatal(!mContext, ""); 337 338 init(window->getVideoMode(), window); 339 GFXGLWindowTarget *ggwt = new GFXGLWindowTarget(window, this); 340 ggwt->registerResourceWithDevice(this); 341 ggwt->mContext = mContext; 342 AssertFatal(ggwt->mContext, "GFXGLDevice::allocWindowTarget - failed to allocate window target!"); 343 344 return ggwt; 345} 346 347GFXFence* GFXGLDevice::_createPlatformSpecificFence() 348{ 349 return NULL; 350} 351 352 353//----------------------------------------------------------------------------- 354void GFXGLWindowTarget::_WindowPresent() 355{ 356 HWND hwnd = GETHWND(getWindow()); 357 SwapBuffers(GetDC(hwnd)); 358} 359 360void GFXGLWindowTarget::_teardownCurrentMode() 361{ 362} 363 364void GFXGLWindowTarget::_setupNewMode() 365{ 366} 367 368void GFXGLWindowTarget::_makeContextCurrent() 369{ 370 HWND hwnd = GETHWND(getWindow()); 371 HDC hdc = GetDC(hwnd); 372 373 if (!wglMakeCurrent(hdc, (HGLRC)mContext)) 374 { 375 //HRESULT if needed for debug 376 //HRESULT hr = HRESULT_FROM_WIN32(GetLastError()); 377 AssertFatal(false, "GFXGLWindowTarget::_makeContextCurrent() - cannot make our context current."); 378 } 379 380} 381