~ubuntu-branches/ubuntu/trusty/openscenegraph/trusty

« back to all changes in this revision

Viewing changes to OpenSceneGraph/src/osgViewer/PixelBufferWin32.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Cyril Brulebois
  • Date: 2008-07-29 04:34:38 UTC
  • mfrom: (1.1.6 upstream) (2.1.3 lenny)
  • Revision ID: james.westby@ubuntu.com-20080729043438-no1h9h0dpsrlzp1y
* Non-maintainer upload.
* No longer try to detect (using /proc/cpuinfo when available) how many
  CPUs are available, fixing the FTBFS (due to -j0) on various platforms
  (Closes: #477353). The right way to do it is to support parallel=n in
  DEB_BUILD_OPTIONS (see Debian Policy §4.9.1), and adequate support has
  been implemented.
* Add patch to fix FTBFS due to the build system now refusing to handle
  whitespaces (Policy CMP0004 say the logs), thanks to Andreas Putzo who
  provided it (Closes: #482239):
   - debian/patches/fix-cmp0004-build-failure.dpatch
* Remove myself from Uploaders, as requested a while ago, done by Luk in
  his 2.2.0-2.1 NMU, which was never acknowledged.

Show diffs side-by-side

added added

removed removed

Lines of Context:
154
154
namespace 
155
155
{
156
156
 
 
157
static std::string sysError()
 
158
{
 
159
    DWORD stat, err = GetLastError();
 
160
    LPVOID lpMsgBuf = 0;
 
161
 
 
162
    stat = FormatMessage(   FORMAT_MESSAGE_ALLOCATE_BUFFER |
 
163
                     FORMAT_MESSAGE_FROM_SYSTEM |
 
164
                     FORMAT_MESSAGE_IGNORE_INSERTS,
 
165
                     NULL,
 
166
                     err,
 
167
                     MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
 
168
                     (LPTSTR) &lpMsgBuf,\
 
169
                     0,NULL 
 
170
                     );
 
171
 
 
172
    std::ostringstream msgResult;
 
173
    if ( stat > 0 && lpMsgBuf )
 
174
    {
 
175
        msgResult << (LPCTSTR)lpMsgBuf;
 
176
        LocalFree( lpMsgBuf );
 
177
    }
 
178
    else
 
179
    {
 
180
        msgResult << "Error code " << err;
 
181
    }
 
182
    
 
183
    return msgResult.str();
 
184
}
 
185
 
 
186
 
157
187
    static int __tempwnd_id = 0;
158
188
class TemporaryWindow: public osg::Referenced
159
189
{
233
263
                                    _instance,
234
264
                                    0)))
235
265
    {
 
266
        osg::notify(osg::WARN) << "PixelBufferWin32, could not create temporary window: " << sysError() << std::endl;
236
267
        kill();
237
268
        return;
238
269
    }
239
270
 
240
271
    if (!(_dc = GetDC(_handle)))
241
272
    {
 
273
        osg::notify(osg::WARN) << "PixelBufferWin32, could not get device context for temporary window: " << sysError() << std::endl;
242
274
        kill();
243
275
        return;
244
276
    }
267
299
 
268
300
    if (!SetPixelFormat(_dc, visual_id, &pfd))
269
301
    {
 
302
        osg::notify(osg::WARN) << "PixelBufferWin32, could not set pixel format for temporary window: " << sysError() << std::endl;
270
303
        kill();
271
304
        return;
272
305
    }
273
306
 
274
307
    if (!(_context = wglCreateContext(_dc)))
275
308
    {
 
309
        osg::notify(osg::WARN) << "PixelBufferWin32, could not get graphics context for temporary window: " << sysError() << std::endl;
276
310
        kill();
277
311
        return;
278
312
    }
313
347
 
314
348
bool TemporaryWindow::makeCurrent()
315
349
{
316
 
    return wglMakeCurrent(_dc, _context) == TRUE ? true : false;
 
350
    bool result = wglMakeCurrent(_dc, _context) == TRUE ? true : false;
 
351
    if (!result)
 
352
    {
 
353
        osg::notify(osg::NOTICE) << "PixelBufferWin32, could not make the temporary window's context active: " << sysError() << std::endl;
 
354
    }
 
355
    return result;
317
356
}
318
357
 
319
358
class WGLExtensions : public osg::Referenced
377
416
bool WGLExtensions::isValid()
378
417
{
379
418
    return (wglCreatePbufferARB && wglGetPbufferDCARB && wglReleasePbufferDCARB && wglDestroyPbufferARB &&
380
 
        wglQueryPbufferARB && wglBindTexImageARB && wglReleaseTexImageARB && wglChoosePixelFormatARB && 
381
 
        wglMakeContextCurrentARB);
 
419
        wglQueryPbufferARB && wglChoosePixelFormatARB );
382
420
}
383
421
 
