| 73 | } |
| 74 | |
| 75 | TexturePtr TextureLoader::load( const std::string &name, int maximumResolution ) |
| 76 | { |
| 77 | TexturesMapKey key( name, maximumResolution ); |
| 78 | TexturesMap::const_iterator it = m_loadedTextures.find( key ); |
| 79 | if( it!=m_loadedTextures.end() ) |
| 80 | { |
| 81 | return it->second; |
| 82 | } |
| 83 | |
| 84 | boost::filesystem::path path = m_searchPaths.find( name ); |
| 85 | if( path.empty() ) |
| 86 | { |
| 87 | IECore::msg( IECore::Msg::Error, "IECoreGL::TextureLoader::load", boost::format( "Couldn't find \"%s\"." ) % name ); |
| 88 | m_loadedTextures[key] = nullptr; // to save us trying over and over again |
| 89 | return nullptr; |
| 90 | } |
| 91 | |
| 92 | OIIO::ustring oiioPath( path.string() ); |
| 93 | |
| 94 | // We currently use automip to downsample textures without mipmaps. This feels pretty ineffective, it would |
| 95 | // be better to just explicitly resize to maxResolution if the texture is larger than maximumResolution and |
| 96 | // doesn't have mipmaps on disk ... but I'm keeping this consistent for now. |
| 97 | // To set automip, we need to create an ImageCache - currently I just destroy it when this function exits: |
| 98 | // we cache the GL texture ourselves, so dropping the OIIO cache should be OK. |
| 99 | #if OIIO_VERSION >= 30000 |
| 100 | std::shared_ptr<OIIO::ImageCache> imageCache = OIIO::ImageCache::create( /* shared */ false ); |
| 101 | #else |
| 102 | std::unique_ptr<OIIO::ImageCache, decltype(&destroyImageCache) > imageCache( OIIO::ImageCache::create( /* shared */ false ), &destroyImageCache ); |
| 103 | #endif |
| 104 | |
| 105 | imageCache->attribute( "automip", 1 ); |
| 106 | |
| 107 | OIIO::ImageSpec mipSpec; |
| 108 | if( !imageCache->get_imagespec( oiioPath, mipSpec, 0, 0 ) ) |
| 109 | { |
| 110 | IECore::msg( IECore::Msg::Error, "IECoreGL::TextureLoader::load", boost::format( "Couldn't load \"%s\"." ) % path.string() ); |
| 111 | m_loadedTextures[key] = nullptr; // to save us trying over and over again |
| 112 | return nullptr; |
| 113 | } |
| 114 | |
| 115 | // Set miplevel if texture resolution is limited |
| 116 | int miplevel = 0; |
| 117 | if( maximumResolution < std::numeric_limits<int>::max() ) |
| 118 | { |
| 119 | while( |
| 120 | std::max( mipSpec.full_width, mipSpec.full_height ) > maximumResolution && |
| 121 | #if OIIO_VERSION >= 30000 |
| 122 | imageCache->get_cache_dimensions( oiioPath, mipSpec, 0, miplevel + 1 ) |
| 123 | #else |
| 124 | imageCache->get_imagespec( oiioPath, mipSpec, 0, miplevel + 1 ) |
| 125 | #endif |
| 126 | ) |
| 127 | { |
| 128 | miplevel++; |
| 129 | } |
| 130 | } |
| 131 | |
| 132 | OIIO::ImageBuf imageBuf( |