Пример #1
0
void WindowCaptureCallback::operator () (osg::RenderInfo& renderInfo) const
{
#if !defined(OSG_GLES1_AVAILABLE) && !defined(OSG_GLES2_AVAILABLE)
    glReadBuffer(_readBuffer);
#endif

    osg::GraphicsContext* gc = renderInfo.getState()->getGraphicsContext();
    osg::ref_ptr<ContextData> cd = getContextData(gc);
    cd->read();

    // If _numFrames is > 0 it means capture that number of frames.
    if (_numFrames > 0)
    {
        --_numFrames;
        if (_numFrames == 0)
        {
            // the callback must remove itself when it's done.
            if (_position == START_FRAME)
                renderInfo.getCurrentCamera()->setInitialDrawCallback(0);
            if (_position == END_FRAME)
                renderInfo.getCurrentCamera()->setFinalDrawCallback(0);
        }
    }

    int prec = osg::notify(osg::INFO).precision(5);
    OSG_INFO << "ScreenCaptureHandler: "
                           << "copy="      << (cd->_timeForFullCopy*1000.0f)             << "ms, "
                           << "operation=" << (cd->_timeForCaptureOperation*1000.0f)     << "ms, "
                           << "total="     << (cd->_timeForFullCopyAndOperation*1000.0f) << std::endl;
    osg::notify(osg::INFO).precision(prec);

    cd->_timeForFullCopy = 0;
}
Пример #2
0
    virtual void operator () (osg::RenderInfo& renderInfo) const
    {
        if (!_frameCapture)
        {
            OSG_NOTICE<<"No FrameCamera assigned"<<std::endl;
            return;
        }

        unsigned int frameNumber = renderInfo.getState()->getFrameStamp()->getFrameNumber();
        
        CameraNumMap::const_iterator itr = _cameraNumMap.find(renderInfo.getCurrentCamera());
        std::string outputFileName = (itr!=_cameraNumMap.end()) ?
                                     _frameCapture->getOutputFileName(itr->second, frameNumber) :
                                     _frameCapture->getOutputFileName(frameNumber);
                                     
        OSG_NOTICE<<"outputFileName="<<outputFileName<<std::endl;

        osg::Camera* camera = renderInfo.getCurrentCamera();
        osg::Viewport* viewport = camera ? camera->getViewport() : 0;
        if (viewport)
        {
            OSG_NOTICE<<"Doing read of ="<<viewport->x()<<", "<<viewport->y()<<", "<<viewport->width()<<", "<<viewport->height()<<" with pixelFormat=0x"<<std::hex<<_pixelFormat<<std::dec<<std::endl;

            glReadBuffer(camera->getDrawBuffer());
            osg::ref_ptr<osg::Image> image = new osg::Image;
            
            image->readPixels(viewport->x(),viewport->y(),viewport->width(),viewport->height(),
                              _pixelFormat, GL_UNSIGNED_BYTE, 1);

            if (_flip) image->flipVertical();

            osgDB::writeImageFile(*image, outputFileName);
        }
        
    }
Пример #3
0
        virtual void operator () (osg::RenderInfo& renderInfo) const
        {
            mTexture->copyTexImage2D(*renderInfo.getState(), 0, 0, mWidth, mHeight);

            // Callback removes itself when done
            if (renderInfo.getCurrentCamera())
                renderInfo.getCurrentCamera()->setInitialDrawCallback(NULL);
        }
Пример #4
0
        virtual void operator () (osg::RenderInfo& renderInfo) const
        {
            int w = renderInfo.getCurrentCamera()->getViewport()->width();
            int h = renderInfo.getCurrentCamera()->getViewport()->height();
            mTexture->copyTexImage2D(*renderInfo.getState(), 0, 0, w, h);

            // Callback removes itself when done
            if (renderInfo.getCurrentCamera())
                renderInfo.getCurrentCamera()->setInitialDrawCallback(NULL);
        }
Пример #5
0
void Camera::DrawCallback::operator () (osg::RenderInfo& renderInfo) const
{
    if (renderInfo.getCurrentCamera())
    {
        operator()(*(renderInfo.getCurrentCamera()));
    }
    else
    {
        OSG_WARN<<"Error: Camera::DrawCallback called without valid camera."<<std::endl;
    }
}
Пример #6
0
 virtual void operator()( osg::RenderInfo& renderInfo ) const
 {
     osg::Viewport* viewport = renderInfo.getCurrentCamera()->getViewport();
     if ( viewport ) TwWindowSize( viewport->width(), viewport->height() );
     updateEvents();
     TwDraw();
 }
Пример #7
0
	virtual void operator()(osg::RenderInfo& renderInfo) const
	{
		osg::GraphicsOperation* graphicsOperation = renderInfo.getCurrentCamera()->getRenderer();
		osgViewer::Renderer* renderer = dynamic_cast<osgViewer::Renderer*>(graphicsOperation);
		if (renderer != nullptr)
		{
			// Disable normal OSG FBO camera setup because it will undo the MSAA FBO configuration.
			renderer->setCameraRequiresSetUp(false);
		}
	}
