2

外部デバイスのビデオからフレームをキャプチャし、openSceneGraph ノードでレンダリングする必要があるプロジェクトに取り組んでいます。GLSL シェーダーも使用しています。しかし、実行時にテクスチャを更新する方法がわかりません。他のユニフォームについてはコールバックを作成する必要がありますが、 glsl と 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 );
4

2 に答える 2

1

呼び出すだけimage->dirty()で、その画像を使用するすべてのテクスチャが自動的に更新されます

于 2012-06-13T13:19:31.717 に答える
0

bf->setFunction(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);これはデフォルトの機能であるため、これを行う必要はありません。

于 2016-03-01T02:09:41.467 に答える