Torque3D Documentation / _generateds / gfxGLDevice.win.cpp

gfxGLDevice.win.cpp

Engine/source/gfx/gl/win32/gfxGLDevice.win.cpp

More...

Public Defines

define
GETHWND(x) static_cast<*>(x)->getHWND()

Public Functions

CreatePixelFormat(PIXELFORMATDESCRIPTOR * pPFD, S32 colorBits, S32 depthBits, S32 stencilBits, bool stereo)

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