Пример #8
0
void KinectCallback::operator () ( osg::RenderInfo& info ) const  {
  if (!m_done) {
    osg::Camera* camera = info.getCurrentCamera();
    ColorCloudPtr cloud = computePointCloud(camera, depthbufferimg.get(), colorbufferimg.get());

    KinectCallback* this2 = const_cast<KinectCallback*>(this);
    this2->m_done = true;
    this2->m_cloud = cloud;

  }
}
void
SkyDrawable::drawImplementation(osg::RenderInfo& renderInfo) const
{
    osg::Camera* camera = renderInfo.getCurrentCamera();
#ifndef SL_USE_CULL_MASK
	//Check if this is the target camera
	if (_contextNode->getTargetCamera() == camera) 
#endif 
	{
	if ( camera)
    {
        renderInfo.getState()->disableAllVertexArrays();

        _SL->initialize( renderInfo );

        // convey the sky box size (far plane) to SL:
        double fovy, ar, znear, zfar;
        _SL->setCamera(camera);
        camera->getProjectionMatrixAsPerspective(fovy, ar, znear, zfar);
        _SL->setSkyBoxSize( zfar < 100000.0 ? zfar : 100000.0 );

        // invoke the user callback if it exists
        if (_SL->getCallback())
            _SL->getCallback()->onDrawSky(_SL->getAtmosphereWrapper());

        // draw the sky.
        _SL->getAtmosphere()->DrawSky(
            true,
            _SL->getSRS()->isGeographic(),
            _SL->getSkyBoxSize(),
            true,
            false );

        // Dirty the state and the program tracking to prevent GL state conflicts.
        renderInfo.getState()->dirtyAllVertexArrays();
        renderInfo.getState()->dirtyAllAttributes();

#if 0
#if OSG_VERSION_GREATER_OR_EQUAL(3,4,0)
        osg::GLExtensions* api = renderInfo.getState()->get<osg::GLExtensions>();
#else
        osg::GL2Extensions* api = osg::GL2Extensions::Get(renderInfo.getState()->getContextID(), true);
#endif
        api->glUseProgram((GLuint)0);
        renderInfo.getState()->setLastAppliedProgramObject(0L);
#endif

        renderInfo.getState()->apply();
    }
	}
}
    /**
     * Draws a bin. Most of this code is copied from osgUtil::RenderBin::drawImplementation.
     * The modifications are (a) skipping code to render child bins, (b) setting a bin-global
     * projection matrix in orthographic space, and (c) calling our custom "renderLeaf()" method 
     * instead of RenderLeaf::render()
     */
    void drawImplementation( osgUtil::RenderBin* bin, osg::RenderInfo& renderInfo, osgUtil::RenderLeaf*& previous )
    {
        osg::State& state = *renderInfo.getState();

        unsigned int numToPop = (previous ? osgUtil::StateGraph::numToPop(previous->_parent) : 0);
        if (numToPop>1) --numToPop;
        unsigned int insertStateSetPosition = state.getStateSetStackSize() - numToPop;

        if (bin->getStateSet())
        {
            state.insertStateSet(insertStateSetPosition, bin->getStateSet());
        }

        // apply a window-space projection matrix.
        const osg::Viewport* vp = renderInfo.getCurrentCamera()->getViewport();
        if ( vp )
        {
            //TODO see which is faster

            osg::ref_ptr<osg::RefMatrix>& m = _ortho2D.get();
            if ( !m.valid() )
                m = new osg::RefMatrix();

            m->makeOrtho2D( vp->x(), vp->x()+vp->width()-1, vp->y(), vp->y()+vp->height()-1 );
            state.applyProjectionMatrix( m.get() );

            //osg::ref_ptr<osg::RefMatrix> rm = new osg::RefMatrix( osg::Matrix::ortho2D(
            //    vp->x(), vp->x()+vp->width()-1,
            //    vp->y(), vp->y()+vp->height()-1 ) );
            //state.applyProjectionMatrix( rm.get() );
        }

        // render the list
        osgUtil::RenderBin::RenderLeafList& leaves = bin->getRenderLeafList();
        for(osgUtil::RenderBin::RenderLeafList::reverse_iterator rlitr = leaves.rbegin();
            rlitr!= leaves.rend();
            ++rlitr)
        {
            osgUtil::RenderLeaf* rl = *rlitr;
            renderLeaf( rl, renderInfo, previous );
            previous = rl;
        }

        if ( bin->getStateSet() )
        {
            state.removeStateSet(insertStateSetPosition);
        }
    }
Пример #11
0
     virtual void operator () (osg::RenderInfo& renderInfo) const
    {
//        osg::notify(osg::NOTICE)<<"Camera callback"<<std::endl;
        cout << "callbck\n";
        osg::Camera * camera = renderInfo.getCurrentCamera();
        osg::Viewport * viewport = camera ? camera->getViewport() : 0;
        osg::Image * image = new osg::Image();

        if( viewport )
        {
            cout << "take screenshot "<< viewport->width() << " " << viewport->height() << endl;
            image->readPixels(int(viewport->x()),int(viewport->y()),int(viewport->width()),int(viewport->height()),GL_RGBA,GL_UNSIGNED_BYTE);
//            osgDB::writeImageFile( *image, string("out.png") );
        }
        else
            cout << "error with viewport\n";
    }
Пример #12
0
void
TileDrawable::drawPrimitivesImplementation(osg::RenderInfo& renderInfo) const
{
    if ( _drawPatch )
    {
        drawPatches( renderInfo );
    }
    else
    {
        const osg::Camera* camera = renderInfo.getCurrentCamera();

        bool renderColor =
            //(camera->getRenderOrder() != osg::Camera::PRE_RENDER) ||
            ((camera->getClearMask() & GL_COLOR_BUFFER_BIT) != 0L);

        drawSurface( renderInfo, renderColor );
    }
}
Пример #13
0
  void operator () ( osg::RenderInfo& info ) const  {
    if (!m_done) {
      osg::Camera* camera = info.getCurrentCamera();
      FinalDrawCallback* this2 = const_cast<FinalDrawCallback*>(this);



      // MatrixXf rangeData = computeDepthImage(camera, depthbufferimg);
      // ofstream outfile("depth.txt");
      // outfile << rangeData << endl;
      // outfile.close();
      ColorCloudPtr cloud = computePointCloud(camera, depthbufferimg.get(), colorbufferimg.get());
      pcl::io::savePCDFileBinary("q.pcd", *cloud);

      this2->m_done = true;
      cout << "writing depth image" << endl;

    }
  }
