私は、WP7用のXNAフレームワークと、AndroidおよびiOS用のMonoに基づいて、クロスプラットフォームのフレームワーク/抽象化レイヤーに数か月間取り組んできました。機能の大部分がAndroidで機能するようになったので、最近、両方のプラットフォームで簡単なゲームを機能させるためにWP7に戻りました。
問題は、非常に奇妙なグラフィックエラーが発生したことです。このエラーは、WindowsベースのXNAゲームでは発生せず、方向が横向き(デフォルトまたは指定)の場合にのみWP7で発生します。グリッチはエミュレータに表示されますが、物理デバイスには表示されません。テストの目的で、赤い背景に1つの画像を表示しています。
Windows XNA
Windows http://www.genius-i.com/images/Windows.png
Windows Phone 7(ポートレート)
Portait http://www.genius-i.com/images/Portrait.png
Windows Phone 7(風景)
風景http://www.genius-i.com/images/Landscape.png
明らかに、風景画像は期待どおりに出ていません。すべて抽象化レイヤーを介して処理されますが、XNAプラットフォームファイルは同一であり、WindowsバージョンとWP7バージョンの唯一の違いはターゲットプラットフォーム/フレームワークです。
同様に、グラフィックスデバイスとレンダラーの呼び出しは同じです。
構築中(さまざまなクラスおよび関数から抽出)
device = new Microsoft.Xna.Framework.GraphicsDeviceManager(game);
device.PreferredBackBufferHeight = 480;
device.PreferredBackBufferWidth = 800;
Backend.SupportedOrientations = DisplayOrientation.LandscapeLeft | DisplayOrientation.LandscapeRight;
// Whether or not I set the orientation, the glitchoccurs.
初期化中(さまざまなクラスおよび関数から抽出)
renderer = new SpriteBatch(device.GraphicsDevice);
描画中
device.Clear(Color.Red);
renderer.Begin();
renderer.Draw(ZNGTexture, new Rectangle(10, 400, 145, 66), null, Color.White, 0f, Vector.Zero, SpriteEffects.none, 0f);
renderer.End()
私が説明したようなグラフィカルなグリッチを引き起こす可能性のあるものについて誰かが洞察を持っていますか?
あなたが提供するかもしれないどんな助けにも感謝します、そして数日の間に2番目の質問で侵入して申し訳ありません。
完全なコード
問題を特定するのに役立つように、実際のコードをたくさん紹介しています。少し長いので、もともと除外しました。クラスは、XNAのほとんどの機能の単純なラッパーです。
ゲームクラス
public class Game : Microsoft.Xna.Framework.Game, IGame
{
#region Data: Fields
private GraphicsBackendXNA graphics;
private Renderer2DXNA renderer;
ContentLoaderXNA content;
#endregion
#region Data: Properties
public GraphicsBackend Backend { get { return graphics; } }
public Renderer2D Renderer { get { return renderer; } }
public ContentLoader Loader { get { return content; } }
#endregion
#region Methods: Construction
public Game()
{
graphics = new GraphicsBackendXNA(this);
content = new ContentLoaderXNA(this.Services, "Content");
FinaliseConstruction();
}
protected virtual void FinaliseConstruction() { }
#endregion
#region Methods: Initialisation
protected override void Initialize()
{
Core.Console.Initialise(); // Initialised once for error logging.
base.Initialize();
renderer = new RendererXNA(graphics);
Core.Console.Initialise(renderer); // Initialised a second time for graphics services.
Transform.ScreenSize = new Vector2(Backend.ScreenWidth, Backend.ScreenHeight);
Core.Audio.MediaPlayer.Initialise(new Audio.MediaHandler());
Core.Audio.SoundEffect.Initialise(Audio.SoundEffectXNA.SetVolume);
Core.Input.Input.Set(new KeyboardReaderXNA(), new MouseReaderXNA(), new GamePadReaderXNA(), new Input.Touch.TouchPanelXNA(), new GamePadOutputXNA());
Core.Input.InputManager.Initialise();
}
#endregion
#region Methods: Loading and Unloading Content
protected override void UnloadContent()
{
content.Unload();
base.UnloadContent();
}
#endregion
#region Methods: Drawing
protected override void EndDraw()
{
Camera2D.AllOff();
base.EndDraw();
}
#endregion
グラフィックスバックエンドクラス
グラフィックスバックエンド(XNA)クラスは、単純なラッパークラスです。これは、抽象的で機能を含まないGraphicsBackendクラスを拡張します。
public class GraphicsBackendXNA : GraphicsBackend
{
#region Data: Fields
private Microsoft.Xna.Framework.GraphicsDeviceManager device;
#endregion
#region Data: Properties
public override Display Display { get { return device.GraphicsDevice.PresentationParameters.ToHeron(); } }
public override Core.Graphics.Viewport Viewport { get { return device.GraphicsDevice.Viewport.ToHeron(); } }
public override int ScreenWidth { get { return device.PreferredBackBufferWidth; } set { device.PreferredBackBufferWidth = value; } }
public override int ScreenHeight { get { return device.PreferredBackBufferHeight; } set { device.PreferredBackBufferHeight = value; } }
public override bool IsFullScreen { get { return device.IsFullScreen; } set { device.IsFullScreen = value; } }
public override Core.DisplayOrientation SupportedOrientations
{
get { return ((Core.DisplayOrientation)((int)device.SupportedOrientations); }
set { device.SupportedOrientations = (Microsoft.Xna.Framework.DisplayOrientation)((int)value); }
}
#endregion
#region Methods: Construction
public GraphicsBackendXNA(Microsoft.Xna.Framework.Game game)
{
device = new Microsoft.Xna.Framework.GraphicsDeviceManager(game);
}
#endregion
#region Methods: Settings
public override void ApplyChanges()
{
device.ApplyChanges();
}
#endregion
#region Methods: Rendering
public override void Clear(Colour colour)
{
device.GraphicsDevice.Clear(new Microsoft.Xna.Framework.Color(colour.R, colour.G, colour.B, colour.A));
}
#endregion
#region Methods: Renderer
public override Renderer2D CreateRenderer() { return new Renderer2DXNA(this); }
#endregion
レンダラー2DXNAクラス
Renderer 2D XNAクラスは、もう1つの単純なラッパーです。これは、コンテンツを描画するための多数の抽象メソッドを実装するRenderer2D基本クラスから継承します。最初に詳しく説明する非常に基本的な機能がいくつかありますが、すべての空白のメソッドを含める必要はありません。
public class Renderer2D : IDisposable
{
private GraphicsBackend backend;
private Matrix currentMatrix;
public virtual GraphicsBackend Backend { get { return backend; } protected set { backend = value; } }
public Matrix CurrentMatrix { get { return currentMatrix; } set { currentMatrix = value; } }
public Renderer2D(GraphicsBackend backend) { this.backend = backend; CurrentMatrix = Matrix.Identity; }
}
public class Renderer2DXNA : Renderer2D
{
#region Static: 1 Pixel Texture
private static Texture2D filler;
private static bool Initialised { get { return filler != null; } }
public static void Initialise(GraphicsBackendXNA backend)
{
filler = CreateFiller(backend)
}
private static Texture2D CreateFiller(GraphicsBackendXNA backend)
{
Texture2D rt = new Texture2D(backend.Device.GraphicsDevice, 1, 1);
rt.SetData<Microsoft.Xna.Framework.Color>(new Microsoft.Xna.Framework.Color[] { Microsoft.Xna.Framework.Color.White });
return rt;
}
#endregion
#region Data: Fields
private SpriteBatch renderer;
#endregion
#region Methods: Construction
public Renderer2DXNA(GraphicsBackendXNA backend) : base(backend)
{
if (!Initialised)
Initialise(backend);
renderer = new SpriteBatch(backend.Device.GraphicsDevice);
}
#endregion
#region Methods: Begin and End
public override void Begin(Core.Graphics.SpriteSortMode sortMode, BlendMode blendMode, Core.Matrix transformMatrix)
{
renderer.Begin(); // Obviously not fully implemented, but simple for now.
}
public override void End() { renderer.End(); }
#endregion
#region Methods: Draw Image
public override void Draw(Image Image, Core.Rectangle Boundary, Core.Rectangle? Source, Colour DrawColour, float RotationRadians, Core.Vector2 Origin, Core.SpriteEffects Effects, float Layer)
{
if (!(Image is ImageXNA))
return;
ImageXNA realImage = Image as ImageXNA;
Microsoft.Xna.Framework.Rectangle finalSource =
Source.HasValue ? Source.Value.ToXNARectangle()
: new Microsoft.Xna.Framework.Rectangle(0, 0, realImage.Width, realImage.Height);
renderer.Draw(
realImage.Texture,
Boundary.ToXNARectangle(),
finalSource,
new Microsoft.Xna.Framework.Color(DrawColour.R, DrawColour.G, DrawColour.B, DrawColour.A),
RotationRadians,
Origin.ToXNAVector2(),
(SpriteEffects)((int)Effects),
Layer);
}
#endregion
}
// I'll leave off string and shape drawing, considering they're not being used here.