2012-06-08 101 views
1

我正在處理一個項目,在該項目中我需要從外部設備視頻捕獲幀並將它們呈現在openSceneGraph節點上。我也在使用GLSL着色器。但我不知道如何在運行時更新紋理。對於其他制服,我們需要進行回調,但是我們是否也需要爲glsl和openSceneGraph中的採樣器進行回調?在OpenSceneGraph中運行時更新紋理

我的代碼看起來像這樣。我現在所得到的只是一個黑色的窗口。

osg::ref_ptr<osg::Geometry> pictureQuad = osg::createTexturedQuadGeometry(osg::Vec3(0.0f,0.0f,0.0f), 
    osg::Vec3(_deviceNameToImageFrameMap[deviceName].frame->s(),0.0f,0.0f), osg::Vec3(0.0f,0.0f,_deviceNameToImageFrameMap[deviceName].frame->t()), 
    0.0f, 1.0f,_deviceNameToImageFrameMap[deviceName].frame->s(), _deviceNameToImageFrameMap[deviceName].frame->t()); 

    //creating texture and setting up parameters for video frame 
    osg::ref_ptr<osg::TextureRectangle> myTex= new osg::TextureRectangle(_deviceNameToImageFrameMap[deviceName].frame.get()); 
    myTex->setFilter(osg::Texture::MIN_FILTER,osg::Texture::LINEAR); 
    myTex->setFilter(osg::Texture::MAG_FILTER,osg::Texture::LINEAR); 
    myTex->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_EDGE); 
    myTex->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_EDGE); 



    _videoSourceNameToNodeMap[sourceName].geode = new osg::Geode(); 
    _videoSourceNameToNodeMap[sourceName].geode->setDataVariance(osg::Object::DYNAMIC); 
    _videoSourceNameToNodeMap[sourceName].geode->addDrawable(pictureQuad.get()); 

    //apply texture to node 
    _videoSourceNameToNodeMap[sourceName].geode->getOrCreateStateSet()->setTextureAttributeAndModes(0, myTex.get(), osg::StateAttribute::ON); 
    _videoSourceNameToNodeMap[sourceName].geode->getOrCreateStateSet()->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF); 
    _videoSourceNameToNodeMap[sourceName].geode->setDataVariance(osg::Object::DYNAMIC); 

    //Set uniform sampler 
    osg::Uniform* srcFrame = new osg::Uniform(osg::Uniform::SAMPLER_2D, "srcFrame"); 
    srcFrame->set(0); 
    //Set Uniform Alpha 
    osg::Uniform* alpha = new osg::Uniform(osg::Uniform::FLOAT, "alpha"); 
    alpha->set(.5f); 
    alpha->setUpdateCallback(new ExampleCallback()); 

    //Enable blending 
    _videoSourceNameToNodeMap[sourceName].geode->getOrCreateStateSet()->setMode(GL_BLEND, osg::StateAttribute::ON); 
    //Adding blend function to node 
    osg::BlendFunc *bf = new osg::BlendFunc(); 
    bf->setFunction(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 
    _videoSourceNameToNodeMap[sourceName].geode->getOrCreateStateSet()->setAttributeAndModes(bf); 

    //apply shader to quad 
    _videoSourceNameToNodeMap[sourceName].geode->getOrCreateStateSet()->setAttributeAndModes(program, osg::StateAttribute::ON); 
    //add Uniform to shader 
    _videoSourceNameToNodeMap[sourceName].geode->getOrCreateStateSet()->addUniform(srcFrame); 
    _videoSourceNameToNodeMap[sourceName].geode->getOrCreateStateSet()->addUniform(alpha); 

回答

1

只要打電話image->dirty()並使用該圖像所有紋理就會自動

0

更新你並不需要這樣做bf->setFunction(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);,因爲這是默認的功能。