Есть ли способ проверить, не используется ли Texture2D в данный момент, чтобы я мог выполнить SetData () на нем? - PullRequest
0 голосов
/ 12 августа 2010

Попытка сделать SetData () для Texture2D, который был недавно Draw () - n SpriteBatch, приводит к следующему исключению:

Операция была прервана. Вы не можете изменять ресурс, который был установлен на устройстве, или после того, как он был использован в скобках.

Могу ли я заранее определить, вызовет ли выполнение SetData () это исключение?

Ответы [ 3 ]

1 голос
/ 12 августа 2010

В основном нет.

Самое простое, что нужно сделать - это вызвать SetData в вашем Update методе.

Неправильно использовать SetData в вашем Draw методе, так как устройство может использовать все виды магии вуду со старыми данными. Это подробно объясняется в поле «Осторожно» на странице MSDN .

Теперь, вплоть до XNA 3.1 вы можете использовать SetDataOptions с Texture2D.SetData. Но похоже, что эта функциональность была удалена в XNA 4.0 для текстур.

Шон Харгривз объясняет здесь , как SetDataOptions можно использовать, чтобы сказать графическому процессору: «Да, я делаю хочу перезаписать те данные, которые вы могли использовать, не жалуйтесь». И почему трудно получить права.

1 голос
/ 14 августа 2010

Я решил проблему, подобную этой, создав две текстуры и переключившись между активной, по сути, с двойной буферизацией:

void CreateTextures()
{

  depth_1 = new Texture2D(this.GraphicsDevice, width, height, false, SurfaceFormat.Single);
  depth_2 = new Texture2D(this.GraphicsDevice, width, height, false, SurfaceFormat.Single);

  depth_current = depth_1;

  ...

}

void Draw(GameTime gt)
{
  depth_current = depth_current == depth_1 ? depth_2 : depth_1;
  Depth.SetData(this.DepthBuffer);

  ...

}

В моем случае было невозможно переместить SetData вне Draw, но я полагаю, это самый хороший способ сделать это.

1 голос
/ 12 августа 2010

По существу, у вас есть три варианта:

1) Посмотрите, завершил ли SpriteBatch свою работу, и затем вызовите SetData ().Методы рисования обычно являются асинхронными.Это означает, что они просто добавляются в очередь please-render-me, и метод немедленно возвращается.Вам нужно либо уведомление об обратном вызове после завершения рисования, либо синхронный вызов Draw ().

2) Чтобы избежать прерывания SetData ().Вы можете сделать это, поместив его в критический раздел, который я бы не рекомендовал.Должна быть возможность заблокировать данные текстуры.В Direct3D он называется LockRect (), в XNA он должен быть похожим.

3) Должен быть какой-то метод, например Flush (), который ожидает завершения всех операций, связанных с графикой.Извините за довольно расплывчатую помощь, но вы сможете найти имена методов из документа XNA.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...