В моем игровом окне разрешено ручное изменение размеров, что означает, что его можно изменить как любое другое нормальное окно, перетаскивая его края. В игре также используется RenderTarget2D rt2d
, для которой основная цель Render задана в основном методе Draw: GraphicsDevice.SetRenderTarget(rt2d)
, но она reset возвращается к null
(целевой рендеринга по умолчанию) в конце основной метод Draw, что делает его несколько запутанным: действительно ли это источник проблемы, изменяя размер окна игры прямо между моментом, когда Render Target установлен на rt2d
, а не reset обратно на значение по умолчанию? Сейчас это похоже.
Код в основном методе Draw должен всегда reset основной целевой рендеринга вернуться к null
, поэтому ожидаемых случаев не будет, когда этого обычно не будет.
Тем не менее, результат изменения размера окна игры иногда вызывает GraphicsDevice.isDisposed
return true
, а затем игра бросает System.ObjectDisposedException
на первый SpriteBatch.End()
. Я нашел сообщения об этой ошибке, возвращаясь к первым дням XNA, но без хорошего объяснения (а также без упоминания об изменении Render Target, поэтому, возможно, это и послужило источником проблемы для этих плакатов).
Сейчас я могу вызвать эту ошибку, вызвав этот метод несколько раз:
graphics.PreferredBackBufferWidth = graphics.PreferredBackBufferWidth;
graphics.PreferredBackBufferHeight = graphics.PreferredBackBufferHeight;
graphics.ApplyChanges();
... Со следующими строками в основном методе Draw:
RenderTarget2D rt2d = new RenderTarget2D(GraphicsDevice,
graphics.PreferredBackBufferWidth,
graphics.PreferredBackBufferHeight);
GraphicsDevice.SetRenderTarget(rt2d);
sb.Begin();
// main draw method here, it pretty big, so it might be taking long
// enough to process to actually resize before resetting render target
sb.End();
GraphicsDevice.SetRenderTarget(null);
sb.Begin();
// draw the whole rt2d to the screen
sb.End();
Мое предположение заключается в том, что я должен отменить рисование кадра и сбросить цель рендеринга, если изменение размера произойдет до того, как цель визуализации будет reset, но я все еще не уверен, что это именно то, что вызывает это.
UPD. Есть события Window.ClientSizeChanged
и graphics.PreparingDeviceSettings
, но даже когда они срабатывают, по умолчанию цель рендеринга не помогает.
Я предполагаю, что это не "тайм-аут между изменением размера клиентской области и применением новых графических настроек" или что-то еще. Это, скорее всего, вызвано неиндексной целью рендеринга.
И, вероятно, это не так, что размер целевого объекта рендеринга отличается от нового размера экрана, поскольку это также вызывает исключение при изменении размеров графического устройства с такими же значениями.
UPD2. Я просто попробовал сделать полноэкранный режим переключением ожидающей операции, установив для параметра F11 значение isFullscreenTogglePending
значение true и проверив его в начале основного метода Update
, и он не сделал Не помогите. Затем я понял, что ранее полноэкранный режим также переключился с основного метода обновления, только не в самом начале, а на полпути через метод обновления ввода, поэтому на самом деле не имеет значения, где в основном методе Update
он по-прежнему вызывает эту ошибку. Интересно, что GraphicsDevice.isDisposed
является ложным, когда генерируется исключение.
Это сообщение об ошибке:
System.ObjectDisposedException occurred
Message=Cannot access a disposed object.
Object name: 'GraphicsDevice'.
Source=Microsoft.Xna.Framework
ObjectName=GraphicsDevice
StackTrace:
at Microsoft.Xna.Framework.Helpers.CheckDisposed(Object obj, IntPtr pComPtr)
at Microsoft.Xna.Framework.Graphics.BlendState.Apply(GraphicsDevice device)
at Microsoft.Xna.Framework.Graphics.GraphicsDevice.set_BlendState(BlendState value)
at Microsoft.Xna.Framework.Graphics.SpriteBatch.SetRenderState()
at Microsoft.Xna.Framework.Graphics.SpriteBatch.End()
at secret_project.Game1.Draw(GameTime gameTime) in P:\msvs projects\secret_project\Game1.cs:line 3310
InnerException:
Он находится в SpriteBatch.End()
в главном вызове Draw.
Как предотвратить эту ошибку?
Возможно, связанные вопросы: