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 <stdlib.h>
00044 #include <stdio.h>
00045
00046 #include "OSGConfig.h"
00047
00048 #include <OSGBase.h>
00049 #include <OSGGL.h>
00050
00051 #if !defined(WIN32) && !defined(darwin)
00052 #include <GL/glx.h>
00053 #endif
00054
00055 #if defined(__sgi) || defined(__hpux) || defined(__linux)
00056 #include <dlfcn.h>
00057 #endif
00058
00059 #if defined(darwin)
00060 #include <mach-o/dyld.h>
00061 #endif
00062
00063 #if defined(__sun)
00064 #include <dlfcn.h>
00065 #include <link.h>
00066 #endif
00067
00068 #include <OSGBaseFunctions.h>
00069 #include <OSGDrawAction.h>
00070 #include <OSGRenderActionBase.h>
00071 #include "OSGViewport.h"
00072
00073 #include "OSGBackground.h"
00074 #include "OSGCamera.h"
00075 #include "OSGWindow.h"
00076
00077 OSG_USING_NAMESPACE
00078
00079 #if defined(OSG_WIN32_ICL) && !defined(OSG_CHECK_FIELDSETARG)
00080 #pragma warning (disable)
00081 #endif
00082
00083
00084
00085
00086
00102
00103
00132
00133
00134 #if !defined(OSG_DO_DOC) || defined(OSG_DOC_DEV)
00135
00193 #endif
00194
00195
00196
00197
00198
00202 std::vector<WindowPtr > OSG::Window::_allWindows;
00203 UInt32 OSG::Window::_currentWindowId = 0;
00204
00205
00210 Lock *OSG::Window::_GLObjectLock;
00211
00215 Lock *OSG::Window::_staticWindowLock;
00216
00220 std::vector<OSG::Window::GLObject *> OSG::Window::_glObjects;
00221
00224
00225
00226
00227
00228
00229
00230
00231 const Char8 *OSG::Window::_glLibraryName = NULL;
00232
00233 std::vector<std::string > OSG::Window::_registeredExtensions;
00234 std::vector<std::string > OSG::Window::_ignoredExtensions;
00235 std::vector<bool > OSG::Window::_commonExtensions;
00236 std::vector<std::string > OSG::Window::_registeredFunctions;
00237 std::vector<Int32 > OSG::Window::_registeredFunctionExts;
00238 std::vector<UInt32 > OSG::Window::_registeredFunctionVersions;
00239
00240
00241
00242 std::vector<GLenum > OSG::Window::_registeredConstants;
00243
00244
00245
00246 const Real32 OSG::Window::unknownConstant = -1e100;
00247
00248
00249
00250
00251
00252
00253
00254
00255
00259 void OSG::Window::initMethod (void)
00260 {
00261 }
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00277 OSG::Window::Window(void) :
00278 Inherited( ),
00279 _windowId (0)
00280 {
00281
00282 }
00283
00287 OSG::Window::Window(const Window &source) :
00288 Inherited(source),
00289 _glObjectDestroyList(source._glObjectDestroyList),
00290 _lastValidate(source._lastValidate.size(),0),
00291 _ids(source._ids.size(),0),
00292 _extensions(),
00293 _availExtensions(),
00294 _extFunctions(),
00295 _availConstants(),
00296 _numAvailConstants(0),
00297 _windowId(0)
00298 {
00299
00300 doInitRegisterGLObject(1, _glObjects.size() - 1);
00301 }
00302
00306 OSG::Window::~Window(void)
00307 {
00308
00309 }
00310
00311
00312
00313
00314
00315
00319 void OSG::Window::onCreate(const Window *)
00320 {
00321
00322 if(GlobalSystemState != Running)
00323 return;
00324
00325 _allWindows.push_back(WindowPtr(this));
00326
00327 _windowId = ++_currentWindowId;
00328 }
00329
00330 void OSG::Window::onCreateAspect(const Window *, const Window *)
00331 {
00332
00333 if(GlobalSystemState != Running)
00334 return;
00335
00336 _windowId = _currentWindowId;
00337 }
00338
00342 void OSG::Window::onDestroy(void)
00343 {
00344
00345 for(UInt32 i = 1; i < _glObjects.size(); ++i)
00346 {
00347 GLObject *obj = _glObjects[i];
00348 if(obj == NULL)
00349 {
00350 FDEBUG(("Window::onDestroy: object %u already destroyed!\n", i));
00351 continue;
00352 }
00353
00354 if(i < getGlObjectLastReinitialize().size() && getGlObjectLastReinitialize()[i] != 0)
00355 {
00356 obj->decRefCounter();
00357
00358
00359
00360 }
00361 }
00362
00363 std::vector<WindowPtr>::iterator it;
00364 it = std::find(_allWindows.begin(), _allWindows.end(), WindowPtr(this));
00365
00366
00367 if(it != _allWindows.end())
00368 _allWindows.erase( it );
00369 }
00370
00371 void OSG::Window::staticAcquire(void)
00372 {
00373
00374 if(GlobalSystemState != Running)
00375 return;
00376
00377 if(_staticWindowLock == NULL)
00378 {
00379 _staticWindowLock = ThreadManager::the()->getLock(NULL);
00380 }
00381 _staticWindowLock->aquire();
00382 }
00383
00384 void OSG::Window::staticRelease(void)
00385 {
00386
00387 if(GlobalSystemState != Running)
00388 return;
00389
00390 _staticWindowLock->release();
00391 }
00392
00393
00394
00395
00396
00400 void OSG::Window::changed(BitVector whichField, UInt32 origin)
00401 {
00402 Inherited::changed(whichField, origin);
00403 }
00404
00405
00406
00407 void OSG::Window::addPort(const ViewportPtr &portP)
00408 {
00409 if(portP != NullFC)
00410 {
00411 _mfPort.push_back(portP);
00412
00413
00414
00415 beginEditCP(portP, Viewport::ParentFieldMask);
00416 {
00417 _mfPort.back()->setParent(WindowPtr(*this));
00418 }
00419 endEditCP (portP, Viewport::ParentFieldMask);
00420 }
00421 }
00422
00423 void OSG::Window::insertPort(UInt32 portIndex, const ViewportPtr &portP)
00424 {
00425 MFViewportPtr::iterator portIt = _mfPort.begin();
00426
00427 if(portP != NullFC)
00428 {
00429 portIt += portIndex;
00430
00431
00432
00433
00434
00435 beginEditCP(portP, Viewport::ParentFieldMask);
00436 {
00437 (*(_mfPort.insert(portIt, portP)))->setParent(
00438 WindowPtr(*this));
00439 }
00440 endEditCP (portP, Viewport::ParentFieldMask);
00441
00442 }
00443 }
00444
00445
00446 void OSG::Window::replacePort(UInt32 portIndex, const ViewportPtr &portP)
00447 {
00448 if(portP != NullFC)
00449 {
00450 _mfPort[portIndex]->setParent(NullFC);
00451 _mfPort[portIndex] = portP;
00452
00453
00454
00455 _mfPort[portIndex]->setParent(
00456 WindowPtr(*this));
00457 }
00458 }
00459
00460 void OSG::Window::replacePortBy(const ViewportPtr &portP,
00461 const ViewportPtr &newportP)
00462 {
00463 MFViewportPtr::iterator portIt = _mfPort.find(portP);
00464
00465 if(newportP != NullFC)
00466 {
00467 if(portIt != _mfPort.end())
00468 {
00469 (*portIt)->setParent(NullFC);
00470 (*portIt) = newportP;
00471
00472
00473
00474 (*portIt)->setParent(
00475 WindowPtr(*this));
00476 }
00477 }
00478 }
00479
00480 void OSG::Window::subPort(const ViewportPtr &portP)
00481 {
00482 MFViewportPtr::iterator portIt = _mfPort.find(portP);
00483
00484 if(portIt != _mfPort.end())
00485 {
00486 (*portIt)->setParent(NullFC);
00487
00488 _mfPort.erase(portIt);
00489 }
00490
00491 }
00492
00493 void OSG::Window::subPort(UInt32 portIndex)
00494 {
00495 MFViewportPtr::iterator portIt = _mfPort.begin();
00496
00497 portIt += portIndex;
00498
00499 if(portIt != _mfPort.end())
00500 {
00501 (*portIt)->setParent(NullFC);
00502
00503 _mfPort.erase(portIt);
00504 }
00505 }
00506
00507 void OSG::Window::clearPorts(void)
00508 {
00509 MFViewportPtr::iterator portIt = _mfPort.begin();
00510
00511 while(portIt != _mfPort.end())
00512 {
00513 (*portIt)->setParent(NullFC);
00514
00515 subRefCP(*portIt);
00516 }
00517
00518 _mfPort.clear();
00519 }
00520
00521
00522 #if !defined(OSG_DO_DOC) || defined(OSG_DOC_EXT)
00523
00524
00525
00534 UInt32 OSG::Window::registerGLObject(GLObjectFunctor functor, UInt32 num)
00535 {
00536 UInt32 id, i;
00537 GLObject *pGLObject;
00538
00539 staticAcquire();
00540
00541
00542 if(_glObjects.empty())
00543 _glObjects.push_back( NULL );
00544
00545 id = _glObjects.size();
00546 pGLObject = new GLObject(functor);
00547
00548
00549
00550 if(_glObjects.capacity() >= id + num)
00551 {
00552 _glObjects.insert(_glObjects.end(), num, pGLObject );
00553
00554 initRegisterGLObject(id, num);
00555
00556 staticRelease();
00557
00558 return id;
00559 }
00560
00561
00562
00563 UInt32 cnt = 0;
00564
00565
00566 for(i = 1; i < _glObjects.size(); ++i)
00567 {
00568 if(_glObjects[i] == NULL)
00569 {
00570 if(cnt == 0)
00571 {
00572 id = i;
00573 }
00574
00575 ++cnt;
00576
00577 if(cnt == num)
00578 {
00579
00580
00581 while(i >= id)
00582 {
00583 _glObjects[i] = pGLObject;
00584 i = i - 1;
00585 }
00586
00587 initRegisterGLObject(id, num);
00588
00589 staticRelease();
00590
00591 return id;
00592 }
00593 }
00594 else
00595 {
00596 cnt = 0;
00597 id = 0;
00598 }
00599 }
00600
00601
00602
00603 if(id > 0)
00604 {
00605
00606 i = id + cnt - 1;
00607 while ( i >= id )
00608 {
00609 _glObjects[i] = pGLObject;
00610 i = i - 1;
00611 }
00612 }
00613 else
00614 {
00615
00616 id = _glObjects.size();
00617 }
00618
00619
00620 for ( i = 1; i <= num - cnt; i++ )
00621 {
00622 _glObjects.push_back( pGLObject );
00623 }
00624
00625 initRegisterGLObject(id, num);
00626
00627 staticRelease();
00628
00629 return id;
00630 }
00631
00638 void OSG::Window::validateGLObject(UInt32 id)
00639 {
00640 if ( id == 0 )
00641 {
00642 SWARNING << "Window::validateGLObject: id is 0!" << std::endl;
00643 return;
00644 }
00645
00646 GLObject *obj = _glObjects[id];
00647
00648 if(obj == NULL)
00649 {
00650 SWARNING << "Window::validateGLObject: obj with id " << id << " is NULL!" << std::endl;
00651 return;
00652 }
00653
00654 if(id >= _lastValidate.size())
00655 {
00656 _lastValidate.insert(_lastValidate.end(),
00657 id + 1 - _lastValidate.size(),
00658 0);
00659 }
00660
00661 FDEBUG(("Window 0x%p (event %d,ri:%d,rf:%d): "
00662 "Validating object %d: last reinit:%d, last validate:"
00663 "%d last refresh: %d => %s\n",
00664 this, getGlObjectEventCounter(),
00665 _mfGlObjectLastReinitialize.size(),
00666 _mfGlObjectLastRefresh.size(),
00667 id,
00668 (_mfGlObjectLastReinitialize.size() > id)?
00669 _mfGlObjectLastReinitialize[id]:0xffffffff,
00670 _lastValidate[id],
00671 (_mfGlObjectLastRefresh.size() > id)?
00672 _mfGlObjectLastRefresh[id]:0xffffffff,
00673 (_mfGlObjectLastReinitialize[id] == 0)?"init":
00674 ((_mfGlObjectLastReinitialize[id] > _lastValidate[id])?"reinit":
00675 ((_mfGlObjectLastRefresh[id] > _lastValidate[id])?"refresh":
00676 "up-to-date"))
00677 ));
00678
00679 if(_mfGlObjectLastReinitialize[id] == 0)
00680 {
00681 obj->incRefCounter();
00682 obj->getFunctor().call(this, packIdStatus(id, initialize));
00683 _mfGlObjectLastReinitialize[id] = 1;
00684 _lastValidate[id] = getGlObjectEventCounter();
00685 }
00686 else if(_mfGlObjectLastReinitialize[id] > _lastValidate[id])
00687 {
00688 obj->getFunctor().call(this, packIdStatus(id, reinitialize));
00689 _lastValidate[id] = getGlObjectEventCounter();
00690 }
00691 else if(_mfGlObjectLastRefresh[id] > _lastValidate[id])
00692 {
00693 obj->getFunctor().call(this, packIdStatus(id, needrefresh));
00694 _lastValidate[id] = getGlObjectEventCounter();
00695 }
00696 }
00697
00698
00705 void OSG::Window::validateAllGLObjects(void)
00706 {
00707 activate();
00708 frameInit();
00709
00710 for (UInt32 i = 1; i < _glObjects.size(); ++i)
00711 validateGLObject(i);
00712
00713 frameExit();
00714 }
00715
00722 void OSG::Window::refreshGLObject( UInt32 id )
00723 {
00724 if ( id == 0 )
00725 {
00726 SWARNING << "Window::refreshGLObject: id is 0!" << std::endl;
00727 return;
00728 }
00729
00730 std::vector<WindowPtr>::iterator it;
00731
00732 for ( it = _allWindows.begin(); it != _allWindows.end(); ++it)
00733 {
00734 beginEditCP(*it, GlObjectEventCounterFieldMask|
00735 GlObjectLastRefreshFieldMask);
00736
00737 UInt32 lastinv = (*it)->getGlObjectEventCounter() + 1;
00738 MFUInt32 &field = (*it)->_mfGlObjectLastRefresh;
00739 if(field.size() <= id)
00740 field.getValues().insert(field.end(), id - field.size() + 1, 0 );
00741 field[id] = lastinv;
00742 (*it)->setGlObjectEventCounter(lastinv);
00743
00744 endEditCP (*it, GlObjectEventCounterFieldMask|
00745 GlObjectLastRefreshFieldMask);
00746 }
00747 }
00748
00754 void OSG::Window::refreshAllGLObjects(void)
00755 {
00756 for (UInt32 i = 1; i < _glObjects.size(); ++i)
00757 refreshGLObject(i);
00758 }
00759
00766 void OSG::Window::reinitializeGLObject(UInt32 id)
00767 {
00768 if ( id == 0 )
00769 {
00770 SWARNING << "Window::reinitializeGLObject: id is 0!" << std::endl;
00771 return;
00772 }
00773
00774 std::vector<WindowPtr>::iterator it;
00775
00776 for(it = _allWindows.begin(); it != _allWindows.end(); ++it)
00777 {
00778 beginEditCP(*it, GlObjectEventCounterFieldMask|
00779 GlObjectLastReinitializeFieldMask);
00780
00781 UInt32 lastinv = (*it)->getGlObjectEventCounter() + 1;
00782
00783 MFUInt32 &field = (*it)->_mfGlObjectLastReinitialize;
00784 if(field.size() <= id)
00785 field.getValues().insert(field.end(), id - field.size() + 1, 0 );
00786
00787 if(field[id] == 0)
00788 continue;
00789 field[id] = lastinv;
00790 (*it)->setGlObjectEventCounter(lastinv);
00791
00792 endEditCP (*it, GlObjectEventCounterFieldMask|
00793 GlObjectLastReinitializeFieldMask);
00794 }
00795 }
00796
00802 void OSG::Window::reinitializeAllGLObjects(void)
00803 {
00804 for (UInt32 i = 1; i < _glObjects.size(); ++i)
00805 reinitializeGLObject(i);
00806 }
00807
00814 void OSG::Window::initRegisterGLObject(UInt32 id, UInt32 num)
00815 {
00816 if ( id == 0 )
00817 {
00818 SWARNING << "Window::initRegisterGLObject: id is 0!" << std::endl;
00819 return;
00820 }
00821
00822 std::vector<WindowPtr>::iterator it;
00823
00824 for(it = _allWindows.begin(); it != _allWindows.end(); ++it)
00825 {
00826 (*it)->doInitRegisterGLObject(id, num);
00827 }
00828 }
00829
00836 void OSG::Window::doInitRegisterGLObject(UInt32 id, UInt32 num)
00837 {
00838 WindowPtr win(this);
00839
00840 beginEditCP(win, GlObjectLastReinitializeFieldMask|
00841 GlObjectLastRefreshFieldMask);
00842
00843 if(_mfGlObjectLastReinitialize.size() < id + num)
00844 _mfGlObjectLastReinitialize.resize(id + num);
00845
00846 if(_mfGlObjectLastRefresh.size() < id + num)
00847 _mfGlObjectLastRefresh.resize(id + num);
00848
00849 if(_lastValidate.size() < id + num)
00850 _lastValidate.resize(id + num);
00851
00852 for(UInt32 i = id; i < id + num; ++i)
00853 {
00854 _mfGlObjectLastReinitialize[i] = 0;
00855 _mfGlObjectLastRefresh [i] = 0;
00856 _lastValidate[i] = 0;
00857 }
00858
00859 endEditCP (win, GlObjectLastReinitializeFieldMask|
00860 GlObjectLastRefreshFieldMask);
00861 }
00862
00869 void OSG::Window::destroyGLObject(UInt32 id, UInt32 num)
00870 {
00871 #ifdef OSG_DEBUG
00872 if(id >= _glObjects.size() || _glObjects[id] == NULL)
00873 {
00874 FWARNING(("Window::destroyGLObject: object %d is NULL!\n", id));
00875 return;
00876 }
00877 #endif
00878
00879
00880 if(_glObjects[id] && _glObjects[id]->getRefCounter() == 0)
00881 {
00882 if(_glObjects[id])
00883 delete _glObjects[ id ];
00884
00885 for ( UInt32 j = 0; j < num ; j++)
00886 {
00887 _glObjects[id+j] = NULL;
00888 }
00889
00890 return;
00891 }
00892
00893 std::vector<WindowPtr>::iterator it;
00894
00895 for(it = _allWindows.begin(); it != _allWindows.end(); ++it)
00896 {
00897 #ifdef OSG_DEBUG
00898 if(id + num > (*it)->_mfGlObjectLastReinitialize.size())
00899 {
00900 FWARNING(("Window::destroyGLObject: id %d + num %d exceed"
00901 "registered objects size %d!\n", id, num,
00902 (*it)->_mfGlObjectLastReinitialize.size()));
00903 return;
00904 }
00905 #endif
00906
00907
00908 if((*it)->getGlObjectLastReinitialize()[id] != 0)
00909 (*it)->_glObjectDestroyList.push_back(DestroyEntry(id,num));
00910 }
00911 }
00912
00913
00914
00915
00916
00920 UInt32 OSG::Window::registerExtension(const Char8 *s)
00921 {
00922 FDEBUG(("Window::registerExtension: register '%s': ", s));
00923 staticAcquire();
00924
00925 if(s == NULL)
00926 {
00927 staticRelease();
00928 return TypeTraits<UInt32>::getMax();
00929 }
00930
00931 std::vector<std::string>::iterator i;
00932
00933 i = std::find(_registeredExtensions.begin(), _registeredExtensions.end(),
00934 s);
00935
00936 if(i < _registeredExtensions.end())
00937 {
00938 staticRelease();
00939 FPDEBUG(("reusing id %d\n", i - _registeredExtensions.begin()));
00940 return i - _registeredExtensions.begin();
00941 }
00942
00943 UInt32 r = _registeredExtensions.size();
00944 _registeredExtensions.push_back(s);
00945
00946 FPDEBUG(("new id %d\n", r));
00947
00948 staticRelease();
00949 return r;
00950 }
00951
00956 bool OSG::Window::hasExtension(const Char8 *s)
00957 {
00958 if(std::find(_ignoredExtensions.begin(),
00959 _ignoredExtensions.end(),
00960 s) != _ignoredExtensions.end())
00961 {
00962 return false;
00963 }
00964
00965 if(std::find(_extensions.begin(),
00966 _extensions.end(),
00967 s) != _extensions.end())
00968 {
00969 return true;
00970 }
00971
00972 return false;
00973 }
00974
00977 void OSG::Window::ignoreExtensions(const Char8 *s)
00978 {
00979 FDEBUG(("Window:: Ignoring extensions '%s'\n", s));
00980
00981 staticAcquire();
00982
00983 std::back_insert_iterator< std::vector<std::string> >
00984 extension_back_inserter(_ignoredExtensions);
00985
00986 std::string toex(s);
00987
00988 for(string_token_iterator ignit = string_token_iterator(toex, ",. ");
00989 ignit != string_token_iterator(); ++ignit)
00990 {
00991 std::string ignore = *ignit;
00992
00993 FDEBUG(("Ignoring '%s':", ignore.c_str()));
00994
00995 if(std::find(_ignoredExtensions.begin(),
00996 _ignoredExtensions.end(),
00997 ignore.c_str()) != _ignoredExtensions.end())
00998 {
00999 FPDEBUG((" already ignored.\n"));
01000 continue;
01001 }
01002
01003 _ignoredExtensions.push_back(ignore);
01004
01005 std::vector<std::string>::iterator regit;
01006
01007
01008
01009 regit = std::find(_registeredExtensions.begin(),
01010 _registeredExtensions.end(),
01011 ignore.c_str());
01012
01013 Int32 ind = -1;
01014
01015 if(regit != _registeredExtensions.end())
01016 {
01017 ind = regit - _registeredExtensions.begin();
01018 FPDEBUG(("(reg as %d)", ind));
01019 }
01020
01021
01022
01023
01024 std::vector<WindowPtr>::iterator winit;
01025
01026 for(winit = _allWindows.begin(); winit != _allWindows.end(); ++winit)
01027 {
01028 FPDEBUG((" %p:", (*winit).getCPtr()));
01029
01030 std::vector<std::string>::iterator extit;
01031
01032 extit = std::find((*winit)->_extensions.begin(),
01033 (*winit)->_extensions.end(),
01034 ignore.c_str());
01035
01036 if(extit != (*winit)->_extensions.end())
01037 {
01038 FPDEBUG((" removed"));
01039 (*winit)->_extensions.erase(extit);
01040 }
01041 else
01042 {
01043 FPDEBUG((" nonsupp"));
01044 }
01045
01046 if(ind >= 0)
01047 {
01048 if((*winit)->_availExtensions.size() > UInt32(ind))
01049 {
01050 (*winit)->_availExtensions[ind] = false;
01051 FPDEBUG((" disabled"));
01052 }
01053 if((*winit)->_commonExtensions.size() > UInt32(ind))
01054 {
01055 (*winit)->_commonExtensions[ind] = false;
01056 FPDEBUG((" uncommoned"));
01057 }
01058 }
01059 }
01060 FPDEBUG(("\n"));
01061 }
01062
01063 std::sort(_ignoredExtensions.begin(), _ignoredExtensions.end());
01064
01065 staticRelease();
01066 }
01067
01071 UInt32 OSG::Window::registerFunction(const Char8 *s, Int32 ext,
01072 UInt32 version)
01073 {
01074 if(s == NULL)
01075 return TypeTraits<UInt32>::getMax();
01076
01077 FDEBUG(("Window::registerFunction: register '%s': ", s));
01078
01079 staticAcquire();
01080
01081 std::vector<std::string>::iterator i;
01082
01083 i = std::find(_registeredFunctions.begin(), _registeredFunctions.end(),
01084 s);
01085
01086 if(i < _registeredFunctions.end())
01087 {
01088 staticRelease();
01089 FPDEBUG(("reusing id %d\n", i - _registeredFunctions.begin()));
01090 return i - _registeredFunctions.begin();
01091 }
01092
01093 UInt32 r=_registeredFunctions.size();
01094 _registeredFunctions.push_back(s);
01095 _registeredFunctionExts.push_back(ext);
01096 _registeredFunctionVersions.push_back(version);
01097
01098 FPDEBUG(("new id %d\n", r));
01099
01100 staticRelease();
01101 return r;
01102 }
01103
01107 void OSG::Window::registerConstant(GLenum val)
01108 {
01109 staticAcquire();
01110
01111 if(std::find(_registeredConstants.begin(),
01112 _registeredConstants.end(),
01113 val) == _registeredConstants.end())
01114 {
01115 _registeredConstants.push_back(val);
01116 }
01117
01118 staticRelease();
01119 }
01120
01121 #endif // remove the OpenGL object handling from user docs
01122
01128 void OSG::Window::dumpExtensions(void)
01129 {
01130 std::vector<std::string>::iterator it;
01131 std::cout << "GL Extensions: ";
01132 for ( it = _extensions.begin(); it != _extensions.end(); it++ )
01133 {
01134 std::cout << it->c_str() << ", ";
01135 }
01136 std::cout << std::endl;
01137 }
01138
01139
01150 void OSG::Window::frameInit(void)
01151 {
01152 static bool ignoreEnvDone = false;
01153
01154 if(!ignoreEnvDone)
01155 {
01156 ignoreEnvDone = true;
01157 char *p = getenv("OSG_IGNORE_EXTENSIONS");
01158 if(p)
01159 ignoreExtensions(p);
01160 }
01161
01162
01163 if(_extensions.empty())
01164 {
01165 const char *version =
01166 reinterpret_cast<const char *>(glGetString(GL_VERSION));
01167
01168 int major = atoi(version);
01169 int minor = atoi(strchr(version, '.') + 1);
01170
01171 _glVersion = (major << 8) + minor;
01172
01173 #ifdef __APPLE__
01174
01175 const char* glVendor = (const char*) glGetString(GL_VENDOR);
01176 const char* glRenderer = (const char*) glGetString(GL_RENDERER);
01177
01178
01179
01180 FLOG (( "GL Vendor/Renderer: %s/%s\n", glVendor, glRenderer ));
01181
01182 if ( strstr(glVendor, "ATI") && strstr(glRenderer,"X1600") ) {
01183 FWARNING (("Switch of non_power_of_two for ATI\n"));
01184 ignoreExtensions("GL_ARB_texture_non_power_of_two");
01185 }
01186
01187 #endif // __APPLE
01188
01189 FDEBUG(("Window %p: GL Version: %4x ('%s')\n", this,
01190 _glVersion, glGetString(GL_VERSION) ));
01191
01192 FDEBUG(("Window %p: GL Extensions: %s\n", this,
01193 glGetString(GL_EXTENSIONS) ));
01194
01195 std::string foo(reinterpret_cast<const char*>
01196 (glGetString(GL_EXTENSIONS)));
01197
01198 FDEBUG(("Window %p: Ignored: ", this));
01199
01200 for(string_token_iterator it = string_token_iterator(foo, ",. ");
01201 it != string_token_iterator(); ++it)
01202 {
01203 if(! std::binary_search(_ignoredExtensions.begin(),
01204 _ignoredExtensions.end(),
01205 *it))
01206 {
01207 _extensions.push_back(*it);
01208 }
01209 else
01210 {
01211 FPDEBUG(("%s ", (*it).c_str()));
01212 }
01213 }
01214 FPDEBUG(("\n"));
01215 std::sort(_extensions.begin(), _extensions.end());
01216
01217
01218 if(_extensions.empty())
01219 _availExtensions.resize(_registeredExtensions.size(), false);
01220 }
01221
01222
01223 if(_registeredExtensions.size() > _availExtensions.size())
01224 {
01225 staticAcquire();
01226 FDEBUG(("Window %p: exts: ", this));
01227
01228 while(_registeredExtensions.size() > _availExtensions.size())
01229 {
01230 UInt32 s = _availExtensions.size();
01231
01232
01233
01234
01235 bool supported = std::binary_search(
01236 _extensions.begin(),
01237 _extensions.end(),
01238 _registeredExtensions[s]);
01239
01240
01241 bool ignored = std::binary_search(
01242 _ignoredExtensions.begin(),
01243 _ignoredExtensions.end(),
01244 _registeredExtensions[s]);
01245
01246 _availExtensions.push_back(supported && !ignored);
01247
01248 FPDEBUG(("%s:", _registeredExtensions[s].c_str()));
01249 if(_commonExtensions.size() <= s)
01250 {
01251 _commonExtensions.push_back(supported && !ignored);
01252 if(supported && !ignored)
01253 {
01254 FPDEBUG(("ok "));
01255 }
01256 else if(!supported)
01257 {
01258 FPDEBUG(("NF "));
01259 }
01260 else
01261 {
01262 FPDEBUG(("IGN "));
01263 }
01264 }
01265 else if (!supported)
01266 {
01267 _commonExtensions[s] = false;
01268 FPDEBUG(("NF "));
01269 }
01270 else
01271 {
01272 _commonExtensions[s] = false;
01273 FPDEBUG(("IGN "));
01274 }
01275 }
01276 FPDEBUG(("\n"));
01277 staticRelease();
01278 }
01279
01280
01281 while(_registeredFunctions.size() > _extFunctions.size())
01282 {
01283 const Char8 *s = _registeredFunctions[_extFunctions.size()].c_str();
01284 Int32 ext = _registeredFunctionExts[_extFunctions.size()];
01285 UInt32 ver = _registeredFunctionVersions[_extFunctions.size()];
01286 void *func = NULL;
01287
01288 if(ext == -1 || _availExtensions[ext] == true || _glVersion >= ver)
01289 func = (void*)getFunctionByName(s);
01290
01291 _extFunctions.push_back(func);
01292 }
01293
01294
01295 while(_registeredConstants.size() > _numAvailConstants)
01296 {
01297 for(std::vector<GLenum>::iterator it = _registeredConstants.begin() +
01298 _numAvailConstants;
01299 it != _registeredConstants.end();
01300 ++it)
01301 {
01302 Vec2f val(unknownConstant, unknownConstant);
01303 glGetFloatv(*it, static_cast<GLfloat*>(val.getValues()));
01304 _availConstants[*it] = val;
01305 FDEBUG(("Window(%p): Constant 0x%x value is %.3f %.3f\n", this,
01306 *it, val[0], val[1]));
01307 }
01308 _numAvailConstants = _registeredConstants.size();
01309 glGetError();
01310 }
01311 }
01312
01321 void OSG::Window::frameExit(void)
01322 {
01323 std::list<DestroyEntry>::iterator st,en;
01324
01325 st = _glObjectDestroyList.begin();
01326 en = _glObjectDestroyList.end ();
01327
01328 while(st != en)
01329 {
01330 UInt32 i = st->first, n = st->second;
01331
01332 GLObject *obj = _glObjects[ i ];
01333
01334 if(obj == NULL)
01335 {
01336 FDEBUG(("Window::frameExit: objects %d (%d) already destroyed?!?\n",
01337 i, n));
01338 ++st;
01339 continue;
01340 }
01341
01342 UInt32 rc = obj->getRefCounter();
01343
01344
01345 if(getGlObjectLastReinitialize()[i] != 0)
01346 {
01347 _glObjects[i]->getFunctor().call( this, packIdStatus(i, destroy));
01348
01349 if((rc = _glObjects[ i ]->decRefCounter()) <= 0)
01350 {
01351
01352 _glObjects[i]->getFunctor().call( this,
01353 packIdStatus(i, finaldestroy));
01354 }
01355 }
01356
01357
01358 if(rc <= 0)
01359 {
01360 delete _glObjects[ i ];
01361 for ( UInt32 j = 0; j < n ; j++)
01362 {
01363 _glObjects[i+j] = NULL;
01364 }
01365 }
01366
01367 ++st;
01368 }
01369
01370 _glObjectDestroyList.clear();
01371
01372
01373
01374
01375
01376 static bool inited = false;
01377 #ifndef OSG_DEBUG
01378 static bool testGLErrors = false;
01379 #else
01380 static bool testGLErrors = true;
01381 #endif
01382
01383 if(!inited)
01384 {
01385 inited = true;
01386 char *p = getenv("OSG_DEBUG");
01387 if(p)
01388 testGLErrors = true;
01389 }
01390
01391 if(testGLErrors)
01392 {
01393 GLenum glerr;
01394
01395 while((glerr = glGetError()) != GL_NO_ERROR)
01396 {
01397 FWARNING(("Window::frameExit: Caught stray OpenGL error %s (%#x).\n",
01398 gluErrorString(glerr),
01399 glerr));
01400 #ifndef OSG_DEBUG
01401 FWARNING(("Rerun with debug-libraries to get more accurate "
01402 "information.\n"));
01403 #endif
01404 }
01405 }
01406
01407 }
01408
01409
01410
01411
01412
01413
01414
01415
01421 OSG::Window::GLExtensionFunction OSG::Window::getFunctionByName(
01422 const Char8 *s)
01423 {
01424 GLExtensionFunction retval = NULL;
01425
01426 #if defined(darwin)
01427
01428 if (NSIsSymbolNameDefined(s))
01429 {
01430 NSSymbol symbol = NSLookupAndBindSymbol(s);
01431 if (symbol != 0)
01432 retval = GLExtensionFunction(NSAddressOfSymbol(symbol));
01433 }
01434
01435 #elif defined(WIN32)
01436
01437 retval = (void(__cdecl*)(void)) wglGetProcAddress(s);
01438
01439 #elif defined(__sgi) || defined(darwin) || defined(__hpux) || \
01440 defined(__linux) || defined(__sun)
01441
01442
01443
01444
01445 static void (*(*__GetProcAddress)(const GLubyte *))(void) = NULL;
01446
01447 static void *libHandle = NULL;
01448
01449 if(libHandle == NULL)
01450 {
01451 libHandle = dlopen(_glLibraryName, RTLD_NOW | RTLD_LOCAL);
01452
01453 if(!libHandle)
01454 {
01455 FWARNING(("Error in dlopen: %s\n",dlerror()));
01456 abort();
01457 }
01458 else
01459 {
01460 FDEBUG(("Opened lib %s for GL extension handling.\n",
01461 (_glLibraryName==NULL)?"(executable)":_glLibraryName));
01462 }
01463 }
01464
01465 if(__GetProcAddress == NULL)
01466 {
01467 __GetProcAddress = (void (*(*)(const GLubyte*))())
01468 dlsym(libHandle, "glXGetProcAddressARB");
01469
01470 if(__GetProcAddress == NULL)
01471 {
01472 __GetProcAddress = (void (*(*)(const GLubyte*))())
01473 dlsym(libHandle, "glXGetProcAddress");
01474
01475 if(__GetProcAddress == NULL)
01476 {
01477
01478
01479
01480 dlclose(libHandle);
01481
01482 libHandle = dlopen("libGL.so", RTLD_NOW | RTLD_GLOBAL);
01483
01484 if(!libHandle)
01485 {
01486 FWARNING(("Error in dlopen: %s\n",dlerror()));
01487 abort();
01488 }
01489 else
01490 {
01491 FDEBUG(("Opened lib libGL.so for GL extension handling.\n"));
01492 }
01493
01494 __GetProcAddress = (void (*(*)(const GLubyte*))())
01495 dlsym(libHandle, "glXGetProcAddressARB");
01496
01497 if(__GetProcAddress == NULL)
01498 {
01499 __GetProcAddress = (void (*(*)(const GLubyte*))())
01500 dlsym(libHandle, "glXGetProcAddress");
01501 }
01502
01503 if(__GetProcAddress == NULL)
01504 {
01505 FWARNING(("Neither glXGetProcAddress nor "
01506 "glXGetProcAddressARB found! Disabling all "
01507 " extensions for Window %p!\n"));
01508 _availExtensions.clear();
01509 _availExtensions.resize(_registeredExtensions.size(), false);
01510 }
01511 }
01512 else
01513 {
01514 FDEBUG(("Using glXGetProcAddress for GL extension handling.\n"));
01515 }
01516 }
01517 else
01518 {
01519 FDEBUG(("Using glXGetProcAddressARB for GL extension handling.\n"));
01520 }
01521 }
01522
01523 if(__GetProcAddress != NULL)
01524 {
01525 retval = reinterpret_cast<GLExtensionFunction>(__GetProcAddress((const GLubyte*)s));
01526 }
01527 else
01528 {
01529 retval = (GLExtensionFunction)(dlsym(libHandle, s));
01530 }
01531
01532 #else
01533
01534 FWARNING(("Window::getFunctionByName: couldn't find implementation!\n"
01535 "Please contact the developers at info@opensg.org.\n"));
01536 retval = NULL;
01537
01538 #endif
01539
01540 if(retval == NULL)
01541 {
01542 FWARNING(("Window::getFunctionByName: Couldn't get function '%s' for "
01543 "Window %p.\n", s, this));
01544 }
01545 else
01546 {
01547 FDEBUG(("Window::getFunctionByName: got function '%s' for "
01548 "Window %p at %p.\n", s, this, retval));
01549 }
01550
01551 return retval;
01552 }
01553
01554
01558 const Vec2f& OSG::Window::getConstantValuev(GLenum id)
01559 {
01560 static Vec2f inf(Inf, Inf);
01561
01562 ConstHash::iterator it = _availConstants.find(id);
01563
01564 if(it != _availConstants.end())
01565 return _availConstants[id];
01566
01567 return inf;
01568 }
01569
01570
01577 void OSG::Window::setupGL( void )
01578 {
01579 glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
01580 glPixelStorei( GL_PACK_ALIGNMENT, 1 );
01581
01582 glDepthFunc( GL_LEQUAL );
01583 glEnable( GL_DEPTH_TEST );
01584
01585 glEnable( GL_NORMALIZE );
01586
01587
01588 GLfloat nul[4]={0,0,0,0};
01589 glLightfv(GL_LIGHT0, GL_DIFFUSE, nul);
01590 glLightfv(GL_LIGHT0, GL_SPECULAR, nul);
01591
01592 frameInit();
01593 }
01594
01595
01596
01603 void OSG::Window::draw(DrawAction * action)
01604 {
01605 activate();
01606 frameInit();
01607
01608 resizeGL();
01609
01610 drawAllViewports(action);
01611
01612 swap();
01613 frameExit();
01614 }
01615
01621 void OSG::Window::drawAllViewports(DrawAction * action)
01622 {
01623 MFViewportPtr::iterator portIt = _mfPort.begin();
01624 MFViewportPtr::const_iterator portEnd = _mfPort.end();
01625
01626 if(action != NULL)
01627 {
01628 action->setWindow(this);
01629
01630 while(portIt != portEnd)
01631 {
01632 (*portIt)->draw(action);
01633
01634 ++portIt;
01635 }
01636 }
01637 else
01638 {
01639 SWARNING << "Window::drawAllViewports: no action!" << std::endl;
01640 }
01641 }
01642
01649 void OSG::Window::render(RenderActionBase *action)
01650 {
01651 activate();
01652 frameInit();
01653
01654
01655
01656 renderAllViewports(action);
01657
01658 swap();
01659 frameExit();
01660 }
01661
01662
01668 void OSG::Window::renderAllViewports(RenderActionBase *action)
01669 {
01670 MFViewportPtr::iterator portIt = _mfPort.begin();
01671 MFViewportPtr::const_iterator portEnd = _mfPort.end();
01672
01673 if(action != NULL)
01674 {
01675 action->setWindow(this);
01676
01677 while(portIt != portEnd)
01678 {
01679 (*portIt)->render(action);
01680 ++portIt;
01681 }
01682 }
01683 else
01684 {
01685 SWARNING << "Window::renderAllViewports: no action!" << std::endl;
01686 }
01687 }
01688
01689
01695 void OSG::Window::resize( int width, int height )
01696 {
01697 WindowPtr win(*this);
01698 beginEditCP(win, WidthFieldMask|HeightFieldMask|ResizePendingFieldMask);
01699 setWidth( width );
01700 setHeight( height );
01701 setResizePending( true );
01702 endEditCP (win, WidthFieldMask|HeightFieldMask|ResizePendingFieldMask);
01703 }
01704
01705
01711 void OSG::Window::resizeGL( void )
01712 {
01713 if ( isResizePending () )
01714 {
01715 glViewport( 0, 0, getWidth(), getHeight() );
01716 WindowPtr win(*this);
01717 beginEditCP(win, ResizePendingFieldMask);
01718 setResizePending( false );
01719 endEditCP (win, ResizePendingFieldMask);
01720 }
01721 }
01722
01723
01724
01728 OSG::Window& OSG::Window::operator = (const OSG::Window &source)
01729 {
01730 if(this == &source)
01731 return *this;
01732
01733
01734
01735 setWidth(source.getWidth());
01736 setHeight(source.getHeight());
01737 _mfPort.setValues( source._mfPort.getValues() );
01738
01739
01740 doInitRegisterGLObject(1, _glObjects.size() - 1);
01741
01742 return *this;
01743 }
01744
01745
01746
01747
01750 void OSG::Window::dump( UInt32 OSG_CHECK_ARG(uiIndent),
01751 const BitVector OSG_CHECK_ARG(bvFlags )) const
01752 {
01753 SLOG << "Dump Window NI" << std::endl;
01754 }
01755
01756
01757
01758
01759
01760 #ifdef OSG_SGI_CC
01761 #pragma set woff 1174
01762 #endif
01763
01764 #ifdef OSG_LINUX_ICC
01765 #pragma warning( disable : 177 )
01766 #endif
01767
01768 namespace
01769 {
01770 static Char8 cvsid_cpp [] = "@(#)$Id: FCTemplate_cpp.h,v 1.13 2002/06/01 10:37:25 vossg Exp $";
01771 static Char8 cvsid_hpp [] = OSGWINDOW_HEADER_CVSID;
01772 static Char8 cvsid_inl [] = OSGWINDOW_INLINE_CVSID;
01773
01774 static Char8 cvsid_fields_hpp[] = OSGWINDOWFIELDS_HEADER_CVSID;
01775 }
01776
01777 #ifdef __sgi
01778 #pragma reset woff 1174
01779 #endif
01780