From Colin McDonald, "Attached is an updated to osgViewer::PixelBufferWin32.
The win32 pbuffer implementation returned an error unless both the WGL_ARB_pbuffer and the WGL_ARB_render_texture functions were present. This was too restrictive, as a pbuffer can usefully be created without render-to-texture, e.g. for use with glReadPixels. The osg 1.2/Producer pbuffers worked without RTT, and osgUtil::RenderStage has all the code to handle both RTT and non-RTT pbuffers, doing a read and copy in the latter case. With these changes I have successfully tested the osgprerender example on a graphics card which supports RTT, and one which doesn't. Plus tested in my own application. In order to aid diagnostics I have also added more function status return checks, and associated error messages. I have included the win32 error text in all error messages output. And there were some errors with multi-threaded handling of "bind to texture" and a temporary window context which I have corrected. These is one (pre-existing) problem with multi-threaded use of pbuffers in osgViewer & osgprerender, which I have not been able to fix. A win32 device context (HDC) can only be destroyed from the thread that created it. The pbuffers for pre-render cameras are created in osgUtil::RenderStage::runCameraSetUp, from the draw thread. But closeImplementation is normally invoked from the destructor in the main application thread. With the additional error messages I have added, osgprerender will now output a couple of warnings from osgViewer::PixelBufferWin32::closeImplementation() at exit, after running multi-threaded on windows. I think that is a good thing, to highlight the problem. I looked into fixing it in osgViewer::Renderer & osgUtil::RenderStage, but it was too involved for me. My own application requirements are only single-threaded. Unrelated fix - an uninitialised variable in osg::GraphicsThread::FlushDeletedGLObjectsOperation(). "
This commit is contained in:
parent
dd2b4ed83e
commit
9d0c950bb0
@ -84,6 +84,7 @@ class OSGVIEWER_EXPORT PixelBufferWin32 : public osg::GraphicsContext
|
|||||||
bool _initialized;
|
bool _initialized;
|
||||||
bool _valid;
|
bool _valid;
|
||||||
bool _realized;
|
bool _realized;
|
||||||
|
int _boundBuffer;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -112,7 +112,8 @@ void BlockAndFlushOperation::operator () (GraphicsContext*)
|
|||||||
}
|
}
|
||||||
|
|
||||||
FlushDeletedGLObjectsOperation::FlushDeletedGLObjectsOperation(double availableTime, bool keep):
|
FlushDeletedGLObjectsOperation::FlushDeletedGLObjectsOperation(double availableTime, bool keep):
|
||||||
GraphicsOperation("FlushDeletedGLObjectsOperation",keep)
|
GraphicsOperation("FlushDeletedGLObjectsOperation",keep),
|
||||||
|
_availableTime(availableTime)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -154,6 +154,36 @@ DECLARE_HANDLE(HPBUFFERARB);
|
|||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
|
||||||
|
static std::string sysError()
|
||||||
|
{
|
||||||
|
DWORD stat, err = GetLastError();
|
||||||
|
LPVOID lpMsgBuf = 0;
|
||||||
|
|
||||||
|
stat = FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||||
|
FORMAT_MESSAGE_FROM_SYSTEM |
|
||||||
|
FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||||
|
NULL,
|
||||||
|
err,
|
||||||
|
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
|
||||||
|
(LPTSTR) &lpMsgBuf,\
|
||||||
|
0,NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
std::ostringstream msgResult;
|
||||||
|
if ( stat > 0 && lpMsgBuf )
|
||||||
|
{
|
||||||
|
msgResult << (LPCTSTR)lpMsgBuf;
|
||||||
|
LocalFree( lpMsgBuf );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
msgResult << "Error code " << err;
|
||||||
|
}
|
||||||
|
|
||||||
|
return msgResult.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int __tempwnd_id = 0;
|
static int __tempwnd_id = 0;
|
||||||
class TemporaryWindow: public osg::Referenced
|
class TemporaryWindow: public osg::Referenced
|
||||||
{
|
{
|
||||||
@ -233,12 +263,14 @@ void TemporaryWindow::create()
|
|||||||
_instance,
|
_instance,
|
||||||
0)))
|
0)))
|
||||||
{
|
{
|
||||||
|
osg::notify(osg::WARN) << "PixelBufferWin32, could not create temporary window: " << sysError() << std::endl;
|
||||||
kill();
|
kill();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(_dc = GetDC(_handle)))
|
if (!(_dc = GetDC(_handle)))
|
||||||
{
|
{
|
||||||
|
osg::notify(osg::WARN) << "PixelBufferWin32, could not get device context for temporary window: " << sysError() << std::endl;
|
||||||
kill();
|
kill();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -267,12 +299,14 @@ void TemporaryWindow::create()
|
|||||||
|
|
||||||
if (!SetPixelFormat(_dc, visual_id, &pfd))
|
if (!SetPixelFormat(_dc, visual_id, &pfd))
|
||||||
{
|
{
|
||||||
|
osg::notify(osg::WARN) << "PixelBufferWin32, could not set pixel format for temporary window: " << sysError() << std::endl;
|
||||||
kill();
|
kill();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(_context = wglCreateContext(_dc)))
|
if (!(_context = wglCreateContext(_dc)))
|
||||||
{
|
{
|
||||||
|
osg::notify(osg::WARN) << "PixelBufferWin32, could not get graphics context for temporary window: " << sysError() << std::endl;
|
||||||
kill();
|
kill();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -313,7 +347,12 @@ void TemporaryWindow::kill()
|
|||||||
|
|
||||||
bool TemporaryWindow::makeCurrent()
|
bool TemporaryWindow::makeCurrent()
|
||||||
{
|
{
|
||||||
return wglMakeCurrent(_dc, _context) == TRUE ? true : false;
|
bool result = wglMakeCurrent(_dc, _context) == TRUE ? true : false;
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
osg::notify(osg::NOTICE) << "PixelBufferWin32, could not make the temporary window's context active: " << sysError() << std::endl;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
class WGLExtensions : public osg::Referenced
|
class WGLExtensions : public osg::Referenced
|
||||||
@ -377,39 +416,28 @@ WGLExtensions::~WGLExtensions()
|
|||||||
bool WGLExtensions::isValid()
|
bool WGLExtensions::isValid()
|
||||||
{
|
{
|
||||||
return (wglCreatePbufferARB && wglGetPbufferDCARB && wglReleasePbufferDCARB && wglDestroyPbufferARB &&
|
return (wglCreatePbufferARB && wglGetPbufferDCARB && wglReleasePbufferDCARB && wglDestroyPbufferARB &&
|
||||||
wglQueryPbufferARB && wglBindTexImageARB && wglReleaseTexImageARB && wglChoosePixelFormatARB &&
|
wglQueryPbufferARB && wglChoosePixelFormatARB );
|
||||||
wglMakeContextCurrentARB);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
osg::ref_ptr<TemporaryWindow> __default_wnd;
|
|
||||||
WGLExtensions *WGLExtensions::instance()
|
WGLExtensions *WGLExtensions::instance()
|
||||||
{
|
{
|
||||||
HGLRC context = wglGetCurrentContext();
|
HGLRC context = wglGetCurrentContext();
|
||||||
bool nocontext = (context == 0);
|
|
||||||
|
// Get wgl function pointers for the current graphics context, or if there is no
|
||||||
if (nocontext || !__default_wnd.valid())
|
// current context then use a temporary window.
|
||||||
{
|
|
||||||
if (!__default_wnd.valid() || !__default_wnd->getHandle())
|
|
||||||
{
|
|
||||||
__default_wnd = new TemporaryWindow;
|
|
||||||
if (!__default_wnd ->getHandle())
|
|
||||||
{
|
|
||||||
osg::notify(osg::NOTICE) << "WGLExtensions: could not create and initialize the temporary window" << std::endl;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
context = __default_wnd->getContext();
|
|
||||||
if (!__default_wnd->makeCurrent())
|
|
||||||
{
|
|
||||||
osg::notify(osg::NOTICE) << "WGLExtensions: could not make the temporary window's context active" << std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (!_instances[context])
|
if (!_instances[context])
|
||||||
{
|
{
|
||||||
_instances[context] = new WGLExtensions;
|
if ( context == 0 )
|
||||||
|
{
|
||||||
|
osg::ref_ptr<TemporaryWindow> tempWin= new TemporaryWindow;
|
||||||
|
tempWin->makeCurrent();
|
||||||
|
_instances[0] = new WGLExtensions;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_instances[context] = new WGLExtensions;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return _instances[context].get();
|
return _instances[context].get();
|
||||||
@ -427,7 +455,8 @@ PixelBufferWin32::PixelBufferWin32( osg::GraphicsContext::Traits* traits ):
|
|||||||
_hglrc(0),
|
_hglrc(0),
|
||||||
_initialized(false),
|
_initialized(false),
|
||||||
_valid(false),
|
_valid(false),
|
||||||
_realized(false)
|
_realized(false),
|
||||||
|
_boundBuffer(0)
|
||||||
{
|
{
|
||||||
_traits = traits;
|
_traits = traits;
|
||||||
|
|
||||||
@ -454,24 +483,6 @@ PixelBufferWin32::~PixelBufferWin32()
|
|||||||
{
|
{
|
||||||
closeImplementation();
|
closeImplementation();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void doInternalError( char *msg )
|
|
||||||
{
|
|
||||||
DWORD err = GetLastError();
|
|
||||||
LPVOID lpMsgBuf = 0;
|
|
||||||
FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
|
||||||
FORMAT_MESSAGE_FROM_SYSTEM |
|
|
||||||
FORMAT_MESSAGE_IGNORE_INSERTS,
|
|
||||||
NULL,
|
|
||||||
err,
|
|
||||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
|
|
||||||
(LPTSTR) &lpMsgBuf,\
|
|
||||||
0,NULL
|
|
||||||
);
|
|
||||||
std::string szMessage = std::string("osgViewer::PixelBufferWin32: Internal Error ")+std::string(msg);
|
|
||||||
MessageBox( NULL, (LPCTSTR)lpMsgBuf, szMessage.c_str(), MB_OK | MB_ICONINFORMATION );
|
|
||||||
if (lpMsgBuf) LocalFree( lpMsgBuf );
|
|
||||||
}
|
|
||||||
|
|
||||||
void PixelBufferWin32::init()
|
void PixelBufferWin32::init()
|
||||||
{
|
{
|
||||||
@ -479,25 +490,6 @@ void PixelBufferWin32::init()
|
|||||||
if (!_traits) return;
|
if (!_traits) return;
|
||||||
if (!_traits->pbuffer) return;
|
if (!_traits->pbuffer) return;
|
||||||
|
|
||||||
struct RestoreContext
|
|
||||||
{
|
|
||||||
RestoreContext()
|
|
||||||
{
|
|
||||||
_hdc = wglGetCurrentDC();
|
|
||||||
_hglrc = wglGetCurrentContext();
|
|
||||||
}
|
|
||||||
~RestoreContext()
|
|
||||||
{
|
|
||||||
if (_hdc)
|
|
||||||
{
|
|
||||||
wglMakeCurrent(_hdc,_hglrc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
protected:
|
|
||||||
HDC _hdc;
|
|
||||||
HGLRC _hglrc;
|
|
||||||
} restoreContext;
|
|
||||||
|
|
||||||
WGLExtensions* wgle = WGLExtensions::instance();
|
WGLExtensions* wgle = WGLExtensions::instance();
|
||||||
|
|
||||||
if (!wgle || !wgle->isValid())
|
if (!wgle || !wgle->isValid())
|
||||||
@ -555,7 +547,7 @@ void PixelBufferWin32::init()
|
|||||||
fAttribList.push_back(true);
|
fAttribList.push_back(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_traits->target != 0)
|
if (_traits->target != 0 && wgle->wglBindTexImageARB )
|
||||||
{
|
{
|
||||||
// TODO: Cube Maps
|
// TODO: Cube Maps
|
||||||
if (_traits->target == GL_TEXTURE_RECTANGLE)
|
if (_traits->target == GL_TEXTURE_RECTANGLE)
|
||||||
@ -621,24 +613,21 @@ void PixelBufferWin32::init()
|
|||||||
_hwnd = reinterpret_cast<HWND>(wgle->wglCreatePbufferARB(hdc, format, _traits->width, _traits->height, &bAttribList[0]));
|
_hwnd = reinterpret_cast<HWND>(wgle->wglCreatePbufferARB(hdc, format, _traits->width, _traits->height, &bAttribList[0]));
|
||||||
if (!_hwnd)
|
if (!_hwnd)
|
||||||
{
|
{
|
||||||
//doInternalError("wglCreatePbufferARB() failed");
|
osg::notify(osg::NOTICE) << "PixelBufferWin32::init, wglCreatePbufferARB error: " << sysError() << std::endl;
|
||||||
osg::notify(osg::NOTICE) << "PixelBufferWin32::init(), Error: wglCreatePbufferARB failed" << std::endl;
|
|
||||||
return ;
|
return ;
|
||||||
}
|
}
|
||||||
|
|
||||||
_hdc = wgle->wglGetPbufferDCARB(reinterpret_cast<HPBUFFERARB>(_hwnd));
|
_hdc = wgle->wglGetPbufferDCARB(reinterpret_cast<HPBUFFERARB>(_hwnd));
|
||||||
if (!_hdc)
|
if (!_hdc)
|
||||||
{
|
{
|
||||||
//doInternalError("wglGetPbufferDCARB() failed");
|
osg::notify(osg::NOTICE) << "PixelBufferWin32::init, wglGetPbufferDCARB error: " << sysError() << std::endl;
|
||||||
osg::notify(osg::NOTICE) << "PixelBufferWin32::init(), Error: wglGetPbufferDCARB failed" << std::endl;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_hglrc = wglCreateContext(_hdc);
|
_hglrc = wglCreateContext(_hdc);
|
||||||
if (!_hglrc)
|
if (!_hglrc)
|
||||||
{
|
{
|
||||||
//doInternalError("wglCreateContext() failed");
|
osg::notify(osg::NOTICE) << "PixelBufferWin32::init, wglCreateContext error: " << sysError() << std::endl;
|
||||||
osg::notify(osg::NOTICE) << "PixelBufferWin32::init(), Error: wglCreateContext failed" << std::endl;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -692,7 +681,10 @@ bool PixelBufferWin32::realizeImplementation()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
wglShareLists(hglrc, _hglrc);
|
if ( !wglShareLists(hglrc, _hglrc) )
|
||||||
|
{
|
||||||
|
osg::notify(osg::NOTICE) << "PixelBufferWin32::realizeImplementation, wglShareLists error: " << sysError() << std::endl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_realized = true;
|
_realized = true;
|
||||||
@ -703,13 +695,28 @@ void PixelBufferWin32::closeImplementation()
|
|||||||
{
|
{
|
||||||
if (_hwnd)
|
if (_hwnd)
|
||||||
{
|
{
|
||||||
wglDeleteContext(_hglrc);
|
|
||||||
|
|
||||||
WGLExtensions* wgle = WGLExtensions::instance();
|
WGLExtensions* wgle = WGLExtensions::instance();
|
||||||
|
|
||||||
|
wglMakeCurrent(NULL,NULL);
|
||||||
|
|
||||||
|
if ( !wglDeleteContext(_hglrc) )
|
||||||
|
{
|
||||||
|
osg::notify(osg::NOTICE) << "PixelBufferWin32::closeImplementation, wglDeleteContext error: " << sysError() << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
if (wgle && wgle->isValid())
|
if (wgle && wgle->isValid())
|
||||||
{
|
{
|
||||||
wgle->wglReleasePbufferDCARB(reinterpret_cast<HPBUFFERARB>(_hwnd), _hdc);
|
// Note that closeImplementation() should only be called from the same thread as created the pbuffer,
|
||||||
wgle->wglDestroyPbufferARB(reinterpret_cast<HPBUFFERARB>(_hwnd));
|
// otherwise these routines will return an error.
|
||||||
|
|
||||||
|
if ( !wgle->wglReleasePbufferDCARB(reinterpret_cast<HPBUFFERARB>(_hwnd), _hdc) )
|
||||||
|
{
|
||||||
|
osg::notify(osg::NOTICE) << "PixelBufferWin32::closeImplementation, wglReleasePbufferDCARB error: " << sysError() << std::endl;
|
||||||
|
}
|
||||||
|
if ( !wgle->wglDestroyPbufferARB(reinterpret_cast<HPBUFFERARB>(_hwnd)) )
|
||||||
|
{
|
||||||
|
osg::notify(osg::NOTICE) << "PixelBufferWin32::closeImplementation, wglDestroyPbufferARB error: " << sysError() << std::endl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_valid = false;
|
_valid = false;
|
||||||
@ -721,36 +728,50 @@ void PixelBufferWin32::closeImplementation()
|
|||||||
|
|
||||||
bool PixelBufferWin32::makeCurrentImplementation()
|
bool PixelBufferWin32::makeCurrentImplementation()
|
||||||
{
|
{
|
||||||
WGLExtensions* wgle = WGLExtensions::instance();
|
|
||||||
if (!wgle) return false;
|
|
||||||
|
|
||||||
if (_traits->target != 0)
|
|
||||||
{
|
|
||||||
wgle->wglReleaseTexImageARB(reinterpret_cast<HPBUFFERARB>(_hwnd), WGL_FRONT_LEFT_ARB);
|
|
||||||
wgle->wglReleaseTexImageARB(reinterpret_cast<HPBUFFERARB>(_hwnd), WGL_BACK_LEFT_ARB);
|
|
||||||
}
|
|
||||||
bool result = wglMakeCurrent(_hdc, _hglrc)==TRUE?true:false;
|
bool result = wglMakeCurrent(_hdc, _hglrc)==TRUE?true:false;
|
||||||
if (!result)
|
if (!result)
|
||||||
{
|
{
|
||||||
//doInternalError("wglMakeCurrent() failed");
|
osg::notify(osg::NOTICE) << "PixelBufferWin32::makeCurrentImplementation, wglMakeCurrent error: " << sysError() << std::endl;
|
||||||
osg::notify(osg::NOTICE) << "PixelBufferWin32::makeCurrentImplementation(), failed" << std::endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If the pbuffer is bound to a texture then release it. This operation requires a current context, so
|
||||||
|
// do it after the MakeCurrent.
|
||||||
|
|
||||||
|
if ( _boundBuffer!=0 )
|
||||||
|
{
|
||||||
|
WGLExtensions* wgle = WGLExtensions::instance();
|
||||||
|
if ( wgle && wgle->wglReleaseTexImageARB )
|
||||||
|
{
|
||||||
|
if ( !wgle->wglReleaseTexImageARB(reinterpret_cast<HPBUFFERARB>(_hwnd), _boundBuffer) )
|
||||||
|
{
|
||||||
|
osg::notify(osg::NOTICE) << "PixelBufferWin32::makeCurrentImplementation, wglReleaseTexImageARB error: " << sysError() << std::endl;
|
||||||
|
}
|
||||||
|
_boundBuffer=0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PixelBufferWin32::makeContextCurrentImplementation( GraphicsContext* readContext )
|
bool PixelBufferWin32::makeContextCurrentImplementation( GraphicsContext* readContext )
|
||||||
{
|
{
|
||||||
|
WGLExtensions* wgle = WGLExtensions::instance();
|
||||||
|
|
||||||
|
if ( !wgle || !wgle->wglMakeContextCurrentARB )
|
||||||
|
{
|
||||||
|
osg::notify(osg::NOTICE) << "PixelBufferWin32, wglMakeContextCurrentARB not available" << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
GraphicsWindowWin32* graphicsWindowWin32 = dynamic_cast<GraphicsWindowWin32*>(readContext);
|
GraphicsWindowWin32* graphicsWindowWin32 = dynamic_cast<GraphicsWindowWin32*>(readContext);
|
||||||
if (graphicsWindowWin32)
|
if (graphicsWindowWin32)
|
||||||
{
|
{
|
||||||
if (WGLExtensions::instance()->wglMakeContextCurrentARB(_hdc, graphicsWindowWin32->getHDC(), _hglrc))
|
return wgle->wglMakeContextCurrentARB(_hdc, graphicsWindowWin32->getHDC(), _hglrc);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
PixelBufferWin32* pixelBufferWin32 = dynamic_cast<PixelBufferWin32*>(_traits->sharedContext);
|
PixelBufferWin32* pixelBufferWin32 = dynamic_cast<PixelBufferWin32*>(_traits->sharedContext);
|
||||||
if (pixelBufferWin32)
|
if (pixelBufferWin32)
|
||||||
{
|
{
|
||||||
if (WGLExtensions::instance()->wglMakeContextCurrentARB(_hdc, pixelBufferWin32->getHDC(), _hglrc))
|
return wgle->wglMakeContextCurrentARB(_hdc, pixelBufferWin32->getHDC(), _hglrc);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -768,28 +789,41 @@ bool PixelBufferWin32::releaseContextImplementation()
|
|||||||
|
|
||||||
void PixelBufferWin32::bindPBufferToTextureImplementation( GLenum buffer )
|
void PixelBufferWin32::bindPBufferToTextureImplementation( GLenum buffer )
|
||||||
{
|
{
|
||||||
bool result;
|
|
||||||
|
|
||||||
WGLExtensions* wgle = WGLExtensions::instance();
|
WGLExtensions* wgle = WGLExtensions::instance();
|
||||||
if (!wgle) return;
|
|
||||||
|
if ( !wgle || !wgle->wglBindTexImageARB )
|
||||||
|
{
|
||||||
|
osg::notify(osg::NOTICE) << "PixelBufferWin32, wglBindTexImageARB not available" << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int bindBuffer;
|
||||||
|
|
||||||
switch (buffer)
|
switch (buffer)
|
||||||
{
|
{
|
||||||
case GL_BACK:
|
case GL_BACK:
|
||||||
result = wgle->wglBindTexImageARB(reinterpret_cast<HPBUFFERARB>(_hwnd), WGL_BACK_LEFT_ARB);
|
bindBuffer = WGL_BACK_LEFT_ARB;
|
||||||
break;
|
break;
|
||||||
case GL_FRONT:
|
case GL_FRONT:
|
||||||
result = wgle->wglBindTexImageARB(reinterpret_cast<HPBUFFERARB>(_hwnd), WGL_FRONT_LEFT_ARB);
|
bindBuffer = WGL_FRONT_LEFT_ARB;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
result = wgle->wglBindTexImageARB(reinterpret_cast<HPBUFFERARB>(_hwnd), static_cast<GLenum>(buffer));
|
bindBuffer = static_cast<int>(buffer);
|
||||||
}
|
|
||||||
if (!result)
|
|
||||||
{
|
|
||||||
//doInternalError("wglBindTexImageARB() failed");
|
|
||||||
osg::notify(osg::NOTICE) << "PixelBufferWin32::wglBindTexImageARB(), failed" << std::endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( bindBuffer != _boundBuffer )
|
||||||
|
{
|
||||||
|
if ( _boundBuffer != 0 && !wgle->wglReleaseTexImageARB(reinterpret_cast<HPBUFFERARB>(_hwnd), _boundBuffer) )
|
||||||
|
{
|
||||||
|
osg::notify(osg::NOTICE) << "PixelBufferWin32::bindPBufferToTextureImplementation, wglReleaseTexImageARB error: " << sysError() << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !wgle->wglBindTexImageARB(reinterpret_cast<HPBUFFERARB>(_hwnd), bindBuffer) )
|
||||||
|
{
|
||||||
|
osg::notify(osg::NOTICE) << "PixelBufferWin32::bindPBufferToTextureImplementation, wglBindTexImageARB error: " << sysError() << std::endl;
|
||||||
|
}
|
||||||
|
_boundBuffer = bindBuffer;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PixelBufferWin32::swapBuffersImplementation()
|
void PixelBufferWin32::swapBuffersImplementation()
|
||||||
|
Loading…
Reference in New Issue
Block a user