void
CloudsDrawable::drawImplementation(osg::RenderInfo& renderInfo) const
{
	osg::Camera* camera = renderInfo.getCurrentCamera();
#ifndef SL_USE_CULL_MASK
	if(_contextNode->getTargetCamera() == camera)
#endif
	{
	if ( _SL->ready())
	{
	    osg::State* state = renderInfo.getState();

        // adapt the SL shaders so they can accept OSG uniforms:
        osgEarth::NativeProgramAdapterCollection& adapters = _adapters[ state->getContextID() ]; // thread safe.
        if ( adapters.empty() )
        {
            adapters.push_back( new osgEarth::NativeProgramAdapter(state, _SL->getAtmosphere()->GetSkyShader()) );
            adapters.push_back( new osgEarth::NativeProgramAdapter(state, _SL->getAtmosphere()->GetBillboardShader()) );
            adapters.push_back( new osgEarth::NativeProgramAdapter(state, _SL->getAtmosphere()->GetStarShader()) );
            adapters.push_back( new osgEarth::NativeProgramAdapter(state, _SL->getAtmosphere()->GetPrecipitationShader()) );
            //adapters.push_back(new osgEarth::NativeProgramAdapter(state, _SL->getAtmosphere()->GetAtmosphericLimbShader()) );

            SL_VECTOR(unsigned) handles = _SL->getAtmosphere()->GetActivePlanarCloudShaders();
            for(int i=0; i<handles.size(); ++i)          
                adapters.push_back( new osgEarth::NativeProgramAdapter(state, handles[i]) );
        }
        adapters.apply( state );

        // invoke the user callback if it exists
        if (_SL->getCallback())
            _SL->getCallback()->onDrawClouds(_SL->getAtmosphereWrapper());

        renderInfo.getState()->disableAllVertexArrays();
        _SL->getAtmosphere()->DrawObjects( true, true, true );

        // Restore the GL state to where it was before.
        state->dirtyAllVertexArrays();
        state->dirtyAllAttributes();

        state->apply();
    }
	}
}
Пример #15
0
    virtual void operator () (osg::RenderInfo& renderInfo) const
    {

        if (!_snapImage) return;
    
        osg::notify(osg::NOTICE)<<"Camera callback"<<std::endl;

        osg::Camera* camera = renderInfo.getCurrentCamera();
        osg::Viewport* viewport = camera ? camera->getViewport() : 0;

        osg::notify(osg::NOTICE)<<"Camera callback "<<camera<<" "<<viewport<<std::endl;

        if (viewport && _image.valid())
        {
            _image->readPixels(int(viewport->x()),int(viewport->y()),int(viewport->width()),int(viewport->height()),
                               GL_RGBA,
                               GL_UNSIGNED_BYTE);
            osgDB::writeImageFile(*_image, _filename);
            
            osg::notify(osg::NOTICE)<<"Taken screenshot, and written to '"<<_filename<<"'"<<std::endl;             
        }
       
        _snapImage = false;
    }
