#include #include #include #include #include #include #include #include #include #include #include #include // // A simple demo demonstrating different texturing modes, // including using of texture extensions. // typedef std::vector< osg::ref_ptr > ImageList; /** * Function to read several images files (typically one) as specified * on the command line, and return them in an ImageList */ ImageList getImagesFromFiles(std::vector& commandLine) { ImageList imageList; for(std::vector::iterator itr=commandLine.begin(); itr!=commandLine.end(); ++itr) { if ((*itr)[0]!='-') { // not an option so assume string is a filename. osg::Image *image = osgDB::readImageFile( *itr ); if (image) { imageList.push_back(image); } } } if (imageList.size()==0) { osg::notify(osg::WARN) << "No image data loaded."<setCoords(coords); osg::Vec3* norms = new osg::Vec3 [1]; norms[0].set(0.0f,-1.0f,0.0f); gset->setNormals(norms); gset->setNormalBinding(osg::GeoSet::BIND_OVERALL); osg::Vec2* tcoords = new osg::Vec2 [4]; tcoords[0].set(0.0f,textureCoordMax); tcoords[1].set(0.0f,0.0f); tcoords[2].set(textureCoordMax,0.0f); tcoords[3].set(textureCoordMax,textureCoordMax); gset->setTextureCoords(tcoords); gset->setTextureBinding(osg::GeoSet::BIND_PERVERTEX); gset->setNumPrims(1); gset->setPrimType(osg::GeoSet::QUADS); return gset; } osg::Node* createTexturedItem(const osg::Vec3& offset,osg::Texture* texture,osg::Node* geometry) { // create a tranform node to position each square in appropriate // place and also to add individual texture set to it, so that // that state is inherited down to its children. osg::Transform* local_transform = new osg::Transform; local_transform->postMult(osg::Matrix::translate(offset)); // create the StateSet to store the texture data osg::StateSet* stateset = new osg::StateSet; stateset->setAttributeAndModes(texture,osg::StateAttribute::ON); // turn the face culling off so you can see the texture from // all angles. stateset->setMode(GL_CULL_FACE,osg::StateAttribute::OFF); // attach the setset to tranform node. local_transform->setStateSet(stateset); // add the geode to the transform. local_transform->addChild(geometry); return local_transform; } osg::Node* createLayer(const osg::Vec3& offset,osg::Image* image,osg::Node* geometry,osg::Node* geometryRep) { if (image==NULL) return NULL; osg::Transform* top_transform = new osg::Transform; top_transform->postMult(osg::Matrix::translate(offset)); osg::Vec3 local_offset(0.0f,0.0f,0.0f); osg::Vec3 local_delta(3.0f,0.0f,0.0f); // defaults mipmapped texturing. { // create the texture attribute osg::Texture* texture = new osg::Texture; texture->setImage(image); // add the transform node to root group node. top_transform->addChild(createTexturedItem(local_offset,texture,geometry)); local_offset += local_delta; } // bilinear { // create the texture attribute osg::Texture* texture = new osg::Texture; texture->setImage(image); // set up bilinear filtering. texture->setFilter(osg::Texture::MIN_FILTER,osg::Texture::LINEAR_MIPMAP_NEAREST); texture->setFilter(osg::Texture::MAG_FILTER,osg::Texture::LINEAR); // add the transform node to root group node. top_transform->addChild(createTexturedItem(local_offset,texture,geometry)); local_offset += local_delta; } // trilinear { // create the texture attribute osg::Texture* texture = new osg::Texture; texture->setImage(image); // set up trilinear filtering. texture->setFilter(osg::Texture::MIN_FILTER,osg::Texture::LINEAR_MIPMAP_LINEAR); texture->setFilter(osg::Texture::MAG_FILTER,osg::Texture::LINEAR); // add the transform node to root group node. top_transform->addChild(createTexturedItem(local_offset,texture,geometry)); local_offset += local_delta; } // anisotropic { // create the texture attribute osg::Texture* texture = new osg::Texture; texture->setImage(image); // set up anistropic filtering. texture->setFilter(osg::Texture::MIN_FILTER,osg::Texture::LINEAR_MIPMAP_LINEAR); texture->setFilter(osg::Texture::MAG_FILTER,osg::Texture::ANISOTROPIC); // add the transform node to root group node. top_transform->addChild(createTexturedItem(local_offset,texture,geometry)); local_offset += local_delta; } // arb compression { // create the texture attribute osg::Texture* texture = new osg::Texture; texture->setImage(image); texture->setInternalFormatMode(osg::Texture::USE_ARB_COMPRESSION); // add the transform node to root group node. top_transform->addChild(createTexturedItem(local_offset,texture,geometry)); local_offset += local_delta; } // s3tc_dxt1 compression { // create the texture attribute osg::Texture* texture = new osg::Texture; texture->setImage(image); texture->setInternalFormatMode(osg::Texture::USE_S3TC_DXT1_COMPRESSION); // add the transform node to root group node. top_transform->addChild(createTexturedItem(local_offset,texture,geometry)); local_offset += local_delta; } // default wrap mode. (osg::Texture::CLAMP) { // create the texture attribute osg::Texture* texture = new osg::Texture; texture->setImage(image); // add the transform node to root group node. top_transform->addChild(createTexturedItem(local_offset,texture,geometryRep)); local_offset += local_delta; } // clamp-to-edge mode. { // create the texture attribute osg::Texture* texture = new osg::Texture; texture->setImage(image); texture->setWrap(osg::Texture::WRAP_S,osg::Texture::CLAMP_TO_EDGE); texture->setWrap(osg::Texture::WRAP_T,osg::Texture::CLAMP_TO_EDGE); // add the transform node to root group node. top_transform->addChild(createTexturedItem(local_offset,texture,geometryRep)); local_offset += local_delta; } // repeat wrap mode. { // create the texture attribute osg::Texture* texture = new osg::Texture; texture->setImage(image); texture->setWrap(osg::Texture::WRAP_S,osg::Texture::REPEAT); texture->setWrap(osg::Texture::WRAP_T,osg::Texture::REPEAT); // add the transform node to root group node. top_transform->addChild(createTexturedItem(local_offset,texture,geometryRep)); local_offset += local_delta; } // mirror wrap mode. { // create the texture attribute osg::Texture* texture = new osg::Texture; texture->setImage(image); texture->setWrap(osg::Texture::WRAP_S,osg::Texture::MIRROR); texture->setWrap(osg::Texture::WRAP_T,osg::Texture::MIRROR); // add the transform node to root group node. top_transform->addChild(createTexturedItem(local_offset,texture,geometryRep)); local_offset += local_delta; } return top_transform; } osg::Node* createModelFromImages(ImageList& imageList) { if (imageList.empty()) return NULL; // create the root node which will hold the model. osg::Group* root = new osg::Group(); // create a single drawable to be shared by each texture instance. osg::Drawable* drawable_noTexCoodRep = createSquare(1.0f); // add the drawable into a single goede to be shared... osg::Geode* geode_noTexCoodRep = new osg::Geode(); geode_noTexCoodRep->addDrawable(drawable_noTexCoodRep); // create a single drawable to be shared by each texture instance. osg::Drawable* drawable_texCoodRep = createSquare(2.0f); // add the drawable into a single goede to be shared... osg::Geode* geode_texCoodRep = new osg::Geode(); geode_texCoodRep->addDrawable(drawable_texCoodRep); osg::Vec3 offset(0.0f,0.0f,0.0f); osg::Vec3 delta(0.0f,0.0f,3.0f); // step through the image list processing each image in turn. for(ImageList::iterator itr=imageList.begin(); itr!=imageList.end(); ++itr) { // add the transform node to root group node. root->addChild(createLayer(offset,itr->get(),geode_noTexCoodRep,geode_texCoodRep)); offset += delta; } return root; } void write_usage(std::ostream& out,const std::string& name) { out << std::endl; out <<"usage:"<< std::endl; out <<" "< commandLine; for(int i=1;i