Hi,

im using several RTT Cameras in my scene. So far, I have only rendered to 
osg::Texture2D and that worked fine, however, I need to render to NPOD textures 
now so that will no longer work.

For that, I changed my render target to a osg::TextureRectangle and left 
everything else pretty much unchanged. I'm displaying the texture using a 
custom QUAD. 

Unfortunately I only see a black texture when using TextureRectangle instead of 
Texture2D. I checked the osg prerender example and noticed that I need to use 
un-normalized texture coordinates for my QUAD in this case, however, to my own 
surprise that didn't fix the issue either.

Does anyone have an idea whats wrong?

Some relevant code bits:

Texture creation:


Code:
osg::ref_ptr<osg::Texture> osgHelper::createDefaultRttTexture(int width,
                int height, GLenum sourceFormat, GLenum sourceType,
                GLint internalFormat) {

        osg::ref_ptr<osg::Texture> tex;

        auto texImg = osgHelper::make_osgref<osg::Image>();
        texImg->setInternalTextureFormat(internalFormat);
        texImg->allocateImage(width, height, 1, sourceFormat, sourceType);

        if (isPowerOfTwo(width) && isPowerOfTwo(height)) {
                auto specTex = make_osgref<osg::Texture2D>();
                specTex->setTextureSize(width, height);
                specTex->setImage(texImg);

                tex = specTex;
        } else {
                auto specTex = make_osgref<osg::TextureRectangle>();
                specTex->setTextureSize(width, height);
                specTex->setImage(texImg);

                tex = specTex;
        }

        tex->setInternalFormat(internalFormat);
        tex->setSourceFormat(sourceFormat);
        tex->setSourceType(sourceType);
        tex->setFilter(osg::Texture::FilterParameter::MIN_FILTER,
                        osg::Texture::FilterMode::NEAREST);
        tex->setFilter(osg::Texture::FilterParameter::MAG_FILTER,
                        osg::Texture::FilterMode::NEAREST);
        tex->setDataVariance(osg::Object::DYNAMIC);
        tex->setMaxAnisotropy(0);

        return tex;
}



RTT Camera setup:


Code:
RTTCamera::RTTCamera(osg::Texture *dest, osg::Viewport *vp) :
                osg::Camera() {

        // set clear the color and depth buffer
        this->setClearColor(osg::Vec4(1, 0, 0, 1));

//matrices get set properly later.
        setProjectionMatrix(osg::Matrix::identity());
        setViewMatrix(osg::Matrix::identity());

        setComputeNearFarMode(ComputeNearFarMode::DO_NOT_COMPUTE_NEAR_FAR);

        // set viewport
        this->setViewport(vp);

        // set the camera to render before the main camera.
        this->setRenderOrder(osg::Camera::RenderOrder::PRE_RENDER);

        // tell the camera to use OpenGL frame buffer object where supported.
        
this->setRenderTargetImplementation(osg::Camera::RenderTargetImplementation::FRAME_BUFFER_OBJECT);

        // attach the texture and use it as the color buffer.
        this->attach(osg::Camera::COLOR_BUFFER0, dest);

}



Texture display:

Code:

TextureView::TextureView() {
        setViewMatrix(osg::Matrix::identity());
        setProjectionMatrix(osg::Matrix::ortho2D(0, 1, 0, 1));
        setClearColor(osg::Vec4(1, 0, 0, 1));

        auto mt = osgHelper::make_osgref<osg::MatrixTransform>();
        mt->setMatrix(osg::Matrix::identity());
        mt->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
        addChild(mt);

        auto geode = osgHelper::make_osgref<osg::Geode>();
        geometry = osgHelper::make_osgref<osg::Geometry>();
        geode->addDrawable(geometry);
        mt->addChild(geode);

        auto quadVertices = osgHelper::make_osgref<osg::Vec3Array>();
        quadVertices->push_back(osg::Vec3(0, 0, 0));
        quadVertices->push_back(osg::Vec3(1, 0, 0));
        quadVertices->push_back(osg::Vec3(1, 1, 0));
        quadVertices->push_back(osg::Vec3(0, 1, 0));
        geometry->setVertexArray(quadVertices);

        auto quadPrimitiveSet = osgHelper::make_osgref<osg::DrawElementsUInt>(
                        osg::PrimitiveSet::QUADS, 0);
        quadPrimitiveSet->push_back(0);
        quadPrimitiveSet->push_back(1);
        quadPrimitiveSet->push_back(2);
        quadPrimitiveSet->push_back(3);
        geometry->addPrimitiveSet(quadPrimitiveSet);

        auto texCoords = osgHelper::make_osgref<osg::Vec2Array>();
        texCoords->push_back(osg::Vec2(0, 0));
        texCoords->push_back(osg::Vec2(1, 0));
        texCoords->push_back(osg::Vec2(1, 1));
        texCoords->push_back(osg::Vec2(0, 1));
        geometry->setTexCoordArray(0, texCoords, osg::Array::BIND_PER_VERTEX);

        auto ss = geode->getOrCreateStateSet();

        auto program = osgHelper::make_osgref<osg::Program>();
        auto vertShader = osg::Shader::readShaderFile(osg::Shader::Type::VERTEX,
                        "res/CustomShaders/FrameHeader.vert");
        auto fragShader = 
osg::Shader::readShaderFile(osg::Shader::Type::FRAGMENT,
                        "res/CustomShaders/FrameHeader.frag");

        if (!vertShader || !fragShader) {
                throw MDRTExceptionBase("error loading textureview shaders");
        }

        bool ok = true;

        ok = ok && program->addShader(vertShader);
        ok = ok && program->addShader(fragShader);

        if (!ok) {
                throw MDRTExceptionBase(
                                "error adding textureview shaders to program 
obj");
        }

        ss->setAttributeAndModes(program);
        ss->getOrCreateUniform("tex", osg::Uniform::Type::SAMPLER_2D, 0);

}

TextureView::~TextureView() {
        // TODO Auto-generated destructor stub
}

void TextureView::setTexture(osg::Texture* tex) {

        auto texRec = dynamic_cast<osg::TextureRectangle*>(tex);
        if (texRec) {
                auto texWidth = texRec->getImage()->s();
                auto texHeight = texRec->getImage()->t();

                auto texCoords = osgHelper::make_osgref<osg::Vec2Array>();
                texCoords->push_back(osg::Vec2(0, 0));
                texCoords->push_back(osg::Vec2(1 * texWidth, 0));
                texCoords->push_back(osg::Vec2(1 * texWidth, 1 * texHeight));
                texCoords->push_back(osg::Vec2(0, 1 * texHeight));
                geometry->setTexCoordArray(0, texCoords, 
osg::Array::BIND_PER_VERTEX);
                geometry->dirtyDisplayList();
        }

        geometry->getOrCreateStateSet()->setTextureAttributeAndModes(0, tex);

}



Thank you!

Cheers,
Philipp

------------------
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=67873#67873





_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Reply via email to