384
 
osg::ref_ptr<TemporaryWindow> __default_wnd;
385
422
WGLExtensions *WGLExtensions::instance()
386
423
{
387
424
    HGLRC context = wglGetCurrentContext();
388
 
    bool nocontext = (context == 0);
389
 
 
390
 
    if (nocontext || !__default_wnd.valid())
391
 
    {
392
 
        if (!__default_wnd.valid() || !__default_wnd->getHandle())
393
 
        {
394
 
            __default_wnd = new TemporaryWindow;
395
 
            if (!__default_wnd ->getHandle())
396
 
            {
397
 
                osg::notify(osg::NOTICE) << "WGLExtensions: could not create and initialize the temporary window" << std::endl;
398
 
                return 0;
399
 
            }
400
 
        }
401
 
 
402
 
        context = __default_wnd->getContext();
403
 
        if (!__default_wnd->makeCurrent())
404
 
        {
405
 
            osg::notify(osg::NOTICE) << "WGLExtensions: could not make the temporary window's context active" << std::endl;
406
 
        }
407
 
    }
408
 
 
 
425
    
 
426
    // Get wgl function pointers for the current graphics context, or if there is no
 
427
    // current context then use a temporary window.
409
428
 
410
429
    if (!_instances[context])
411
430
    {
412
 
        _instances[context] = new WGLExtensions;
 
431
        if ( context == 0 )
 
432
        {
 
433
            osg::ref_ptr<TemporaryWindow> tempWin= new TemporaryWindow;
 
434
            tempWin->makeCurrent();
 
435
            _instances[0] = new WGLExtensions;
 
436
        }
 
437
        else
 
438
        {
 
439
            _instances[context] = new WGLExtensions;
 
440
        }
413
441
    }
414
442
 
415
443
    return _instances[context].get();
427
455
  _hglrc(0),
428
456
  _initialized(false),
429
457
  _valid(false),
430
 
  _realized(false)
 
458
  _realized(false),
 
459
  _boundBuffer(0)
431
460
{
432
461
    _traits = traits;
433
462
 
454
483
{
455
484
    closeImplementation();
456
485
}
457
 
 
458
 
static void doInternalError( char *msg )
459
 
{
460
 
    DWORD err = GetLastError();
461
 
    LPVOID lpMsgBuf = 0;
462
 
    FormatMessage(   FORMAT_MESSAGE_ALLOCATE_BUFFER |
463
 
                     FORMAT_MESSAGE_FROM_SYSTEM |
464
 
                     FORMAT_MESSAGE_IGNORE_INSERTS,
465
 
                     NULL,
466
 
                     err,
467
 
                     MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
468
 
                     (LPTSTR) &lpMsgBuf,\
469
 
                     0,NULL 
470
 
                     );
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 );
474
 
}
475
486
    
476
487
void PixelBufferWin32::init()
477
488
{
479
490
    if (!_traits) return;
480
491
    if (!_traits->pbuffer) return;
481
492
 
482
 
    struct RestoreContext
483
 
    {
484
 
        RestoreContext()
485
 
        {
486
 
            _hdc = wglGetCurrentDC();
487
 
            _hglrc = wglGetCurrentContext();
488
 
        }
489
 
        ~RestoreContext()
490
 
        {
491
 
            if (_hdc)
492
 
            {
493
 
                wglMakeCurrent(_hdc,_hglrc);
494
 
            }
495
 
        }
496
 
    protected:
497
 
        HDC        _hdc;
498
 
        HGLRC    _hglrc;
499
 
    } restoreContext;
500
 
 
501
493
    WGLExtensions* wgle = WGLExtensions::instance();
502
494
 
503
495
    if (!wgle || !wgle->isValid())
555
547
        fAttribList.push_back(true);
556
548
    }
557
549
 
558
 
    if (_traits->target != 0)
 
550
    if (_traits->target != 0 && wgle->wglBindTexImageARB )
559
551
    {
560
552
        // TODO: Cube Maps
561
553
       if (_traits->target == GL_TEXTURE_RECTANGLE)
621
613
    _hwnd = reinterpret_cast<HWND>(wgle->wglCreatePbufferARB(hdc, format, _traits->width, _traits->height, &bAttribList[0]));
622
614
    if (!_hwnd)
623
615
    {
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;
626
617
        return ;
627
618
    }
628
619
 
629
620
    _hdc = wgle->wglGetPbufferDCARB(reinterpret_cast<HPBUFFERARB>(_hwnd));
630
621
    if (!_hdc)
631
622
    {
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;
634
624
        return;
635
625
    }
636
626
 
637
627
    _hglrc = wglCreateContext(_hdc);
638
628
    if (!_hglrc)
639
629
    {
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;
642
631
        return;
643
632
    }
644
633
 
692
681
            }
693
682
        }
