Я пытаюсь написать свою первую игру для XNA, и я хотел бы включить функцию ALT + ENTER для переключения между полноэкранным и оконным режимами. Моя игра сейчас очень проста, ничего особенного. Я могу заставить его работать либо в оконном (по умолчанию), либо в полноэкранном режиме (вызывая ToggleFullScreen) в моей функции LoadContent, и все отлично работает.
Однако, когда я вызываю ToggleFullScreen в своей функции обновления, используя точно такой же код, моя игра заканчивается неудачей. Если я запускаю окно и переключаюсь в полноэкранный режим, кажется, что он зависает, отображая только один кадр и не принимая ввод с клавиатуры (мне нужно CTRL + ALT + DEL). Если я запускаю полноэкранный режим и переключаюсь в оконный режим, он вызывает ошибку DrawIndexedPrimitive с сообщением «Текущее объявление вершины не включает в себя все элементы, необходимые текущему вершинному шейдеру. Normal0 отсутствует». (что не соответствует действительности; мой буфер вершин - VertexPositionNormalTexture и содержит данные, а состояние GraphicsDevice - Normal).
Обе эти проблемы, похоже, указывают на потерянное соединение с устройством, но я не могу понять, почему. Каждый ресурс, который я нашел в Интернете, говорит, что переключение в полноэкранный режим так же просто, как вызов функции ToggleFullScreen, без упоминания о сбросе устройств или буферов. Есть идеи?
Редактировать: Вот некоторый код с пропущенными посторонними вещами:
protected override void LoadContent()
{
graphics.PreferredBackBufferWidth = 800;
graphics.PreferredBackBufferHeight = 600;
graphics.ToggleFullScreen();
basicEffect = new BasicEffect(graphics.GraphicsDevice);
// etc.
}
protected override void Update(GameTime gameTime)
{
if (k.IsKeyDown(Keys.Enter) && (k.IsKeyDown(Keys.LeftAlt) || k.IsKeyDown(Keys.RightAlt)) && !oldKeys.Contains(Keys.Enter)) {
graphics.ToggleFullScreen();
gameWorld.Refresh();
}
// update the world's graphics; this fills my buffers
GraphicsBuffers gb = gameWorld.Render(graphics.GraphicsDevice);
graphics.GraphicsDevice.SetVertexBuffer(gb.vb, 0);
graphics.GraphicsDevice.Indices = gb.ib;
}
protected override void Draw(GameTime gameTime)
{
// buffer reference again; these are persistent once filled in Update, they don't get created anew
GraphicsBuffers gb = gameWorld.Render(graphics.GraphicsDevice);
foreach (EffectPass effectPass in basicEffect.CurrentTechnique.Passes)
{
effectPass.Apply();
basicEffect.Texture = textures;
graphics.GraphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, gb.vb.VertexCount, 0, gb.ib.IndexCount / 3);
}
}