2

最新の XNA (C#) で 2D ゲームを作成しています。私は古いコードのオーバーホールを少し行っており、ボタンを元に戻して解像度を変更しました。ただし、フルスクリーンモードを切り替えたり、ウィンドウサイズ/解像度を変更したりした後、キーを押すことでゲームを終了できるため、ゲームは引き続き実行されますが、画面は永遠に黒 (クリアスクリーンコールの色) になります。これは私の以前のバージョンでは発生しませんでした - すべて正常に動作しました - しかし、私が見つけた関連コードに違いはありません. しかし、コンテンツ ローダーの代わりに独自のテクスチャ ローダーを使用するように、グラフィックスの読み込みをやり直しました。これが問題でしょうか?

他に選択肢がない場合、ゲームを再起動する簡単な方法はありますか?

私のコードは次のとおりです。

 public override void Click()
    {
        base.Click();
        Settings.Default.screenWidth = resolution[0];
        Settings.Default.screenHeight = resolution[1];
        Settings.Default.Save();
        Variables.screenWidth = Settings.Default.screenWidth;
        Variables.screenHeight = Settings.Default.screenHeight;

        Game1.graphics.PreferredBackBufferWidth = Variables.screenWidth;
        Game1.graphics.PreferredBackBufferHeight = Variables.screenHeight;
        Game1.graphics.ApplyChanges();
    }

ありがとう!

編集: 私のテクスチャ読み込みコード - 列挙型に含まれる名前を持つすべてのファイルを Texture2Ds.. として読み込みます。

public static void LoadAll(string subFolder)
    {
        List<string> s = Directory.GetFiles(path + "\\" + subFolder, "*.png", SearchOption.AllDirectories).ToList<string>();
        foreach (string S in s)
        {
            if (Enum.IsDefined(typeof(T), Path.GetFileNameWithoutExtension(S)))
            {
                FileStream stream = new FileStream(S, FileMode.Open);
                Texture2D t = Texture2D.FromStream(Game1.graphics.GraphicsDevice, stream);
                RenderTarget2D result = null;

                //Setup a render target to hold our final texture which will have premulitplied alpha values
                result = new RenderTarget2D(Game1.graphics.GraphicsDevice, t.Width, t.Height);

                Game1.graphics.GraphicsDevice.SetRenderTarget(result);
                Game1.graphics.GraphicsDevice.Clear(Microsoft.Xna.Framework.Color.Black);

                //Multiply each color by the source alpha, and write in just the color values into the final texture
                BlendState blendColor = new BlendState();
                blendColor.ColorWriteChannels = ColorWriteChannels.Red | ColorWriteChannels.Green | ColorWriteChannels.Blue;

                blendColor.AlphaDestinationBlend = Blend.Zero;
                blendColor.ColorDestinationBlend = Blend.Zero;

                blendColor.AlphaSourceBlend = Blend.SourceAlpha;
                blendColor.ColorSourceBlend = Blend.SourceAlpha;


                Game1.spriteBatch.Begin(SpriteSortMode.Immediate, blendColor);
                Game1.spriteBatch.Draw(t, t.Bounds, Microsoft.Xna.Framework.Color.White);
                Game1.spriteBatch.End();

                //Now copy over the alpha values from the PNG source texture to the final one, without multiplying them
                BlendState blendAlpha = new BlendState();
                blendAlpha.ColorWriteChannels = ColorWriteChannels.Alpha;

                blendAlpha.AlphaDestinationBlend = Blend.Zero;
                blendAlpha.ColorDestinationBlend = Blend.Zero;

                blendAlpha.AlphaSourceBlend = Blend.One;
                blendAlpha.ColorSourceBlend = Blend.One;

                Game1.spriteBatch.Begin(SpriteSortMode.Immediate, blendAlpha);
                Game1.spriteBatch.Draw(t, t.Bounds, Microsoft.Xna.Framework.Color.White);
                Game1.spriteBatch.End();

                //Release the GPU back to drawing to the screen

                Game1.graphics.GraphicsDevice.SetRenderTarget(null);


                t = result;

                textureDictionary.Add(Path.GetFileNameWithoutExtension(S), t);
            }
           // else
            //  Console.WriteLine("Did not load -- " + Path.GetFileNameWithoutExtension(S) + " -- (add to enum to enable loading)");
        }
    }

編集:以下のアドバイスに従う作業コード - おそらく最も効率的ではありませんが、機能します!

public static void LoadAll(string subFolder)
    {
        List<string> s = Directory.GetFiles(path + "\\" + subFolder, "*.png", SearchOption.AllDirectories).ToList<string>();
        foreach (string S in s)
        {
            if (Enum.IsDefined(typeof(T), Path.GetFileNameWithoutExtension(S)))
            {
                FileStream stream = new FileStream(S, FileMode.Open);
                Texture2D t = Texture2D.FromStream(Game1.graphics.GraphicsDevice, stream);
                RenderTarget2D result = null;
                Texture2D resultTexture;

                //Setup a render target to hold our final texture which will have premulitplied alpha values
                result = new RenderTarget2D(Game1.graphics.GraphicsDevice, t.Width, t.Height);

                Game1.graphics.GraphicsDevice.SetRenderTarget(result);
                Game1.graphics.GraphicsDevice.Clear(Microsoft.Xna.Framework.Color.Black);

                //Multiply each color by the source alpha, and write in just the color values into the final texture
                BlendState blendColor = new BlendState();
                blendColor.ColorWriteChannels = ColorWriteChannels.Red | ColorWriteChannels.Green | ColorWriteChannels.Blue;

                blendColor.AlphaDestinationBlend = Blend.Zero;
                blendColor.ColorDestinationBlend = Blend.Zero;

                blendColor.AlphaSourceBlend = Blend.SourceAlpha;
                blendColor.ColorSourceBlend = Blend.SourceAlpha;


                Game1.spriteBatch.Begin(SpriteSortMode.Immediate, blendColor);
                Game1.spriteBatch.Draw(t, t.Bounds, Microsoft.Xna.Framework.Color.White);
                Game1.spriteBatch.End();

                //Now copy over the alpha values from the PNG source texture to the final one, without multiplying them
                BlendState blendAlpha = new BlendState();
                blendAlpha.ColorWriteChannels = ColorWriteChannels.Alpha;

                blendAlpha.AlphaDestinationBlend = Blend.Zero;
                blendAlpha.ColorDestinationBlend = Blend.Zero;

                blendAlpha.AlphaSourceBlend = Blend.One;
                blendAlpha.ColorSourceBlend = Blend.One;

                Game1.spriteBatch.Begin(SpriteSortMode.Immediate, blendAlpha);
                Game1.spriteBatch.Draw(t, t.Bounds, Microsoft.Xna.Framework.Color.White);
                Game1.spriteBatch.End();

                //Release the GPU back to drawing to the screen

                Game1.graphics.GraphicsDevice.SetRenderTarget(null);

                resultTexture = new Texture2D(Game1.graphics.GraphicsDevice, result.Width, result.Height);
                Color[] data = new Color[result.Height * result.Width];
                Color[] textureColor = new Color[result.Height * result.Width];

                result.GetData<Color>(textureColor);

                resultTexture.SetData(textureColor);

                textureDictionary.Add(Path.GetFileNameWithoutExtension(S), resultTexture);
            }
           // else
            //  Console.WriteLine("Did not load -- " + Path.GetFileNameWithoutExtension(S) + " -- (add to enum to enable loading)");
        }
    }
4

1 に答える 1

2

更新されたコードに従って、テクスチャをレンダー ターゲット ( RenderTarget2D) にコピーしています。

通常のテクスチャとは異なり、これらは CPU 側のメモリに支えられていません。通常のテクスチャは、グラフィック デバイスが失われると、GPU 上のデータを自動的に再設定します。ただし、レンダー ターゲットはそのContentLostイベントをIsContentLost発生させて設定します。その後、コンテンツを自分でリセットする必要があります。

いくつかの解決策がありContentLostます。データに応答して更新するだけです。

私はロード時にGetDataandを使用して、レンダー ターゲットのコンテンツを通常の にコピーすることを好みます。これは「うまく機能する」からです。テクスチャを切り替えて事前に乗算されたアルファを使用するような単純なケースでは、すべてを CPU に保持することを好みます。SetDataTexture2D

here の固定テクスチャの使用法について非常に詳細な回答RenderTarget2Dがあります。CPU で直接前乗算を行うコードが含まれています。

あなたの場合は、コンテンツマネージャーを試してみたいと思います. ディレクトリ内のすべてのファイルを処理してから、それらを動的にロードすることができます

于 2013-05-29T16:28:41.197 に答える