В моем игровом окне разрешено изменение размера вручную, что означает, что его можно изменять, как и любого другого обычного окна, перетаскивая его края. В игре также используется RenderTarget2D rt2d
, для которого устанавливается основная цель рендеринга в основном методе Draw: GraphicsDevice.SetRenderTarget(rt2d)
, но он сбрасывается обратно на null
(цель рендеринга по умолчанию) в конце основного метода Draw, что делает его немного сбивает с толку: действительно ли это источник проблемы, изменение размера окна игры прямо между моментом, когда Render Target устанавливается на rt2d
, а не сбрасывается до значений по умолчанию? Прямо сейчас похоже на это.
Код в основном методе Draw должен всегда сбрасывать основную цель Render Target обратно на 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's 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();
Я предполагаю, что я должен прервать отрисовку кадра и сбросить цель рендеринга, если изменение размера произойдет до сброса цели рендеринга, но я все еще не уверен, что это именно то, что вызывает это.
UPD: есть события Window.ClientSizeChanged
и graphics.PreparingDeviceSettings
, но даже когда они срабатывают, установка цели рендеринга по умолчанию не помогает.
Я предполагаю, что это не «тайм-аут между изменением размера клиентской области и применением новых настроек графики» или что-то еще. Скорее всего, это вызвано целью рендеринга, отличной от заданной по умолчанию.
И, вероятно, не то, чтобы размер цели рендеринга стал отличаться от нового размера экрана, потому что это также вызывает исключение при изменении размеров графического устройства на те же самые значения.
UPD2: я просто попытался переключить полноэкранный режим на ожидающую операцию, установив для F11 isFullscreenTogglePending
значение true и проверив его в начале основного Update
метод, и это совсем не помогло. Затем я понял, что ранее полноэкранный режим также переключается из основного метода обновления, но не в самом начале, а в середине метода обновления ввода, поэтому на самом деле не имеет значения, где в основном методе Update
он запускается, это все еще вызывает эту ошибку. Интересно, что GraphicsDevice.isDisposed
имеет значение false при возникновении исключения.
Это сообщение об исключении:
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.
Как мне предотвратить эту ошибку?
Возможно связанные вопросы:
Update()
, вызывая их каждый кадр, когда кнопка мыши удерживается нажатой, сделал размер окна изменяемым, а остальные поместил вDraw()
. Что бы я ни делал, он не вылетает. Вы уверены, что утилизировано GraphicsDevice? Ошибки, возникающие внутри Begin () и End (), могут не проявляться до End (), возможно, что-то, что вы пытаетесь нарисовать, было удалено. Кратко, xboxforums.create.msdn.com/forums/p /86840/536058.aspx кажется актуальным. - person Elle   schedule 14.05.2013