Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/302.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 带Winform的XNA,视口错误_C#_Winforms_Xna_Viewport - Fatal编程技术网

C# 带Winform的XNA,视口错误

C# 带Winform的XNA,视口错误,c#,winforms,xna,viewport,C#,Winforms,Xna,Viewport,我有一个winforms应用程序,它使用xna充当各种2d编辑器。我基本上有一个自定义控件,用于包装新创建的GraphicsDevice(使用面板控制柄和宽度/高度创建视口)和绘制循环 现在,每次我尝试使用此控件时,我都会收到一个异常,说: 视口无效。视口不能大于或超出当前渲染目标的边界。MinDepth和MaxDepth的值必须介于0和1之间 当我创建这样一个图形设备时,我有点困惑: public class GraphicsDeviceBuilder { private Viewpo

我有一个winforms应用程序,它使用xna充当各种2d编辑器。我基本上有一个自定义控件,用于包装新创建的GraphicsDevice(使用面板控制柄和宽度/高度创建视口)和绘制循环

现在,每次我尝试使用此控件时,我都会收到一个异常,说:

视口无效。视口不能大于或超出当前渲染目标的边界。MinDepth和MaxDepth的值必须介于0和1之间

当我创建这样一个图形设备时,我有点困惑:

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();
}
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"); }
}
该错误意味着视口的大小无效(调试时,该大小与面板的大小匹配,因此为假),并且深度无效,但正如您所看到的,它被设置为0和1,使其在范围内(调试也证明这是真的)


在运行时,我没有收到设计器中的错误,但我只是在面板上看到一个红色的十字,让我觉得它也不工作。

我改变了一些事情,但对我来说,问题似乎是我在重置之前设置了视口,我还需要将PresentationParameters传递到reset方法中,否则它们没有效果,所以类似这样:

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();
}
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"); }
}

我已经改变了一些事情,但对我来说,问题似乎围绕着这样一个事实:我在重置之前设置了视口,并且我还需要将PresentationParameters传递到重置方法中,否则它们没有效果,所以类似这样的事情:

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();
}
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"); }
}