2012-03-11 51 views
1

我有一个winforms应用程序,它使用xna作为各种二维编辑器。我基本上有一个自定义控件包装一个新创建的GraphicsDevice(使用面板的句柄和宽度/高度来创建视口)并绘制循环。XNA与Winform,视口错误

现在每次我尝试使用这个控制我不断收到一个异常说:

The viewport is invalid. The viewport cannot be larger than or outside the bounds of the current render target.The MinDepth and MaxDepth but be between 0 and 1

我有点困惑,因为我的创造,就像这样的GraphicsDevice:

public class GraphicsDeviceBuilder 
{ 
    private Viewport viewport; 
    private PresentationParameters presentationParameters; 
    private GraphicsProfile graphicsProfile; 
    private GraphicsAdapter graphicsAdapter; 

    private void ResetBuilder() 
    { 
     viewport = new Viewport(0, 0, 128, 128); 
     presentationParameters = new PresentationParameters(); 
     presentationParameters.BackBufferFormat = SurfaceFormat.Color; 
     presentationParameters.DepthStencilFormat = DepthFormat.Depth24; 
     presentationParameters.PresentationInterval = PresentInterval.Immediate; 
     presentationParameters.IsFullScreen = false; 
     graphicsProfile = GraphicsProfile.Reach; 
     graphicsAdapter = GraphicsAdapter.DefaultAdapter; 
    } 

    public GraphicsDeviceBuilder Create() 
    { 
     ResetBuilder(); 
     return this; 
    } 

    public GraphicsDeviceBuilder WithViewport(Viewport viewport) 
    { 
     this.viewport = viewport; 
     return this; 
    } 

    public GraphicsDeviceBuilder WithPresentationParameters(PresentationParameters presentationParameters) 
    { 
     this.presentationParameters = presentationParameters; 
     return this; 
    } 

    public GraphicsDeviceBuilder WithGraphicsProfile(GraphicsProfile graphicsProfile) 
    { 
     this.graphicsProfile = graphicsProfile; 
     return this; 
    } 

    public GraphicsDeviceBuilder WithGraphicsAdapter(GraphicsAdapter graphicsAdapter) 
    { 
     this.graphicsAdapter = graphicsAdapter; 
     return this; 
    } 

    public GraphicsDevice Build(IntPtr handle) 
    { 
     presentationParameters.DeviceWindowHandle = handle; 
     presentationParameters.BackBufferWidth = viewport.Width; 
     presentationParameters.BackBufferHeight = viewport.Height; 
     return new GraphicsDevice(graphicsAdapter, graphicsProfile, presentationParameters) 
     { 
      Viewport = viewport 
     }; 
    } 
} 

然后在封装此创建设备的面板中:

private void SetupGraphics(GraphicsDeviceBuilder graphicsDeviceBuilder) 
{ 
    var viewport = new Viewport() 
    { 
     X = 0, 
     Y = 0, 
     Width = Math.Max(Width, 1), 
     Height = Math.Max(Height, 1), 
     MinDepth = 0.0f, 
     MaxDepth = 1.0f 
    }; 
    GraphicsDevice = graphicsDeviceBuilder.Create().WithViewport(viewport).Build(Handle); 
} 

我也有这将重置()的方法在重新调整形式的GraphicsDevice,它还更新,如果所需的高度/宽度,它看起来像这样:

private void ResetDevice() 
{ 
    if (GraphicsDevice.GraphicsDeviceStatus == GraphicsDeviceStatus.Lost) 
    { throw new DeviceLostException("Cannot regain access to video hardware"); } 

    var safeWidth = Math.Max(Width, 1); 
    var safeHeight = Math.Max(Height, 1); 
    var newViewport = new Viewport(0, 0, safeWidth, safeHeight) { MinDepth = 0.0f, MaxDepth = 1.0f }; 

    GraphicsDevice.Viewport = newViewport; 
    GraphicsDevice.PresentationParameters.BackBufferWidth = newViewport.Width; 
    GraphicsDevice.PresentationParameters.BackBufferHeight = newViewport.Height; 
    GraphicsDevice.PresentationParameters.DeviceWindowHandle = Handle; 
    GraphicsDevice.Reset(); 
} 

的错误意味着视口的大小无效(在调试时它看起来是错误的,因为它与面板的大小相匹配)并且也具有无效的深度,但正如您可以看到它设置为0和1,使其在范围内(调试也证明这是真实的)。

在运行时运行时,我没有收到类似于设计器中的错误,但我只是在面板上出现了一个红色横线,使我认为它在那里不工作。

回答

1

我已经改变了几件事情,但我的问题似乎是因为我在复位前设置视口,我还需要将PresentationParameters传递到复位方法或他们没有效果,所以像这样:

private void ResetDevice() 
{ 
    var safeWidth = Math.Max(Width, 1); 
    var safeHeight = Math.Max(Height, 1); 
    var newViewport = new Viewport(0, 0, safeWidth, safeHeight) { MinDepth = 0.0f, MaxDepth = 1.0f }; 

    var presentationParams = GraphicsDevice.PresentationParameters; 
    presentationParams.BackBufferWidth = safeWidth; 
    presentationParams.BackBufferHeight = safeHeight; 
    presentationParams.DeviceWindowHandle = Handle; 
    GraphicsDevice.Reset(presentationParams); 

    GraphicsDevice.Viewport = newViewport; 

    if (GraphicsDevice.GraphicsDeviceStatus == GraphicsDeviceStatus.Lost) 
    { throw new DeviceLostException("Cannot regain access to video hardware"); } 
}