Giter VIP home page Giter VIP logo

Comments (2)

kcat avatar kcat commented on August 16, 2024

If you're using OpenAL Soft directly or through OpenAL Soft's router, it should be enough to get the Direct functions by calling alcGetProcAddress with an appropriate device handle (device handle not needed if not using the router). Any contexts then created from a device with support for the extension can be used with the same device's Direct functions. So for example:

ALCdevice *device = alcOpenDevice(NULL);
if(!alcIsExtensionSupported(device, "ALC_EXT_direct_context"))
    error("Direct contexts not supported");
alEnableDirect = alcGetProcAddress(device, "alEnableDirect");
alDisableDirect = alcGetProcAddress(device, "alDisableDirect");
... etc ...

ALCcontext *context = alcCreateContext(device, NULL);

alGenSourcesDirect(context, ...);

However, if you're using Creative's router, it needs to be done in two stages:

First, open a device normally with alcOpenDevice (from the router) and check that it supports the ALC_EXT_direct_context extension. Then, use alcGetProcAddress with the device handle to get the alcGetProcAddress2 function, and close the device with the router's alcCloseDevice. Then use alcGetProcAddress2 with the NULL device handle to load all the standard alcOpenDevice, alcCloseDevice, alcGetProcAddress, etc, functions to get the given device's driver-specific functions. E.g.:

ALCdevice *device = alcOpenDevice(NULL);
if(!alcIsExtensionSupported(device, "ALC_EXT_direct_context"))
    error("Direct contexts not supported");
alcGetProcAddress2 = alcGetProcAddress(device, "alcGetProcAddress2");
alcCloseDevice(device);

alcOpenDevice = alcGetProcAddress2(NULL, "alcOpenDevice");
alcCloseDevice = alcGetProcAddress2(NULL, "alcCloseDevice");
... etc ...

Then you can open the device again with the driver-specific alcOpenDevice function you just loaded, and treat it as if you're not using the router by using all the driver-specific functions directly.

This is necessary because Creative's router wraps the drivers' ALCdevice and ALCcontext handles, so even though you could get the Direct functions from the driver through the router, the driver's Direct functions won't recognize the router's ALCcontext handles the app has. Creative's router also has checks in alcGetProcAddress to always return its own functions when querying known functions, which necessitates the need for alcGetProcAddress2. This kind of bootstrapping is similar to how WGL works to bypass Microsoft's OpenGL layer; open the desired device from the system API, load in all the functions from the driver, then close the device with the system API and reopen it directly with the driver. This does unfortunately create an issue if you want to have multiple devices open from different drivers at the same time (you would need to maintain separate sets of function pointers for each device, and use the appropriate set for the given device/context), but I don't know of a way around it when using Creative's router.

from openal-soft.

hypatia-of-sva avatar hypatia-of-sva commented on August 16, 2024

Hello kcat,

it took me some time to get back to this, but I now decided on a way to deal with it. I was thinking about it, and in my opinion, no way of dealing with this with global function pointers is truly satisfying. Therefore, I settled on the following compromise: the old interface will simply not load the direct context functions at all, instead, you have to create a struct and load them yourself. For example, this is one way of replicating the later, more complicated result of yours:

aladDirectFunctions myDirectLoadingFunctions;
aladALFunctions alDirect;
aladALCFunctions alcDirect;
aladDirectFunctions direct;

ALCdevice *bakeDeviceForALCGetProcAddress = NULL;
ALCdevice *bakeDeviceForALCGetProcAddress2 = NULL;
aladFunction bakeALCGetProcAddress(const char *name) {
    return alcGetProcAddress(bakeDeviceForALCGetProcAddress, name);
}
aladFunction bakeALCGetProcAddress2(const char *name) {
    return myDirectLoadingFunctions.alcGetProcAddress2(bakeDeviceForALCGetProcAddress2 , name);
}

aladLoadAL();
ALCdevice *device = alcOpenDevice(NULL);
if(!alcIsExtensionSupported(device, "ALC_EXT_direct_context"))
    error("Direct contexts not supported");
bakeDeviceForALCGetProcAddress  = device;
aladLoadDirectExtension(&myDirectLoadingFunctions, bakeALCGetProcAddress);
alcCloseDevice(device);

bakeDeviceForALCGetProcAddress2  = NULL;
aladLoadALCoreMinimal(&alDirect, bakeALCGetProcAddress2);
aladLoadALCoreRest(&alDirect, bakeALCGetProcAddress2);
aladLoadEFX(&alDirect, bakeALCGetProcAddress2);
aladLoadALExtensions(&alDirect, bakeALCGetProcAddress2);
aladLoadALCCore(&alcDirect, bakeALCGetProcAddress2);
aladLoadALCExtensions(&alcDirect, bakeALCGetProcAddress2);
aladLoadDirectExtension(&direct, bakeALCGetProcAddress2);

/* now we can use the newly loaded alcOpenDevice als alcDirect.OpenDevice
   We can also still use myDirectLoadingFunctions function members to use direct
   functions loaded with the device before, if the function pointers are still valid
   and the same with the global alcOpenDevice, which is a shorthand for aladALC.OpenDevice. */

This is a bit more clunky, but also more flexible. It took me some time to sit with this to actually be comfortable with it, but I do think this is better than the alternative of focing some sort of scheme that may very well look wrong in the future.

Also, I wanted you to give a little heads up that you switched the order of alSourceRewindvDirect and alSourceRewindDirect in comparison to the pointer types LPALSOURCEREWINDVDIRECT and LPALSOURCEREWINDDIRECT, and the same with alSourcePausevDirect and alSourcePauseDirect in comparison to LPALSOURCEPAUSEVDIRECT and LPALSOURCEPAUSEDIRECT. Not something really important, but a little annoyance if you are trying to copy-paste these correctly into a struct with block selection cursors.

With regards,
Hypatia of Sva.

from openal-soft.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.