OpenXR basically has a hard requirement that a graphics API is available
before its session can be created. Currently the graphics module isn't
always around when headset initialization takes place. Polling the
graphics availability in update/renderTo has some consequences for calls
made to the headset module in lovr.load or during the first few frames.
So instead we're going to delay headset initialization to a special
function that is called after modules are required. It can also be
called manually if the window creation is delayed.
- Make the renderloop synchronous by hijacking the RAF to run on the
XRSession when active.
- Convert os_web to use emscripten's native HTML5 interface instead
of going through GLFW.
- Stop using preinitialized GL context -- lovrPlatformCreateWindow
now creates the context.
- GLES2/3 emulation is not necessary.
- Remove inline sessions. The VR simulator is used to render to the
Canvas instead. webxr_attach and webxr_detach are used to replace
replace the active headset driver with the webxr driver when an
immersive session starts.
- Add noop desktop_getSkeleton.
It doesn't need to check it for RGB and compressed textures because
those are already rejected.
It may also be a good idea to zero-out the srgb flag for formats that
it doesn't apply to.
- lovr.headset.newModel accepts an optional options table as the
second argument. There is currently a single option named
'animated' that can be used to request an animatable model.
Currently it isn't clear if this should be a hint or not.
- lovr.headset.animate (name pending) can be called with a device
and a model (usually with an animated model from headset.newModel,
but this is not required). The function attempts to animate the
Model to match the pose of the device in an opaque driver-specific
way, and returns whether or not this was successful.
- OpenVR has models for controllers with a system called "components"
that can be used to animate the individual buttons. Now the OpenVR
headset driver implements the 'animate' function to make use of the
controller components, to easily load and render animated controllers.
ModelData manages a single allocation and creates pointers into
that allocation. These pointers were tightly packed, creating
alignment issues which triggered undefined behavior. Now, the
pointers are all aligned to 8 byte boundaries.
* lovrPlatformGetBundlePath was missing the root argument
* ANDROID_SDK can't be assumed to be the parent of the ndk folder, in case it's a side-by-side installation of the NDK. Instead, ANDROID_SDK should be provided with -D
* One more thing we could mention in the docs that I ran into: Installing java with apt gave me an incompatible version. It worked better to just -DJAVA_HOME= to the java that comes with Android studio (/snap/android-studio/91/android-studio/jre on ubuntu).
There are some attributes that don't have a location (gl_InstanceID
is being reported for some reason). Their location is -1 and this
causes a left shift of a negative value which is undefined.
The new t.graphics.debug flag controls the following:
- If enabled, a debug context is created
- If disabled, a no-error context is created
- If enabled, GL debug messages are forwarded to lovr.log
Add entrypoints, headset backend code, fill in the Activity, and
add various special cases to account for the asynchronous render loop,
lack of sRGB support, and OpenGL state resets.
I added header files with #include to prevent the implicit declaration warnings and fixed a typo in function size_t lovrPlatformGetExecutablePath(char* buffer, size_t size).
lovr.log is a new callback that is invoked whenever LÖVR wants to
send the project a message. For example, this could be a performance
warning from the graphics module, an error message from one of the
headset backends, or an API deprecation notice.
The callback's signature is (message, level, tag). The message is a
string containing the message to log, level is a string that is currently
one of "debug", "info", "warn", "error", and tag is an optional string
that is used to indicate the source of the message for grouping purposes.
The default implementation of the callback just prints the message,
but the callback can be overridden to do things like filter messages,
write them to a file, or even render them in VR. Projects can also
invoke the callback directly to log their own messages.