OpenAL 버퍼를 바인딩 해제하고 삭제하려면 어떻게해야합니까?


12

소리를 재생하기 위해 OpenAL을 사용하고 있습니다. 버퍼 ID를 가져 와서 이전에 할당 한 풀의 소스에 할당하고 재생하는 fire-and-getget 재생 기능을 구현하려고합니다. 그러나 개체 수명에 문제가 있습니다.

OpenGL에서 delete 함수는 사물을 자동으로 바인드 해제 (예 : 텍스처)하거나 바인딩이 해제 될 때 사물을 자동으로 삭제하므로 (예 : 쉐이더) 일반적으로 삭제를 관리하기 쉽습니다. 그러나 버퍼가 여전히 소스에 바인딩되어 있으면 alDeleteBuffers단순히 실패합니다 AL_INVALID_OPERATION.

OpenAL 버퍼를 "삭제"하는 관용적 방법으로 재생을 마친 다음 자동으로 바인딩을 해제하고 실제로 풀 수 있습니까? 버퍼 관리를 소스 풀에 더 깊이 묶어야합니까 (예 : 버퍼를 삭제하려면 할당 된 모든 소스도 확인해야 함)?

마찬가지로, 버퍼 재생이 끝났을 때 버퍼를 바인딩 해제 (삭제는 안 함)하는 관용적 방법이 있습니까? 무료 소스를 찾을 때 버퍼가 전혀 연결되어 있는지 확인하고 소스 상태를 확인하는 데 방해가되지 않으면 좋을 것입니다.

(C에 대한 접근 방식도 훌륭하지만 C ++을 사용하고 있습니다. GCd 언어를 가정하고 종료자를 사용하는 접근법은 해당되지 않을 수 있습니다.)

openal 

: 당신은 여전히 대답을해야 할 경우, 나는 고르곤 엔진의 가비지 컬렉션 방법을 사용 sf.net/p/gorgon-ge
인 Cem Kalyoncu을

답변:


8

버퍼를 삭제하기 전에 버퍼를 사용하는 각 소스에서 버퍼를 바인딩 해제 해야 합니다 (예 : alSourcei(mSourceId, AL_BUFFER, NULL);버퍼에 바인딩 된 모든 소스를 삭제).

완료시 소리를 해제하려면 각 소리의 길이를 추적해야합니다. 각 음원의 구조를 사용하여 사운드 길이와 재생 시간을 유지할 수 있습니다 (각 게임 틱 업데이트). 전의:

struct AudioVoice
{
    ALuint          mSourceId;
    ALuint          mMsDuration;
    ALuint          mMsPlayed;
};

컴포넌트 기반 시스템을 사용하는 경우 완료중인 모든 실행 소스를 주기적으로 확인하고 바인드 해제 / 소스 삭제를 수행 할 수 있습니다.

코드에서 재생 / 일시 정지 변경 사항을 추적하지 않으면 재생 시간을 늘리기 전에 소스가 재생 중인지 확인해야합니다.

ALint sourceState;
alGetSourcei(mSourceId, AL_SOURCE_STATE, &sourceState);
if (sourceState == AL_PLAYING) { /* increase played time */  }

버퍼에 바인딩 된 소스를 추적하려는 경우 버퍼 ID와 함께 소스 구조에 연결되는 벡터를 사용하여 구조를 사용할 수 있습니다. 이렇게하면 버퍼에 바인딩 된 모든 소스를 중단해야 할 수도 있습니다. 최대한 빨리. 전의:

struct AudioData
{
    RKuint                      mMsDuration;
    ALuint                      mSourceId;
    std::vector<AudioVoice*>    mVoices;
};

이것은 당신을 올바른 길로 인도하기에 충분해야합니다. 매크로와 수작업으로 만든 RTTI 메커니즘에 크게 의존하므로 프로젝트에서 더 자세한 코드를 줄 수는 없습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.