00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043 #include <cstdlib>
00044 #include <cstdio>
00045
00046 #include "OSGConfig.h"
00047
00048 #include "OSGGLU.h"
00049
00050 #if !defined(WIN32) && !defined(__APPLE__) && !defined(OSG_EMBEDDED)
00051 #include <GL/glx.h>
00052 #endif
00053
00054 #if defined(OSG_EMBEDDED) && defined(WIN32)
00055 #include <gles/egl.h>
00056 #endif
00057
00058 #if defined(__sgi) || defined(__APPLE__) || defined(__linux)
00059 #include <dlfcn.h>
00060 #endif
00061
00062 #if defined(__APPLE__)
00063 #include <mach-o/dyld.h>
00064 #endif
00065
00066 #if defined(__sun)
00067 #include <dlfcn.h>
00068 #include <link.h>
00069 #endif
00070
00071 #include "OSGBaseFunctions.h"
00072
00073 #include "OSGViewport.h"
00074
00075 #include "OSGBackground.h"
00076 #include "OSGCamera.h"
00077 #include "OSGWindow.h"
00078
00079 #include "OSGRenderActionBase.h"
00080
00081 #include "OSGStageValidator.h"
00082
00083 #ifdef OSG_NEW_SHADER
00084 #include "OSGShaderCache.h"
00085 #endif
00086
00087
00088
00089 OSG_BEGIN_NAMESPACE
00090
00091 #if defined(OSG_WIN32_ICL) && !defined(OSG_CHECK_FIELDSETARG)
00092 #pragma warning (disable)
00093 #endif
00094
00095
00096 #define TRY_USING_GLXGETPROC_DIRECTLY 1
00097
00098
00099
00100
00101
00187
00188
00217
00218
00219
00220
00225 Window::WindowStore OSG::Window::_allWindows;
00226 Int32 OSG::Window::_currentWindowId = 0;
00227
00228
00229
00230 #ifndef OSG_EMBEDDED
00231
00236 LockRefPtr OSG::Window::_GLObjectLock = NULL;
00237
00242 LockRefPtr OSG::Window::_staticWindowLock = NULL;
00243 #endif
00244
00249 std::vector<OSG::Window::GLObject *> OSG::Window::_glObjects;
00250
00251
00252
00253
00254
00255
00256 const Char8 *OSG::Window::_glLibraryName = NULL;
00257
00258 std::vector<std::string > OSG::Window::_registeredExtensions;
00259 std::vector<std::string > OSG::Window::_ignoredExtensions;
00260 std::vector<bool > OSG::Window::_commonExtensions;
00261 std::vector<std::string > OSG::Window::_registeredFunctions;
00262 std::vector<Int32 > OSG::Window::_registeredFunctionExts;
00263 std::vector<UInt32 > OSG::Window::_registeredFunctionVersions;
00264
00265
00266
00267 std::vector<GLenum > OSG::Window::_registeredConstants;
00268
00269
00270
00271
00272 const Real32 OSG::Window::unknownConstant = TypeTraits<Real32>::getMax();
00273
00274
00275
00276
00277
00278
00279
00280
00281
00285 void OSG::Window::initMethod(InitPhase ePhase)
00286 {
00287 Inherited::initMethod(ePhase);
00288 }
00289
00290 bool OSG::Window::cleanup(void)
00291 {
00292 #ifndef OSG_EMBEDDED
00293 _staticWindowLock = NULL;
00294 _GLObjectLock = NULL;
00295 #endif
00296
00297 for(UInt32 i = 0; i < _glObjects.size(); ++i)
00298 {
00299 delete _glObjects[i];
00300 }
00301
00302 return true;
00303 }
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00319 OSG::Window::Window(void) :
00320 Inherited ( ),
00321 _glObjectDestroyList( ),
00322 _lastValidate ( ),
00323 _ids ( ),
00324 _glVersion ( ),
00325 _extensions ( ),
00326 _availExtensions ( ),
00327 _extFunctions ( ),
00328 _availConstants ( ),
00329 _numAvailConstants ( ),
00330 _windowId ( -1),
00331 _pStageValidator (NULL),
00332 _pShaderCache (NULL),
00333
00334 _pWaitTask (NULL),
00335 _pSwapTask (NULL),
00336 _pFrameInitTask (NULL),
00337 _pFrameExitTask (NULL),
00338 _pActivateTask (NULL),
00339 _oEnv ( )
00340 {
00341
00342 _oEnv.setWindow(this);
00343 }
00344
00348 OSG::Window::Window(const Window &source) :
00349 Inherited (source ),
00350 _glObjectDestroyList(source._glObjectDestroyList ),
00351 _lastValidate (source._lastValidate.size(), 0),
00352 _ids (source._ids.size(), 0),
00353 _extensions ( ),
00354 _availExtensions ( ),
00355 _extFunctions ( ),
00356 _availConstants ( ),
00357 _numAvailConstants ( 0),
00358 _windowId ( -1),
00359 _pStageValidator (NULL ),
00360 _pShaderCache (NULL ),
00361 _pWaitTask (NULL ),
00362 _pSwapTask (NULL ),
00363 _pFrameInitTask (NULL ),
00364 _pFrameExitTask (NULL ),
00365 _pActivateTask (NULL ),
00366 _oEnv ( )
00367 {
00368 _oEnv.setWindow(this);
00369 }
00370
00374 OSG::Window::~Window(void)
00375 {
00376
00377 }
00378
00379
00380
00381
00382
00383
00387 void OSG::Window::onCreate(const Window *source)
00388 {
00389 Inherited::onCreate(source);
00390
00391
00392 if(GlobalSystemState != Running)
00393 return;
00394
00395 if(source != NULL)
00396 {
00397
00398 doResetGLObjectStatus(1, _glObjects.size() - 1);
00399 }
00400
00401 _allWindows.push_back(this);
00402
00403 _windowId = _currentWindowId++;
00404
00405 _pContextThread = WindowDrawThread::get(NULL, false);
00406 }
00407
00408 void OSG::Window::onCreateAspect(const Window *createAspect,
00409 const Window *source)
00410 {
00411 Inherited::onCreateAspect(createAspect, source);
00412
00413
00414 if(GlobalSystemState != Running)
00415 return;
00416
00417 if(createAspect != NULL)
00418 {
00419 _windowId = createAspect->_windowId;
00420 }
00421
00422 _pStageValidator = new StageValidator;
00423 #ifdef OSG_NEW_SHADER
00424 _pShaderCache = new ShaderCache;
00425 #endif
00426 }
00427
00431 void OSG::Window::onDestroy(UInt32 uiContainerId)
00432 {
00433
00434 for(UInt32 i = 1; i < _glObjects.size(); ++i)
00435 {
00436 GLObject *obj = _glObjects[i];
00437
00438 if(obj == NULL)
00439 {
00440 FDEBUG(("Window::onDestroy: object %u already destroyed!\n", i));
00441 continue;
00442 }
00443
00444
00445 if(i < getMFGlObjectLastReinitialize()->size() &&
00446 getGlObjectLastReinitialize(i) != 0)
00447 {
00448 obj->decRefCounter();
00449
00450
00451
00452 }
00453 }
00454
00455 WindowStore::iterator winIt;
00456
00457 winIt = std::find(_allWindows.begin(),
00458 _allWindows.end (),
00459 this);
00460
00461
00462
00463 if(winIt != _allWindows.end())
00464 _allWindows.erase(winIt);
00465
00466 Inherited::onDestroy(uiContainerId);
00467 }
00468
00469 void OSG::Window::onDestroyAspect(UInt32 uiContainerId,
00470 UInt32 uiAspect )
00471 {
00472 delete _pStageValidator;
00473 #ifdef OSG_NEW_SHADER
00474 delete _pShaderCache;
00475 #endif
00476
00477 _pStageValidator = NULL;
00478 _pShaderCache = NULL;
00479
00480 _pWaitTask = NULL;
00481 _pSwapTask = NULL;
00482 _pFrameInitTask = NULL;
00483 _pFrameExitTask = NULL;
00484 _pActivateTask = NULL;
00485
00486 if(_pAspectStore->getRefCount() == 1 && _pContextThread != NULL)
00487 {
00488 fprintf(stderr, "Terminate context thread %p\n", this);
00489
00490 _pContextThread->queueTask(
00491 new WindowDrawTask(WindowDrawTask::EndThread));
00492
00493 Thread::join(_pContextThread);
00494 }
00495
00496 _pContextThread = NULL;
00497
00498 Inherited::onDestroyAspect(uiContainerId, uiAspect);
00499 }
00500
00501 void OSG::Window::staticAcquire(void)
00502 {
00503
00504 if(GlobalSystemState != Running)
00505 return;
00506
00507 #ifndef OSG_EMBEDDED
00508 if(_staticWindowLock == NULL)
00509 {
00510 _staticWindowLock =
00511 ThreadManager::the()->getLock("OSG::Window::_staticWindowLock",
00512 false);
00513
00514 addPostFactoryExitFunction(&Window::cleanup);
00515 }
00516 _staticWindowLock->acquire();
00517 #endif
00518 }
00519
00520 void OSG::Window::staticRelease(void)
00521 {
00522
00523 if(GlobalSystemState != Running)
00524 return;
00525
00526 #ifndef OSG_EMBEDDED
00527 _staticWindowLock->release();
00528 #endif
00529 }
00530
00531
00532
00533
00534
00538 void OSG::Window::changed(ConstFieldMaskArg whichField,
00539 UInt32 origin,
00540 BitVector details)
00541 {
00542 Inherited::changed(whichField, origin, details);
00543 }
00544
00545
00546
00547 #if !defined(OSG_DO_DOC) || defined(OSG_DOC_EXT)
00548
00549
00550
00559 UInt32 OSG::Window::registerGLObject(GLObjectFunctor functor,
00560 GLObjectDestroyFunctor destroy,
00561 UInt32 num)
00562 {
00563 UInt32 osgId, i;
00564 GLObject *pGLObject;
00565
00566 staticAcquire();
00567
00568
00569 if(_glObjects.empty())
00570 _glObjects.push_back(NULL);
00571
00572 osgId = _glObjects.size();
00573 pGLObject = new GLObject(functor, destroy);
00574
00575
00576
00577 if(_glObjects.capacity() >= osgId + num)
00578 {
00579 _glObjects.insert(_glObjects.end(), num, pGLObject );
00580
00581 resetGLObjectStatus(osgId, num);
00582
00583 staticRelease();
00584
00585 return osgId;
00586 }
00587
00588
00589
00590 UInt32 cnt = 0;
00591
00592
00593 for(i = 1; i < _glObjects.size(); ++i)
00594 {
00595 if(_glObjects[i] == NULL)
00596 {
00597 if(cnt == 0)
00598 {
00599 osgId = i;
00600 }
00601
00602 ++cnt;
00603
00604 if(cnt == num)
00605 {
00606
00607
00608 while(i >= osgId)
00609 {
00610 _glObjects[i] = pGLObject;
00611 i = i - 1;
00612 }
00613
00614 resetGLObjectStatus(osgId, num);
00615
00616 staticRelease();
00617
00618 return osgId;
00619 }
00620 }
00621 else
00622 {
00623 cnt = 0;
00624 osgId = 0;
00625 }
00626 }
00627
00628
00629
00630 if(osgId > 0)
00631 {
00632
00633 i = osgId + cnt - 1;
00634
00635 while(i >= osgId)
00636 {
00637 _glObjects[i] = pGLObject;
00638
00639 i = i - 1;
00640 }
00641 }
00642 else
00643 {
00644
00645 osgId = _glObjects.size();
00646 }
00647
00648
00649 for(i = 1; i <= num - cnt; i++)
00650 {
00651 _glObjects.push_back(pGLObject);
00652 }
00653
00654 resetGLObjectStatus(osgId, num);
00655
00656 staticRelease();
00657
00658 return osgId;
00659 }
00660
00667 UInt32 OSG::Window::validateGLObject(UInt32 osgId,
00668 DrawEnv *pEnv,
00669 UInt32 uiOptions)
00670 {
00671 UInt32 returnValue = 0;
00672
00673 if ( osgId == 0 )
00674 {
00675 SWARNING << "Window::validateGLObject: id is 0!" << std::endl;
00676 return returnValue;
00677 }
00678
00679 GLObject *obj = _glObjects[osgId];
00680
00681 if(obj == NULL)
00682 {
00683 SWARNING << "Window::validateGLObject: obj with id " << osgId
00684 <<" is NULL!" << std::endl;
00685 return returnValue;
00686 }
00687
00688 if(osgId >= _lastValidate.size())
00689 {
00690
00691
00692
00693
00694
00695 _lastValidate.resize(osgId + 1, 0);
00696 }
00697
00698 if(osgId >= _mfGlObjectLastReinitialize.size())
00699 {
00700 editMField( GlObjectLastReinitializeFieldId,
00701 _mfGlObjectLastReinitialize );
00702
00703 _mfGlObjectLastReinitialize.resize(osgId + 1, 0);
00704 }
00705
00706 FDEBUG(("Window 0x%p (event %d,ri:%d,rf:%d): "
00707 "Validating object %d: last reinit:%d, last validate:"
00708 "%d last refresh: %d => %s\n",
00709 this, getGlObjectEventCounter(),
00710 _mfGlObjectLastReinitialize.size(),
00711 _mfGlObjectLastRefresh.size(),
00712 osgId,
00713 (_mfGlObjectLastReinitialize.size() > osgId)?
00714 _mfGlObjectLastReinitialize[osgId]:0xffffffff,
00715 _lastValidate[osgId],
00716 (_mfGlObjectLastRefresh.size() > osgId)?
00717 _mfGlObjectLastRefresh[osgId]:0xffffffff,
00718 (_mfGlObjectLastReinitialize[osgId] == 0)?"init":
00719 ((_mfGlObjectLastReinitialize[osgId] > _lastValidate[osgId])?"reinit":
00720 ((_mfGlObjectLastRefresh[osgId] > _lastValidate[osgId])?"refresh":
00721 "up-to-date"))
00722 ));
00723
00724 if(_mfGlObjectLastReinitialize[osgId] == 0)
00725 {
00726 editMField( GlObjectLastReinitializeFieldId,
00727 _mfGlObjectLastReinitialize );
00728
00729 obj->incRefCounter();
00730 returnValue = obj->getFunctor()(pEnv, osgId, initialize, uiOptions);
00731 _mfGlObjectLastReinitialize[osgId] = 1;
00732 _lastValidate[osgId] = getGlObjectEventCounter();
00733 }
00734 else if(_mfGlObjectLastReinitialize[osgId] > _lastValidate[osgId])
00735 {
00736 returnValue = obj->getFunctor()(pEnv, osgId, reinitialize, uiOptions);
00737 _lastValidate[osgId] = getGlObjectEventCounter();
00738 }
00739 else if(_mfGlObjectLastRefresh[osgId] > _lastValidate[osgId])
00740 {
00741 returnValue = obj->getFunctor()(pEnv, osgId, needrefresh, uiOptions);
00742 _lastValidate[osgId] = getGlObjectEventCounter();
00743 }
00744
00745 return returnValue;
00746 }
00747
00754 void OSG::Window::validateAllGLObjects(void)
00755 {
00756 if((_sfDrawMode.getValue() & PartitionDrawMask) == SequentialPartitionDraw)
00757 {
00758 activate();
00759 doFrameInit();
00760
00761 for (UInt32 i = 1; i < _glObjects.size(); ++i)
00762 {
00763 if(_glObjects[i] != NULL)
00764 validateGLObject(i, &_oEnv);
00765 }
00766
00767 doFrameExit();
00768 deactivate();
00769 }
00770 else if((_sfDrawMode.getValue() & PartitionDrawMask) ==
00771 ParallelPartitionDraw)
00772 {
00773 fprintf(stderr, "Window::validateAllGLObjects::pardraw NI\n");
00774 }
00775 else
00776 {
00777 fprintf(stderr, "Unknow partition draw mode\n");
00778 }
00779 }
00780
00788 void OSG::Window::refreshGLObject(UInt32 osgId)
00789 {
00790 if(osgId == 0)
00791 {
00792 SWARNING << "Window::refreshGLObject: id is 0!" << std::endl;
00793 return;
00794 }
00795
00796 staticAcquire();
00797
00798 doRefreshGLObject(osgId);
00799
00800 staticRelease();
00801 }
00802
00808 void OSG::Window::refreshAllGLObjects(void)
00809 {
00810 staticAcquire();
00811
00812 for(UInt32 i = 1; i < _glObjects.size(); ++i)
00813 doRefreshGLObject(i);
00814
00815 staticRelease();
00816 }
00817
00822 void Window::doRefreshGLObject(UInt32 osgId)
00823 {
00824 WindowStore::const_iterator winIt = _allWindows.begin();
00825 WindowStore::const_iterator winEnd = _allWindows.end ();
00826
00827 for(; winIt != winEnd; ++winIt)
00828 {
00829 Window *pWin = *winIt;
00830
00831 if(pWin == NULL)
00832 continue;
00833
00834 pWin->editMField(GlObjectLastRefreshFieldMask,
00835 pWin->_mfGlObjectLastRefresh);
00836
00837 UInt32 lastinv = pWin->getGlObjectEventCounter() + 1;
00838
00839 MFUInt32 &field = pWin->_mfGlObjectLastRefresh;
00840
00841 if(field.size() <= osgId)
00842 field.resize(osgId + 1, 0);
00843
00844 field[osgId] = lastinv;
00845
00846 pWin->setGlObjectEventCounter(lastinv);
00847 }
00848 }
00849
00850
00859 void OSG::Window::reinitializeGLObject(UInt32 osgId)
00860 {
00861 if ( osgId == 0 )
00862 {
00863 SWARNING << "Window::reinitializeGLObject: id is 0!" << std::endl;
00864 return;
00865 }
00866
00867 staticAcquire();
00868
00869 doReinitializeGLObject(osgId);
00870
00871 staticRelease();
00872 }
00873
00879 void OSG::Window::reinitializeAllGLObjects(void)
00880 {
00881 staticAcquire();
00882
00883 for(UInt32 i = 1; i < _glObjects.size(); ++i)
00884 doReinitializeGLObject(i);
00885
00886 staticRelease();
00887 }
00888
00894 void Window::doReinitializeGLObject(UInt32 osgId)
00895 {
00896 WindowStore::const_iterator winIt = _allWindows.begin();
00897 WindowStore::const_iterator winEnd = _allWindows.end ();
00898
00899 for(; winIt != winEnd; ++winIt)
00900 {
00901 Window *pWin = *winIt;
00902
00903 if(pWin == NULL)
00904 continue;
00905
00906 pWin->editMField(GlObjectLastReinitializeFieldMask,
00907 pWin->_mfGlObjectLastReinitialize);
00908
00909 UInt32 lastinv = pWin->getGlObjectEventCounter() + 1;
00910
00911 MFUInt32 &field = pWin->_mfGlObjectLastReinitialize;
00912
00913 if(field.size() <= osgId)
00914 field.resize(osgId + 1, 0);
00915
00916
00917 if(field[osgId] == 0)
00918 continue;
00919
00920 field[osgId] = lastinv;
00921
00922 pWin->setGlObjectEventCounter(lastinv);
00923 }
00924 }
00925
00926
00934 void Window::resetGLObjectStatus(UInt32 osgId, UInt32 num)
00935 {
00936 if(osgId == 0)
00937 {
00938 SWARNING << "Window::resetGLObject: osgId is 0." << std::endl;
00939 return;
00940 }
00941
00942 WindowStore::const_iterator winIt = _allWindows.begin();
00943 WindowStore::const_iterator winEnd = _allWindows.end ();
00944
00945 for(; winIt != winEnd; ++winIt)
00946 {
00947 Window *pWin = *winIt;
00948
00949 if(pWin == NULL)
00950 continue;
00951
00952 pWin->doResetGLObjectStatus(osgId, num);
00953 }
00954 }
00955
00962 void Window::doResetGLObjectStatus(UInt32 osgId, UInt32 num)
00963 {
00964 editMField(GlObjectLastReinitializeFieldMask, _mfGlObjectLastReinitialize);
00965 editMField(GlObjectLastRefreshFieldMask, _mfGlObjectLastRefresh );
00966
00967 if(_mfGlObjectLastReinitialize.size() < osgId + num)
00968 _mfGlObjectLastReinitialize.resize(osgId + num, 0);
00969
00970 if(_mfGlObjectLastRefresh.size() < osgId + num)
00971 _mfGlObjectLastRefresh.resize(osgId + num, 0);
00972
00973 if(_lastValidate.size() < osgId + num)
00974 _lastValidate.resize(osgId + num, 0);
00975
00976 for(UInt32 i = osgId; i < osgId + num; ++i)
00977 {
00978 _mfGlObjectLastReinitialize[i] = 0;
00979 _mfGlObjectLastRefresh [i] = 0;
00980 _lastValidate [i] = 0;
00981 }
00982 }
00983
00991 void OSG::Window::destroyGLObject(UInt32 osgId, UInt32 num)
00992 {
00993 #ifdef OSG_DEBUG
00994 if(osgId >= _glObjects.size() || _glObjects[osgId] == NULL)
00995 {
00996 FWARNING(("Window::destroyGLObject: object %d is NULL!\n", osgId));
00997 return;
00998 }
00999 #endif
01000
01001
01002 if(_glObjects[osgId] && _glObjects[osgId]->getRefCounter() == 0)
01003 {
01004 if(_glObjects[osgId])
01005 delete _glObjects[osgId];
01006
01007 for(UInt32 j = 0; j < num ; j++)
01008 {
01009 _glObjects[osgId + j] = NULL;
01010 }
01011
01012 return;
01013 }
01014
01015 WindowStore::const_iterator winIt = _allWindows.begin();
01016 WindowStore::const_iterator winEnd = _allWindows.end ();
01017
01018 for(; winIt != winEnd; ++winIt)
01019 {
01020 Window *pWin = *winIt;
01021
01022 if(pWin == NULL)
01023 continue;
01024
01025 if(osgId + num > pWin->_mfGlObjectLastReinitialize.size())
01026 {
01027
01028
01029
01030
01031 #ifdef OSG_DEBUG
01032 FWARNING(("Window::destroyGLObject: id %d + num %d exceed "
01033 "registered objects size %d!\n", osgId, num,
01034 pWin->_mfGlObjectLastReinitialize.size()));
01035 #endif
01036 continue;
01037 }
01038
01039
01040 if(pWin->getGlObjectLastReinitialize(osgId) != 0)
01041 pWin->_glObjectDestroyList.push_back(DestroyEntry(osgId, num));
01042 }
01043 }
01044
01045
01046
01047
01048
01054 UInt32 OSG::Window::registerExtension(const Char8 *s)
01055 {
01056 FDEBUG(("Window::registerExtension: register '%s': \n", s));
01057
01058 staticAcquire();
01059
01060 if(s == NULL)
01061 {
01062 staticRelease();
01063 return TypeTraits<UInt32>::getMax();
01064 }
01065
01066
01067
01068 Int32 r = getExtensionId(s);
01069
01070 if(-1 != r)
01071 {
01072 FPDEBUG(("reusing id %d\n", r));
01073 }
01074 else
01075 {
01076 r = _registeredExtensions.size();
01077
01078 _registeredExtensions.push_back(s);
01079
01080 FPDEBUG(("new id %d\n", r));
01081 }
01082
01083 staticRelease();
01084 return r;
01085 }
01086
01093 bool OSG::Window::hasExtension(const Char8 *s)
01094 {
01095 if(std::find(_ignoredExtensions.begin(),
01096 _ignoredExtensions.end(),
01097 s) != _ignoredExtensions.end())
01098 {
01099 return false;
01100 }
01101
01102 if(std::find(_extensions.begin(),
01103 _extensions.end(),
01104 s) != _extensions.end())
01105 {
01106 return true;
01107 }
01108
01109 return false;
01110 }
01111
01118 void OSG::Window::ignoreExtensions(const Char8 *s)
01119 {
01120 FDEBUG(("Window:: Ignoring extensions '%s'\n", s));
01121
01122 staticAcquire();
01123
01124 std::back_insert_iterator< std::vector<std::string> >
01125 extension_back_inserter(_ignoredExtensions);
01126
01127 std::string toex(s);
01128
01129 for(string_token_iterator ignit = string_token_iterator(toex, ",. ");
01130 ignit != string_token_iterator(); ++ignit)
01131 {
01132 std::string ignore = *ignit;
01133
01134 FDEBUG(("Ignoring '%s':", ignore.c_str()));
01135
01136 if(std::find(_ignoredExtensions.begin(),
01137 _ignoredExtensions.end(),
01138 ignore.c_str()) != _ignoredExtensions.end())
01139 {
01140 FPDEBUG((" already ignored.\n"));
01141 continue;
01142 }
01143
01144 _ignoredExtensions.push_back(ignore);
01145
01146 std::vector<std::string>::iterator regit;
01147
01148
01149
01150 regit = std::find(_registeredExtensions.begin(),
01151 _registeredExtensions.end(),
01152 ignore.c_str());
01153
01154 Int32 ind = -1;
01155
01156 if(regit != _registeredExtensions.end())
01157 {
01158 ind = regit - _registeredExtensions.begin();
01159 FPDEBUG(("(reg as %d)", ind));
01160 }
01161
01162
01163
01164
01165 WindowStore::const_iterator winIt = _allWindows.begin();
01166 WindowStore::const_iterator winEnd = _allWindows.end ();
01167
01168 for(; winIt != winEnd; ++winIt)
01169 {
01170 FPDEBUG((" %p:", winIt->get()));
01171
01172 std::vector<std::string>::iterator extit;
01173
01174 extit = std::find((*winIt)->_extensions.begin(),
01175 (*winIt)->_extensions.end(),
01176 ignore.c_str());
01177
01178 if(extit != (*winIt)->_extensions.end())
01179 {
01180 FPDEBUG((" removed"));
01181 (*winIt)->_extensions.erase(extit);
01182 }
01183 else
01184 {
01185 FPDEBUG((" nonsupp"));
01186 }
01187
01188 if(ind >= 0)
01189 {
01190 if((*winIt)->_availExtensions.size() > UInt32(ind))
01191 {
01192 (*winIt)->_availExtensions[ind] = false;
01193 FPDEBUG((" disabled"));
01194 }
01195 if((*winIt)->_commonExtensions.size() > UInt32(ind))
01196 {
01197 (*winIt)->_commonExtensions[ind] = false;
01198 FPDEBUG((" uncommoned"));
01199 }
01200 }
01201 }
01202 FPDEBUG(("\n"));
01203 }
01204
01205 std::sort(_ignoredExtensions.begin(), _ignoredExtensions.end());
01206
01207 staticRelease();
01208 }
01209
01214 UInt32 OSG::Window::registerFunction(const Char8 *s,
01215 Int32 ext,
01216 UInt32 version)
01217 {
01218 if(s == NULL)
01219 return TypeTraits<UInt32>::getMax();
01220
01221 FDEBUG(("Window::registerFunction: register '%s': \n", s));
01222
01223 staticAcquire();
01224
01225 std::vector<std::string>::iterator i;
01226
01227 i = std::find(_registeredFunctions.begin(), _registeredFunctions.end(),
01228 s);
01229
01230 if(i < _registeredFunctions.end())
01231 {
01232 staticRelease();
01233 FDEBUG(("reusing id %td\n", i - _registeredFunctions.begin()));
01234 return i - _registeredFunctions.begin();
01235 }
01236
01237 UInt32 r=_registeredFunctions.size();
01238
01239 _registeredFunctions .push_back(s);
01240 _registeredFunctionExts .push_back(ext);
01241 _registeredFunctionVersions.push_back(version);
01242
01243 FPDEBUG(("new id %d\n", r));
01244
01245 staticRelease();
01246 return r;
01247 }
01248
01253 void OSG::Window::registerConstant(GLenum val)
01254 {
01255 staticAcquire();
01256
01257 if(std::find(_registeredConstants.begin(),
01258 _registeredConstants.end (),
01259 val ) == _registeredConstants.end())
01260 {
01261 _registeredConstants.push_back(val);
01262 }
01263
01264 staticRelease();
01265 }
01266
01267 #endif // remove the OpenGL object handling from user docs
01268
01275 void OSG::Window::dumpExtensions(void)
01276 {
01277 std::vector<std::string>::iterator it;
01278 std::cout << "GL Extensions: ";
01279
01280 for(it = _extensions.begin(); it != _extensions.end(); ++it)
01281 {
01282 std::cout << it->c_str() << ", ";
01283 }
01284
01285 std::cout << std::endl;
01286 }
01287
01288 void OSG::Window::doTerminate(void)
01289 {
01290 if(_pContextThread != NULL)
01291 {
01292 fprintf(stderr, "Terminate draw thread %p\n", this);
01293
01294 _pContextThread->queueTask(
01295 new WindowDrawTask(WindowDrawTask::EndThread));
01296
01297 Thread::join(_pContextThread);
01298 }
01299
01300 _pContextThread = NULL;
01301 }
01302
01312 void OSG::Window::doFrameInit(bool reinitExtFuctions)
01313 {
01314 static bool ignoreEnvDone = false;
01315
01316 if(!ignoreEnvDone)
01317 {
01318 ignoreEnvDone = true;
01319
01320 #ifndef OSG_EMBEDDED
01321 Char8 *p = getenv("OSG_IGNORE_EXTENSIONS");
01322
01323 if(p)
01324 ignoreExtensions(p);
01325 #endif
01326 }
01327
01328
01329 if(_extensions.empty())
01330 {
01331 const char *version =
01332 reinterpret_cast<const char *>(glGetString(GL_VERSION));
01333
01334 if(version != NULL)
01335 {
01336 int major = atoi(version);
01337 int minor = atoi(strchr(version, '.') + 1);
01338
01339 _glVersion = (major << 8) + minor;
01340 }
01341 else
01342 {
01343 FFATAL(("Window::frameInit: Couldn't detect OpenGL version "
01344 "assuming version 1.1!\n"));
01345 _glVersion = (1 << 8) + 1;
01346 }
01347
01348 #ifdef __APPLE__
01349
01350 const char* glVendor =
01351 reinterpret_cast<const char *>(glGetString(GL_VENDOR));
01352 const char* glRenderer =
01353 reinterpret_cast<const char *>(glGetString(GL_RENDERER));
01354
01355 if(glVendor != NULL && glRenderer != NULL)
01356 {
01357
01358
01359 FLOG (( "GL Vendor/Renderer: %s/%s\n", glVendor, glRenderer ));
01360
01361 if ( strstr(glVendor, "ATI") && strstr(glRenderer,"X1600") )
01362 {
01363 FWARNING (("Switch of non_power_of_two for ATI\n"));
01364 ignoreExtensions("GL_ARB_texture_non_power_of_two");
01365 }
01366 }
01367
01368 #endif // __APPLE
01369
01370 const char *gl_extensions =
01371 reinterpret_cast<const char*> (glGetString(GL_EXTENSIONS));
01372
01373 FDEBUG(("Window %p: GL Version: %4x ('%s')\n", this,
01374 _glVersion, glGetString(GL_VERSION) ));
01375
01376 FDEBUG(("Window %p: GL Extensions: %s\n", this, gl_extensions));
01377
01378 std::string foo(gl_extensions != NULL ? gl_extensions : "");
01379
01380 FDEBUG(("Window %p: Ignored extensions: ", this));
01381
01382 for(string_token_iterator it = string_token_iterator(foo, ",. ");
01383 it != string_token_iterator(); ++it)
01384 {
01385 if(! std::binary_search(_ignoredExtensions.begin(),
01386 _ignoredExtensions.end(),
01387 *it))
01388 {
01389 _extensions.push_back(*it);
01390 }
01391 else
01392 {
01393 FPDEBUG(("%s ", (*it).c_str()));
01394 }
01395 }
01396 FPDEBUG(("\n"));
01397 std::sort(_extensions.begin(), _extensions.end());
01398
01399
01400 if(_extensions.empty())
01401 _availExtensions.resize(_registeredExtensions.size(), false);
01402 }
01403
01404
01405 if(_registeredExtensions.size() > _availExtensions.size())
01406 {
01407 staticAcquire();
01408 FDEBUG(("Window %p: exts: ", this));
01409
01410 while(_registeredExtensions.size() > _availExtensions.size())
01411 {
01412 UInt32 s = _availExtensions.size();
01413
01414
01415
01416
01417 bool supported = std::binary_search(
01418 _extensions.begin(),
01419 _extensions.end(),
01420 _registeredExtensions[s]);
01421
01422
01423 bool ignored = std::binary_search(
01424 _ignoredExtensions.begin(),
01425 _ignoredExtensions.end(),
01426 _registeredExtensions[s]);
01427
01428 _availExtensions.push_back(supported && !ignored);
01429
01430 FPDEBUG(("%s:", _registeredExtensions[s].c_str()));
01431
01432 if(_commonExtensions.size() <= s)
01433 {
01434 _commonExtensions.push_back(supported && !ignored);
01435
01436 if(supported && !ignored)
01437 {
01438 FPDEBUG(("ok "));
01439 }
01440 else if(!supported)
01441 {
01442 FPDEBUG(("NF "));
01443 }
01444 else
01445 {
01446 FPDEBUG(("IGN "));
01447 }
01448 }
01449 else if (!supported)
01450 {
01451 _commonExtensions[s] = false;
01452 FPDEBUG(("NF "));
01453 }
01454 else
01455 {
01456 _commonExtensions[s] = false;
01457 FPDEBUG(("IGN "));
01458 }
01459 }
01460 FPDEBUG(("\n"));
01461 staticRelease();
01462 }
01463
01464 if(reinitExtFuctions == true)
01465 {
01466 _extFunctions.clear();
01467 }
01468
01469
01470 while(_registeredFunctions.size() > _extFunctions.size())
01471 {
01472 const Char8 *s = _registeredFunctions[_extFunctions.size()].c_str();
01473 FPDEBUG(("Window %p: Looking up ext function: %s ... ", this, s));
01474
01475 Int32 ext = _registeredFunctionExts [_extFunctions.size()];
01476 UInt32 ver = _registeredFunctionVersions[_extFunctions.size()];
01477
01478 GLExtensionFunction func = NULL;
01479
01480
01481 if(ext == -1 || _availExtensions[ext] == true || _glVersion >= ver)
01482 {
01483 func = getFunctionByName(s);
01484 if (NULL != func)
01485 {
01486 FDEBUG((" FOUND\n"));
01487 }
01488 else
01489 {
01490 FDEBUG((" NULL\n"));
01491 }
01492 }
01493 else
01494 {
01495 FDEBUG((" N/A\n"));
01496 }
01497
01498 _extFunctions.push_back(func);
01499 }
01500
01501 #ifndef OSG_EMBEDDED
01502
01503 while(_registeredConstants.size() > _numAvailConstants)
01504 {
01505 for(std::vector<GLenum>::iterator it = _registeredConstants.begin() +
01506 _numAvailConstants;
01507 it != _registeredConstants.end();
01508 ++it)
01509 {
01510 Vec2f val(unknownConstant, unknownConstant);
01511 glGetFloatv(*it, static_cast<GLfloat*>(val.getValues()));
01512 _availConstants[*it] = val;
01513 FDEBUG(("Window(%p): Constant 0x%x value is %.3f %.3f\n", this,
01514 *it, val[0], val[1]));
01515 }
01516 _numAvailConstants = _registeredConstants.size();
01517
01518 glGetError();
01519 }
01520 #endif
01521
01522 _pStageValidator->incEventCounter();
01523 }
01524
01534 void OSG::Window::doFrameExit(void)
01535 {
01536 std::list<DestroyEntry>::iterator st,en;
01537
01538 st = _glObjectDestroyList.begin();
01539 en = _glObjectDestroyList.end ();
01540
01541 while(st != en)
01542 {
01543 UInt32 i = st->first, n = st->second;
01544
01545 GLObject *obj = _glObjects[i];
01546
01547 if(obj == NULL)
01548 {
01549 FDEBUG(("Window::doFrameExit: objects %d (%d) already destroyed ?\n",
01550 i, n));
01551 ++st;
01552 continue;
01553 }
01554
01555 FDEBUG(("Window::doFrameExit: Destroying GLObject %d (%d) - GL id %d\n",
01556 i, n, getGLObjectId(i)));
01557
01558 UInt32 rc = obj->getRefCounter();
01559
01560
01561 if(getGlObjectLastReinitialize(i) != 0)
01562 {
01563 _glObjects[i]->getDestroyFunctor()(&_oEnv, i, destroy);
01564 doResetGLObjectStatus(i, n);
01565
01566 if((rc = _glObjects[ i ]->decRefCounter()) <= 0)
01567 {
01568
01569 _glObjects[i]->getDestroyFunctor()(&_oEnv, i, finaldestroy);
01570 }
01571 }
01572
01573
01574 if(rc <= 0)
01575 {
01576 delete _glObjects[i];
01577
01578 for(UInt32 j = 0; j < n ; j++)
01579 {
01580 _glObjects[i+j] = NULL;
01581 this->setGLObjectId(i+j, 0);
01582 }
01583 }
01584
01585 ++st;
01586 }
01587
01588 _glObjectDestroyList.clear();
01589
01590
01591
01592
01593
01594
01595 static bool inited = false;
01596 #ifndef OSG_DEBUG
01597 static bool testGLErrors = false;
01598 #else
01599 static bool testGLErrors = true;
01600 #endif
01601
01602 if(!inited)
01603 {
01604 inited = true;
01605 char *p = getenv("OSG_DEBUG");
01606 if(p)
01607 testGLErrors = true;
01608 }
01609
01610 if(testGLErrors)
01611 {
01612 GLenum glerr;
01613
01614 while((glerr = glGetError()) != GL_NO_ERROR)
01615 {
01616 #ifndef OSG_EMBEDDED
01617 FWARNING(("Window::frameExit: Caught stray OpenGL "
01618 "error %s (%#x).\n",
01619 gluErrorString(glerr),
01620 glerr));
01621 #else
01622 FWARNING(("Window::frameExit: Caught stray OpenGL error %#x.\n",
01623 glerr));
01624 #endif
01625
01626 #ifndef OSG_DEBUG
01627 FWARNING(("Rerun with debug-libraries to get more accurate "
01628 "information.\n"));
01629 #endif
01630 }
01631 }
01632
01633 }
01634
01635
01636
01637
01638
01639
01640
01641
01647 OSG::Window::GLExtensionFunction OSG::Window::getFunctionByName(
01648 const Char8 *s)
01649 {
01650 GLExtensionFunction retval = NULL;
01651
01652 FINFO(("Window::getFunctionByName: %s\n", s));
01653
01654 FDEBUG(("Window %p: GL Vendor: %s\n", this, glGetString(GL_VENDOR)));
01655
01656 #if defined(__APPLE__)
01657
01658 if (NSIsSymbolNameDefined(s))
01659 {
01660 NSSymbol symbol = NSLookupAndBindSymbol(s);
01661
01662 if(symbol != 0)
01663 retval = GLExtensionFunction(NSAddressOfSymbol(symbol));
01664 }
01665 #elif defined(OSG_EMBEDDED) && defined(WIN32)
01666
01667 retval = (void(__cdecl*)(void)) eglGetProcAddress(s);
01668
01669 #elif defined(WIN32)
01670
01671 retval = (void(__cdecl*)(void)) wglGetProcAddress(s);
01672
01673 #elif defined(__sgi) || defined(__hpux) || \
01674 defined(__linux) || defined(__sun)
01675
01676
01677
01678
01679
01680
01681 static void (*(*__GetProcAddress)(const GLubyte *))(void) = NULL;
01682
01683 static void *libHandle = NULL;
01684 std::string libHandleName;
01685
01686
01687 if(libHandle == NULL)
01688 {
01689 libHandle = dlopen(_glLibraryName, RTLD_NOW | RTLD_LOCAL);
01690
01691 if(!libHandle)
01692 {
01693 FWARNING(("Error in dlopen when opening GL lib: %s\n",dlerror()));
01694 abort();
01695 }
01696 else
01697 {
01698 libHandleName = (_glLibraryName == NULL ? "(executable)"
01699 : _glLibraryName);
01700 FDEBUG(("Opened lib %s for GL extension handling.\n",
01701 libHandleName.c_str()));
01702 }
01703 }
01704
01705 if(__GetProcAddress == NULL)
01706 {
01707 FINFO(("Finding glxGetProcAddress method: "));
01708
01709 #ifdef TRY_USING_GLXGETPROC_DIRECTLY
01710
01711
01712
01713
01714
01715
01716
01717
01718
01719
01720
01721
01722 #ifdef GLX_VERSION_1_4
01723 if(__GetProcAddress == NULL)
01724 {
01725 __GetProcAddress = glXGetProcAddress;
01726 FPINFO((" Using glxGetProcAddress directly.\n"));
01727 }
01728 #endif
01729 #endif
01730 if(__GetProcAddress == NULL)
01731 {
01732 __GetProcAddress =
01733 #if __GNUC__ < 4
01734 (void (*(*)(const GLubyte*))())
01735 #else
01736 reinterpret_cast<void (*(*)(const GLubyte*))()>
01737 #endif
01738 (dlsym(libHandle,
01739 "glXGetProcAddressARB"));
01740
01741 if(__GetProcAddress == NULL)
01742 {
01743 __GetProcAddress =
01744 #if __GNUC__ < 4
01745 (void (*(*)(const GLubyte*))())
01746 #else
01747 reinterpret_cast<void (*(*)(const GLubyte*))()>
01748 #endif
01749 (dlsym(libHandle,
01750 "glXGetProcAddress"));
01751
01752 if(__GetProcAddress == NULL)
01753 {
01754
01755
01756
01757 dlclose(libHandle);
01758
01759 libHandle = dlopen("libGL.so", RTLD_NOW | RTLD_GLOBAL);
01760
01761 if(!libHandle)
01762 {
01763 FWARNING(("Error in dlopen: %s\n",dlerror()));
01764 abort();
01765 }
01766 else
01767 {
01768 FPINFO((" Using libGL.so directly.\n"));
01769 }
01770
01771 __GetProcAddress =
01772 #if __GNUC__ < 4
01773 (void (*(*)(const GLubyte*))())
01774 #else
01775 reinterpret_cast<void (*(*)(const GLubyte*))()>
01776 #endif
01777 (dlsym(libHandle, "glXGetProcAddressARB"));
01778
01779 if(__GetProcAddress == NULL)
01780 {
01781 __GetProcAddress =
01782 #if __GNUC__ < 4
01783 (void (*(*)(const GLubyte*))())
01784 #else
01785 reinterpret_cast<void (*(*)(const GLubyte*))()>
01786 #endif
01787 (dlsym(libHandle, "glXGetProcAddress"));
01788 }
01789
01790
01791 if(__GetProcAddress == NULL)
01792 {
01793 FWARNING(("Neither glXGetProcAddress nor "
01794 "glXGetProcAddressARB found! Disabling all "
01795 " extensions for Window %p!\n", this));
01796
01797 _availExtensions.clear();
01798 _availExtensions.resize(_registeredExtensions.size(),
01799 false);
01800 }
01801 }
01802 else
01803 {
01804 FPINFO((" Using glXGetProcAddress (from %s).\n",
01805 libHandleName.c_str()));
01806 }
01807 }
01808 else
01809 {
01810 FPINFO(("Using glXGetProcAddressARB (from %s).\n",
01811 libHandleName.c_str()));
01812 }
01813 }
01814 }
01815
01816 if(__GetProcAddress != NULL)
01817 {
01818 retval =
01819 reinterpret_cast<GLExtensionFunction>(
01820 __GetProcAddress(reinterpret_cast<const GLubyte*>(s)));
01821 }
01822 else
01823 {
01824 retval =
01825 #if __GNUC__ < 4
01826 (GLExtensionFunction)
01827 #else
01828 reinterpret_cast<GLExtensionFunction>
01829 #endif
01830 (dlsym(libHandle, s));
01831 }
01832
01833 #else
01834
01835 FWARNING(("Window::getFunctionByName: couldn't find implementation!\n"
01836 "Please contact the developers at info@opensg.org.\n"));
01837
01838 retval = NULL;
01839 #endif
01840
01841 if(retval == NULL)
01842 {
01843 FWARNING(("Window::getFunctionByName: Couldn't get function '%s' for "
01844 "Window %p.\n", s, this));
01845 }
01846 else
01847 {
01848 FDEBUG(("Window::getFunctionByName: got function '%s' for "
01849 "Window %p at %p.\n", s, this, retval));
01850 }
01851
01852 return retval;
01853 }
01854
01855
01859 const Vec2f& OSG::Window::getConstantValuev(GLenum val)
01860 {
01861 static Vec2f inf(Inf, Inf);
01862
01863 ConstHash::iterator it = _availConstants.find(val);
01864
01865 if(it != _availConstants.end())
01866 return _availConstants[val];
01867
01868 return inf;
01869 }
01870
01871
01879 void OSG::Window::setupGL( void )
01880 {
01881 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
01882 glPixelStorei(GL_PACK_ALIGNMENT, 1);
01883
01884 glDepthFunc(GL_LEQUAL );
01885 glEnable (GL_DEPTH_TEST);
01886
01887 glEnable (GL_NORMALIZE );
01888
01889
01890 Real nul[4]={0.f,0.f,0.f,0.f};
01891
01892 GLP::glLightfv(GL_LIGHT0, GL_DIFFUSE, nul);
01893 GLP::glLightfv(GL_LIGHT0, GL_SPECULAR, nul);
01894
01895 _sfRendererInfo.getValue().assign(
01896 reinterpret_cast<const char *>(glGetString(GL_VERSION)));
01897
01898 _sfRendererInfo.getValue() += " - ";
01899
01900 _sfRendererInfo.getValue() +=
01901 reinterpret_cast<const char *>(glGetString(GL_RENDERER));
01902
01903
01904 doFrameInit();
01905 }
01906
01907 void Window::setupTasks(void)
01908 {
01909 _pWaitTask = new WindowDrawTask(WindowDrawTask::WaitAtBarrier);
01910 _pSwapTask = new WindowDrawTask(WindowDrawTask::Swap );
01911 _pFrameInitTask = new WindowDrawTask(WindowDrawTask::FrameInit );
01912 _pFrameExitTask = new WindowDrawTask(WindowDrawTask::FrameExit );
01913 _pActivateTask = new WindowDrawTask(WindowDrawTask::Activate );
01914 }
01915
01916
01917
01925 void OSG::Window::render(RenderActionBase *action)
01926 {
01927 if((_sfDrawMode.getValue() & PartitionDrawMask) == SequentialPartitionDraw)
01928 {
01929 activate ();
01930 doFrameInit();
01931
01932 if(_mfDrawTasks.empty() == false)
01933 {
01934 MFDrawTask::const_iterator tIt = _mfDrawTasks.begin();
01935 MFDrawTask::const_iterator tEnd = _mfDrawTasks.end ();
01936
01937 for(; tIt != tEnd; ++tIt)
01938 {
01939 (*tIt)->execute(this, &_oEnv);
01940 }
01941
01942 editMField(DrawTasksFieldMask, _mfDrawTasks);
01943
01944 _mfDrawTasks.clear();
01945 }
01946
01947 doRenderAllViewports(action);
01948
01949 swap ();
01950 doFrameExit();
01951 deactivate ();
01952 }
01953 else if((_sfDrawMode.getValue() & PartitionDrawMask) ==
01954 ParallelPartitionDraw)
01955 {
01956 OSG_ASSERT(_pContextThread != NULL);
01957
01958 if(_pContextThread->isRunning() == false)
01959 {
01960 WindowDrawThread *pDrawThread =
01961 dynamic_cast<WindowDrawThread *>(_pContextThread.get());
01962
01963 OSG_ASSERT(pDrawThread != NULL);
01964
01965 fprintf(stderr, "running partition drawthread r\n");
01966
01967 if(_pInitTask == NULL)
01968 {
01969 _pInitTask = new WindowDrawTask(WindowDrawTask::Init);
01970 }
01971
01972 pDrawThread->queueTaskFront(_pInitTask);
01973
01974 pDrawThread->setWindow(this);
01975 pDrawThread->run(Thread::getCurrentAspect());
01976
01977 _pInitTask = NULL;
01978 }
01979
01980 if(_pWaitTask == NULL)
01981 {
01982 setupTasks();
01983 }
01984
01985
01986 #ifdef OSG_WIN_QUEUE_ALL
01987 _pContextThread->queueTask(_pWaitTask);
01988 #endif
01989
01990 if(this->getKeepContextActive() == false)
01991 this->doDeactivate();
01992
01993 _pContextThread->queueTask(_pFrameInitTask);
01994
01995 if(_mfDrawTasks.empty() == false)
01996 {
01997 MFDrawTask::const_iterator tIt = _mfDrawTasks.begin();
01998 MFDrawTask::const_iterator tEnd = _mfDrawTasks.end ();
01999
02000 for(; tIt != tEnd; ++tIt)
02001 {
02002 _pContextThread->queueTask(*tIt);
02003 }
02004
02005 editMField(DrawTasksFieldMask, _mfDrawTasks);
02006
02007 _mfDrawTasks.clear();
02008 }
02009
02010 doRenderAllViewports(action);
02011
02012 #ifdef OSG_WIN_QUEUE_ALL
02013
02014
02015 _pWaitTask->waitForBarrier();
02016 #endif
02017
02018 _pContextThread->queueTask(_pSwapTask );
02019
02020 _pContextThread->queueTask(_pFrameExitTask);
02021
02022 _pContextThread->queueTask(_pWaitTask );
02023
02024 _pWaitTask->waitForBarrier();
02025 }
02026 else
02027 {
02028 fprintf(stderr, "Unknow partition draw mode\n");
02029 }
02030 }
02031
02032 void OSG::Window::renderNoFinish(RenderActionBase *action)
02033 {
02034 if((_sfDrawMode.getValue() & PartitionDrawMask) == SequentialPartitionDraw)
02035 {
02036 activate ();
02037 doFrameInit();
02038
02039 if(_mfDrawTasks.empty() == false)
02040 {
02041 MFDrawTask::const_iterator tIt = _mfDrawTasks.begin();
02042 MFDrawTask::const_iterator tEnd = _mfDrawTasks.end ();
02043
02044 for(; tIt != tEnd; ++tIt)
02045 {
02046 (*tIt)->execute(this, &_oEnv);
02047 }
02048
02049 editMField(DrawTasksFieldMask, _mfDrawTasks);
02050
02051 _mfDrawTasks.clear();
02052 }
02053
02054 doRenderAllViewports(action);
02055 }
02056 else if((_sfDrawMode.getValue() & PartitionDrawMask) ==
02057 ParallelPartitionDraw)
02058 {
02059 OSG_ASSERT(_pContextThread != NULL);
02060
02061 if(_pContextThread->isRunning() == false)
02062 {
02063 WindowDrawThread *pDrawThread =
02064 dynamic_cast<WindowDrawThread *>(_pContextThread.get());
02065
02066 OSG_ASSERT(pDrawThread != NULL);
02067
02068 fprintf(stderr, "running partition drawthread rnf\n");
02069
02070 if(_pInitTask == NULL)
02071 {
02072 _pInitTask = new WindowDrawTask(WindowDrawTask::Init);
02073 }
02074
02075 pDrawThread->queueTaskFront(_pInitTask);
02076
02077 pDrawThread->setWindow(this);
02078 pDrawThread->run(Thread::getCurrentAspect());
02079
02080 _pInitTask = NULL;
02081 }
02082
02083 if(_pWaitTask == NULL)
02084 {
02085 setupTasks();
02086 }
02087
02088 _pContextThread->queueTask(_pFrameInitTask);
02089
02090 if(_mfDrawTasks.empty() == false)
02091 {
02092 MFDrawTask::const_iterator tIt = _mfDrawTasks.begin();
02093 MFDrawTask::const_iterator tEnd = _mfDrawTasks.end ();
02094
02095 for(; tIt != tEnd; ++tIt)
02096 {
02097 _pContextThread->queueTask(*tIt);
02098 }
02099
02100 editMField(DrawTasksFieldMask, _mfDrawTasks);
02101
02102 _mfDrawTasks.clear();
02103 }
02104
02105 this->doRenderAllViewports(action);
02106 }
02107 else
02108 {
02109 fprintf(stderr, "Unknow partition draw mode\n");
02110 }
02111 }
02112
02113 void OSG::Window::frameFinish(bool bActivate)
02114 {
02115 if((_sfDrawMode.getValue() & PartitionDrawMask) == SequentialPartitionDraw)
02116 {
02117 if(bActivate == true)
02118 activate();
02119
02120 swap ();
02121 doFrameExit();
02122
02123 }
02124 else if((_sfDrawMode.getValue() & PartitionDrawMask) ==
02125 ParallelPartitionDraw)
02126 {
02127 OSG_ASSERT(_pContextThread != NULL);
02128
02129 if(_pWaitTask == NULL || _pContextThread->isRunning() == false)
02130 {
02131 fprintf(stderr, "Window::frameFinish::frame not started\n");
02132 }
02133
02134 if(bActivate == true)
02135 _pContextThread->queueTask(_pActivateTask);
02136
02137 _pContextThread->queueTask(_pSwapTask );
02138
02139 _pContextThread->queueTask(_pFrameExitTask);
02140
02141 _pContextThread->queueTask(_pWaitTask );
02142
02143 _pWaitTask->waitForBarrier();
02144 }
02145 else
02146 {
02147 fprintf(stderr, "Unknow partition draw mode\n");
02148 }
02149 }
02150
02151 void OSG::Window::runFrameExit(void)
02152 {
02153 if((_sfDrawMode.getValue() & PartitionDrawMask) == SequentialPartitionDraw)
02154 {
02155 doActivate ();
02156 doFrameExit ();
02157 doDeactivate();
02158 }
02159 else if((_sfDrawMode.getValue() & PartitionDrawMask) ==
02160 ParallelPartitionDraw)
02161 {
02162 if(_pWaitTask == NULL || _pContextThread->isRunning() == false)
02163 {
02164 fprintf(stderr, "Window::runFrameExit::frame not started\n");
02165 }
02166
02167 _pContextThread->queueTask(_pActivateTask);
02168 _pContextThread->queueTask(_pFrameExitTask);
02169
02170 _pContextThread->queueTask(_pWaitTask );
02171
02172 _pWaitTask->waitForBarrier();
02173 }
02174 else
02175 {
02176 fprintf(stderr, "Unknow partition draw mode\n");
02177 }
02178 }
02179
02180 void OSG::Window::frameInit(void)
02181 {
02182 if((_sfDrawMode.getValue() & PartitionDrawMask) == SequentialPartitionDraw)
02183 {
02184 this->doFrameInit();
02185 }
02186 }
02187
02188 void OSG::Window::frameExit(void)
02189 {
02190 if((_sfDrawMode.getValue() & PartitionDrawMask) == SequentialPartitionDraw)
02191 {
02192 this->doFrameExit();
02193 }
02194 }
02195
02196 void OSG::Window::renderAllViewports(RenderActionBase *action)
02197 {
02198 if((_sfDrawMode.getValue() & PartitionDrawMask) == SequentialPartitionDraw)
02199 {
02200 this->doRenderAllViewports(action);
02201 }
02202 }
02203
02210 void OSG::Window::doRenderAllViewports(RenderActionBase *action)
02211 {
02212 MFUnrecChildViewportPtr::const_iterator portIt = getMFPort()->begin();
02213 MFUnrecChildViewportPtr::const_iterator portEnd = getMFPort()->end();
02214 Int32 iVPId = 0;
02215
02216 if(action != NULL)
02217 {
02218 commitChanges();
02219
02220 action->setWindow(this);
02221
02222 if(this->getDrawerId() < 0)
02223 {
02224 action->setDrawerId(this->_windowId);
02225 }
02226 else
02227 {
02228 action->setDrawerId(this->getDrawerId());
02229 }
02230
02231 if((_sfDrawMode.getValue() & PartitionDrawMask) ==
02232 SequentialPartitionDraw)
02233 {
02234 action->setDrawPartPar(false);
02235 }
02236 else if((_sfDrawMode.getValue() & PartitionDrawMask) ==
02237 ParallelPartitionDraw)
02238 {
02239 action->setDrawPartPar(true);
02240 }
02241
02242 action->frameInit();
02243
02244 for(; portIt != portEnd; ++portIt, ++iVPId)
02245 {
02246 if((*portIt)->getDrawableId() < 0)
02247 {
02248 action->setDrawableId(iVPId);
02249 }
02250 else
02251 {
02252 action->setDrawableId((*portIt)->getDrawableId());
02253 }
02254
02255 if((_sfDrawMode.getValue() & PartitionDrawMask) ==
02256 SequentialPartitionDraw)
02257 {
02258 (*portIt)->render(action);
02259 }
02260 else if((_sfDrawMode.getValue() & PartitionDrawMask) ==
02261 ParallelPartitionDraw)
02262 {
02263 (*portIt)->render(action);
02264
02265 #if 0
02266 OSG_ASSERT(_pWaitTask != NULL);
02267
02268 _pContextThread->queueTask(_pWaitTask );
02269
02270 _pWaitTask->waitForBarrier();
02271 #endif
02272 }
02273 }
02274 }
02275 else
02276 {
02277 SWARNING << "Window::renderAllViewports: no action!" << std::endl;
02278 }
02279 }
02280
02287 void OSG::Window::resize( int width, int height )
02288 {
02289 setWidth (width );
02290 setHeight (height);
02291 setResizePending(true );
02292 }
02293
02294
02295 void OSG::Window::init(GLInitFunctor oFunc)
02296 {
02297 if((_sfDrawMode.getValue() & PartitionDrawMask) == SequentialPartitionDraw)
02298 {
02299 this->activate();
02300
02301 setupGL();
02302
02303 if(oFunc)
02304 oFunc();
02305
02306 this->deactivate();
02307 }
02308 else if((_sfDrawMode.getValue() & DrawerMask) == StdDrawer)
02309 {
02310 if(_pInitTask == NULL)
02311 {
02312 _pInitTask = new WindowDrawTask(WindowDrawTask::Init);
02313 }
02314
02315 _pInitTask->setInitFunc(oFunc);
02316
02317 OSG_ASSERT(_pContextThread != NULL);
02318
02319 if(_pContextThread->isRunning() == false)
02320 {
02321 WindowDrawThread *pDrawThread =
02322 dynamic_cast<WindowDrawThread *>(_pContextThread.get());
02323
02324 OSG_ASSERT(pDrawThread != NULL);
02325
02326 fprintf(stderr, "running partition drawthread init\n");
02327
02328 pDrawThread->queueTaskFront(_pInitTask);
02329
02330 pDrawThread->setWindow(this);
02331 pDrawThread->run(Thread::getCurrentAspect());
02332
02333 _pInitTask = NULL;
02334 }
02335
02336 if(_pWaitTask == NULL)
02337 {
02338 setupTasks();
02339 }
02340
02341 _pContextThread->queueTask(_pWaitTask);
02342
02343 _pWaitTask->waitForBarrier();
02344 }
02345 else
02346 {
02347 fprintf(stderr, "Unknown partition draw mode\n");
02348 }
02349 }
02350
02351
02358 void OSG::Window::doResizeGL( void )
02359 {
02360 if(isResizePending() == true)
02361 {
02362 glViewport(0, 0, getWidth(), getHeight());
02363
02364 setResizePending(false);
02365 }
02366 }
02367
02368 void OSG::Window::requestStageRun(Int32 iStageId)
02369 {
02370 if(iStageId < 0)
02371 {
02372 SWARNING << "Window::requestStageRun: id is < 0!" << std::endl;
02373 return;
02374 }
02375
02376 WindowStore::const_iterator winIt = _allWindows.begin();
02377 WindowStore::const_iterator winEnd = _allWindows.end ();
02378
02379 for(; winIt != winEnd; ++winIt)
02380 {
02381 Window *pWin = *winIt;
02382
02383 if(pWin == NULL)
02384 continue;
02385
02386 pWin->_pStageValidator->requestRun(iStageId);
02387 }
02388 }
02389
02390
02391
02394 void OSG::Window::dump( UInt32 OSG_CHECK_ARG(uiIndent),
02395 const BitVector OSG_CHECK_ARG(bvFlags )) const
02396 {
02397 SLOG << "Dump Window NI" << std::endl;
02398 }
02399
02400 void Window::resolveLinks(void)
02401 {
02402 Inherited::resolveLinks();
02403 }
02404
02405 void Window::queueTaskFromDrawer(DrawTask *pTask)
02406 {
02407 if(pTask == NULL)
02408 return;
02409
02410 OSG_ASSERT(_pContextThread != NULL);
02411
02412 if((_sfDrawMode.getValue() & PartitionDrawMask) == ParallelPartitionDraw)
02413 {
02414 _pContextThread->queueTask(pTask);
02415 }
02416 else
02417 {
02418 pTask->execute(this, &_oEnv);
02419 }
02420 }
02421
02422 void Window::queueTask(DrawTask *pTask)
02423 {
02424 if(pTask == NULL)
02425 return;
02426
02427 if((_sfDrawMode.getValue() & DrawerMask) == StdDrawer)
02428 {
02429 if((_sfDrawMode.getValue() & PartitionDrawMask) ==
02430 ParallelPartitionDraw)
02431 {
02432 OSG_ASSERT(_pContextThread != NULL);
02433
02434 _pContextThread->queueTask(pTask);
02435 }
02436 else
02437 {
02438 editMField(DrawTasksFieldMask, _mfDrawTasks);
02439
02440 _mfDrawTasks.push_back(pTask);
02441 }
02442 }
02443 else if((_sfDrawMode.getValue() & DrawerMask) == ParallelDrawer)
02444 {
02445 editMField(DrawTasksFieldMask, _mfDrawTasks);
02446
02447 _mfDrawTasks.push_back(pTask);
02448 }
02449 }
02450
02451 void OSG::Window::queueGlobalTask(DrawTask *pTask)
02452 {
02453 WindowStore::const_iterator winIt = _allWindows.begin();
02454 WindowStore::const_iterator winEnd = _allWindows.end ();
02455
02456 for(; winIt != winEnd; ++winIt)
02457 {
02458 Window *pWin = *winIt;
02459
02460 if(pWin == NULL)
02461 continue;
02462
02463 pWin->queueTask(pTask);
02464 }
02465 }
02466
02467 void Window::pushToDrawTasks(DrawTask * const value)
02468 {
02469 if(value == NULL)
02470 return;
02471
02472 editMField(DrawTasksFieldMask, _mfDrawTasks);
02473
02474 _mfDrawTasks.push_back(value);
02475 }
02476
02477 void Window::clearDrawTasks(void)
02478 {
02479 editMField(DrawTasksFieldMask, _mfDrawTasks);
02480
02481 _mfDrawTasks.clear();
02482 }
02483
02484 OSG_END_NAMESPACE