示例#1
0
    ReadResult readNode(const std::string& fileName, const osgDB::ReaderWriter::Options* /*options*/) const
    {
        std::string ext( osgDB::getLowerCaseFileExtension(fileName) );
        if( !acceptsExtension(ext) )
            return ReadResult::FILE_NOT_HANDLED;

        osg::notify(osg::INFO) << "ReaderWriterGLOBE( \"" << fileName << "\" )" << std::endl;

        // strip the ".globe" pseudo-loader extension
        std::string tmpName( osgDB::getNameLessExtension(fileName) );

        // get the next "extension", which actually contains the globe radius parameter
        std::string params( osgDB::getFileExtension(tmpName) );
        if( params.empty() )
        {
            osg::notify(osg::WARN) << "Missing parameters for " EXTENSION_NAME " pseudo-loader" << std::endl;
            return ReadResult::FILE_NOT_HANDLED;
        }

        // strip the "params extension", which must leave an image subfilename.
        std::string subFileName( osgDB::getNameLessExtension(tmpName) );
        if( subFileName.empty() || subFileName == tmpName )
        {
            osg::notify(osg::WARN) << "Missing image subfilename for " EXTENSION_NAME " pseudo-loader" << std::endl;
            return ReadResult::FILE_NOT_HANDLED;
        }

        osg::notify(osg::INFO) << EXTENSION_NAME " params = \"" << params << "\"" << std::endl;

        int radius;
        int count( sscanf( params.c_str(), "%d", &radius ) );
        if( count != 1 )
        {
            osg::notify(osg::WARN) << "Bad parameters for " EXTENSION_NAME " pseudo-loader: \"" << params << "\"" << std::endl;
            return ReadResult::FILE_NOT_HANDLED;
        }

        // recursively load the image subfile.
        osg::Image *image( osgDB::readImageFile(subFileName) );
        if( !image )
        {
            // propagate the read failure upwards
            osg::notify(osg::WARN) << "Image file \"" << subFileName << "\" could not be loaded" << std::endl;
            return ReadResult::FILE_NOT_HANDLED;
        }

        // create an osg::Sphere for the globe geometry
        osg::Geode* geode( new osg::Geode() );
        geode->addDrawable(new osg::ShapeDrawable(new osg::Sphere(osg::Vec3(0,0,0), radius)));

        // apply the image as a texture to the globe
        osg::Texture2D* tex2d( new osg::Texture2D );
        tex2d->setImage( image );
        tex2d->setWrap( osg::Texture::WRAP_S, osg::Texture::REPEAT );
        tex2d->setWrap( osg::Texture::WRAP_T, osg::Texture::REPEAT );

        osg::StateSet* stateset( geode->getOrCreateStateSet() );
        stateset->setTextureAttributeAndModes( 0, tex2d, osg::StateAttribute::ON );

        return geode;
    }
示例#2
0
osg::ref_ptr<osg::Texture> TextureManager::getTexture(size_t idx, int16_t *xoffset, int16_t *yoffset, float *xscale, float *yscale)
{
    auto iter = mTexCache.find(idx);
    if(iter != mTexCache.end())
    {
        osg::ref_ptr<osg::Texture> tex;
        if(iter->second.mTexture.lock(tex))
        {
            *xoffset = iter->second.mXOffset;
            *yoffset = iter->second.mYOffset;
            *xscale = iter->second.mXScale;
            *yscale = iter->second.mYScale;
            return tex;
        }
    }

    int16_t x_offset, y_offset, x_scale, y_scale;
    std::vector<osg::ref_ptr<osg::Image>> images = DFOSG::TexLoader::get().load(
        idx, &x_offset, &y_offset, &x_scale, &y_scale, mCurrentPalette
    );
    *xoffset = x_offset;
    *yoffset = y_offset;
    *xscale = 1.0f + x_scale/256.0f;
    *yscale = 1.0f + y_scale/256.0f;
    if(images.empty())
        return osg::ref_ptr<osg::Texture>();

    osg::ref_ptr<osg::Texture> tex;
    if(images.size() == 1)
    {
        osg::ref_ptr<osg::Texture2D> tex2d(new osg::Texture2D(images[0]));
        tex2d->setTextureSize(images[0]->s(), images[0]->t());
        tex = tex2d;
    }
    else
    {
        /* Multiframe textures would ideally be loaded as a Texture2DArray and
         * animated by offseting the R texture coord. However, they don't work
         * in the fixed-function pipeline.
         */
#if 0
        osg::ref_ptr<osg::Texture2DArray> tex2darr(new osg::Texture2DArray());
        tex2darr->setTextureSize(images[0]->s(), images[0]->t(), images.size());
        tex2darr->setResizeNonPowerOfTwoHint(false);
        for(size_t i = 0;i < images.size();++i)
            tex2darr->setImage(i, images[i]);
        tex = tex2darr;
#else
        osg::ref_ptr<osg::Texture2D> tex2d(new osg::Texture2D(images[0]));
        tex2d->setTextureSize(images[0]->s(), images[0]->t());
        tex = tex2d;
#endif
    }

    tex->setResizeNonPowerOfTwoHint(false);
    tex->setWrap(osg::Texture::WRAP_S, osg::Texture::REPEAT);
    tex->setWrap(osg::Texture::WRAP_T, osg::Texture::REPEAT);
    tex->setUnRefImageDataAfterApply(true);
    // Filter should be configurable. Defaults to nearest to retain DF's pixely
    // look (with linear mipmapping to reduce aliasing).
    tex->setFilter(osg::Texture::MIN_FILTER, osg::Texture::NEAREST_MIPMAP_LINEAR);
    tex->setFilter(osg::Texture::MAG_FILTER, osg::Texture::NEAREST);

    mTexCache[idx] = TextureInfo{
        tex, x_offset, y_offset, 1.0f + x_scale/256.0f, 1.0f + y_scale/256.0f
    };
    return tex;
}