157
static std::string sysError()
159
DWORD stat, err = GetLastError();
162
stat = FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER |
163
FORMAT_MESSAGE_FROM_SYSTEM |
164
FORMAT_MESSAGE_IGNORE_INSERTS,
167
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
172
std::ostringstream msgResult;
173
if ( stat > 0 && lpMsgBuf )
175
msgResult << (LPCTSTR)lpMsgBuf;
176
LocalFree( lpMsgBuf );
180
msgResult << "Error code " << err;
183
return msgResult.str();
157
187
static int __tempwnd_id = 0;
158
188
class TemporaryWindow: public osg::Referenced
266
osg::notify(osg::WARN) << "PixelBufferWin32, could not create temporary window: " << sysError() << std::endl;
240
271
if (!(_dc = GetDC(_handle)))
273
osg::notify(osg::WARN) << "PixelBufferWin32, could not get device context for temporary window: " << sysError() << std::endl;
268
300
if (!SetPixelFormat(_dc, visual_id, &pfd))
302
osg::notify(osg::WARN) << "PixelBufferWin32, could not set pixel format for temporary window: " << sysError() << std::endl;
274
307
if (!(_context = wglCreateContext(_dc)))
309
osg::notify(osg::WARN) << "PixelBufferWin32, could not get graphics context for temporary window: " << sysError() << std::endl;
314
348
bool TemporaryWindow::makeCurrent()
316
return wglMakeCurrent(_dc, _context) == TRUE ? true : false;
350
bool result = wglMakeCurrent(_dc, _context) == TRUE ? true : false;
353
osg::notify(osg::NOTICE) << "PixelBufferWin32, could not make the temporary window's context active: " << sysError() << std::endl;
319
358
class WGLExtensions : public osg::Referenced
377
416
bool WGLExtensions::isValid()
379
418
return (wglCreatePbufferARB && wglGetPbufferDCARB && wglReleasePbufferDCARB && wglDestroyPbufferARB &&
380
wglQueryPbufferARB && wglBindTexImageARB && wglReleaseTexImageARB && wglChoosePixelFormatARB &&
381
wglMakeContextCurrentARB);
419
wglQueryPbufferARB && wglChoosePixelFormatARB );
384
osg::ref_ptr<TemporaryWindow> __default_wnd;
385
422
WGLExtensions *WGLExtensions::instance()
387
424
HGLRC context = wglGetCurrentContext();
388
bool nocontext = (context == 0);
390
if (nocontext || !__default_wnd.valid())
392
if (!__default_wnd.valid() || !__default_wnd->getHandle())
394
__default_wnd = new TemporaryWindow;
395
if (!__default_wnd ->getHandle())
397
osg::notify(osg::NOTICE) << "WGLExtensions: could not create and initialize the temporary window" << std::endl;
402
context = __default_wnd->getContext();
403
if (!__default_wnd->makeCurrent())
405
osg::notify(osg::NOTICE) << "WGLExtensions: could not make the temporary window's context active" << std::endl;
426
// Get wgl function pointers for the current graphics context, or if there is no
427
// current context then use a temporary window.
410
429
if (!_instances[context])
412
_instances[context] = new WGLExtensions;
433
osg::ref_ptr<TemporaryWindow> tempWin= new TemporaryWindow;
434
tempWin->makeCurrent();
435
_instances[0] = new WGLExtensions;
439
_instances[context] = new WGLExtensions;
415
443
return _instances[context].get();
455
484
closeImplementation();
458
static void doInternalError( char *msg )
460
DWORD err = GetLastError();
462
FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER |
463
FORMAT_MESSAGE_FROM_SYSTEM |
464
FORMAT_MESSAGE_IGNORE_INSERTS,
467
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
471
std::string szMessage = std::string("osgViewer::PixelBufferWin32: Internal Error ")+std::string(msg);
472
MessageBox( NULL, (LPCTSTR)lpMsgBuf, szMessage.c_str(), MB_OK | MB_ICONINFORMATION );
473
if (lpMsgBuf) LocalFree( lpMsgBuf );
476
487
void PixelBufferWin32::init()
479
490
if (!_traits) return;
480
491
if (!_traits->pbuffer) return;
482
struct RestoreContext
486
_hdc = wglGetCurrentDC();
487
_hglrc = wglGetCurrentContext();
493
wglMakeCurrent(_hdc,_hglrc);
501
493
WGLExtensions* wgle = WGLExtensions::instance();
503
495
if (!wgle || !wgle->isValid())
621
613
_hwnd = reinterpret_cast<HWND>(wgle->wglCreatePbufferARB(hdc, format, _traits->width, _traits->height, &bAttribList[0]));
624
//doInternalError("wglCreatePbufferARB() failed");
625
osg::notify(osg::NOTICE) << "PixelBufferWin32::init(), Error: wglCreatePbufferARB failed" << std::endl;
616
osg::notify(osg::NOTICE) << "PixelBufferWin32::init, wglCreatePbufferARB error: " << sysError() << std::endl;
629
620
_hdc = wgle->wglGetPbufferDCARB(reinterpret_cast<HPBUFFERARB>(_hwnd));
632
//doInternalError("wglGetPbufferDCARB() failed");
633
osg::notify(osg::NOTICE) << "PixelBufferWin32::init(), Error: wglGetPbufferDCARB failed" << std::endl;
623
osg::notify(osg::NOTICE) << "PixelBufferWin32::init, wglGetPbufferDCARB error: " << sysError() << std::endl;
637
627
_hglrc = wglCreateContext(_hdc);
640
//doInternalError("wglCreateContext() failed");
641
osg::notify(osg::NOTICE) << "PixelBufferWin32::init(), Error: wglCreateContext failed" << std::endl;
630
osg::notify(osg::NOTICE) << "PixelBufferWin32::init, wglCreateContext error: " << sysError() << std::endl;
695
wglShareLists(hglrc, _hglrc);
684
if ( !wglShareLists(hglrc, _hglrc) )
686
osg::notify(osg::NOTICE) << "PixelBufferWin32::realizeImplementation, wglShareLists error: " << sysError() << std::endl;
698
690
_realized = true;
706
wglDeleteContext(_hglrc);
708
698
WGLExtensions* wgle = WGLExtensions::instance();
700
wglMakeCurrent(NULL,NULL);
702
if ( !wglDeleteContext(_hglrc) )
704
osg::notify(osg::NOTICE) << "PixelBufferWin32::closeImplementation, wglDeleteContext error: " << sysError() << std::endl;
709
707
if (wgle && wgle->isValid())
711
wgle->wglReleasePbufferDCARB(reinterpret_cast<HPBUFFERARB>(_hwnd), _hdc);
712
wgle->wglDestroyPbufferARB(reinterpret_cast<HPBUFFERARB>(_hwnd));
709
// Note that closeImplementation() should only be called from the same thread as created the pbuffer,
710
// otherwise these routines will return an error.
712
if ( !wgle->wglReleasePbufferDCARB(reinterpret_cast<HPBUFFERARB>(_hwnd), _hdc) )
714
osg::notify(osg::NOTICE) << "PixelBufferWin32::closeImplementation, wglReleasePbufferDCARB error: " << sysError() << std::endl;
716
if ( !wgle->wglDestroyPbufferARB(reinterpret_cast<HPBUFFERARB>(_hwnd)) )
718
osg::notify(osg::NOTICE) << "PixelBufferWin32::closeImplementation, wglDestroyPbufferARB error: " << sysError() << std::endl;
722
729
bool PixelBufferWin32::makeCurrentImplementation()
724
WGLExtensions* wgle = WGLExtensions::instance();
725
if (!wgle) return false;
727
if (_traits->target != 0)
729
wgle->wglReleaseTexImageARB(reinterpret_cast<HPBUFFERARB>(_hwnd), WGL_FRONT_LEFT_ARB);
730
wgle->wglReleaseTexImageARB(reinterpret_cast<HPBUFFERARB>(_hwnd), WGL_BACK_LEFT_ARB);
732
731
bool result = wglMakeCurrent(_hdc, _hglrc)==TRUE?true:false;
735
//doInternalError("wglMakeCurrent() failed");
736
osg::notify(osg::NOTICE) << "PixelBufferWin32::makeCurrentImplementation(), failed" << std::endl;
734
osg::notify(osg::NOTICE) << "PixelBufferWin32::makeCurrentImplementation, wglMakeCurrent error: " << sysError() << std::endl;
737
// If the pbuffer is bound to a texture then release it. This operation requires a current context, so
738
// do it after the MakeCurrent.
740
if ( _boundBuffer!=0 )
742
WGLExtensions* wgle = WGLExtensions::instance();
743
if ( wgle && wgle->wglReleaseTexImageARB )
745
if ( !wgle->wglReleaseTexImageARB(reinterpret_cast<HPBUFFERARB>(_hwnd), _boundBuffer) )
747
osg::notify(osg::NOTICE) << "PixelBufferWin32::makeCurrentImplementation, wglReleaseTexImageARB error: " << sysError() << std::endl;
741
756
bool PixelBufferWin32::makeContextCurrentImplementation( GraphicsContext* readContext )
758
WGLExtensions* wgle = WGLExtensions::instance();
760
if ( !wgle || !wgle->wglMakeContextCurrentARB )
762
osg::notify(osg::NOTICE) << "PixelBufferWin32, wglMakeContextCurrentARB not available" << std::endl;
743
766
GraphicsWindowWin32* graphicsWindowWin32 = dynamic_cast<GraphicsWindowWin32*>(readContext);
744
767
if (graphicsWindowWin32)
746
if (WGLExtensions::instance()->wglMakeContextCurrentARB(_hdc, graphicsWindowWin32->getHDC(), _hglrc))
769
return wgle->wglMakeContextCurrentARB(_hdc, graphicsWindowWin32->getHDC(), _hglrc);
749
771
PixelBufferWin32* pixelBufferWin32 = dynamic_cast<PixelBufferWin32*>(_traits->sharedContext);
750
772
if (pixelBufferWin32)
752
if (WGLExtensions::instance()->wglMakeContextCurrentARB(_hdc, pixelBufferWin32->getHDC(), _hglrc))
774
return wgle->wglMakeContextCurrentARB(_hdc, pixelBufferWin32->getHDC(), _hglrc);
769
790
void PixelBufferWin32::bindPBufferToTextureImplementation( GLenum buffer )
773
792
WGLExtensions* wgle = WGLExtensions::instance();
794
if ( !wgle || !wgle->wglBindTexImageARB )
796
osg::notify(osg::NOTICE) << "PixelBufferWin32, wglBindTexImageARB not available" << std::endl;
779
result = wgle->wglBindTexImageARB(reinterpret_cast<HPBUFFERARB>(_hwnd), WGL_BACK_LEFT_ARB);
805
bindBuffer = WGL_BACK_LEFT_ARB;
782
result = wgle->wglBindTexImageARB(reinterpret_cast<HPBUFFERARB>(_hwnd), WGL_FRONT_LEFT_ARB);
808
bindBuffer = WGL_FRONT_LEFT_ARB;
785
result = wgle->wglBindTexImageARB(reinterpret_cast<HPBUFFERARB>(_hwnd), static_cast<GLenum>(buffer));
811
bindBuffer = static_cast<int>(buffer);
814
if ( bindBuffer != _boundBuffer )
789
//doInternalError("wglBindTexImageARB() failed");
790
osg::notify(osg::NOTICE) << "PixelBufferWin32::wglBindTexImageARB(), failed" << std::endl;
816
if ( _boundBuffer != 0 && !wgle->wglReleaseTexImageARB(reinterpret_cast<HPBUFFERARB>(_hwnd), _boundBuffer) )
818
osg::notify(osg::NOTICE) << "PixelBufferWin32::bindPBufferToTextureImplementation, wglReleaseTexImageARB error: " << sysError() << std::endl;
821
if ( !wgle->wglBindTexImageARB(reinterpret_cast<HPBUFFERARB>(_hwnd), bindBuffer) )
823
osg::notify(osg::NOTICE) << "PixelBufferWin32::bindPBufferToTextureImplementation, wglBindTexImageARB error: " << sysError() << std::endl;
825
_boundBuffer = bindBuffer;
795
829
void PixelBufferWin32::swapBuffersImplementation()