2011-09-29 85 views
1

我想在較大的窗口上創建低分辨率遊戲。 (例如,在960x540大小的窗口上96x54 res)。XNA在不提高分辨率的情況下調整窗口大小

我該怎麼辦?有沒有辦法調整獨立於首選後緩衝區寬度和高度的窗口大小?或者我應該只保留一個低分辨率渲染目標,然後在完成最近紋理採樣調整後,將其作爲全屏幕四邊形繪製在我的窗口上?

由於提前,

xoorath

回答

1

使用你在談論可能是一個好主意(另外,如果你想要做的後期處理着色器這將是您更容易)的RenderToTexture方法。 或者,您可以設置窗口的大小,但您的代碼只能在桌面上使用。

您必須添加在你的項目中的2個引用:

using System.Drawing; 
using System.Windows.Forms; 

,然後在遊戲類(在初始化方法即)

GraphicsDeviceManager.PreferredBackBufferWidth = 96; 
GraphicsDeviceManager.PreferredBackBufferHeight = 54; 
IntPtr ptr = this.Window.Handle; 
Form form = (Form) Control.FromHandle(ptr); 
form.Size = new Size(960, 540); 
+0

謝謝兄弟,這就是我一直在尋找。我不確定我是否可以解決這個問題,這樣抽樣就會更加接近和清晰(對我的比賽來說是可取的)。但是,如果沒有,那麼我會執行渲染目標方法。 – Xoorath

+0

不客氣:) – Panos

7

我傾向於選擇在「渲染到紋理「解決方案,以便我可以允許像全屏幕一樣沒有扭曲的情況。

我用它來實現這一目標的類通常看起來是這樣的:

class VirtualScreen 
{ 
    public readonly int VirtualWidth; 
    public readonly int VirtualHeight; 
    public readonly float VirtualAspectRatio; 

    private GraphicsDevice graphicsDevice; 
    private RenderTarget2D screen; 

    public VirtualScreen(int virtualWidth, int virtualHeight, GraphicsDevice graphicsDevice) 
    { 
     VirtualWidth = virtualWidth; 
     VirtualHeight = virtualHeight; 
     VirtualAspectRatio = (float)(virtualWidth)/(float)(virtualHeight); 

     this.graphicsDevice = graphicsDevice; 
     screen = new RenderTarget2D(graphicsDevice, virtualWidth, virtualHeight, false, graphicsDevice.PresentationParameters.BackBufferFormat, graphicsDevice.PresentationParameters.DepthStencilFormat, graphicsDevice.PresentationParameters.MultiSampleCount, RenderTargetUsage.DiscardContents); 
    } 

    private bool areaIsDirty = true; 

    public void PhysicalResolutionChanged() 
    { 
     areaIsDirty = true; 
    } 

    private Rectangle area; 

    public void Update() 
    { 
     if (!areaIsDirty) 
     { 
      return; 
     } 

     areaIsDirty = false; 
     var physicalWidth = graphicsDevice.Viewport.Width; 
     var physicalHeight = graphicsDevice.Viewport.Height; 
     var physicalAspectRatio = graphicsDevice.Viewport.AspectRatio; 

     if ((int)(physicalAspectRatio * 10) == (int)(VirtualAspectRatio * 10)) 
     { 
      area = new Rectangle(0, 0, physicalWidth, physicalHeight); 
      return; 
     } 


     if (VirtualAspectRatio > physicalAspectRatio) 
     { 
      var scaling = (float)physicalWidth/(float)VirtualWidth; 
      var width = (float)(VirtualWidth) * scaling; 
      var height = (float)(VirtualHeight) * scaling; 
      var borderSize = (int)((physicalHeight - height)/2); 
      area = new Rectangle(0, borderSize, (int)width, (int)height); 
     } 
     else 
     { 
      var scaling = (float)physicalHeight/(float)VirtualHeight; 
      var width = (float)(VirtualWidth) * scaling; 
      var height = (float)(VirtualHeight) * scaling; 
      var borderSize = (int)((physicalWidth - width)/2); 
      area = new Rectangle(borderSize, 0, (int)width, (int)height); 
     } 
    } 

    public void BeginCapture() 
    { 
     graphicsDevice.SetRenderTarget(screen); 
    } 

    public void EndCapture() 
    { 
     graphicsDevice.SetRenderTarget(null); 
    } 

    public void Draw(SpriteBatch spriteBatch) 
    { 
     spriteBatch.Draw(screen, area, Color.White); 
    } 


} 

然後在我的比賽中,初始化往往是這樣:

VirtualScreen virtualScreen; 

    protected override void Initialize() 
    { 
     virtualScreen = new VirtualScreen(96, 54, GraphicsDevice); 
     Window.ClientSizeChanged += new EventHandler<EventArgs>(Window_ClientSizeChanged); 
     Window.AllowUserResizing = true; 
     base.Initialize(); 
    } 

    void Window_ClientSizeChanged(object sender, EventArgs e) 
    { 
     virtualScreen.PhysicalResolutionChanged(); 
    } 

隨着所有重要調用Update :

protected override void Update(GameTime gameTime) 
    { 
     virtualScreen.Update(); 

     base.Update(gameTime); 
    } 

然後繪製自己的行爲:

protected override void Draw(GameTime gameTime) 
    { 
     virtualScreen.BeginCapture(); 


     GraphicsDevice.Clear(Color.CornflowerBlue); 
     // game rendering happens here... 


     virtualScreen.EndCapture(); 

     GraphicsDevice.Clear(Color.Black); 
     spriteBatch.Begin(); 
     virtualScreen.Draw(spriteBatch); 
     spriteBatch.End(); 

     base.Draw(gameTime); 
    } 

有了這個,我基本上可以停止關心分辨率,只關注遊戲。

+0

非常感謝lzcd。這是一個非常好的參考,現在有了這兩種解決方案,希望這個線程能夠幫助其他人偶然發現它。我很欣賞你爲此付出的時間。 – Xoorath

相關問題