Пример #16
0
// After 1.2, param 1 changed from State to RenderInfo.
// Warning: Version was still 1.2 on dev branch long after the 1.2 release,
//   and finally got bumped to 1.9 in April 2007.
void
QueryGeometry::drawImplementation( osg::RenderInfo& renderInfo ) const
{
    unsigned int contextID = renderInfo.getState()->getContextID();
    osg::Drawable::Extensions* ext = getExtensions( contextID, true );
    osg::Camera* cam = renderInfo.getCurrentCamera();

    // Add callbacks if necessary.
    if (!cam->getPostDrawCallback())
    {
        RetrieveQueriesCallback* rqcb = new RetrieveQueriesCallback( ext );
        cam->setPostDrawCallback( rqcb );

        ClearQueriesCallback* cqcb = new ClearQueriesCallback;
        cqcb->_rqcb = rqcb;
        cam->setPreDrawCallback( cqcb );
    }

    // Get TestResult from Camera map
    TestResult* tr;
    {
        OpenThreads::ScopedLock<OpenThreads::Mutex> lock( _mapMutex );
        tr = &( _results[ cam ] );
    }

    // Add TestResult to RQCB.
    RetrieveQueriesCallback* rqcb = dynamic_cast<
        RetrieveQueriesCallback* >( cam->getPostDrawCallback() );
    if (!rqcb)
    {
        osg::notify( osg::FATAL ) << "osgOQ: QG: Invalid RQCB." << std::endl;
        return;
    }
    rqcb->add( tr );


    // Issue query
    if (!tr->_init)
    {
        ext->glGenQueries( 1, &(tr->_id) );
        tr->_contextID = contextID;
        tr->_init = true;
    }

    osg::notify( osg::DEBUG_INFO ) <<
        "osgOQ: QG: Querying for: " << _oqnName << std::endl;

    ext->glBeginQuery( GL_SAMPLES_PASSED_ARB, tr->_id );
    osg::Geometry::drawImplementation( renderInfo );
    ext->glEndQuery( GL_SAMPLES_PASSED_ARB );
    tr->_active = true;


    osg::notify( osg::DEBUG_INFO ) <<
        "osgOQ: QG. OQNName: " << _oqnName <<
        ", Ctx: " << contextID <<
        ", ID: " << tr->_id << std::endl;
#ifdef _DEBUG
    {
        GLenum err;
        if ((err = glGetError()) != GL_NO_ERROR)
            osg::notify( osg::FATAL ) <<
            "osgOQ: QG: OpenGL error: " << err << "." << std::endl;
    }
#endif


}
Пример #17
0
void CEGUIDrawable::drawImplementation( osg::RenderInfo& renderInfo ) const
{
    unsigned int contextID = renderInfo.getContextID();
    
    if ( !_initialized )
    {

        OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);

        if ( !_initialized )
        {
        CEGUI::OpenGLRenderer::bootstrapSystem( CEGUI::OpenGLRenderer::TTT_NONE );
        if ( !CEGUI::System::getSingletonPtr() ) return;

        CEGUI::DefaultResourceProvider* resource =
            static_cast<CEGUI::DefaultResourceProvider*>( CEGUI::System::getSingleton().getResourceProvider() );
        resource->setResourceGroupDirectory( "schemes", "./datafiles/schemes/" );
        resource->setResourceGroupDirectory( "imagesets", "./datafiles/imagesets/" );
        resource->setResourceGroupDirectory( "fonts", "./datafiles/fonts/" );
        resource->setResourceGroupDirectory( "layouts", "./datafiles/layouts/" );
        resource->setResourceGroupDirectory( "looknfeels", "./datafiles/looknfeel/" );
        resource->setResourceGroupDirectory( "lua_scripts", "./datafiles/lua_scripts/" );

        CEGUI::ImageManager::setImagesetDefaultResourceGroup( "imagesets" );
        CEGUI::Font::setDefaultResourceGroup( "fonts" );
        CEGUI::Scheme::setDefaultResourceGroup( "schemes" );
        CEGUI::WidgetLookManager::setDefaultResourceGroup( "looknfeels" );
        CEGUI::WindowManager::setDefaultResourceGroup( "layouts" );
        CEGUI::ScriptModule::setDefaultResourceGroup( "lua_scripts" );

         ready_for_init_signal_();
        _activeContextID = contextID;
        _initialized = true;
        }
   }
    else if ( contextID==_activeContextID )
    {
        osg::State* state = renderInfo.getState();
        state->disableAllVertexArrays();
        state->disableTexCoordPointer( 0 );
        auto tex_unit = state->getActiveTextureUnit();
		state->setActiveTextureUnit(0);
        
		glPushMatrix();
        glPushAttrib( GL_ALL_ATTRIB_BITS );

        CEGUI::OpenGLRenderer* renderer = static_cast<CEGUI::OpenGLRenderer*>(
            CEGUI::System::getSingleton().getRenderer() );
        osg::Viewport* viewport = renderInfo.getCurrentCamera()->getViewport();
        if ( renderer && viewport )
        {
            const CEGUI::Sizef& size = renderer->getDisplaySize();
            if ( size.d_width!=viewport->width() || size.d_height!=viewport->height() )
            {
                CEGUI::System::getSingleton().notifyDisplaySizeChanged(
                    CEGUI::Sizef(viewport->width(), viewport->height()) );
            }
        }

        double currentTime = (state->getFrameStamp() ? state->getFrameStamp()->getSimulationTime() : 0.0);
        CEGUI::System::getSingleton().injectTimePulse( (currentTime - _lastSimulationTime)/1000.0 );
        CEGUI::System::getSingleton().renderAllGUIContexts();
        _lastSimulationTime = currentTime;

        glPopAttrib();
        glPopMatrix();

        state->setActiveTextureUnit(tex_unit);
    }

}
Пример #18
0
void
TritonDrawable::drawImplementation(osg::RenderInfo& renderInfo) const
{
    osg::State* state = renderInfo.getState();

    state->disableAllVertexArrays();

    _TRITON->initialize( renderInfo );
    if ( !_TRITON->ready() )
        return;

    // Configure the height map generator.
    // If configuration fails, attempt to continue without a heightmap.
    if (_heightMapGenerator.valid())
    {
        bool configOK = _heightMapGenerator->configure(_TRITON->getHeightMapSize(), *state);
        if (configOK == false)
        {
            _heightMapGenerator = 0L;
            OE_WARN << LC << "Failed to establish a legal FBO configuration; disabling height map generator!" << std::endl;
        }
    }

    ::Triton::Environment* environment = _TRITON->getEnvironment();

    // Find or create the Triton camera for this OSG camera:
    CameraLocal& local = _local.get(renderInfo.getCurrentCamera());
    if (local._tritonCam == 0L)
    {
        local._tritonCam = environment->CreateCamera();
        local._tritonCam->SetName(renderInfo.getCurrentCamera()->getName().c_str());
    }
    ::Triton::Camera* tritonCam = local._tritonCam;

    osgEarth::NativeProgramAdapterCollection& adapters = _adapters[ state->getContextID() ];
    if ( adapters.empty() )
    {
        OE_INFO << LC << "Initializing Triton program adapters" << std::endl;
        const char* prefix = "oe_"; // because, don't forget osg_*
        adapters.push_back( new osgEarth::NativeProgramAdapter(state, getOceanShader(_TRITON->getOcean(), ::Triton::WATER_SURFACE, 0L, tritonCam), prefix, "WATER_SURFACE"));
        adapters.push_back( new osgEarth::NativeProgramAdapter(state, getOceanShader(_TRITON->getOcean(), ::Triton::WATER_SURFACE_PATCH, 0L, tritonCam), prefix, "WATER_SURFACE_PATCH"));
        adapters.push_back( new osgEarth::NativeProgramAdapter(state, getOceanShader(_TRITON->getOcean(), ::Triton::GOD_RAYS, 0L, tritonCam), prefix, "GOD_RAYS"));
        adapters.push_back( new osgEarth::NativeProgramAdapter(state, getOceanShader(_TRITON->getOcean(), ::Triton::SPRAY_PARTICLES, 0L, tritonCam), prefix, "SPRAY_PARTICLES"));
        adapters.push_back( new osgEarth::NativeProgramAdapter(state, getOceanShader(_TRITON->getOcean(), ::Triton::WAKE_SPRAY_PARTICLES, 0L, tritonCam), prefix, "WAKE_SPRAY_PARTICLES"));
#if 0
        // In older Triton (3.91), this line causes problems in Core profile and prevents the ocean from drawing.  In newer Triton (4.01),
        // this line causes a crash because there is no context passed in to GetShaderObject(), resulting in multiple NULL references.
        adapters.push_back( new osgEarth::NativeProgramAdapter(state, getOceanShader(_TRITON->getOcean(), ::Triton::WATER_DECALS, 0L, tritonCam), prefix, "WATER_DECALS"));
#endif
    }
    adapters.apply( state );


    // Pass the final view and projection matrices into Triton.
    if ( environment )
    {
        tritonCam->SetCameraMatrix(state->getModelViewMatrix().ptr());
        tritonCam->SetProjectionMatrix(state->getProjectionMatrix().ptr());
    }

    if (_heightMapGenerator.valid())
    {
        GLint texName;
        osg::Matrix hMM;
        if (_heightMapGenerator->getTextureAndMatrix(renderInfo, texName, hMM))
        {
            // copy the OSG matrix to a Triton matrix:
            ::Triton::Matrix4 texMat(
                hMM(0, 0), hMM(0, 1), hMM(0, 2), hMM(0, 3),
                hMM(1, 0), hMM(1, 1), hMM(1, 2), hMM(1, 3),
                hMM(2, 0), hMM(2, 1), hMM(2, 2), hMM(2, 3),
                hMM(3, 0), hMM(3, 1), hMM(3, 2), hMM(3, 3));

            environment->SetHeightMap((::Triton::TextureHandle)texName, texMat, 0L, tritonCam);
                
            OE_DEBUG << LC << "Updating height map, FN=" << renderInfo.getState()->getFrameStamp()->getFrameNumber() << std::endl;
        }
    }

    state->dirtyAllVertexArrays();

    // Now light and draw the ocean:
    if ( environment )
    {
        // User pre-draw callback:
        if (_TRITON->getCallback())
        {
            _TRITON->getCallback()->onDrawOcean(
                _TRITON->getEnvironmentWrapper(),
                _TRITON->getOceanWrapper());
        }

        // The sun position is roughly where it is in our skybox texture:

        // Since this is a simple example we will just assume that Sun is the light from View light source
        // TODO: fix this...
        osg::Light* light = renderInfo.getView() ? renderInfo.getView()->getLight() : NULL;

        // This is the light attached to View so there are no transformations above..
        // But in general case you would need to accumulate all transforms above the light into this matrix
        osg::Matrix lightLocalToWorldMatrix = osg::Matrix::identity();

        // If you don't know where the sun lightsource is attached and don't know its local to world matrix you may use
        // following elaborate scheme to grab the light source while drawing Triton ocean:
        // - Install cull callback to catch CullVisitor and record pointer to its associated RenderStage
        //   I was hoping RenderStage can be found from renderInfo in drawImplementation but I didn't figure how ...
        // - When TritonDrawable::drawImplementation is called all lights will be already applied to OpenGL
        //   then just find proper infinite directional light by scanning renderStage->PositionalStateContainer.
        // - Note that we canot scan for the lights inside cull because they may not be traversed before Triton drawable
        // - When you found interesting ligt source that can work as Sun, read its modelview matrix and lighting params
        //   Multiply light position by ( modelview * inverse camera view ) and pass this to Triton with lighting colors

        if ( light && light->getPosition().w() == 0 )
        {
            osg::Vec4 ambient = light->getAmbient();
            osg::Vec4 diffuse = light->getDiffuse();
            osg::Vec4 position = light->getPosition();

            // Compute light position/direction in the world
            position = position * lightLocalToWorldMatrix;

            // Diffuse direction and color
            environment->SetDirectionalLight(
                ::Triton::Vector3( position[0], position[1], position[2] ),
                ::Triton::Vector3( diffuse[0],  diffuse[1],  diffuse[2] ) );

            // Sun-based ambient value:
            osg::Vec3d up = osg::Vec3d(0,0,0) * renderInfo.getCurrentCamera()->getInverseViewMatrix();
            up.normalize();
            osg::Vec3d pos3 = osg::Vec3d(position.x(), position.y(), position.z());
            pos3.normalize();
            float dot = osg::clampAbove(up*pos3, 0.0); dot*=dot;
            float sunAmbient = (float)osg::clampBetween( dot, 0.0f, 0.88f );
            float fa = osg::maximum(sunAmbient, ambient[0]);

            // Ambient color based on the zenith color in the cube map
            environment->SetAmbientLight( ::Triton::Vector3(fa, fa, fa) );
        }

        else
        {
            environment->SetDirectionalLight( ::Triton::Vector3(0,0,1), ::Triton::Vector3(1,1,1) );
            environment->SetAmbientLight( ::Triton::Vector3(0.88f, 0.88f, 0.88f) );
        }

        if ( _cubeMap.valid() )
        {
            // Build transform from our cube map orientation space to native Triton orientation
            // See worldToCubeMap function used in SkyBox to orient sky texture so that sky is up and earth is down
            osg::Matrix m = osg::Matrix::rotate( osg::PI_2, osg::X_AXIS ); // = worldToCubeMap

            ::Triton::Matrix3 transformFromYUpToZUpCubeMapCoords(
                m(0,0), m(0,1), m(0,2),
                m(1,0), m(1,1), m(1,2),
                m(2,0), m(2,1), m(2,2) );

            // Grab the cube map from our sky box and give it to Triton to use as an _environment map
            // GLenum texture = renderInfo.getState()->getLastAppliedTextureAttribute( _stage, osg::StateAttribute::TEXTURE );
            environment->SetEnvironmentMap(
                (::Triton::TextureHandle)_cubeMap->getTextureObject( state->getContextID() )->id(),
                transformFromYUpToZUpCubeMapCoords );

            if( _planarReflectionMap.valid() && _planarReflectionProjection.valid() )
            {
                osg::Matrix & p = *_planarReflectionProjection;

                ::Triton::Matrix3 planarProjection(
                    p(0,0), p(0,1), p(0,2),
                    p(1,0), p(1,1), p(1,2),
                    p(2,0), p(2,1), p(2,2) );

                environment->SetPlanarReflectionMap(
                    (::Triton::TextureHandle)_planarReflectionMap->getTextureObject( state->getContextID() )->id(),
                    planarProjection,
                    0.125 );
            }
        }

        // Draw the ocean for the current time sample
        if ( _TRITON->getOcean() )
        {
            osg::GLExtensions* ext = osg::GLExtensions::Get(state->getContextID(), true);

            bool writeDepth = true;
            const osg::Depth* depth = static_cast<const osg::Depth*>(state->getLastAppliedAttribute(osg::StateAttribute::DEPTH));
            if (depth)
                writeDepth = depth->getWriteMask();

            double simTime = renderInfo.getView()->getFrameStamp()->getSimulationTime();
            simTime = fmod(simTime, 86400.0);

            _TRITON->getOcean()->Draw(
                simTime,
                writeDepth, // depth writes
                true, // draw water
                true, // draw particles
                NULL, // optional context
                tritonCam);

        }
    }
            
    // Put GL back in a state that won't confuse the OSG state tracking:
    state->dirtyAllVertexArrays();
    state->dirtyAllAttributes();
    state->dirtyAllModes();    

#ifndef OSG_GL_FIXED_FUNCTION_AVAILABLE
    // Keep OSG from reapplying GL_LIGHTING on next state change after dirtyAllModes().
    state->setModeValidity(GL_LIGHTING, false);
#endif

    // Keep an eye on this.
    // I had to remove something similar in another module (Rex engine) because it was causing
    // positional attributes (like clip planes) to re-apply with an incorrect MVM. -gw
    state->apply();    
}
Пример #19
0
void
TritonDrawable::drawImplementation(osg::RenderInfo& renderInfo) const
{
    osg::State* state = renderInfo.getState();

    state->disableAllVertexArrays();

    _TRITON->initialize( renderInfo );
    if ( !_TRITON->ready() )
        return;

    if ( _TRITON->passHeightMapToTriton() && !_terrainChangedCallback.valid() )
    {
        const_cast<TritonDrawable*>(this)->setupHeightMap(*state);
    }

    ::Triton::Environment* environment = _TRITON->getEnvironment();

    osgEarth::NativeProgramAdapterCollection& adapters = _adapters[ state->getContextID() ];
    if ( adapters.empty() )
    {
        const char* prefix = "oe_";
        adapters.push_back( new osgEarth::NativeProgramAdapter(state, (GLint)_TRITON->getOcean()->GetShaderObject(::Triton::GOD_RAYS), prefix));
        adapters.push_back( new osgEarth::NativeProgramAdapter(state, (GLint)_TRITON->getOcean()->GetShaderObject(::Triton::SPRAY_PARTICLES), prefix));
        adapters.push_back( new osgEarth::NativeProgramAdapter(state, (GLint)_TRITON->getOcean()->GetShaderObject(::Triton::WAKE_SPRAY_PARTICLES), prefix));
        adapters.push_back( new osgEarth::NativeProgramAdapter(state, (GLint)_TRITON->getOcean()->GetShaderObject(::Triton::WATER_DECALS), prefix));
        adapters.push_back( new osgEarth::NativeProgramAdapter(state, (GLint)_TRITON->getOcean()->GetShaderObject(::Triton::WATER_SURFACE_PATCH), prefix));
        adapters.push_back( new osgEarth::NativeProgramAdapter(state, (GLint)_TRITON->getOcean()->GetShaderObject(::Triton::WATER_SURFACE), prefix));
    }
    adapters.apply( state );

    // Pass the final view and projection matrices into Triton.
    if ( environment )
    {
        environment->SetCameraMatrix( state->getModelViewMatrix().ptr() );
        environment->SetProjectionMatrix( state->getProjectionMatrix().ptr() );
    }

    if ( _TRITON->passHeightMapToTriton() )
    {
        unsigned cid = renderInfo.getContextID();

        bool dirty =
            ( _contextDirty[cid] ) ||
            ( renderInfo.getView()->getCamera()->getViewMatrix()       != _viewMatrix ) ||
            ( renderInfo.getView()->getCamera()->getProjectionMatrix() != _projMatrix );

        if ( dirty )
        {
            updateHeightMap( renderInfo );
            _contextDirty[renderInfo.getContextID()] = 0;
            _viewMatrix = renderInfo.getView()->getCamera()->getViewMatrix();
            _projMatrix = renderInfo.getView()->getCamera()->getProjectionMatrix();
        }
    }

    state->dirtyAllVertexArrays();

    // Now light and draw the ocean:
    if ( environment )
    {
        // User pre-draw callback:
        if (_TRITON->getCallback())
        {
            _TRITON->getCallback()->onDrawOcean(
                _TRITON->getEnvironmentWrapper(),
                _TRITON->getOceanWrapper());
        }

        // The sun position is roughly where it is in our skybox texture:

        // Since this is a simple example we will just assume that Sun is the light from View light source
        // TODO: fix this...
        osg::Light* light = renderInfo.getView() ? renderInfo.getView()->getLight() : NULL;

        // This is the light attached to View so there are no transformations above..
        // But in general case you would need to accumulate all transforms above the light into this matrix
        osg::Matrix lightLocalToWorldMatrix = osg::Matrix::identity();

        // If you don't know where the sun lightsource is attached and don't know its local to world matrix you may use
        // following elaborate scheme to grab the light source while drawing Triton ocean:
        // - Install cull callback to catch CullVisitor and record pointer to its associated RenderStage
        //   I was hoping RenderStage can be found from renderInfo in drawImplementation but I didn't figure how ...
        // - When TritonDrawable::drawImplementation is called all lights will be already applied to OpenGL
        //   then just find proper infinite directional light by scanning renderStage->PositionalStateContainer.
        // - Note that we canot scan for the lights inside cull because they may not be traversed before Triton drawable
        // - When you found interesting ligt source that can work as Sun, read its modelview matrix and lighting params
        //   Multiply light position by ( modelview * inverse camera view ) and pass this to Triton with lighting colors

        if ( light && light->getPosition().w() == 0 )
        {
            osg::Vec4 ambient = light->getAmbient();
            osg::Vec4 diffuse = light->getDiffuse();
            osg::Vec4 position = light->getPosition();

            // Compute light position/direction in the world
            position = position * lightLocalToWorldMatrix;

            // Diffuse direction and color
            environment->SetDirectionalLight(
                ::Triton::Vector3( position[0], position[1], position[2] ),
                ::Triton::Vector3( diffuse[0],  diffuse[1],  diffuse[2] ) );

            // Sun-based ambient value:
            osg::Vec3d up = osg::Vec3d(0,0,0) * renderInfo.getCurrentCamera()->getInverseViewMatrix();
            up.normalize();
            osg::Vec3d pos3 = osg::Vec3d(position.x(), position.y(), position.z());
            pos3.normalize();
            float dot = osg::clampAbove(up*pos3, 0.0);
            dot*=dot;
            float sunAmbient = (float)osg::clampBetween( dot, 0.0f, 0.88f );
            float fa = std::max(sunAmbient, ambient[0]);

            // Ambient color based on the zenith color in the cube map
            environment->SetAmbientLight( ::Triton::Vector3(fa, fa, fa) );
            //::Triton::Vector3( ambient[0], ambient[1], ambient[2] ) );
        }

        else
        {
            environment->SetDirectionalLight( ::Triton::Vector3(0,0,1), ::Triton::Vector3(1,1,1) );
            environment->SetAmbientLight( ::Triton::Vector3(0.88f, 0.88f, 0.88f) );
        }

        // Build transform from our cube map orientation space to native Triton orientation
        // See worldToCubeMap function used in SkyBox to orient sky texture so that sky is up and earth is down
        osg::Matrix m = osg::Matrix::rotate( osg::PI_2, osg::X_AXIS ); // = worldToCubeMap

        ::Triton::Matrix3 transformFromYUpToZUpCubeMapCoords(
            m(0,0), m(0,1), m(0,2),
            m(1,0), m(1,1), m(1,2),
            m(2,0), m(2,1), m(2,2) );

        // Grab the cube map from our sky box and give it to Triton to use as an _environment map
        // GLenum texture = renderInfo.getState()->getLastAppliedTextureAttribute( _stage, osg::StateAttribute::TEXTURE );
        if ( _cubeMap.valid() )
        {
            environment->SetEnvironmentMap(
                (::Triton::TextureHandle)_cubeMap->getTextureObject( state->getContextID() )->id(), transformFromYUpToZUpCubeMapCoords );

            if( _planarReflectionMap.valid() && _planarReflectionProjection.valid() )
            {
                osg::Matrix & p = *_planarReflectionProjection;

                ::Triton::Matrix3 planarProjection( p(0,0), p(0,1), p(0,2),
                                                    p(1,0), p(1,1), p(1,2),
                                                    p(2,0), p(2,1), p(2,2) );

                environment->SetPlanarReflectionMap( (::Triton::TextureHandle)
                                                     _planarReflectionMap->getTextureObject( state->getContextID() )->id(),
                                                     planarProjection, 0.125  );
            }
        }

        // Draw the ocean for the current time sample
        if ( _TRITON->getOcean() )
        {
            _TRITON->getOcean()->Draw( renderInfo.getView()->getFrameStamp()->getSimulationTime() );
        }
    }

    // Put GL back in a state that won't confuse the OSG state tracking:
    state->dirtyAllVertexArrays();
    state->dirtyAllAttributes();
    //osg::GL2Extensions* api = osg::GL2Extensions::Get(state->getContextID(), true);
    //api->glUseProgram((GLuint)0);
    //state->setLastAppliedProgramObject( 0L );
    state->apply();
}
Пример #20
0
void
TritonDrawable::updateHeightMap(osg::RenderInfo& renderInfo) const
{
    if ( !_TRITON->ready() )
        return;

    osg::ref_ptr<MapNode> mapNode;
    if (!_mapNode.lock(mapNode))
        return;

    const osg::Matrix& viewMatrix = renderInfo.getCurrentCamera()->getViewMatrix();
    const osg::Matrix& projectionMatrix = renderInfo.getCurrentCamera()->getProjectionMatrix();

    osg::Vec3d eye, center, up;
    viewMatrix.getLookAt(eye, center, up);
    double fovyDEG=0.0, aspectRatio=0.0, zNear=0.0, zFar=0.0;
    projectionMatrix.getPerspective(fovyDEG, aspectRatio,zNear,zFar);

    // aspect_ratio = tan( HFOV/2 ) / tan( VFOV/2 )
    // tan( HFOV/2 ) = tan( VFOV/2 ) * aspect_ratio
    // HFOV/2 = atan( tan( VFOV/2 ) * aspect_ratio )
    // HFOV = 2.0 * atan( tan( VFOV/2 ) * aspect_ratio )
    double fovxDEG = osg::RadiansToDegrees( 2.0 * atan( tan(osg::DegreesToRadians(fovyDEG))/2.0 * aspectRatio ));

    double eyeLat=0.0, eyeLon=0.0, eyeHeight=0.0;
    mapNode->getMap()->getSRS()->getEllipsoid()->convertXYZToLatLongHeight(eye.x(), eye.y(), eye.z(), eyeLat, eyeLon, eyeHeight);
    double clampedEyeX=0.0, clampedEyeY=0.0,clampedEyeZ=0.0;
    mapNode->getMap()->getSRS()->getEllipsoid()->convertLatLongHeightToXYZ(eyeLat, eyeLon, 0.0, clampedEyeX, clampedEyeY, clampedEyeZ);
    osg::Vec3 mslEye(clampedEyeX,clampedEyeY,clampedEyeZ);
    double lookAtLat=0.0, lookAtLon=0.0, lookAtHeight=0.0;
    mapNode->getMap()->getSRS()->getEllipsoid()->convertXYZToLatLongHeight(center.x(), center.y(), center.z(), lookAtLat, lookAtLon, lookAtHeight);

    // Calculate the distance to the horizon from the eyepoint
    double eyeLen = eye.length();
    double radE = mslEye.length();
    double hmax = radE + 8848.0;
    double hmin = radE - 12262.0;
    double hasl = osg::maximum(0.1, eyeLen - radE);
    double radius = eyeLen - hasl;
    double horizonDistance = osg::minimum(radE, sqrt( 2.0*radius*hasl + hasl*hasl ));

    osg::Vec3d heightCamEye(eye);

    double near = osg::maximum(1.0, heightCamEye.length() - hmax);
    double far = osg::maximum(10.0, heightCamEye.length() - hmin + radE);
    //osg::notify( osg::ALWAYS ) << "near = " << near << "; far = " << far << std::endl;

    //horizonDistance *= 0.25;

    _heightCamera->setProjectionMatrix(osg::Matrix::ortho(-horizonDistance,horizonDistance,-horizonDistance,horizonDistance,near,far) );
    _heightCamera->setViewMatrixAsLookAt( heightCamEye, osg::Vec3d(0.0,0.0,0.0), osg::Vec3d(0.0,0.0,1.0));

    const osg::Matrixd bias(0.5, 0.0, 0.0, 0.0,
                            0.0, 0.5, 0.0, 0.0,
                            0.0, 0.0, 0.5, 0.0,
                            0.5, 0.5, 0.5, 1.0);

    osg::Matrix hMM = _heightCamera->getViewMatrix() * _heightCamera->getProjectionMatrix() * bias;
    ::Triton::Matrix4 heightMapMatrix(hMM(0,0),hMM(0,1),hMM(0,2),hMM(0,3),
                                      hMM(1,0),hMM(1,1),hMM(1,2),hMM(1,3),
                                      hMM(2,0),hMM(2,1),hMM(2,2),hMM(2,3),
                                      hMM(3,0),hMM(3,1),hMM(3,2),hMM(3,3));

    osg::Texture::TextureObject* texObj = _heightMap->getTextureObject(renderInfo.getContextID());

    if(texObj)
    {
        PassHeightMapToTritonCallback* cb = dynamic_cast<PassHeightMapToTritonCallback*>(_heightCamera->getFinalDrawCallback());
        if( cb )
        {
            cb->_enable = true;
            cb->_id = texObj->id();
            cb->_heightMapMatrix = heightMapMatrix;
        }
    }
    else
    {
        // may happen on the first frame; ignore
        //OE_WARN << LC << "Texture object is NULL (Internal error)" << std::endl;
    }

#ifdef DEBUG_HEIGHTMAP
    mapNode->getParent(0)->removeChild(0, 1);
    mapNode->getParent(0)->insertChild(0, makeFrustumFromCamera(_heightCam));
#endif /* DEBUG_HEIGHTMAP */
}
Пример #21
0
	virtual void operator () (osg::RenderInfo& renderInfo) const
	{
		m_pCamera->setFinalDrawCallback(NULL);
		renderInfo.getCurrentCamera()->setPreDrawCallback(NULL);
	}
