0

私は Windows Phone XNA 向けに開発を行っており、完全なイメージが必要ない場合にメモリへの影響を減らすために、より小さいサイズのテクスチャをロードしたいと考えています。

私の現在の解決策は、rendertarget を使用して描画し、その rendertarget を使用する小さなテクスチャとして返すことです。

public static Texture2D LoadResized(string texturePath, float scale)
{
    Texture2D texLoaded = Content.Load<Texture2D>(texturePath);
    Vector2 resizedSize = new Vector2(texLoaded.Width * scale, texLoaded.Height * scale);
    Texture2D resized = ResizeTexture(texLoaded, resizedSize);
    //texLoaded.Dispose();
    return resized;
}

public static Texture2D ResizeTexture(Texture2D toResize, Vector2 targetSize)
{
    RenderTarget2D renderTarget = new RenderTarget2D(
        GraphicsDevice, (int)targetSize.X, (int)targetSize.Y);

    Rectangle destinationRectangle = new Rectangle(
        0, 0, (int)targetSize.X, (int)targetSize.Y);

    GraphicsDevice.SetRenderTarget(renderTarget);
    GraphicsDevice.Clear(Color.Transparent);

    SpriteBatch.Begin();
    SpriteBatch.Draw(toResize, destinationRectangle, Color.White);
    SpriteBatch.End();
    GraphicsDevice.SetRenderTarget(null);

    return renderTarget;
}

これは、テクスチャのサイズが変更されるという点で機能しますが、メモリ使用量から、テクスチャ「texLoaded」が解放されないように見えます。コメント化されていない Dispose メソッドを使用すると、SpriteBatch.End() は破棄された例外をスローします。

メモリ使用量を減らすためにサイズ変更されたテクスチャをロードする他の方法はありますか?

4

1 に答える 1

0

あなたのコードはほとんど問題ありません。小さなバグがあります。

特定のテクスチャを2回目に呼び出したときにのみ例外がスローされることに気付くでしょう。LoadResizedこれは、ContentManagerロードするコンテンツの内部キャッシュを保持するためです。ロードするすべてのものを「所有」します。そうすれば、何かを 2 回ロードしても、キャッシュされたオブジェクトが返されます。呼び出すDisposeことで、キャッシュ内のオブジェクトを破棄しています!

したがって、解決策は、コンテンツのロードに を使用ContentManagerしないことです。少なくともデフォルトの実装ではありません。ContentManager次のように、アイテムをキャッシュしない独自のクラスを継承できます(コードはこのブログ投稿に基づいています)。

class FreshLoadContentManager : ContentManager
{
    public FreshLoadContentManager(IServiceProvider s) : base(s) { }

    public override T Load<T>(string assetName)
    {
        return ReadAsset<T>(assetName, (d) => { });
    }
}

渡しGame.Servicesて作成します。RootDirectoryプロパティを設定することを忘れないでください。

次に、この派生コンテンツ マネージャーを使用してコンテンツを読み込みます。Dispose自分でロードするすべてのコンテンツを安全に (そして今はすべきです!) できるようになりました。

イベント ハンドラーをイベントにアタッチしてRenderTarget2D.ContentLost、グラフィック デバイスが「失われた」場合に、サイズ変更されたテクスチャが再作成されるようにすることもできます。

于 2013-02-06T15:16:48.900 に答える