Я использую OpenAL для воспроизведения звуков. Я пытаюсь реализовать функцию воспроизведения «забей и забудь», которая берет идентификатор буфера и назначает его источнику из пула, который я ранее выделил, и воспроизводит его. Однако существует проблема с временем жизни объекта.
В OpenGL функции удаления либо автоматически связывают вещи (например, текстуры), либо автоматически удаляют вещь, когда она в конце концов не связана (например, шейдеры), и поэтому обычно легко управлять удалением. Однако alDeleteBuffers
вместо этого просто происходит сбой, AL_INVALID_OPERATION
если буфер все еще связан с источником.
Есть ли идиоматический способ «удалить» буферы OpenAL, который позволяет им закончить игру, а затем автоматически отменяет привязку и действительно их? Нужно ли более тесно связать управление буфером с пулом источников (например, удаление буфера требует проверки всех выделенных источников)?
Точно так же, есть ли идиоматический способ отсоединять (но не удалять) буферы, когда они заканчивают играть? Было бы хорошо, если бы, когда я искал бесплатный источник, мне нужно было только посмотреть, был ли подключен буфер, и не беспокоиться о проверке исходного состояния.
(Я использую C ++, хотя подходы для C тоже хороши. Подходы, предполагающие использование языка GCd и использование финализаторов, вероятно, не применимы.)
Ответы:
Перед удалением буфера вы должны отсоединить его от каждого источника, который его использует (например:
alSourcei(mSourceId, AL_BUFFER, NULL);
или удалить все источники, которые связаны с буфером.Вы должны отслеживать длину каждого из ваших звуков, чтобы выпустить их после завершения. Вы можете сделать это, используя структуру для каждого источника, чтобы сохранить длину звука и время воспроизведения (обновляется каждый тик игры). Пример:
Если вы используете систему, основанную на компонентах, вы можете периодически проверять все работающие источники на завершение и выполнять там удаление, привязку и удаление.
Если вы не отслеживаете изменения воспроизведения / паузы в своем коде, вы также должны проверить, воспроизводятся ли источники, прежде чем увеличивать время воспроизведения.
Если вы хотите отслеживать источники, связанные с буфером, вы можете использовать структуру с идентификатором вашего буфера и вектором, связывающим со структурами источников, таким образом, вы даже можете прервать все источники, которые связаны с буфером, который вы должны освободить. СРОЧНО. Пример:
Этого должно быть достаточно, чтобы вы встали на правильный путь. Я не могу дать вам более подробный код из моих проектов, так как они сильно зависят от макросов и механизмов RTTI, сделанных вручную.
источник