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
00239
00240
00241 std::vector<GLenum > OSG::Window::_registeredConstants;
00242
00243
00244
00245 const Real32 OSG::Window::unknownConstant = -1e100;
00246
00247
00248
00249
00250
00251
00252
00253
00254
00258 void OSG::Window::initMethod (void)
00259 {
00260 }
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00276 OSG::Window::Window(void) :
00277 Inherited( ),
00278 _windowId (0)
00279 {
00280
00281 }
00282
00286 OSG::Window::Window(const Window &source) :
00287 Inherited(source),
00288 _glObjectDestroyList(source._glObjectDestroyList),
00289 _lastValidate(source._lastValidate.size(),0),
00290 _ids(source._ids.size(),0),
00291 _extensions(),
00292 _availExtensions(),
00293 _extFunctions(),
00294 _availConstants(),
00295 _numAvailConstants(0),
00296 _windowId(0)
00297 {
00298
00299 doInitRegisterGLObject(1, _glObjects.size() - 1);
00300 }
00301
00305 OSG::Window::~Window(void)
00306 {
00307
00308 }
00309
00310
00311
00312
00313
00314
00318 void OSG::Window::onCreate(const Window *)
00319 {
00320
00321 if(GlobalSystemState != Running)
00322 return;
00323
00324 _allWindows.push_back(WindowPtr(this));
00325
00326 _windowId = ++_currentWindowId;
00327 }
00328
00329 void OSG::Window::onCreateAspect(const Window *, const Window *)
00330 {
00331
00332 if(GlobalSystemState != Running)
00333 return;
00334
00335 _windowId = _currentWindowId;
00336 }
00337
00341 void OSG::Window::onDestroy(void)
00342 {
00343
00344 for(UInt32 i = 1; i < _glObjects.size(); ++i)
00345 {
00346 GLObject *obj = _glObjects[i];
00347 if(obj == NULL)
00348 {
00349 FDEBUG(("Window::onDestroy: object %u already destroyed!\n", i));
00350 continue;
00351 }
00352
00353 if(i < getGlObjectLastReinitialize().size() && getGlObjectLastReinitialize()[i] != 0)
00354 {
00355 obj->decRefCounter();
00356
00357
00358
00359 }
00360 }
00361
00362 std::vector<WindowPtr>::iterator it;
00363 it = std::find(_allWindows.begin(), _allWindows.end(), WindowPtr(this));
00364
00365
00366 if(it != _allWindows.end())
00367 _allWindows.erase( it );
00368 }
00369
00370 void OSG::Window::staticAcquire(void)
00371 {
00372
00373 if(GlobalSystemState != Running)
00374 return;
00375
00376 if(_staticWindowLock == NULL)
00377 {
00378 _staticWindowLock = ThreadManager::the()->getLock(NULL);
00379 }
00380 _staticWindowLock->aquire();
00381 }
00382
00383 void OSG::Window::staticRelease(void)
00384 {
00385
00386 if(GlobalSystemState != Running)
00387 return;
00388
00389 _staticWindowLock->release();
00390 }
00391
00392
00393
00394
00395
00399 void OSG::Window::changed(BitVector whichField, UInt32 origin)
00400 {
00401 Inherited::changed(whichField, origin);
00402 }
00403
00404
00405
00406 void OSG::Window::addPort(const ViewportPtr &portP)
00407 {
00408 if(portP != NullFC)
00409 {
00410 _mfPort.push_back(portP);
00411
00412
00413
00414 beginEditCP(portP, Viewport::ParentFieldMask);
00415 {
00416 _mfPort.back()->setParent(WindowPtr(*this));
00417 }
00418 endEditCP (portP, Viewport::ParentFieldMask);
00419 }
00420 }
00421
00422 void OSG::Window::insertPort(UInt32 portIndex, const ViewportPtr &portP)
00423 {
00424 MFViewportPtr::iterator portIt = _mfPort.begin();
00425
00426 if(portP != NullFC)
00427 {
00428 portIt += portIndex;
00429
00430
00431
00432
00433
00434 beginEditCP(portP, Viewport::ParentFieldMask);
00435 {
00436 (*(_mfPort.insert(portIt, portP)))->setParent(
00437 WindowPtr(*this));
00438 }
00439 endEditCP (portP, Viewport::ParentFieldMask);
00440
00441 }
00442 }
00443
00444
00445 void OSG::Window::replacePort(UInt32 portIndex, const ViewportPtr &portP)
00446 {
00447 if(portP != NullFC)
00448 {
00449 _mfPort[portIndex]->setParent(NullFC);
00450 _mfPort[portIndex] = portP;
00451
00452
00453
00454 _mfPort[portIndex]->setParent(
00455 WindowPtr(*this));
00456 }
00457 }
00458
00459 void OSG::Window::replacePortBy(const ViewportPtr &portP,
00460 const ViewportPtr &newportP)
00461 {
00462 MFViewportPtr::iterator portIt = _mfPort.find(portP);
00463
00464 if(newportP != NullFC)
00465 {
00466 if(portIt != _mfPort.end())
00467 {
00468 (*portIt)->setParent(NullFC);
00469 (*portIt) = newportP;
00470
00471
00472
00473 (*portIt)->setParent(
00474 WindowPtr(*this));
00475 }
00476 }
00477 }
00478
00479 void OSG::Window::subPort(const ViewportPtr &portP)
00480 {
00481 MFViewportPtr::iterator portIt = _mfPort.find(portP);
00482
00483 if(portIt != _mfPort.end())
00484 {
00485 (*portIt)->setParent(NullFC);
00486
00487 _mfPort.erase(portIt);
00488 }
00489
00490 }
00491
00492 void OSG::Window::subPort(UInt32 portIndex)
00493 {
00494 MFViewportPtr::iterator portIt = _mfPort.begin();
00495
00496 portIt += portIndex;
00497
00498 if(portIt != _mfPort.end())
00499 {
00500 (*portIt)->setParent(NullFC);
00501
00502 _mfPort.erase(portIt);
00503 }
00504 }
00505
00506
00507 #if !defined(OSG_DO_DOC) || defined(OSG_DOC_EXT)
00508
00509
00510
00519 UInt32 OSG::Window::registerGLObject(GLObjectFunctor functor, UInt32 num)
00520 {
00521 UInt32 id, i;
00522 GLObject *pGLObject;
00523
00524 staticAcquire();
00525
00526
00527 if(_glObjects.empty())
00528 _glObjects.push_back( NULL );
00529
00530 id = _glObjects.size();
00531 pGLObject = new GLObject(functor);
00532
00533
00534
00535 if(_glObjects.capacity() >= id + num)
00536 {
00537 _glObjects.insert(_glObjects.end(), num, pGLObject );
00538
00539 initRegisterGLObject(id, num);
00540
00541 staticRelease();
00542
00543 return id;
00544 }
00545
00546
00547
00548 UInt32 cnt = 0;
00549
00550
00551 for(i = 1; i < _glObjects.size(); ++i)
00552 {
00553 if(!_glObjects[i])
00554 {
00555 if(cnt == 0)
00556 {
00557 id = i;
00558 }
00559
00560 ++cnt;
00561
00562 if(cnt == num)
00563 {
00564
00565
00566 while(i >= id)
00567 {
00568 _glObjects[i] = pGLObject;
00569 i = i - 1;
00570 }
00571
00572 initRegisterGLObject(id, num);
00573
00574 staticRelease();
00575
00576 return id;
00577 }
00578 }
00579 else
00580 {
00581 cnt = 0;
00582 }
00583 }
00584
00585
00586
00587
00588 i = id + cnt - 1;
00589 while ( i >= id )
00590 {
00591 _glObjects[i] = pGLObject;
00592 i = i - 1;
00593 }
00594
00595
00596 for ( i = 1; i <= num - cnt; i++ )
00597 {
00598 _glObjects.push_back( pGLObject );
00599 }
00600
00601 initRegisterGLObject(id, num);
00602
00603 staticRelease();
00604
00605 return id;
00606 }
00607
00614 void OSG::Window::validateGLObject(UInt32 id)
00615 {
00616 if ( id == 0 )
00617 {
00618 SWARNING << "Window::validateGLObject: id is 0!" << std::endl;
00619 return;
00620 }
00621
00622 GLObject *obj = _glObjects[id];
00623
00624 if(obj == NULL)
00625 {
00626 SWARNING << "Window::validateGLObject: obj is NULL!" << std::endl;
00627 return;
00628 }
00629
00630 if(id >= _lastValidate.size())
00631 {
00632 _lastValidate.insert(_lastValidate.end(),
00633 id + 1 - _lastValidate.size(),
00634 0);
00635 }
00636
00637 FDEBUG(("Window 0x%p (event %d,ri:%d,rf:%d): "
00638 "Validating object %d: last reinit:%d, last validate:"
00639 "%d last refresh: %d => %s\n",
00640 this, getGlObjectEventCounter(),
00641 _mfGlObjectLastReinitialize.size(),
00642 _mfGlObjectLastRefresh.size(),
00643 id,
00644 (_mfGlObjectLastReinitialize.size() > id)?
00645 _mfGlObjectLastReinitialize[id]:0xffffffff,
00646 _lastValidate[id],
00647 (_mfGlObjectLastRefresh.size() > id)?
00648 _mfGlObjectLastRefresh[id]:0xffffffff,
00649 (_mfGlObjectLastReinitialize[id] == 0)?"init":
00650 ((_mfGlObjectLastReinitialize[id] > _lastValidate[id])?"reinit":
00651 ((_mfGlObjectLastRefresh[id] > _lastValidate[id])?"refresh":
00652 "up-to-date"))
00653 ));
00654
00655 if(_mfGlObjectLastReinitialize[id] == 0)
00656 {
00657 obj->incRefCounter();
00658 obj->getFunctor().call(this, packIdStatus(id, initialize));
00659 _mfGlObjectLastReinitialize[id] = 1;
00660 _lastValidate[id] = getGlObjectEventCounter();
00661 }
00662 else if(_mfGlObjectLastReinitialize[id] > _lastValidate[id])
00663 {
00664 obj->getFunctor().call(this, packIdStatus(id, reinitialize));
00665 _lastValidate[id] = getGlObjectEventCounter();
00666 }
00667 else if(_mfGlObjectLastRefresh[id] > _lastValidate[id])
00668 {
00669 obj->getFunctor().call(this, packIdStatus(id, needrefresh));
00670 _lastValidate[id] = getGlObjectEventCounter();
00671 }
00672 }
00673
00674
00681 void OSG::Window::validateAllGLObjects(void)
00682 {
00683 activate();
00684 frameInit();
00685
00686 for (UInt32 i = 1; i < _glObjects.size(); ++i)
00687 validateGLObject(i);
00688
00689 frameExit();
00690 }
00691
00698 void OSG::Window::refreshGLObject( UInt32 id )
00699 {
00700 if ( id == 0 )
00701 {
00702 SWARNING << "Window::refreshGLObject: id is 0!" << std::endl;
00703 return;
00704 }
00705
00706 std::vector<WindowPtr>::iterator it;
00707
00708 for ( it = _allWindows.begin(); it != _allWindows.end(); ++it)
00709 {
00710 beginEditCP(*it, GlObjectEventCounterFieldMask|
00711 GlObjectLastRefreshFieldMask);
00712
00713 UInt32 lastinv = (*it)->getGlObjectEventCounter() + 1;
00714 MFUInt32 &field = (*it)->_mfGlObjectLastRefresh;
00715 if(field.size() <= id)
00716 field.getValues().insert(field.end(), id - field.size() + 1, 0 );
00717 field[id] = lastinv;
00718 (*it)->setGlObjectEventCounter(lastinv);
00719
00720 endEditCP (*it, GlObjectEventCounterFieldMask|
00721 GlObjectLastRefreshFieldMask);
00722 }
00723 }
00724
00731 void OSG::Window::reinitializeGLObject(UInt32 id)
00732 {
00733 if ( id == 0 )
00734 {
00735 SWARNING << "Window::reinitializeGLObject: id is 0!" << std::endl;
00736 return;
00737 }
00738
00739 std::vector<WindowPtr>::iterator it;
00740
00741 for(it = _allWindows.begin(); it != _allWindows.end(); ++it)
00742 {
00743 beginEditCP(*it, GlObjectEventCounterFieldMask|
00744 GlObjectLastReinitializeFieldMask);
00745
00746 UInt32 lastinv = (*it)->getGlObjectEventCounter() + 1;
00747
00748 MFUInt32 &field = (*it)->_mfGlObjectLastReinitialize;
00749 if(field.size() < id)
00750 field.getValues().insert(field.end(), id - field.size() + 1, 0 );
00751
00752 if(field[id] == 0)
00753 continue;
00754 field[id] = lastinv;
00755 (*it)->setGlObjectEventCounter(lastinv);
00756
00757 endEditCP (*it, GlObjectEventCounterFieldMask|
00758 GlObjectLastReinitializeFieldMask);
00759 }
00760 }
00761
00768 void OSG::Window::initRegisterGLObject(UInt32 id, UInt32 num)
00769 {
00770 if ( id == 0 )
00771 {
00772 SWARNING << "Window::initRegisterGLObject: id is 0!" << std::endl;
00773 return;
00774 }
00775
00776 std::vector<WindowPtr>::iterator it;
00777
00778 for(it = _allWindows.begin(); it != _allWindows.end(); ++it)
00779 {
00780 (*it)->doInitRegisterGLObject(id, num);
00781 }
00782 }
00783
00790 void OSG::Window::doInitRegisterGLObject(UInt32 id, UInt32 num)
00791 {
00792 WindowPtr win(this);
00793
00794 beginEditCP(win, GlObjectLastReinitializeFieldMask|
00795 GlObjectLastRefreshFieldMask);
00796
00797 if(_mfGlObjectLastReinitialize.size() < id + num)
00798 {
00799 _mfGlObjectLastReinitialize.resize(id + num);
00800 _mfGlObjectLastRefresh.resize(id + num);
00801 _lastValidate.resize(id + num);
00802 }
00803
00804 for(UInt32 i = id; i < id + num; ++i)
00805 {
00806 _mfGlObjectLastReinitialize[i] = 0;
00807 _mfGlObjectLastRefresh [i] = 0;
00808 _lastValidate[i] = 0;
00809 }
00810
00811 endEditCP (win, GlObjectLastReinitializeFieldMask|
00812 GlObjectLastRefreshFieldMask);
00813 }
00814
00821 void OSG::Window::destroyGLObject(UInt32 id, UInt32 num)
00822 {
00823 std::vector<WindowPtr>::iterator it;
00824
00825 for(it = _allWindows.begin(); it != _allWindows.end(); ++it)
00826 {
00827 #ifdef OSG_DEBUG
00828 if(id + num > (*it)->_mfGlObjectLastReinitialize.size())
00829 {
00830 FWARNING(("Window::destroyGLObject:: id %d + num %d exceed"
00831 "registered objects size %d!\n", id, num,
00832 (*it)->_mfGlObjectLastReinitialize.size()));
00833 return;
00834 }
00835 #endif
00836
00837 if((*it)->getGlObjectLastReinitialize()[id] != 0)
00838 (*it)->_glObjectDestroyList.push_back(DestroyEntry(id,num));
00839 }
00840 }
00841
00842
00843
00844
00845
00849 UInt32 OSG::Window::registerExtension(const Char8 *s)
00850 {
00851 FDEBUG(("Window::registerExtension: register '%s': ", s));
00852 staticAcquire();
00853
00854 if(s == NULL)
00855 {
00856 staticRelease();
00857 return TypeTraits<UInt32>::getMax();
00858 }
00859
00860 std::vector<std::string>::iterator i;
00861
00862 i = std::find(_registeredExtensions.begin(), _registeredExtensions.end(),
00863 s);
00864
00865 if(i < _registeredExtensions.end())
00866 {
00867 staticRelease();
00868 FPDEBUG(("reusing id %d\n", i - _registeredExtensions.begin()));
00869 return i - _registeredExtensions.begin();
00870 }
00871
00872 UInt32 r = _registeredExtensions.size();
00873 _registeredExtensions.push_back(s);
00874
00875 FPDEBUG(("new id %d\n", r));
00876
00877 staticRelease();
00878 return r;
00879 }
00880
00885 bool OSG::Window::hasExtension(const Char8 *s)
00886 {
00887 if(std::find(_ignoredExtensions.begin(),
00888 _ignoredExtensions.end(),
00889 s) != _ignoredExtensions.end())
00890 {
00891 return false;
00892 }
00893
00894 if(std::find(_extensions.begin(),
00895 _extensions.end(),
00896 s) != _extensions.end())
00897 {
00898 return true;
00899 }
00900
00901 return false;
00902 }
00903
00906 void OSG::Window::ignoreExtensions(const Char8 *s)
00907 {
00908 FDEBUG(("Window:: Ignoring extensions '%s'\n", s));
00909
00910 staticAcquire();
00911
00912 std::back_insert_iterator< std::vector<std::string> >
00913 extension_back_inserter(_ignoredExtensions);
00914
00915 std::string toex(s);
00916
00917 for(string_token_iterator ignit = string_token_iterator(toex, ",. ");
00918 ignit != string_token_iterator(); ++ignit)
00919 {
00920 std::string ignore = *ignit;
00921
00922 FDEBUG(("Ignoring '%s':", ignore.c_str()));
00923
00924 if(std::find(_ignoredExtensions.begin(),
00925 _ignoredExtensions.end(),
00926 ignore.c_str()) != _ignoredExtensions.end())
00927 {
00928 FPDEBUG((" already ignored.\n"));
00929 continue;
00930 }
00931
00932 _ignoredExtensions.push_back(ignore);
00933
00934 std::vector<std::string>::iterator regit;
00935
00936
00937
00938 regit = std::find(_registeredExtensions.begin(),
00939 _registeredExtensions.end(),
00940 ignore.c_str());
00941
00942 Int32 ind = -1;
00943
00944 if(regit != _registeredExtensions.end())
00945 {
00946 ind = regit - _registeredExtensions.begin();
00947 FPDEBUG(("(reg as %d)", ind));
00948 }
00949
00950
00951
00952
00953 std::vector<WindowPtr>::iterator winit;
00954
00955 for(winit = _allWindows.begin(); winit != _allWindows.end(); ++winit)
00956 {
00957 FPDEBUG((" %p:", (*winit).getCPtr()));
00958
00959 std::vector<std::string>::iterator extit;
00960
00961 extit = std::find((*winit)->_extensions.begin(),
00962 (*winit)->_extensions.end(),
00963 ignore.c_str());
00964
00965 if(extit != (*winit)->_extensions.end())
00966 {
00967 FPDEBUG((" removed"));
00968 (*winit)->_extensions.erase(extit);
00969 }
00970 else
00971 {
00972 FPDEBUG((" nonsupp"));
00973 }
00974
00975 if(ind >= 0)
00976 {
00977 if((*winit)->_availExtensions.size() > UInt32(ind))
00978 {
00979 (*winit)->_availExtensions[ind] = false;
00980 FPDEBUG((" disabled"));
00981 }
00982 if((*winit)->_commonExtensions.size() > UInt32(ind))
00983 {
00984 (*winit)->_commonExtensions[ind] = false;
00985 FPDEBUG((" uncommoned"));
00986 }
00987 }
00988 }
00989 FPDEBUG(("\n"));
00990 }
00991
00992 std::sort(_ignoredExtensions.begin(), _ignoredExtensions.end());
00993
00994 staticRelease();
00995 }
00996
01000 UInt32 OSG::Window::registerFunction(const Char8 *s, Int32 ext)
01001 {
01002 if(s == NULL)
01003 return TypeTraits<UInt32>::getMax();
01004
01005 FDEBUG(("Window::registerFunction: register '%s': ", s));
01006
01007 staticAcquire();
01008
01009 std::vector<std::string>::iterator i;
01010
01011 i = std::find(_registeredFunctions.begin(), _registeredFunctions.end(),
01012 s);
01013
01014 if(i < _registeredFunctions.end())
01015 {
01016 staticRelease();
01017 FPDEBUG(("reusing id %d\n", i - _registeredFunctions.begin()));
01018 return i - _registeredFunctions.begin();
01019 }
01020
01021 UInt32 r=_registeredFunctions.size();
01022 _registeredFunctions.push_back(s);
01023 _registeredFunctionExts.push_back(ext);
01024
01025 FPDEBUG(("new id %d\n", r));
01026
01027 staticRelease();
01028 return r;
01029 }
01030
01034 void OSG::Window::registerConstant(GLenum val)
01035 {
01036 staticAcquire();
01037
01038 _registeredConstants.push_back(val);
01039
01040 staticRelease();
01041 }
01042
01043 #endif // remove the OpenGL object handling from user docs
01044
01050 void OSG::Window::dumpExtensions(void)
01051 {
01052 std::vector<std::string>::iterator it;
01053 std::cout << "GL Extensions: ";
01054 for ( it = _extensions.begin(); it != _extensions.end(); it++ )
01055 {
01056 std::cout << it->c_str() << ", ";
01057 }
01058 std::cout << std::endl;
01059 }
01060
01061
01072 void OSG::Window::frameInit(void)
01073 {
01074 static bool ignoreEnvDone = false;
01075
01076 if(!ignoreEnvDone)
01077 {
01078 ignoreEnvDone = true;
01079 char *p = getenv("OSG_IGNORE_EXTENSIONS");
01080 if(p)
01081 ignoreExtensions(p);
01082 }
01083
01084
01085 if(_extensions.empty())
01086 {
01087 FDEBUG(("Window %p: GL Extensions: %s\n", this,
01088 glGetString(GL_EXTENSIONS) ));
01089
01090 std::string foo(reinterpret_cast<const char*>
01091 (glGetString(GL_EXTENSIONS)));
01092
01093 for(string_token_iterator it = string_token_iterator(foo, ",. ");
01094 it != string_token_iterator(); ++it)
01095 {
01096 if(! std::binary_search(_ignoredExtensions.begin(),
01097 _ignoredExtensions.end(),
01098 *it))
01099 {
01100 _extensions.push_back(*it);
01101 }
01102 }
01103 std::sort(_extensions.begin(), _extensions.end());
01104
01105
01106 if(_extensions.empty())
01107 _availExtensions.resize(_registeredExtensions.size(), false);
01108 }
01109
01110
01111 if(_registeredExtensions.size() > _availExtensions.size())
01112 {
01113 staticAcquire();
01114 FDEBUG(("Window %p: exts: ", this));
01115
01116 while(_registeredExtensions.size() > _availExtensions.size())
01117 {
01118 UInt32 s = _availExtensions.size();
01119
01120
01121
01122
01123 bool supported = std::binary_search(
01124 _extensions.begin(),
01125 _extensions.end(),
01126 _registeredExtensions[s]);
01127
01128 _availExtensions.push_back(supported);
01129 FPDEBUG(("%s:", _registeredExtensions[s].c_str()));
01130 if(_commonExtensions.size() <= s)
01131 {
01132 _commonExtensions.push_back(supported);
01133 FPDEBUG(("ok "));
01134 }
01135 else if (!supported)
01136 {
01137 _commonExtensions[s] = false;
01138 FPDEBUG(("NF "));
01139 }
01140 }
01141 FPDEBUG(("\n"));
01142 staticRelease();
01143 }
01144
01145
01146 while(_registeredFunctions.size() > _extFunctions.size())
01147 {
01148 const Char8 *s = _registeredFunctions[_extFunctions.size()].c_str();
01149 Int32 ext = _registeredFunctionExts[_extFunctions.size()];
01150 void *func = NULL;
01151
01152 if(ext == -1 || _availExtensions[ext] == true)
01153 func = (void*)getFunctionByName(s);
01154
01155 _extFunctions.push_back(func);
01156 }
01157
01158
01159 while(_registeredConstants.size() > _numAvailConstants)
01160 {
01161 for(std::vector<GLenum>::iterator it = _registeredConstants.begin() +
01162 _numAvailConstants;
01163 it != _registeredConstants.end();
01164 ++it)
01165 {
01166 Vec2f val(unknownConstant, unknownConstant);
01167 glGetFloatv(*it, static_cast<GLfloat*>(val.getValues()));
01168 _availConstants[*it] = val;
01169 FDEBUG(("Window(%p): Constant 0x%x value is %.3f %.3f\n", this,
01170 *it, val[0], val[1]));
01171 }
01172 _numAvailConstants = _registeredConstants.size();
01173 glGetError();
01174 }
01175 }
01176
01185 void OSG::Window::frameExit(void)
01186 {
01187 std::list<DestroyEntry>::iterator st,en;
01188
01189 st = _glObjectDestroyList.begin();
01190 en = _glObjectDestroyList.end ();
01191
01192 while(st != en)
01193 {
01194 UInt32 i = st->first, n = st->second;
01195
01196 GLObject *obj = _glObjects[ i ];
01197
01198 if(obj == NULL)
01199 {
01200 FDEBUG(("Window::frameExit: objects %d (%d) already destroyed?!?\n",
01201 i, n));
01202 ++st;
01203 continue;
01204 }
01205
01206 UInt32 rc = obj->getRefCounter();
01207
01208
01209 if(getGlObjectLastReinitialize()[i] != 0)
01210 {
01211 _glObjects[i]->getFunctor().call( this, packIdStatus(i, destroy));
01212
01213 if((rc = _glObjects[ i ]->decRefCounter()) <= 0)
01214 {
01215
01216 _glObjects[i]->getFunctor().call( this,
01217 packIdStatus(i, finaldestroy));
01218 }
01219 }
01220
01221
01222 if(rc <= 0)
01223 {
01224 delete _glObjects[ i ];
01225 for ( UInt32 j = 0; j < n ; j++)
01226 {
01227 _glObjects[i+j] = NULL;
01228 }
01229 }
01230 ++st;
01231 }
01232
01233 _glObjectDestroyList.clear();
01234
01235
01236
01237
01238 GLenum glerr;
01239
01240 while((glerr = glGetError()) != GL_NO_ERROR)
01241 {
01242 FWARNING(("Window::frameExit: Caught stray OpenGL error %s (%#x).\n",
01243 gluErrorString(glerr),
01244 glerr));
01245 #ifndef OSG_DEBUG
01246 FWARNING(("Rerun with debug-libraries to get more accurate "
01247 "information.\n"));
01248 #endif
01249 }
01250
01251 }
01252
01253
01254
01255
01256
01257
01258
01259
01265 OSG::Window::GLExtensionFunction OSG::Window::getFunctionByName(
01266 const Char8 *s)
01267 {
01268 GLExtensionFunction retval = NULL;
01269
01270 #if defined(darwin)
01271
01272 if (NSIsSymbolNameDefined(s))
01273 {
01274 NSSymbol symbol = NSLookupAndBindSymbol(s);
01275 if (symbol != 0)
01276 retval = GLExtensionFunction(NSAddressOfSymbol(symbol));
01277 }
01278
01279 #elif defined(WIN32)
01280
01281 retval = (void(__cdecl*)(void)) wglGetProcAddress(s);
01282
01283 #elif defined(__sgi) || defined(darwin) || defined(__hpux) || \
01284 defined(__linux) || defined(__sun)
01285
01286
01287
01288
01289 static void (*(*__GetProcAddress)(const GLubyte *))(void) = NULL;
01290
01291 static void *libHandle = NULL;
01292
01293 if(libHandle == NULL)
01294 {
01295 libHandle = dlopen(_glLibraryName, RTLD_NOW | RTLD_LOCAL);
01296
01297 if(!libHandle)
01298 {
01299 FWARNING(("Error in dlopen: %s\n",dlerror()));
01300 abort();
01301 }
01302 else
01303 {
01304 FDEBUG(("Opened lib %s for GL extension handling.\n",
01305 (_glLibraryName==NULL)?"(executable)":_glLibraryName));
01306 }
01307 }
01308
01309 if(__GetProcAddress == NULL)
01310 {
01311 __GetProcAddress = (void (*(*)(const GLubyte*))()) dlsym(libHandle, "glXGetProcAddressARB");
01312
01313 if(__GetProcAddress == NULL)
01314 {
01315 __GetProcAddress = (void (*(*)(const GLubyte*))()) dlsym(libHandle, "glXGetProcAddress");
01316
01317 if(__GetProcAddress == NULL)
01318 {
01319 FWARNING(("Neither glXGetProcAddress nor "
01320 "glXGetProcAddressARB found! Disabling all "
01321 " extensions for Window %p!"));
01322 _availExtensions.clear();
01323 _availExtensions.resize(_registeredExtensions.size(), false);
01324 }
01325 else
01326 {
01327 FDEBUG(("Using glXGetProcAddress for GL extension handling.\n"));
01328 }
01329 }
01330 else
01331 {
01332 FDEBUG(("Using glXGetProcAddressARB for GL extension handling.\n"));
01333 }
01334 }
01335
01336 if(__GetProcAddress != NULL)
01337 {
01338 retval = reinterpret_cast<GLExtensionFunction>(__GetProcAddress((const GLubyte*)s));
01339 }
01340 else
01341 {
01342 retval = (GLExtensionFunction)(dlsym(libHandle, s));
01343 }
01344
01345 #else
01346
01347 FWARNING(("Window::getFunctionByName: couldn't find implementation!\n"
01348 "Please contact the developers at info@opensg.org.\n"));
01349 retval = NULL;
01350
01351 #endif
01352
01353 if(retval == NULL)
01354 {
01355 FWARNING(("Window::getFunctionByName: Couldn't get function '%s' for "
01356 "Window %p.\n", s, this));
01357 }
01358 else
01359 {
01360 FDEBUG(("Window::getFunctionByName: got function '%s' for "
01361 "Window %p at %p.\n", s, this, retval));
01362 }
01363
01364 return retval;
01365 }
01366
01367
01371 const Vec2f& OSG::Window::getConstantValuev(GLenum id)
01372 {
01373 static Vec2f inf(Inf, Inf);
01374
01375 ConstHash::iterator it = _availConstants.find(id);
01376
01377 if(it != _availConstants.end())
01378 return _availConstants[id];
01379
01380 return inf;
01381 }
01382
01383
01390 void OSG::Window::setupGL( void )
01391 {
01392 glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
01393 glPixelStorei( GL_PACK_ALIGNMENT, 1 );
01394
01395 glDepthFunc( GL_LEQUAL );
01396 glEnable( GL_DEPTH_TEST );
01397
01398 glEnable( GL_NORMALIZE );
01399
01400
01401 GLfloat nul[4]={0,0,0,0};
01402 glLightfv(GL_LIGHT0, GL_DIFFUSE, nul);
01403 glLightfv(GL_LIGHT0, GL_SPECULAR, nul);
01404
01405 frameInit();
01406 }
01407
01408
01409
01416 void OSG::Window::draw(DrawAction * action)
01417 {
01418 activate();
01419 frameInit();
01420
01421 resizeGL();
01422
01423 drawAllViewports(action);
01424
01425 swap();
01426 frameExit();
01427 }
01428
01434 void OSG::Window::drawAllViewports(DrawAction * action)
01435 {
01436 MFViewportPtr::iterator portIt = _mfPort.begin();
01437 MFViewportPtr::const_iterator portEnd = _mfPort.end();
01438
01439 if(action != NULL)
01440 {
01441 action->setWindow(this);
01442
01443 while(portIt != portEnd)
01444 {
01445 (*portIt)->draw(action);
01446
01447 ++portIt;
01448 }
01449 }
01450 else
01451 {
01452 SWARNING << "Window::drawAllViewports: no action!" << std::endl;
01453 }
01454 }
01455
01462 void OSG::Window::render(RenderActionBase *action)
01463 {
01464 activate();
01465 frameInit();
01466
01467
01468
01469 renderAllViewports(action);
01470
01471 swap();
01472 frameExit();
01473 }
01474
01475
01481 void OSG::Window::renderAllViewports(RenderActionBase *action)
01482 {
01483 MFViewportPtr::iterator portIt = _mfPort.begin();
01484 MFViewportPtr::const_iterator portEnd = _mfPort.end();
01485
01486 if(action != NULL)
01487 {
01488 action->setWindow(this);
01489
01490 while(portIt != portEnd)
01491 {
01492 (*portIt)->render(action);
01493 ++portIt;
01494 }
01495 }
01496 else
01497 {
01498 SWARNING << "Window::renderAllViewports: no action!" << std::endl;
01499 }
01500 }
01501
01502
01508 void OSG::Window::resize( int width, int height )
01509 {
01510 WindowPtr win(*this);
01511 beginEditCP(win, WidthFieldMask|HeightFieldMask|ResizePendingFieldMask);
01512 setWidth( width );
01513 setHeight( height );
01514 setResizePending( true );
01515 endEditCP (win, WidthFieldMask|HeightFieldMask|ResizePendingFieldMask);
01516 }
01517
01518
01524 void OSG::Window::resizeGL( void )
01525 {
01526 if ( isResizePending () )
01527 {
01528 glViewport( 0, 0, getWidth(), getHeight() );
01529 WindowPtr