2

私は、Windows の MonoGame GL で非常に単純なはずのことを達成しようとしています。つまり、PNG ファイルからテクスチャをロードし、それをスプライトとして画面にレンダリングします。これまでのところ、私はこれに多くの問題を抱えています。次のコード (F#) を使用して PNG を Texture2D にロードしています。

    use file = System.IO.File.OpenRead("testTexture.png")
    this.texture <- Texture2D.FromStream(this.GraphicsDevice, file)

次に、次を使用してレンダリングします。

    this.spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.NonPremultiplied);
    this.spriteBatch.Draw(this.texture, Vector2.Zero, Color.White)
    this.spriteBatch.End()

問題は、アルファ チャネルでのある種の奇妙な効果です。チャネルが事前に乗算されていないかのように見えますが、正確に何が起こっているのかを確認することはできません。ただし、公式の XNA ライブラリを使用すると、まったく同じコードが完全にレンダリングされることは注目に値します。この問題は、バージョン 3.0 と 3.2 でテストした MonoGame でのみ発生し、どちらも同じ問題を抱えています。

問題を説明するために、MonoGame でテスト用の PNG をレンダリングすると、次のようになります。

http://i.imgur.com/Dny26gI.png

各画像の背景は、コーンフラワー ブルー、そしてそれぞれ純粋な赤、緑、青です。赤い背景の画像で、テクスチャの赤い線の周りに暗い輪郭が表示されていることに注意してください。線と背景は両方とも純粋な赤であるため、このアウトラインは存在しないはずです。青色の背景の画像の青色の線の周りで同じことが発生しますが、緑色の背景の画像では発生しないことに注意してください。その画像では、緑色の線が緑色の背景に溶け込んでいます。

以下は、公式の XNA ライブラリを使用してまったく同じファイルをレンダリングする方法です。

http://i.imgur.com/2Rtqhuk.png

背景が同じ色の場合、青、緑、赤の線がどのように背景に溶け込んでいるかに注目してください。これは正しい動作です。

同じコードが XNA と MonoGame の両方で異なる動作をすることを考えると、フレームワークにバグがあるに違いないと思います。バグがどこにあり、どのような性質のものであるかについて、誰かが推測できますか? 簡単に修正できる場合は、そのバグを自分で修正するのが最善の解決策かもしれません。

それに加えて、PNGをロードしてMonoGameの画面に正しくレンダリングする方法を本当に学びたいだけです。これをやりたいと思ったのは私が最初ではないはずです。シンプルにするために、可能な限りコンテンツ パイプラインは避けたいと思います。

アップデート

この問題の性質を理解しようとして、さらに掘り下げました。testTexture.png ファイルを変更して、アルファ ブレンディングの問題がより明確になるようにしました。この新しいテクスチャ ファイルを使用した後、不適切な MonoGame レンダリングのスクリーンショットを撮り、それを別のカラー チャネルで表示しました。何が起こっているのか、私はかなり困惑しています。最初は無視された単純なケースかもしれないとBlendState.NonPremultiplied思っていましたが、私が見ているのはそれよりも複雑に見えます. 特に、緑のカラー チャネルは、青と赤のチャネルとは異なる方法でブレンドされているように見えます。これは、私が話していることに関するスクリーンショットと説明をまとめたかなり大きな PNG 画像です。

i.imgur.com/CEUQqm0.png

明らかに、MonoGame for Windows GL にある種のバグがあり、おそらく私がこれを試していない他のエディションにも何らかのバグがあります (ただし、検証済みのものを確認したいと思います)。ここで何が起こっているのか知っていると思う人がいたら、私に知らせてください。

最後に、私が抱えている問題を再現するためのプロジェクト ファイルを次に示します。

mega.co.nz/#!llFxBbrb!OrpPIn4Tu2UaHHuoSPL03nqOtAJFK59cfxI5TDzLyYI

4

1 に答える 1

6

この問題は解決されました。フレームワークのバグは MonoGame.Framework/Graphics/ImageEx.cs次のメソッドで見つかりました:

internal static void RGBToBGR(this Image bmp)
{
    System.Drawing.Imaging.ImageAttributes ia = new System.Drawing.Imaging.ImageAttributes();
    System.Drawing.Imaging.ColorMatrix cm = new System.Drawing.Imaging.ColorMatrix(rgbtobgr);

    ia.SetColorMatrix(cm);
    using (System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(bmp))
    {
        g.DrawImage(bmp, new System.Drawing.Rectangle(0, 0, bmp.Width, bmp.Height), 0, 0, bmp.Width, bmp.Height, System.Drawing.GraphicsUnit.Pixel, ia);
    }
}

これに変更すると、問題が修正されます。

internal static void RGBToBGR(this Image bmp)
{
    using (Bitmap bmpCopy = (Bitmap)bmp.Clone())
    {
        System.Drawing.Imaging.ImageAttributes ia = new System.Drawing.Imaging.ImageAttributes();
        System.Drawing.Imaging.ColorMatrix cm = new System.Drawing.Imaging.ColorMatrix(rgbtobgr);

        ia.SetColorMatrix(cm);
        using (System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(bmp))
        {
            g.Clear(Color.Transparent);
            g.DrawImage(bmpCopy, new System.Drawing.Rectangle(0, 0, bmp.Width, bmp.Height), 0, 0, bmp.Width, bmp.Height, System.Drawing.GraphicsUnit.Pixel, ia);
        }
    }
}

RGBToBGR 変換が実行されると、変換元の画像オブジェクトの上に変換された画像が描画されます。これが奇妙な効果の原因です。私が言うことができる唯一のことは、画像オブジェクトを再度描画する前にクリアすることです。これはもちろん、変換元のビットマップをコピーする必要があることを意味します。クリアしただけ。

これについて正しい方向に向けてくれたdellis1972に感謝します:https://github.com/mono/MonoGame/issues/1946

于 2013-08-20T22:57:28.377 に答える