Show
Ignore:
Timestamp:
11/20/09 12:39:10 (5 years ago)
Author:
robert
Message:

From Himar Carmona, " this submission resolves an issue regarding the setup of a slave camera with an (incorrect) coding style. Sharing the same instance of osg::Viewport with a camera and a slave camera causes incorrect rescaling in GraphicsContext::resizedImplementation, due to the viewport being rescaled twice (once per camera). Though viewports sharing is not intentional, it can be done with the current version of OSG and be a potential pitfall for anyone.

As Robert pointed out, i opted for modifying the resize code where the break is to minimize code changes, avoiding the duplicate resize of the viewport with the use of a vector and a search for duplicates. Not very elegant (avoiding an effect of a cause), another approach could be ripping out the method osg::Camera::setViewport(osg::Viewport*) which is more inline with Roberts rationale behind not to share viewports between cameras and left only its overloaded method setViewport(x,y,width,height). But this approach need some refactoring due to the intense use of the method. Notice also that the resize works well without this change if no sharing occurs, and the user of the method can opt for always call setViewport with a new instance.

"

Note from Robert Osfield, changed this submission to use an std::set<Viewport*> rather than an std::vector<> as it keeps the code a bit cleaner and more compact.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • OpenSceneGraph/trunk/src/osg/GraphicsContext.cpp

    r10764 r10804  
    844844void GraphicsContext::resizedImplementation(int x, int y, int width, int height) 
    845845{ 
     846    std::set<osg::Viewport*> processedViewports; 
     847 
    846848    if (!_traits) return; 
    847849     
     
    850852    double aspectRatioChange = widthChangeRatio / heigtChangeRatio;  
    851853     
     854 
    852855    for(Cameras::iterator itr = _cameras.begin(); 
    853856        itr != _cameras.end(); 
     
    862865        if (viewport) 
    863866        { 
    864             if (viewport->x()==0 && viewport->y()==0 && 
    865                 viewport->width()>=_traits->width && viewport->height()>=_traits->height) 
     867            // avoid processing a shared viewport twice 
     868            if (processedViewports.count(viewport)==0) 
    866869            { 
    867                 viewport->setViewport(0,0,width,height); 
    868             } 
    869             else 
    870             { 
    871                 viewport->x() = static_cast<osg::Viewport::value_type>(double(viewport->x())*widthChangeRatio); 
    872                 viewport->y() = static_cast<osg::Viewport::value_type>(double(viewport->y())*heigtChangeRatio); 
    873                 viewport->width() = static_cast<osg::Viewport::value_type>(double(viewport->width())*widthChangeRatio); 
    874                 viewport->height() = static_cast<osg::Viewport::value_type>(double(viewport->height())*heigtChangeRatio); 
     870                processedViewports.insert(viewport); 
     871 
     872                if (viewport->x()==0 && viewport->y()==0 && 
     873                    viewport->width()>=_traits->width && viewport->height()>=_traits->height) 
     874                { 
     875                    viewport->setViewport(0,0,width,height); 
     876                } 
     877                else 
     878                { 
     879                    viewport->x() = static_cast<osg::Viewport::value_type>(double(viewport->x())*widthChangeRatio); 
     880                    viewport->y() = static_cast<osg::Viewport::value_type>(double(viewport->y())*heigtChangeRatio); 
     881                    viewport->width() = static_cast<osg::Viewport::value_type>(double(viewport->width())*widthChangeRatio); 
     882                    viewport->height() = static_cast<osg::Viewport::value_type>(double(viewport->height())*heigtChangeRatio); 
     883                } 
    875884            } 
    876885        }