lovr.graphics.fill renders a fullscreen quad, it's convenient because
you don't need to set up a mesh and toggle all the pipeline states.
However, if you are dealing with copying/rendering between stereo
textures, you have to write your own shader for that. For now.
Instead of boolean shader flags turning into actual booleans defines
in the shader source, for GLSL they turn into defines. This lets you
use ifdef, which is the more common intended usage.
Also MULTICANVAS is now a boolean shader flag. The old MULTICANVAS
define is deprecated.
- Slightly dim background color (may change).
- Use a shader for the logo (it's centered now, not quite 100% like the image).
- Adjust text optical weight (I hate it).
Returns the predicted display time, which is the estimated time at which
the photons of the next frame will hit the eyeballs of a person in the HMD.
This should be used instead of lovr.timer.getTime when used for rendering
something that is time-dependent. Updating simulations, logic, or access
to high frequency times should still use lovr.timer.getTime.
It's still a rough draft and likely only works on my machine, but can be
improved over time.
Rough explanation:
- tup.config contains high-level build configuration defaults.
- Tuprules.tup contains mostly compiler flags (generated from the
tup.config) and declares some macros used to compile code.
- Tupfile takes all generated object files and links them into the
lovr executable.
- src/Tupdefault defines the default build steps for src and all
subdirectories, which is to compile all .c files to .o files and put
them in the <objects> bucket for linking by the toplevel Tupfile.
It's possible to have multiple configs active at once for different
platforms, projects, etc. To do this, create a folder for each build
variant you want, and place a tup.config in each folder (it can be a
symlink, which is helpful). Then, invoking `tup` will build all your
variants, or you can build a specific one by doing `tup <foldername>`.
- Add t.hotkeys flag to conf.lua, which defaults to true.
- If t.hotkeys is truthy, the following hotkeys will be enabled:
- Escape: Quit the experience
- F5: Restart the experience
If we expose both unhanded hands and handed hands, people need to
deal with handling (haha) both cases in their apps. It's simpler
to always deal with left and right hands, even though it is a bit
less general. Still, this is congruent with the current state of
OpenVR and OpenXR, and I think there are still open questions about
the more uncommon cases where there are more than two hands.
Now you can pass in the { skinned = true } flag when creating a Shader
to get skinning behavior without needing to write it yourself. The
default is still false.
Need to profile to make sure the if is getting optimized out.
- Add vsync flag to t.window and lovr.graphics.createWindow.
- vsync is 1 by default.
- Some headset drivers override vsync if they have special timing requirements.
Now the lovr.headset module initializes one display driver (the
first one in the list) and multiple tracking drivers. Only drivers
that implement 'renderTo' will be considered for display driver.
Tracking drivers are stored in a linked list, and retrieving pose
information involves trying all of the tracking drivers until the
pose is found.
It seems too dangerous/annoying to have pools error when they run
out of memory. Instead, we'll make it so you can choose to make
a pool resizable, where it enlarges its memory if it runs out. By
default Pools aren't resizable, but the default math pool is.
Also, reduce the size of the default pool from 640k to 4k.
This requires adding an application id function to platform and adding a mini definition to sds into platform.h. All platforms except Android return NULL (no application id)
Currently provides only a lovr.android.getApplicationId(). This returns an Android-specific identifier that doesn't cleanly map to anything specific in other OSes.
- The pcalls to run conf were triggering their error very late, and were detecting error based on the second return value of pcall being non-nil. In fact the second return value of pcall is often non-nil in the case of *success*. We should check the first parameter, success/failure, instead.
- It is possible in principle to call error() with a non-string value, so errhand should sanitize its values with tostring.
- There is a check in the main boot.lua loop whether xpcall returned a string, which is the sign luajit hit an error in an error handler. This check was occurring in the wrong place (my fault; merge error when preparing PR) so if lovr.load() hit this case we were falling back to the horrible “could not call a string” error.
General changes:
- Amended the boot.lua error handling so when an error occurs in the error handler, the inner error is printed before quitting
- Silent quit instead of crash if a user implements lovr.errhand but it doesn't return a function
Oculus Mobile changes:
- The lovr.errhand screen is now correctly invoked for errors that occur inside lovr.draw. Multiple changes were needed to make this work:
- Instead of calling renderHelper, which uses lua_call (unsafe as Oculus Mobile does not call renderHelper) the oculus driver gets hold of the Lua ref and lua_pcalls itself. A new lovrHeadsetExtractRenderFn is added to make this possible.
- A mechanism is added where if the coroutine resume in boot.lua returns a value, boot.lua treats this as the string returned from luax_getstack and invokes lovr.errhand.
- Added a custom atpanic that routes through lovrThrow (since stderr gets eaten). With the draw() changes this should never be encountered, but it's good just in case. In current testing the tracebacks this prints don't seem to be right.
- Fix major bug in android_vthrow that meant % codes didn't work in lovrThrow on Android
- Nothing to do with errors, but fix getAxis("trigger")
The goal is to ensure that (for 3DOF devices) all poses are reported
to include the state.offset vertical transform applied to them. Previously,
only rendering was using state.offset.
This is important to fix spatial audio.
Is doing this in every driver problematic? What if we did it in the
Lua bindings? That way it could be handled in one place.
- Enable/disable individual modules, including enet/json
- Enable/disable different "backends" (audio/headset)
- Choose to use system vs. source versions of different libraries
- Add FORCE_FILESYSTEM
- Handle THREAD_ERROR event with noop case
- Remove hopefully redundant lovr.graphics.clear in errhand
- Finally use correct type signature for assimpFileTell
There are breaking changes:
- lovr.step is removed.
- lovr.run is expected to return a main loop wrapped in a function. The
returned function is run as a coroutine to facilitate a cooperative
main loop.
- lovr.errhand should return a loop function instead of while true-ing.
Canvases can be created with the "stereo" flag to make it a stereo
Canvas. If a Canvas is stereo, everything rendered to it will be
rendered to the left and right halves of it, using left/right
view and projection matrices. Headset drivers will use stereo
Canvases to improve performance.
- Fix winding order of skybox cubemaps.
- Fix skybox image ordering in lovr.graphics.newTexture.
- Change skybox shader to allow rendering cubemap skyboxes last for
early z rejection.
- Remove overriding of depth write and depth test state for cubemap
skyboxes.