694
683
 
695
 
        wglShareLists(hglrc, _hglrc);
 
684
        if ( !wglShareLists(hglrc, _hglrc) )
 
685
        {
 
686
            osg::notify(osg::NOTICE) << "PixelBufferWin32::realizeImplementation, wglShareLists error: " << sysError() << std::endl;
 
687
        }
696
688
    }
697
689
 
698
690
    _realized = true;
703
695
{
704
696
    if (_hwnd)
705
697
    {
706
 
        wglDeleteContext(_hglrc);
707
 
 
708
698
        WGLExtensions* wgle = WGLExtensions::instance();
 
699
 
 
700
        wglMakeCurrent(NULL,NULL);
 
701
 
 
702
        if ( !wglDeleteContext(_hglrc) )
 
703
        {
 
704
            osg::notify(osg::NOTICE) << "PixelBufferWin32::closeImplementation, wglDeleteContext error: " << sysError() << std::endl;
 
705
        }
 
706
 
709
707
        if (wgle && wgle->isValid())
710
708
        {
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.
 
711
 
 
712
            if ( !wgle->wglReleasePbufferDCARB(reinterpret_cast<HPBUFFERARB>(_hwnd), _hdc) )
 
713
            {
 
714
                osg::notify(osg::NOTICE) << "PixelBufferWin32::closeImplementation, wglReleasePbufferDCARB error: " << sysError() << std::endl;
 
715
            }
 
716
            if ( !wgle->wglDestroyPbufferARB(reinterpret_cast<HPBUFFERARB>(_hwnd)) )
 
717
            {
 
718
                osg::notify(osg::NOTICE) << "PixelBufferWin32::closeImplementation, wglDestroyPbufferARB error: " << sysError() << std::endl;
 
719
            }
713
720
        }
714
721
    }
715
722
    _valid = false;
721
728
 
722
729
bool PixelBufferWin32::makeCurrentImplementation()
723
730
{
724
 
    WGLExtensions* wgle = WGLExtensions::instance();
725
 
    if (!wgle) return false;
726
 
 
727
 
    if (_traits->target != 0)
728
 
    {
729
 
        wgle->wglReleaseTexImageARB(reinterpret_cast<HPBUFFERARB>(_hwnd), WGL_FRONT_LEFT_ARB);
730
 
        wgle->wglReleaseTexImageARB(reinterpret_cast<HPBUFFERARB>(_hwnd), WGL_BACK_LEFT_ARB);
731
 
    }
732
731
    bool result = wglMakeCurrent(_hdc, _hglrc)==TRUE?true:false;
733
732
    if (!result)
734
733
    {
735
 
        //doInternalError("wglMakeCurrent() failed");
736
 
        osg::notify(osg::NOTICE) << "PixelBufferWin32::makeCurrentImplementation(), failed" << std::endl;
737
 
    }
 
734
        osg::notify(osg::NOTICE) << "PixelBufferWin32::makeCurrentImplementation, wglMakeCurrent error: " << sysError() << std::endl;
 
735
    }
 
736
 
 
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.
 
739
    
 
740
    if ( _boundBuffer!=0 )
 
741
    {
 
742
        WGLExtensions* wgle = WGLExtensions::instance();
 
743
        if ( wgle && wgle->wglReleaseTexImageARB )
 
744
        {
 
745
            if ( !wgle->wglReleaseTexImageARB(reinterpret_cast<HPBUFFERARB>(_hwnd), _boundBuffer) )
 
746
            {
 
747
                osg::notify(osg::NOTICE) << "PixelBufferWin32::makeCurrentImplementation, wglReleaseTexImageARB error: " << sysError() << std::endl;
 
748
            }
 
749
            _boundBuffer=0;
 
750
        }
 
751
    }
 
752
 
738
753
    return result;
739
754
}
740
755
        