Пример #22
0
void 
MPGeometry::drawImplementation(osg::RenderInfo& renderInfo) const
{
    // See if this is a pre-render depth-only camera. If so we can skip all the layers
    // and just render the primitive sets.
    osg::Camera* camera = renderInfo.getCurrentCamera();
    bool renderColor =
        (camera->getRenderOrder() != osg::Camera::PRE_RENDER) ||
        ((camera->getClearMask() & GL_COLOR_BUFFER_BIT) != 0L);

    osg::State& state = *renderInfo.getState();

    bool hasVertexAttributes = !_vertexAttribList.empty();

    osg::ArrayDispatchers& arrayDispatchers = state.getArrayDispatchers();

    arrayDispatchers.reset();
    arrayDispatchers.setUseVertexAttribAlias(state.getUseVertexAttributeAliasing());


    //Remove?
#if OSG_VERSION_LESS_THAN(3,1,8)
    arrayDispatchers.setUseGLBeginEndAdapter(false);
#endif

#if OSG_MIN_VERSION_REQUIRED(3,1,8)
    arrayDispatchers.activateNormalArray(_normalArray.get());
#else
    arrayDispatchers.activateNormalArray(_normalData.binding, _normalData.array.get(), _normalData.indices.get());
#endif
    

    if (hasVertexAttributes)
    {
        for(unsigned int unit=0;unit<_vertexAttribList.size();++unit)
        {
#if OSG_MIN_VERSION_REQUIRED(3,1,8)
            arrayDispatchers.activateVertexAttribArray(unit, _vertexAttribList[unit].get());
#else
            arrayDispatchers.activateVertexAttribArray(_vertexAttribList[unit].binding, unit, _vertexAttribList[unit].array.get(), _vertexAttribList[unit].indices.get());
#endif             
        }
    }

    // dispatch any attributes that are bound overall
    arrayDispatchers.dispatch(BIND_OVERALL,0);
    state.lazyDisablingOfVertexAttributes();


    // set up arrays
#if OSG_MIN_VERSION_REQUIRED( 3, 1, 8 )
    if( _vertexArray.valid() )
        state.setVertexPointer(_vertexArray.get());

    if (_normalArray.valid() && _normalArray->getBinding()==osg::Array::BIND_PER_VERTEX)
        state.setNormalPointer(_normalArray.get());
#else
    if( _vertexData.array.valid() )
        state.setVertexPointer(_vertexData.array.get());

    if (_normalData.binding==BIND_PER_VERTEX && _normalData.array.valid())
        state.setNormalPointer(_normalData.array.get());
#endif

    if( hasVertexAttributes )
    {
        for(unsigned int index = 0; index < _vertexAttribList.size(); ++index )
        {
#if OSG_MIN_VERSION_REQUIRED( 3, 1, 8)
            const Array* array = _vertexAttribList[index].get();
            if (array && array->getBinding()==osg::Array::BIND_PER_VERTEX)
            {
                if (array->getPreserveDataType())
                {
                    GLenum dataType = array->getDataType();
                    if (dataType==GL_FLOAT) state.setVertexAttribPointer( index, array );
                    else if (dataType==GL_DOUBLE) state.setVertexAttribLPointer( index, array );
                    else state.setVertexAttribIPointer( index, array );
                }
                else
                {
                    state.setVertexAttribPointer( index, array );
                }
            }
#else            
            const osg::Array* array = _vertexAttribList[index].array.get();
            const AttributeBinding ab = _vertexAttribList[index].binding;
            if( ab == BIND_PER_VERTEX && array )
            {
                state.setVertexAttribPointer( index, array, _vertexAttribList[index].normalize );
            }
#endif
        }
    }

    state.applyDisablingOfVertexAttributes();

    // draw the multipass geometry.
    renderPrimitiveSets(state, renderColor, true);

    // unbind the VBO's if any are used.
    state.unbindVertexBufferObject();
    state.unbindElementBufferObject();
}
Пример #23
0
void CameraResetCallback::operator()( osg::RenderInfo& renderInfo ) const
{
    osg::Camera* cam = renderInfo.getCurrentCamera();
    unsigned int contextID = renderInfo.getState()->getContextID();
    QueryComputation::setCscrOi( 0., cam, contextID );
}