XNA с Winform, ошибка области просмотра - PullRequest
1 голос
/ 11 марта 2012

У меня есть приложение winforms, которое использует xna для своего рода 2d-редактора.В основном у меня есть собственный элемент управления, который оборачивает недавно созданный GraphicsDevice (используя дескриптор панели и ширину / высоту для создания области просмотра) и рисует цикл.

Теперь каждый раз, когда я пытаюсь использовать этот элемент управления, я продолжаю получатьисключение говорит:

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

У меня также есть метод, который будет Reset () 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, что делает его внутриrange (отладка также подтверждает, что это правда).

При работе во время выполнения я не получаю сообщение об ошибке, как в конструкторе, но я просто получаю красный крестик напанель заставляет меня думать, что она там тоже не работает.

1 Ответ

1 голос
/ 15 марта 2012

Я изменил несколько вещей, но проблема для меня казалась в том, что я настраивал область просмотра перед сбросом, и мне также нужно было передать PresentationParameters в метод 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"); }
}
...