741
756
bool PixelBufferWin32::makeContextCurrentImplementation( GraphicsContext* readContext )
742
757
{
 
758
    WGLExtensions* wgle = WGLExtensions::instance();
 
759
 
 
760
    if ( !wgle || !wgle->wglMakeContextCurrentARB )
 
761
    {
 
762
        osg::notify(osg::NOTICE) << "PixelBufferWin32, wglMakeContextCurrentARB not available" << std::endl;
 
763
        return false;
 
764
    }
 
765
 
743
766
    GraphicsWindowWin32* graphicsWindowWin32 = dynamic_cast<GraphicsWindowWin32*>(readContext);
744
767
    if (graphicsWindowWin32) 
745
768
    {
746
 
        if (WGLExtensions::instance()->wglMakeContextCurrentARB(_hdc, graphicsWindowWin32->getHDC(), _hglrc))
747
 
            return true;
 
769
        return wgle->wglMakeContextCurrentARB(_hdc, graphicsWindowWin32->getHDC(), _hglrc);
748
770
    }
749
771
    PixelBufferWin32* pixelBufferWin32 = dynamic_cast<PixelBufferWin32*>(_traits->sharedContext);
750
772
    if (pixelBufferWin32)
751
773
    {
752
 
        if (WGLExtensions::instance()->wglMakeContextCurrentARB(_hdc, pixelBufferWin32->getHDC(), _hglrc))
753
 
            return true;
 
774
        return wgle->wglMakeContextCurrentARB(_hdc, pixelBufferWin32->getHDC(), _hglrc);
754
775
    }
755
776
    return false;
756
777
}
768
789
 
769
790
void PixelBufferWin32::bindPBufferToTextureImplementation( GLenum buffer )
770
791
{
771
 
    bool result;
772
 
 
773
792
    WGLExtensions* wgle = WGLExtensions::instance();
774
 
    if (!wgle) return;
 
793
    
 
794
    if ( !wgle || !wgle->wglBindTexImageARB )
 
795
    {
 
796
        osg::notify(osg::NOTICE) << "PixelBufferWin32, wglBindTexImageARB not available" << std::endl;
 
797
        return;
 
798
    }
 
799
 
 
800
    int bindBuffer;
775
801
 
776
802
    switch (buffer)
777
803
    {
778
804
        case GL_BACK:
779
 
            result = wgle->wglBindTexImageARB(reinterpret_cast<HPBUFFERARB>(_hwnd), WGL_BACK_LEFT_ARB);
 
805
            bindBuffer = WGL_BACK_LEFT_ARB;
780
806
            break;
781
807
        case GL_FRONT:
782
 
            result = wgle->wglBindTexImageARB(reinterpret_cast<HPBUFFERARB>(_hwnd), WGL_FRONT_LEFT_ARB);
 
808
            bindBuffer = WGL_FRONT_LEFT_ARB;
783
809
            break;
784
810
        default:
785
 
            result = wgle->wglBindTexImageARB(reinterpret_cast<HPBUFFERARB>(_hwnd), static_cast<GLenum>(buffer));
786
 
    } 
787
 
    if (!result)
 
811
            bindBuffer = static_cast<int>(buffer);
 
812
    }
 
813
    
 
814
    if ( bindBuffer != _boundBuffer )
788
815
    {
789
 
        //doInternalError("wglBindTexImageARB() failed");
790
 
        osg::notify(osg::NOTICE) << "PixelBufferWin32::wglBindTexImageARB(), failed" << std::endl;
791
 
    }
792
 
        
 
816
        if ( _boundBuffer != 0 && !wgle->wglReleaseTexImageARB(reinterpret_cast<HPBUFFERARB>(_hwnd), _boundBuffer) )
 
817
        {
 
818
            osg::notify(osg::NOTICE) << "PixelBufferWin32::bindPBufferToTextureImplementation, wglReleaseTexImageARB error: " << sysError() << std::endl;
 
819
        }
 
820
 
 
821
        if ( !wgle->wglBindTexImageARB(reinterpret_cast<HPBUFFERARB>(_hwnd), bindBuffer) )
 
822
        {
 
823
            osg::notify(osg::NOTICE) << "PixelBufferWin32::bindPBufferToTextureImplementation, wglBindTexImageARB error: " << sysError() << std::endl;
 
824
        }
 
825
        _boundBuffer = bindBuffer;
 
826
    }       
793
827
}
794
828
 
795
829
void PixelBufferWin32::swapBuffersImplementation()