Originally we made the font texture f16 due to "clamping" of the
distance field, and kept it as floats (but f32 since conversion isn't
automatic with Vulkan) here. However, clamping isn't really an issue.
You can increase the spread of the font to literally get a wider spread
of the SDF for glows, etc. Switching to u8 uses 4x less texture memory,
which is significant.
It can be used to push the current cursor onto the stack, perform some
tmep allocations, and then pop the stack to "free" them all at once.
This can be nice if you're doing some temporary allocations that aren't
going to be needed when the function returns, since it reduces the
amount of allocator growth a bit.
This allocator is meant to be threadlocal eventually, so there are no
thread-safety concerns.
- Padding is automatically computed from spread.
- Spread increases detail at small sizes.
- Remove failure cases where padding < spread/2
- UVs are un16x2, making room for color
- Don't center glyphs inside their atlas bounding box
- Cache normalized UVs and update them (for glyphs and vertices) when
the atlas changes size.
- Updating the UVs is UGLY and duplicates a lot of code. It may be
better to normalize the UVs on the fly, or just re-render the entire
string if the atlas is updated.
This is an experimental take on the "default filter" system. Each
render Pass has its own "global sampler", initialized to trilinear. The
global sampler will be used by default to sample textures/materials in
shaders. You can set it to a filter mode or a full Sampler object. You
can always send your own Sampler objects to Shaders if you want
per-texture sampler settings. The global sampler is designed to be set a
small number of times per pass instead of on every draw. Basically,
just do Pass:setSampler('nearest') and draw your minecraft world.
- Temporary buffers are not tracked
- Sample-only textures are not tracked, but their initial upload is synchronized.
- Default texture something something
The reason is that the glslang C API doesn't support the extra
overloads that let you provide multiple strings or the lengths for
strings. In our case our shader blobs are not null terminated, so
sending them to glslang would overrun the buffer. I forked glslang
and modified the C API to support a length parameter.
OpenXR provides APIs to enumerate the supported refresh-rates, and
selecting a new refresh-rate. This patch adds two new APIs to the
lovr.headset module:
- lovr.headset.getDisplayFrequencies():
Returns a table containing the supported refresh-rates on
success; nil otherwise.
- lovr.headset.setDisplayFrequency(refreshRate:number):
Returns true on success, false otherwise.
Only the OpenXR backend has support for this feature and it is
gated by the "refreshRate" feature flag, similarly to what the
"getDisplayFrequency()" API does.
Physics world's "quick step" is executed in multiple iteration steps.
The getter and setter for this value is now made available as two new
methods in the World object.
This is allows user to balance between the less accurate but quick
simulations, and more stable behavior of physics.
Something similar was already possible, by reducing the delta time and
running the sim multiple times per frame. However, any force user applies
to collider is zeroed after each step. User would thus have to keep track
of applied forces, and re-apply them inside the physics iteration loop.
By default ODE uses 20 iterations in quick step.
This includes the memory allocator and the morgue.
You can't actually write any data to the buffer yet, since we don't have
commands or temp buffers. Temp buffers (scratchpads) are coming soon.
- rm dynamicIndexing and nonUniformIndexing, for now (arrays aren't well
supported)
- rename compressed texture features
- move clip/cull distance to limit instead of feature (limit can be 0)
- Image supports loading files with multiple layers
- Image supports semantic flags like srgb, premultiplied, etc.
- Image:getPixel and :setPixel support more formats
- DDS loader supports BC4-BC7, DXT2/DXT4, uncompressed formats, etc.
We don't have a good way of returning filesystem error messages yet,
but it's still useful to return a boolean instead of a number to
detect failure of zero byte writes. Exposing the number of bytes
written is kind of weird since it's not very actionable.
Notes:
- We can actually use a single Activity.java file for oculus/pico now
- We can unconditionally compile os_android.c on Android
- No need for including extra jars in build system
- Headset rendering is guaranteed synchronous now, no need to ref L
- Add an "android flavor" build setting to differentiate between oculus
and pico devices, since they both use OpenXR.
- Update the pico manifest to reflect their OpenXR sample
- Remove some OpenGL hacks that aren't necessary anymore
This adds the ability to load and animate a mesh for hand tracking on
the Oculus Quest. It is more or less identical to the current
functionality on the vrapi driver.
One key part of this change is that getPose in OpenXR will see if action
spaces are active before locating their spaces. This is due to some
behavior observed on the Oculus Quest with hand tracking where pose
actions for controllers would return invalid data with all of the
location flags erroneously set. The only way to detect and work around
this is to check the pose action state. When this happens, we fall back
to returning the pose of the wrist joint, which is where the Oculus hand
mesh wants to be drawn. In the event that both controllers and hand
tracking are active, the controller pose will be returned by getPose but
the wrist joint can still be accessed using getSkeleton.
Note that this does not yet include support for properly scaling the
hand mesh.
There are numerous opportunities for optimization here that may be
investigated in the future, though performance is well within an
acceptable range right now.
The notdef glyph will get rendered instead, which is slightly better.
Note that the default font does not have a notdef glyph (bug).
Note that notdef will be rasterized multiple times right now.