return {
modules = {
{
name = "enet",
tag = "library",
summary = "Multiplayer utilities.",
description = "ENet is a UDP networking library bundled with LÖVR that allows you to create multiplayer experiences.\n\nTo use it, `require` the `enet` module.\n\nMore information, including full documentation and examples can be found on the [lua-enet](http://leafo.net/lua-enet/) page.",
key = "enet",
enums = {},
examples = {
{
description = "Here's a simple echo server example. The client sends a message to the server and waits for a response. The server waits for a message and sends it back to the client.",
code = "-- client/main.lua\nlocal enet = require 'enet'\n\nfunction lovr.load()\n local host = enet.host_create()\n local server = host:connect('localhost:6789')\n\n local done = false\n while not done do\n local event = host:service(100)\n if event then\n if event.type == 'connect' then\n print('Connected to', event.peer)\n event.peer:send('hello world')\n elseif event.type == 'receive' then\n print('Got message: ', event.data, event.peer)\n done = true\n end\n end\n end\n\n server:disconnect()\n host:flush()\nend\n\n-- server/main.lua\nlocal enet = require 'enet'\n\nfunction lovr.load()\n local host = enet.host_create('localhost:6789')\n while true do\n local event = host:service(100)\n if event and event.type == 'receive' then\n print('Got message: ', event.data, event.peer)\n event.peer:send(event.data)\n end\n end\nend"
}
},
functions = {},
external = true,
objects = {}
},
{
name = "json",
tag = "library",
summary = "Encodes and decodes JSON.",
description = "The json module exposes functions for encoding and decoding JSON. You can use it by requiring the `cjson` module.",
key = "json",
enums = {},
examples = {
{
code = "local json = require 'cjson'\nlocal data = { health = 10, position = { 1, 2, 3 } }\nlocal encoded = json.encode(data)\nprint(encoded)\nlocal decoded = json.decode(encoded)\nprint(decoded.health, unpack(decoded.position))"
}
},
functions = {},
external = true,
objects = {}
},
{
name = "lovr",
summary = "In the beginning, there was nothing.",
description = "`lovr` is the single global table that is exposed to every LÖVR app. It contains a set of **modules** and a set of **callbacks**.",
key = "lovr",
objects = {},
sections = {
{
name = "Modules",
tag = "modules",
description = "Modules are the **what** of your app; you can use the functions in modules to tell LÖVR to do things. For example, you can draw things on the screen, figure out what buttons on a controller are pressed, or load a 3D model from a file. Each module does what it says on the tin, so the `lovr.graphics` module deals with rendering graphics and `lovr.headset` allows you to interact with VR hardware."
},
{
name = "Callbacks",
tag = "callbacks",
description = "Callbacks are the **when** of the application; you write code inside callbacks which LÖVR then calls at certain points in time. For example, the `lovr.load` callback is called once at startup, and `lovr.focus` is called when the VR application gains or loses input focus."
},
{
name = "System",
tag = "system",
description = "The lovr module also exposes some functions for retrieving information about the system."
},
{
name = "Libraries",
tag = "library",
description = "A few helpful third-party libraries are included with LÖVR for convenience."
}
},
enums = {},
functions = {
{
name = "getOS",
tag = "system",
summary = "Get the current operating system.",
description = "Returns the current operating system.",
key = "lovr.getOS",
module = "lovr",
variants = {
{
arguments = {},
returns = {
{
name = "os",
type = "string",
description = "Either \"Windows\", \"macOS\", \"Linux\", \"Android\" or \"Web\"."
}
}
}
}
},
{
name = "getVersion",
tag = "system",
summary = "Get the current version.",
description = "Get the current major, minor, and patch version of LÖVR.",
key = "lovr.getVersion",
module = "lovr",
variants = {
{
arguments = {},
returns = {
{
name = "major",
type = "number",
description = "The major version."
},
{
name = "minor",
type = "number",
description = "The minor version."
},
{
name = "patch",
type = "number",
description = "The patch number."
}
}
}
}
}
}
},
{
name = "audio",
tag = "modules",
summary = "Plays sound.",
description = "The `lovr.audio` module is responsible for playing sound effects and music. Currently, the only supported audio format is .ogg (Vorbis). Playing a sound involves creating a `Source` object for the sound and calling `Source:play` on it.",
key = "lovr.audio",
objects = {
{
name = "Microphone",
summary = "An object that records audio.",
description = "A Microphone object provides audio input by recording sounds.",
key = "Microphone",
module = "lovr.audio",
constructors = {
"lovr.audio.newMicrophone"
},
related = {
"lovr.audio.getMicrophoneNames",
"SoundData"
},
methods = {
{
name = "getBitDepth",
summary = "Get the bit depth of the Microphone.",
description = "Returns the number of bits occupied for each recorded sample. This is a rough indicator of the quality of the recording, and is 16 by default.",
key = "Microphone:getBitDepth",
module = "lovr.audio",
related = {
"Microphone:getChannelCount",
"Microphone:getSampleRate",
"lovr.audio.newMicrophone"
},
variants = {
{
arguments = {},
returns = {
{
name = "bits",
type = "number",
description = "The number of bits per sample."
}
}
}
}
},
{
name = "getChannelCount",
summary = "Get the number of channels recorded by the Microphone.",
description = "Returns the number of channels recorded by the Microphone. One recorded channel will result in a mono sound, and there will be two channels for a stereo sound. Most microphones only support recording a single channel.",
key = "Microphone:getChannelCount",
module = "lovr.audio",
related = {
"Microphone:getBitDepth",
"Microphone:getSampleRate",
"lovr.audio.newMicrophone"
},
variants = {
{
arguments = {},
returns = {
{
name = "channels",
type = "number",
description = "The number of channels recorded."
}
}
}
}
},
{
name = "getData",
summary = "Get a new SoundData with recorded audio.",
description = "Returns a new SoundData with all of the buffered audio samples that the Microphone has recorded.",
key = "Microphone:getData",
module = "lovr.audio",
notes = "There's a limit on the number of samples the Microphone is able to hold, which can be set at creation time in `lovr.audio.newMicrophone`. While the Microphone is recording, be sure to call this function periodically to get a new chunk of audio in order to make room for more.\n\nYou can use `Microphone:getSampleCount` to figure out how many samples the Microphone is currently holding.",
variants = {
{
arguments = {},
returns = {
{
name = "channels",
type = "number",
description = "The number of channels recorded."
}
}
}
},
related = {
"Microphone:getSampleCount",
"Microphone:startRecording",
"Microphone:stopRecording",
"Microphone:isRecording",
"SoundData"
}
},
{
name = "getName",
summary = "Get the name of the Microphone.",
description = "Returns the name of the Microphone.",
key = "Microphone:getName",
module = "lovr.audio",
related = {
"lovr.audio.getMicrophoneNames",
"lovr.audio.newMicrophone"
},
variants = {
{
arguments = {},
returns = {
{
name = "name",
type = "string",
description = "The name of the Microphone."
}
}
}
}
},
{
name = "getSampleCount",
summary = "Get the number of recorded audio samples.",
description = "Returns the number of audio samples the Microphone has recorded so far. This will be zero if the Microphone hasn't started recording yet, see `Microphone:startRecording`.\n\nThere's a limit on the number of samples the Microphone is able to hold, which can be set at creation time in `lovr.audio.newMicrophone`. While the Microphone is recording, be sure to call `Microphone:getData` periodically to get a new chunk of audio in order to make room for more.",
key = "Microphone:getSampleCount",
module = "lovr.audio",
related = {
"Microphone:getData",
"Microphone:isRecording",
"Microphone:startRecording",
"Microphone:stopRecording",
"lovr.audio.newMicrophone"
},
variants = {
{
arguments = {},
returns = {
{
name = "samples",
type = "number",
description = "The number of recorded samples."
}
}
}
}
},
{
name = "getSampleRate",
summary = "Get the sample rate of the Microphone.",
description = "Returns the number of samples recorded each second. Higher sample rates lead to higher quality audio, but they can reduce performance and may not be supported by all microphones.",
key = "Microphone:getSampleRate",
module = "lovr.audio",
related = {
"Microphone:getBitDepth",
"Microphone:getChannelCount",
"lovr.audio.newMicrophone"
},
variants = {
{
arguments = {},
returns = {
{
name = "sampleRate",
type = "number",
description = "The number of samples recorded every second."
}
}
}
}
},
{
name = "isRecording",
summary = "Get whether the Microphone is recording.",
description = "Returns whether or not the Microphone is currently recording.",
key = "Microphone:isRecording",
module = "lovr.audio",
related = {
"Microphone:startRecording",
"Microphone:stopRecording"
},
variants = {
{
arguments = {},
returns = {
{
name = "recording",
type = "boolean",
description = "Whether the Microphone is recording."
}
}
}
}
},
{
name = "startRecording",
summary = "Start recording.",
description = "Starts recording audio samples from the Microphone. You can use `Microphone:getData` to periodically read the captured audio samples, and use `Microphone:stopRecording` when you're done.",
key = "Microphone:startRecording",
module = "lovr.audio",
related = {
"Microphone:getData",
"Microphone:stopRecording",
"Microphone:isRecording"
},
variants = {
{
arguments = {},
returns = {}
}
}
},
{
name = "stopRecording",
summary = "Stop recording.",
description = "Stops recording from the Microphone.",
key = "Microphone:stopRecording",
module = "lovr.audio",
related = {
"Microphone:startRecording",
"Microphone:isRecording"
},
variants = {
{
arguments = {},
returns = {}
}
}
}
}
},
{
name = "Source",
summary = "A playable sound object.",
description = "A Source is an object representing a single sound. Currently, only ogg sounds are supported. Sources can be in three different states:\n\n
\n
\n
Playing
\n
The source is currently playing. It can be stopped, paused, or rewound.
\n
\n
\n
Paused
\n
The source is paused. It can be stopped, played/resumed, or rewound.
\n
\n
\n
Stopped
\n
The source has been stopped. It can be played.
\n
",
key = "Source",
module = "lovr.audio",
constructors = {
"lovr.audio.newSource"
},
methods = {
{
name = "getBitDepth",
summary = "Get the bit depth of the Source.",
description = "Returns the number of bits per sample in the Source. This is a rough indicator of the \"resolution\" or quality of the Source. It's usually 16 or 32.",
key = "Source:getBitDepth",
module = "lovr.audio",
related = {
"SoundData:getBitDepth",
"AudioStream:getBitDepth"
},
variants = {
{
arguments = {},
returns = {
{
name = "bits",
type = "number",
description = "The number of bits per sample."
}
}
}
}
},
{
name = "getChannelCount",
summary = "Get the number of channels in the Source.",
description = "Returns the number of channels in the Source. Mono sounds have 1 channel and stereo sounds have 2 channels.",
key = "Source:getChannelCount",
module = "lovr.audio",
related = {
"SoundData:getChannelCount",
"AudioStream:getChannelCount"
},
variants = {
{
arguments = {},
returns = {
{
name = "channels",
type = "number",
description = "The number of channels."
}
}
}
}
},
{
name = "getCone",
summary = "Get the Source's volume cone.",
description = "Returns the directional volume cone of the Source. The cone is specified by three values: `innerAngle`, `outerAngle`, and `outerVolume`. If the listener is inside the `innerAngle`, the Source won't have its volume reduced. Otherwise, the volume will start to decrease, reaching a minimum volume of `outerVolume` once the listener is `outerAngle` degrees from the direction of the Source.",
key = "Source:getCone",
module = "lovr.audio",
notes = "The default `innerAngle` for a Source is `0`.\n\nThe default `outerAngle` for a Source is `2 * math.pi`.\n\nThe default `outerVolume` for a Source is `0`.\n\n`Source:setOrientation` can be used to change which way the cone points.",
variants = {
{
arguments = {},
returns = {
{
name = "innerAngle",
type = "number",
description = "The inner cone angle, in radians."
},
{
name = "outerAngle",
type = "number",
description = "The outer cone angle, in radians."
},
{
name = "outerVolume",
type = "number",
description = "The outer cone angle, in radians."
}
}
}
}
},
{
name = "getDuration",
summary = "Get the duration of the Source.",
description = "Returns the duration of the Source.",
key = "Source:getDuration",
module = "lovr.audio",
related = {
"AudioStream:getDuration",
"SoundData:getDuration"
},
variants = {
{
arguments = {
{
name = "unit",
type = "TimeUnit",
description = "The unit to return.",
default = "'seconds'"
}
},
returns = {
{
name = "duration",
type = "number",
description = "The duration of the Source."
}
}
}
}
},
{
name = "getFalloff",
summary = "Get the falloff parameters for the Source.",
description = "Returns parameters that control how the volume of the Source falls of with distance.",
key = "Source:getFalloff",
module = "lovr.audio",
related = {
"Source:getVolumeLimits",
"Source:setVolumeLimits"
},
variants = {
{
arguments = {},
returns = {
{
name = "reference",
type = "number",
description = "The distance at which the volume will start to decrease."
},
{
name = "max",
type = "number",
description = "The distance at which the Source will be its quietest."
},
{
name = "rolloff",
type = "number",
description = "How quickly the sound falls off between the reference and max distances (1.0 is the default)."
}
}
}
}
},
{
name = "getOrientation",
summary = "Get the orientation of the Source.",
description = "Returns the orientation of the Source, in angle/axis representation.",
key = "Source:getOrientation",
module = "lovr.audio",
related = {
"Source:getPosition",
"Source:getPose",
"Source:getCone",
"lovr.audio.getOrientation"
},
variants = {
{
arguments = {},
returns = {
{
name = "angle",
type = "number",
description = "The number of radians the Source is rotated around its axis of rotation."
},
{
name = "ax",
type = "number",
description = "The x component of the axis of rotation."
},
{
name = "ay",
type = "number",
description = "The y component of the axis of rotation."
},
{
name = "az",
type = "number",
description = "The z component of the axis of rotation."
}
}
}
}
},
{
name = "getPitch",
summary = "Get the pitch of the Source.",
description = "Returns the current pitch factor of the Source. The default is 1.0.",
key = "Source:getPitch",
module = "lovr.audio",
variants = {
{
arguments = {},
returns = {
{
name = "pitch",
type = "number",
description = "The current pitch."
}
}
}
}
},
{
name = "getPose",
summary = "Get the pose of the Source.",
description = "Returns the position and orientation of the Source.",
key = "Source:getPose",
module = "lovr.audio",
related = {
"Source:getPosition",
"Source:getOrientation",
"Source:getCone",
"lovr.audio.getPose"
},
variants = {
{
arguments = {},
returns = {
{
name = "x",
type = "number",
description = "The x position of the Source, in meters."
},
{
name = "y",
type = "number",
description = "The y position of the Source, in meters."
},
{
name = "z",
type = "number",
description = "The z position of the Source, in meters."
},
{
name = "angle",
type = "number",
description = "The number of radians the Source is rotated around its axis of rotation."
},
{
name = "ax",
type = "number",
description = "The x component of the axis of rotation."
},
{
name = "ay",
type = "number",
description = "The y component of the axis of rotation."
},
{
name = "az",
type = "number",
description = "The z component of the axis of rotation."
}
}
}
}
},
{
name = "getPosition",
summary = "Get the position of the Source.",
description = "Returns the position of the Source, in meters. Setting the position will cause the Source to be distorted and attenuated based on its position relative to the listener.",
key = "Source:getPosition",
module = "lovr.audio",
related = {
"Source:getOrientation",
"Source:getPose",
"Source:getCone",
"lovr.audio.getPosition"
},
variants = {
{
arguments = {},
returns = {
{
name = "x",
type = "number",
description = "The x coordinate."
},
{
name = "y",
type = "number",
description = "The y coordinate."
},
{
name = "z",
type = "number",
description = "The z coordinate."
}
}
}
}
},
{
name = "getSampleRate",
summary = "Get the sample rate of the Source.",
description = "Returns the number of samples per second in the Source. This is usually a high number like 44100.",
key = "Source:getSampleRate",
module = "lovr.audio",
related = {
"SoundData:getSampleRate",
"AudioStream:getSampleRate"
},
variants = {
{
arguments = {},
returns = {
{
name = "frequency",
type = "number",
description = "The number of samples per second in the Source."
}
}
}
}
},
{
name = "getType",
summary = "Get the SourceType of the Source.",
description = "Returns the SourceType of the Source that controls how the Source decodes audio. See `SourceType` for more info.",
key = "Source:getType",
module = "lovr.audio",
related = {
"SourceType",
"lovr.audio.newSource"
},
variants = {
{
arguments = {},
returns = {
{
name = "type",
type = "SourceType",
description = "The SourceType of the Source."
}
}
}
}
},
{
name = "getVelocity",
summary = "Get the velocity of the Source.",
description = "Returns the velocity of the Source, in meters per second. This affects the doppler effect.",
key = "Source:getVelocity",
module = "lovr.audio",
notes = "The Source does not move based on its velocity.",
variants = {
{
arguments = {},
returns = {
{
name = "x",
type = "number",
description = "The x velocity."
},
{
name = "y",
type = "number",
description = "The y velocity."
},
{
name = "z",
type = "number",
description = "The z velocity."
}
}
}
}
},
{
name = "getVolume",
summary = "Get the volume of the Source.",
description = "Returns the current volume factor for the Source. 1.0 is the default and the maximum.",
key = "Source:getVolume",
module = "lovr.audio",
variants = {
{
arguments = {},
returns = {
{
name = "volume",
type = "number",
description = "The volume of the Source."
}
}
}
}
},
{
name = "getVolumeLimits",
summary = "Get the volume limits of the Source.",
description = "Returns the minimum and maximum volume of the Source. These limits have priority over the parameters set by `Source:setFalloff` and `Source:setCone`, so they can be used to make sure a Source can always be heard even if it's far away.",
key = "Source:getVolumeLimits",
module = "lovr.audio",
variants = {
{
arguments = {},
returns = {
{
name = "min",
type = "number",
description = "The minimum volume of the Source."
},
{
name = "max",
type = "number",
description = "The maximum volume of the Source."
}
}
}
}
},
{
name = "isLooping",
summary = "Check if the Source is looping.",
description = "Returns whether or not the Source will loop when it finishes.",
key = "Source:isLooping",
module = "lovr.audio",
variants = {
{
arguments = {},
returns = {
{
name = "looping",
type = "boolean",
description = "Whether or not the Source is looping."
}
}
}
}
},
{
name = "isPaused",
summary = "Check if the Source is paused.",
description = "Returns whether or not the Source is paused.",
key = "Source:isPaused",
module = "lovr.audio",
variants = {
{
arguments = {},
returns = {
{
name = "paused",
type = "boolean",
description = "Whether the Source is paused."
}
}
}
}
},
{
name = "isPlaying",
summary = "Check if the Source is playing.",
description = "Returns whether or not the Source is playing.",
key = "Source:isPlaying",
module = "lovr.audio",
variants = {
{
arguments = {},
returns = {
{
name = "playing",
type = "boolean",
description = "Whether the Source is playing."
}
}
}
}
},
{
name = "isRelative",
summary = "Check if the Source is relative to the listener.",
description = "Returns whether or not the Source is relative to the listener. If a Source is relative then its position, velocity, cone, and orientation are all treated as relative to the audio listener, instead of absolute positions in space.",
key = "Source:isRelative",
module = "lovr.audio",
variants = {
{
arguments = {},
returns = {
{
name = "relative",
type = "boolean",
description = "Whether or not the Source is relative."
}
}
}
}
},
{
name = "isStopped",
summary = "Check if the Source is stopped.",
description = "Returns whether or not the Source is stopped.",
key = "Source:isStopped",
module = "lovr.audio",
variants = {
{
arguments = {},
returns = {
{
name = "stopped",
type = "boolean",
description = "Whether the Source is stopped."
}
}
}
}
},
{
name = "pause",
summary = "Pause the Source.",
description = "Pauses the source. It can be resumed with `Source:resume` or `Source:play`. If a paused source is rewound, it will remain paused.",
key = "Source:pause",
module = "lovr.audio",
variants = {
{
arguments = {},
returns = {}
}
}
},
{
name = "play",
summary = "Play the Source.",
description = "Plays the Source. This doesn't do anything if the Source is already playing.",
key = "Source:play",
module = "lovr.audio",
variants = {
{
arguments = {},
returns = {}
}
}
},
{
name = "resume",
summary = "Resume the Source.",
description = "Resumes the Source.",
key = "Source:resume",
module = "lovr.audio",
variants = {
{
arguments = {},
returns = {}
}
}
},
{
name = "rewind",
summary = "Rewind the Source.",
description = "Rewinds the Source, starting it over at the beginning. Paused Sources will remain paused.",
key = "Source:rewind",
module = "lovr.audio",
variants = {
{
arguments = {},
returns = {}
}
}
},
{
name = "seek",
summary = "Set the playback position of the Source.",
description = "Seeks the Source to the specified position.",
key = "Source:seek",
module = "lovr.audio",
variants = {
{
arguments = {
{
name = "position",
type = "number",
description = "The position to seek to."
},
{
name = "unit",
type = "TimeUnit",
description = "The units for the seek position.",
default = "'seconds'"
}
},
returns = {}
}
}
},
{
name = "setCone",
summary = "Set the Source's volume cone.",
description = "Sets the directional volume cone of the Source. The cone is specified by three values: `innerAngle`, `outerAngle`, and `outerVolume`. If the listener is inside the `innerAngle`, the Source won't have its volume changed. Otherwise, the volume will start to decrease, reaching a minimum volume of `outerVolume` once the listener is `outerAngle` degrees from the direction of the Source.",
key = "Source:setCone",
module = "lovr.audio",
notes = "The default `innerAngle` for a Source is `0`.\n\nThe default `outerAngle` for a Source is `2 * math.pi`.\n\nThe default `outerVolume` for a Source is `0`.\n\nThe direction of the cone can be changed using `Source:setOrientation`.",
variants = {
{
arguments = {
{
name = "innerAngle",
type = "number",
description = "The inner cone angle, in radians."
},
{
name = "outerAngle",
type = "number",
description = "The outer cone angle, in radians."
},
{
name = "outerVolume",
type = "number",
description = "The outer cone angle, in radians."
}
},
returns = {}
}
}
},
{
name = "setFalloff",
summary = "Set the falloff parameters for the Source.",
description = "Sets parameters that control how the volume of the Source falls of with distance.\n\nOnly mono sources support positional falloff. Using this function on a stereo Source will cause an error.",
key = "Source:setFalloff",
module = "lovr.audio",
related = {
"Source:getVolumeLimits",
"Source:setVolumeLimits"
},
variants = {
{
arguments = {
{
name = "reference",
type = "number",
description = "The distance at which the volume will start to decrease."
},
{
name = "max",
type = "number",
description = "The distance at which the Source will be its quietest."
},
{
name = "rolloff",
type = "number",
description = "How quickly the sound falls off between the reference and max distances (1.0 is the default)."
}
},
returns = {}
}
}
},
{
name = "setLooping",
summary = "Set whether or not the Source loops.",
description = "Sets whether or not the Source loops.",
key = "Source:setLooping",
module = "lovr.audio",
variants = {
{
arguments = {
{
name = "loop",
type = "boolean",
description = "Whether or not the Source will loop."
}
},
returns = {}
}
}
},
{
name = "setOrientation",
summary = "Set the orientation of the Source.",
description = "Sets the orientation of the Source in angle/axis representation.",
key = "Source:setOrientation",
module = "lovr.audio",
related = {
"Source:setPosition",
"Source:setPose",
"Source:setCone",
"lovr.audio.setOrientation"
},
variants = {
{
arguments = {
{
name = "angle",
type = "number",
description = "The number of radians the Source should be rotated around its rotation axis."
},
{
name = "ax",
type = "number",
description = "The x component of the axis of rotation."
},
{
name = "ay",
type = "number",
description = "The y component of the axis of rotation."
},
{
name = "az",
type = "number",
description = "The z component of the axis of rotation."
}
},
returns = {}
}
}
},
{
name = "setPitch",
summary = "Set the pitch of the Source.",
description = "Sets the pitch of the Source. The default is 1.0.",
key = "Source:setPitch",
module = "lovr.audio",
variants = {
{
arguments = {
{
name = "pitch",
type = "number",
description = "The new pitch."
}
},
returns = {}
}
}
},
{
name = "setPose",
summary = "Set the pose of the Source.",
description = "Sets the position and orientation of the Source.",
key = "Source:setPose",
module = "lovr.audio",
related = {
"Source:setPosition",
"Source:setOrientation",
"lovr.audio.setPose"
},
variants = {
{
arguments = {
{
name = "x",
type = "number",
description = "The x position of the Source, in meters."
},
{
name = "y",
type = "number",
description = "The y position of the Source, in meters."
},
{
name = "z",
type = "number",
description = "The z position of the Source, in meters."
},
{
name = "angle",
type = "number",
description = "The number of radians the Source is rotated around its axis of rotation."
},
{
name = "ax",
type = "number",
description = "The x component of the axis of rotation."
},
{
name = "ay",
type = "number",
description = "The y component of the axis of rotation."
},
{
name = "az",
type = "number",
description = "The z component of the axis of rotation."
}
},
returns = {}
}
}
},
{
name = "setPosition",
summary = "Set the position of the Source.",
description = "Sets the position of the Source, in meters. Setting the position will cause the Source to be distorted and attenuated based on its position relative to the listener.\n\nOnly mono sources can be positioned. Setting the position of a stereo Source will cause an error.",
key = "Source:setPosition",
module = "lovr.audio",
variants = {
{
arguments = {
{
name = "x",
type = "number",
description = "The x coordinate."
},
{
name = "y",
type = "number",
description = "The y coordinate."
},
{
name = "z",
type = "number",
description = "The z coordinate."
}
},
returns = {}
}
}
},
{
name = "setRelative",
summary = "Set whether or not the Source is relative.",
description = "Sets whether or not the Source is relative to the listener. If a Source is relative then its position, velocity, cone, and orientation are all treated as relative to the audio listener.",
key = "Source:setRelative",
module = "lovr.audio",
variants = {
{
arguments = {
{
name = "relative",
type = "boolean",
description = "Whether or not the Source should be relative."
}
},
returns = {}
}
}
},
{
name = "setVelocity",
summary = "Set the velocity of the Source.",
description = "Sets the velocity of the Source, in meters per second. This affects the doppler effect.",
key = "Source:setVelocity",
module = "lovr.audio",
notes = "The Source does not move based on its velocity.",
variants = {
{
arguments = {
{
name = "x",
type = "number",
description = "The x velocity."
},
{
name = "y",
type = "number",
description = "The y velocity."
},
{
name = "z",
type = "number",
description = "The z velocity."
}
},
returns = {}
}
}
},
{
name = "setVolume",
summary = "Set the volume of the Source.",
description = "Sets the current volume factor for the Source. 1.0 is the default and the maximum.",
key = "Source:setVolume",
module = "lovr.audio",
variants = {
{
arguments = {
{
name = "volume",
type = "number",
description = "The new volume."
}
},
returns = {}
}
}
},
{
name = "setVolumeLimits",
summary = "Set the volume limits of the Source.",
description = "Sets the minimum and maximum volume of the Source. These limits have priority over the parameters set by `Source:setFalloff` and `Source:setCone`, so they can be used to make sure a Source can always be heard even if it's far away.",
key = "Source:setVolumeLimits",
module = "lovr.audio",
variants = {
{
arguments = {
{
name = "min",
type = "number",
description = "The minimum volume of the Source."
},
{
name = "max",
type = "number",
description = "The maximum volume of the Source."
}
},
returns = {}
}
}
},
{
name = "stop",
summary = "Stop the Source.",
description = "Stops the source, also rewinding it to the beginning.",
key = "Source:stop",
module = "lovr.audio",
variants = {
{
arguments = {},
returns = {}
}
}
},
{
name = "tell",
summary = "Get the playback position of the Source.",
description = "Returns the current playback position of the Source.",
key = "Source:tell",
module = "lovr.audio",
variants = {
{
arguments = {
{
name = "unit",
type = "TimeUnit",
description = "The unit to return.",
default = "'seconds'"
}
},
returns = {
{
name = "position",
type = "number",
description = "The current playback position."
}
}
}
}
}
}
}
},
functions = {
{
name = "getDopplerEffect",
tag = "listener",
summary = "Get the doppler effect parameters.",
description = "Returns the parameters that control the simulated doppler effect.",
key = "lovr.audio.getDopplerEffect",
module = "lovr.audio",
notes = "The default factor is 1.0 and the default speed of sound is 343.29.",
variants = {
{
arguments = {},
returns = {
{
name = "factor",
type = "number",
description = "The doppler effect scaling factor."
},
{
name = "speedOfSound",
type = "number",
description = "The speed of sound, in meters per second."
}
}
}
}
},
{
name = "getMicrophoneNames",
tag = "microphones",
summary = "Get the names of all connected microphones.",
description = "Returns a table with the names of all microphones connected to the system.",
key = "lovr.audio.getMicrophoneNames",
module = "lovr.audio",
related = {
"lovr.audio.newMicrophone",
"Microphone"
},
variants = {
{
arguments = {},
returns = {
{
name = "names",
type = "table",
description = "The list of microphone names as strings."
}
}
},
{
arguments = {
{
name = "t",
type = "table",
description = "A table to fill with the microphone names."
}
},
returns = {
{
name = "t",
type = "table",
description = "The original table that was passed in."
}
}
}
}
},
{
name = "getOrientation",
tag = "listener",
summary = "Get the orientation of the listener.",
description = "Returns the orientation of the virtual audio listener in angle/axis representation.",
key = "lovr.audio.getOrientation",
module = "lovr.audio",
related = {
"lovr.audio.getPosition",
"lovr.audio.getPose",
"Source:getOrientation"
},
variants = {
{
arguments = {},
returns = {
{
name = "angle",
type = "number",
description = "The number of radians the listener is rotated around its axis of rotation."
},
{
name = "ax",
type = "number",
description = "The x component of the axis of rotation."
},
{
name = "ay",
type = "number",
description = "The y component of the axis of rotation."
},
{
name = "az",
type = "number",
description = "The z component of the axis of rotation."
}
}
}
}
},
{
name = "getPose",
tag = "listener",
summary = "Get the pose of the listener.",
description = "Returns the position and orientation of the virtual audio listener.",
key = "lovr.audio.getPose",
module = "lovr.audio",
related = {
"lovr.audio.getPosition",
"lovr.audio.getOrientation",
"Source:getPose"
},
variants = {
{
arguments = {},
returns = {
{
name = "x",
type = "number",
description = "The x position of the listener, in meters."
},
{
name = "y",
type = "number",
description = "The y position of the listener, in meters."
},
{
name = "z",
type = "number",
description = "The z position of the listener, in meters."
},
{
name = "angle",
type = "number",
description = "The number of radians the listener is rotated around its axis of rotation."
},
{
name = "ax",
type = "number",
description = "The x component of the axis of rotation."
},
{
name = "ay",
type = "number",
description = "The y component of the axis of rotation."
},
{
name = "az",
type = "number",
description = "The z component of the axis of rotation."
}
}
}
}
},
{
name = "getPosition",
tag = "listener",
summary = "Get the position of the listener.",
description = "Returns the position of the virtual audio listener, in meters.",
key = "lovr.audio.getPosition",
module = "lovr.audio",
variants = {
{
arguments = {},
returns = {
{
name = "x",
type = "number",
description = "The x position of the listener."
},
{
name = "y",
type = "number",
description = "The y position of the listener."
},
{
name = "z",
type = "number",
description = "The z position of the listener."
}
}
}
}
},
{
name = "getVelocity",
tag = "listener",
summary = "Get the velocity of the audio listener.",
description = "Returns the velocity of the audio listener, in meters per second. This affects the doppler effect.",
key = "lovr.audio.getVelocity",
module = "lovr.audio",
notes = "The audio listener does not move based on its velocity.",
variants = {
{
arguments = {},
returns = {
{
name = "x",
type = "number",
description = "The x velocity."
},
{
name = "y",
type = "number",
description = "The y velocity."
},
{
name = "z",
type = "number",
description = "The z velocity."
}
}
}
}
},
{
name = "getVolume",
tag = "listener",
summary = "Get the master volume.",
description = "Returns the master volume. All Source objects have their volume multiplied by this factor.",
key = "lovr.audio.getVolume",
module = "lovr.audio",
notes = "The default is 1.0.",
variants = {
{
arguments = {},
returns = {
{
name = "volume",
type = "number",
description = "The master volume."
}
}
}
}
},
{
name = "isSpatialized",
tag = "listener",
summary = "Check if audio is spatialized.",
description = "Returns whether or not audio is currently spatialized with HRTFs.",
key = "lovr.audio.isSpatialized",
module = "lovr.audio",
variants = {
{
arguments = {},
returns = {
{
name = "spatialized",
type = "boolean",
description = "Whether or not audio is spatialized."
}
}
}
}
},
{
name = "newMicrophone",
tag = "microphones",
summary = "Create a new Microphone.",
description = "Creates a new Microphone based on the name of an existing micrphone and a set of capture parameters. If the specified combination of prameters are not supported for audio capture, `nil` will be returned.",
key = "lovr.audio.newMicrophone",
module = "lovr.audio",
related = {
"lovr.audio.getMicrophoneNames",
"Microphone"
},
variants = {
{
arguments = {
{
name = "name",
type = "string",
description = "The name of the microphone that this Microphone will record from, or `nil` to use the default microphone.",
default = "nil"
},
{
name = "samples",
type = "number",
description = "The maximum number of samples that will be stored in the Microphone's internal buffer.",
default = "1024"
},
{
name = "sampleRate",
type = "number",
description = "The number of audio samples to record each second.",
default = "8000"
},
{
name = "bitDepth",
type = "number",
description = "The number of bits occupied by each sample. Usually 8 or 16.",
default = "16"
},
{
name = "channelCount",
type = "number",
description = "The number of channels to record (1 for mono, 2 for stereo).",
default = "1"
}
},
returns = {
{
name = "microphone",
type = "Microphone",
description = "The new Microphone, or `nil` if the capture settings are not supported."
}
}
}
}
},
{
name = "newSource",
tag = "sources",
summary = "Create a new Source.",
description = "Creates a new Source from an ogg file.",
key = "lovr.audio.newSource",
module = "lovr.audio",
variants = {
{
arguments = {
{
name = "filename",
type = "string",
description = "The filename of the sound to load."
},
{
name = "type",
type = "SourceType",
description = "How to stream in audio data."
}
},
returns = {
{
name = "source",
type = "Source",
description = "The new Source."
}
}
},
{
arguments = {
{
name = "blob",
type = "Blob",
description = "The Blob containing the Source data."
},
{
name = "type",
type = "SourceType",
description = "How to stream in audio data."
}
},
returns = {
{
name = "source",
type = "Source",
description = "The new Source."
}
}
},
{
arguments = {
{
name = "stream",
type = "AudioStream",
description = "The AudioStream used to stream audio data to the Source."
},
{
name = "type",
type = "SourceType",
description = "How to stream in audio data."
}
},
returns = {
{
name = "source",
type = "Source",
description = "The new Source."
}
}
},
{
arguments = {
{
name = "soundData",
type = "SoundData",
description = "The SoundData containing raw audio samples to play."
}
},
returns = {
{
name = "source",
type = "Source",
description = "The new Source."
}
}
}
}
},
{
name = "pause",
tag = "sources",
summary = "Pause all Sources.",
description = "Pause all playing audio.",
key = "lovr.audio.pause",
module = "lovr.audio",
related = {
"Source:pause",
"lovr.audio.resume",
"lovr.audio.rewind",
"lovr.audio.stop"
},
variants = {
{
arguments = {},
returns = {}
}
}
},
{
name = "resume",
tag = "sources",
summary = "Resume all Sources.",
description = "Resume all Sources. Has no effect on Sources that are playing or stopped.",
key = "lovr.audio.resume",
module = "lovr.audio",
related = {
"Source:resume",
"Source:resume",
"lovr.audio.pause",
"lovr.audio.rewind",
"lovr.audio.stop"
},
variants = {
{
arguments = {},
returns = {}
}
}
},
{
name = "rewind",
tag = "sources",
summary = "Rewind all Sources.",
description = "Rewind all playing audio.",
key = "lovr.audio.rewind",
module = "lovr.audio",
notes = "Sources that are paused will remain paused. Sources that are currently playing will restart from the beginning.",
related = {
"Source:rewind",
"lovr.audio.pause",
"lovr.audio.resume",
"lovr.audio.stop"
},
variants = {
{
arguments = {},
returns = {}
}
}
},
{
name = "setDopplerEffect",
tag = "listener",
summary = "Set the doppler effect parameters.",
description = "Sets the parameters that control the simulated doppler effect: The effect intensity and the speed of sound.",
key = "lovr.audio.setDopplerEffect",
module = "lovr.audio",
notes = "The default factor is 1.0 and the default speed of sound is 343.29.",
variants = {
{
arguments = {
{
name = "factor",
type = "number",
description = "The doppler effect scaling factor.",
default = "1.0"
},
{
name = "speedOfSound",
type = "number",
description = "The speed of sound, in meters per second.",
default = "343.29"
}
},
returns = {}
}
}
},
{
name = "setOrientation",
tag = "listener",
summary = "Set the orientation of the listener.",
description = "Sets the orientation of the virtual audio listener in angle/axis representation.",
key = "lovr.audio.setOrientation",
module = "lovr.audio",
variants = {
{
arguments = {
{
name = "angle",
type = "number",
description = "The number of radians the listener should be rotated around its rotation axis."
},
{
name = "ax",
type = "number",
description = "The x component of the axis of rotation."
},
{
name = "ay",
type = "number",
description = "The y component of the axis of rotation."
},
{
name = "az",
type = "number",
description = "The z component of the axis of rotation."
}
},
returns = {}
}
}
},
{
name = "setPose",
tag = "listener",
summary = "Set the pose of the listener.",
description = "Sets the position and orientation of the virtual audio listener.",
key = "lovr.audio.setPose",
module = "lovr.audio",
notes = "The default implementation of `lovr.run` calls this function with the result of `lovr.headset.getPose`, so that the listener automatically tracks the headset.",
related = {
"lovr.audio.setPosition",
"lovr.audio.setOrientation",
"Source:setPose"
},
variants = {
{
arguments = {
{
name = "x",
type = "number",
description = "The x position of the listener, in meters."
},
{
name = "y",
type = "number",
description = "The y position of the listener, in meters."
},
{
name = "z",
type = "number",
description = "The z position of the listener, in meters."
},
{
name = "angle",
type = "number",
description = "The number of radians the listener is rotated around its axis of rotation."
},
{
name = "ax",
type = "number",
description = "The x component of the axis of rotation."
},
{
name = "ay",
type = "number",
description = "The y component of the axis of rotation."
},
{
name = "az",
type = "number",
description = "The z component of the axis of rotation."
}
},
returns = {}
}
}
},
{
name = "setPosition",
tag = "listener",
summary = "Set the position of the listener.",
description = "Sets the position of the virtual audio listener, in meters.",
key = "lovr.audio.setPosition",
module = "lovr.audio",
variants = {
{
arguments = {
{
name = "x",
type = "number",
description = "The x position of the listener."
},
{
name = "y",
type = "number",
description = "The y position of the listener."
},
{
name = "z",
type = "number",
description = "The z position of the listener."
}
},
returns = {}
}
}
},
{
name = "setVelocity",
tag = "listener",
summary = "Set the velocity of the audio listener.",
description = "Sets the velocity of the audio listener, in meters per second. This affects the doppler effect.",
key = "lovr.audio.setVelocity",
module = "lovr.audio",
notes = "The audio listener does not move based on its velocity.",
variants = {
{
arguments = {
{
name = "x",
type = "number",
description = "The x velocity."
},
{
name = "y",
type = "number",
description = "The y velocity."
},
{
name = "z",
type = "number",
description = "The z velocity."
}
},
returns = {}
}
}
},
{
name = "setVolume",
tag = "listener",
summary = "Set the master volume.",
description = "Sets the master volume. The volume of all Sources will be multiplied by this factor.",
key = "lovr.audio.setVolume",
module = "lovr.audio",
notes = "The default is 1.0.",
variants = {
{
arguments = {},
returns = {
{
name = "volume",
type = "number",
description = "The master volume."
}
}
}
}
},
{
name = "stop",
tag = "sources",
summary = "Stop all Sources.",
description = "Stops all audio.",
key = "lovr.audio.stop",
module = "lovr.audio",
notes = "If you want to resume the stopped audio later, see `lovr.audio.pause`.",
related = {
"Source:stop",
"lovr.audio.pause",
"lovr.audio.resume",
"lovr.audio.rewind"
},
variants = {
{
arguments = {},
returns = {}
}
}
},
{
name = "update",
tag = "sources",
summary = "Updates the audio system.",
description = "Updates all playing sources. This must be called regularly for audio playback to occur. This is called automatically by the default implementation of `lovr.run`.",
key = "lovr.audio.update",
module = "lovr.audio",
variants = {
{
arguments = {},
returns = {}
}
}
}
},
enums = {
{
name = "SourceType",
summary = "Different ways to handle audio data for Source objects.",
description = "When you create a Source, you can either decode audio data gradually over time or you can decode it all at once. Streaming it over time will use less memory but cause higher processing overhead because audio is continuously being decoded. On the other hand, decoding a sound all at once means it will take more time to load and use more memory, but after it's loaded there is virtually no processing overhead. It's recommended to use the 'static' mode for short sound effects and the 'stream' mode for longer music tracks.",
key = "SourceType",
module = "lovr.audio",
values = {
{
name = "static",
description = "Decode the entire sound file up front."
},
{
name = "stream",
description = "Decode the sound gradually over time."
}
}
},
{
name = "TimeUnit",
summary = "Time units for sound samples.",
description = "When figuring out how long a Source is or seeking to a specific position in the sound file, units can be expressed in terms of seconds or in terms of samples.",
key = "TimeUnit",
module = "lovr.audio",
values = {
{
name = "seconds",
description = "Seconds."
},
{
name = "samples",
description = "Samples."
}
}
}
},
sections = {
{
name = "Sources",
tag = "sources",
description = "Sources are objects that represent a single sound instance."
},
{
name = "Listener",
tag = "listener",
description = "The listener is a virtual object in 3D space that \"hears\" all the sounds that are playing. The listener can be positioned and oriented in 3D space, which controls how Sources in the world are heard. For example, sounds further away from the listener will be more quiet, and sounds to the left of the listener will be heard from the left speaker. By default, the listener will be synchronized with any connected headset so audio is positioned properly as the headset is moved around and rotated."
},
{
name = "Microphones",
tag = "microphones",
description = "Microphones can be used to receive audio input."
}
}
},
{
name = "data",
tag = "modules",
summary = "Exposes low level functions for working with data.",
description = "The `lovr.data` module provides functions for accessing underlying data representations for several LÖVR objects.",
key = "lovr.data",
objects = {
{
name = "AudioStream",
summary = "An object that gradually decodes audio data.",
description = "An AudioStream is an object that reads and decodes compressed sound data. All Source objects are powered by AudioStreams.\n\nUsually you can just use Sources without having to deal with AudioStreams, but sometimes you may need low-level access to the audio stream.",
key = "AudioStream",
module = "lovr.data",
constructors = {
"lovr.data.newAudioStream"
},
methods = {
{
name = "decode",
summary = "Decode the next chunk of audio in the AudioStream.",
description = "Returns a new SoundData containing the next chunk of audio in the AudioStream.",
key = "AudioStream:decode",
module = "lovr.data",
notes = "This function may return nil if there isn't any audio left in the stream.",
variants = {
{
arguments = {},
returns = {
{
name = "soundData",
type = "SoundData",
description = "The SoundData object containing raw audio samples."
}
}
}
}
},
{
name = "getBitDepth",
summary = "Get the bit depth of the AudioStream.",
description = "Returns the number of bits per sample in the stream's sound data. This is a rough indicator of the \"resolution\" of the sound, and is usually 16.",
key = "AudioStream:getBitDepth",
module = "lovr.data",
related = {
"SoundData:getBitDepth",
"Source:getBitDepth"
},
variants = {
{
arguments = {},
returns = {
{
name = "bits",
type = "number",
description = "The number of bits per sample."
}
}
}
}
},
{
name = "getChannelCount",
summary = "Get the number of channels in the AudioStream.",
description = "Returns the number of channels present in the stream's sound data. Mono sounds have 1 channel and stereo sounds have 2 channels.",
key = "AudioStream:getChannelCount",
module = "lovr.data",
related = {
"SoundData:getChannelCount",
"Source:getChannelCount"
},
variants = {
{
arguments = {},
returns = {
{
name = "channels",
type = "number",
description = "The number of channels."
}
}
}
}
},
{
name = "getDuration",
summary = "Get the duration of the AudioStream.",
description = "Returns the duration of the sound data in seconds.",
key = "AudioStream:getDuration",
module = "lovr.data",
related = {
"SoundData:getDuration",
"Source:getDuration"
},
variants = {
{
arguments = {},
returns = {
{
name = "duration",
type = "number",
description = "The duration of the sound."
}
}
}
}
},
{
name = "getSampleRate",
summary = "Get the sample rate of the AudioStream.",
description = "Returns the number of samples per second in the stream's sound data. This is usually a high number like 44100.",
key = "AudioStream:getSampleRate",
module = "lovr.data",
related = {
"SoundData:getSampleRate",
"Source:getSampleRate"
},
variants = {
{
arguments = {},
returns = {
{
name = "frequency",
type = "number",
description = "The number of samples per second in the AudioStream."
}
}
}
}
}
}
},
{
name = "Blob",
summary = "A chunk of binary data.",
description = "A Blob is an object that holds binary data. It can be passed to most functions that take filename arguments, like `lovr.graphics.newModel` or `lovr.audio.newSource`. Blobs aren't usually necessary for simple projects, but they can be really helpful if:\n\n- You need to work with low level binary data, potentially using the LuaJIT FFI for increased\n performance.\n- You are working with data that isn't stored as a file, such as programmatically generated data\n or a string from a network request.\n- You want to load data from a file once and then use it to create many different objects.\n\nA Blob's size cannot be changed once it is created.",
key = "Blob",
module = "lovr.data",
constructors = {
"lovr.data.newBlob",
"lovr.filesystem.newBlob"
},
methods = {
{
name = "getName",
summary = "Get the label of the Blob.",
description = "Returns the filename the Blob was loaded from, or the custom name given to it when it was created. This label is also used in error messages.",
key = "Blob:getName",
module = "lovr.data",
variants = {
{
arguments = {},
returns = {
{
name = "name",
type = "string",
description = "The name of the Blob."
}
}
}
}
},
{
name = "getPointer",
summary = "Get a raw pointer to the Blob's data.",
description = "Returns a raw pointer to the Blob's data. This can be used to interface with other C libraries using the LuaJIT FFI. Use this only if you know what you're doing!",
key = "Blob:getPointer",
module = "lovr.data",
variants = {
{
arguments = {},
returns = {
{
name = "pointer",
type = "userdata",
description = "A pointer to the data."
}
}
}
}
},
{
name = "getSize",
summary = "Get the size of the Blob's data.",
description = "Returns the size of the Blob's contents, in bytes.",
key = "Blob:getSize",
module = "lovr.data",
variants = {
{
arguments = {},
returns = {
{
name = "bytes",
type = "number",
description = "The size of the Blob, in bytes."
}
}
}
}
},
{
name = "getString",
summary = "Get the Blob's contents as a string.",
description = "Returns a binary string containing the Blob's data.",
key = "Blob:getString",
module = "lovr.data",
variants = {
{
arguments = {},
returns = {
{
name = "data",
type = "string",
description = "The Blob's data."
}
}
}
},
examples = {
{
description = "Manually copy a file using Blobs:",
code = "blob = lovr.filesystem.newBlob('image.png')\nlovr.filesystem.write('copy.png', blob:getString())"
}
}
}
}
},
{
name = "ModelData",
summary = "An object that loads and stores data for 3D models.",
description = "A ModelData is a container object that loads and holds data contained in 3D model files. This can include a variety of things like the node structure of the asset, the vertex data it contains, contains, the `TextureData` and `Material` properties, and any included animations.\n\nThe current supported formats are OBJ and glTF.\n\nUsually you can just load a `Model` directly, but using a `ModelData` can be helpful if you want to load models in a thread or access more low-level information about the Model.",
key = "ModelData",
module = "lovr.data",
constructors = {
"lovr.data.newModelData"
},
methods = {}
},
{
name = "Rasterizer",
summary = "An object that rasterizes glyphs from font files.",
description = "A Rasterizer is an object that parses a TTF file, decoding and rendering glyphs from it.\n\nUsually you can just use `Font` objects.",
key = "Rasterizer",
module = "lovr.data",
constructors = {
"lovr.data.newRasterizer"
},
methods = {
{
name = "getAdvance",
summary = "Get the advance of the font.",
description = "Returns the advance metric of the font, in pixels. The advance is how many pixels the font advances horizontally after each glyph is rendered. This does not include kerning.",
key = "Rasterizer:getAdvance",
module = "lovr.data",
variants = {
{
arguments = {},
returns = {
{
name = "advance",
type = "number",
description = "The advance of the font, in pixels."
}
}
}
}
},
{
name = "getAscent",
summary = "Get the ascent of the font.",
description = "Returns the ascent metric of the font, in pixels. The ascent represents how far any glyph of the font ascends above the baseline.",
key = "Rasterizer:getAscent",
module = "lovr.data",
related = {
"Rasterizer:getDescent",
"Font:getAscent"
},
variants = {
{
arguments = {},
returns = {
{
name = "ascent",
type = "number",
description = "The ascent of the font, in pixels."
}
}
}
}
},
{
name = "getDescent",
summary = "Get the descent of the font.",
description = "Returns the descent metric of the font, in pixels. The descent represents how far any glyph of the font descends below the baseline.",
key = "Rasterizer:getDescent",
module = "lovr.data",
related = {
"Rasterzer:getAscent",
"Font:getDescent"
},
variants = {
{
arguments = {},
returns = {
{
name = "descent",
type = "number",
description = "The descent of the font, in pixels."
}
}
}
}
},
{
name = "getGlyphCount",
summary = "Get the number of glyphs stored in the font file.",
description = "Returns the number of glyphs stored in the font file.",
key = "Rasterizer:getGlyphCount",
module = "lovr.data",
related = {
"Rasterizer:hasGlyphs"
},
variants = {
{
arguments = {},
returns = {
{
name = "count",
type = "number",
description = "The number of glyphs stored in the font file."
}
}
}
}
},
{
name = "getHeight",
summary = "Get the height of the font.",
description = "Returns the height metric of the font, in pixels.",
key = "Rasterizer:getHeight",
module = "lovr.data",
related = {
"Font:getHeight"
},
variants = {
{
arguments = {},
returns = {
{
name = "height",
type = "number",
description = "The height of the font, in pixels."
}
}
}
}
},
{
name = "getLineHeight",
summary = "Get the line height of the font.",
description = "Returns the line height metric of the font, in pixels. This is how far apart lines are.",
key = "Rasterizer:getLineHeight",
module = "lovr.data",
related = {
"Rasterizer:getHeight",
"Font:getLineHeight",
"Font:setLineHeight"
},
variants = {
{
arguments = {},
returns = {
{
name = "height",
type = "number",
description = "The line height of the font, in pixels."
}
}
}
}
},
{
name = "hasGlyphs",
summary = "Get whether the Rasterizer can rasterize a set of glyphs.",
description = "Check if the Rasterizer can rasterize a set of glyphs.",
key = "Rasterizer:hasGlyphs",
module = "lovr.data",
related = {
"Rasterizer:getGlyphCount"
},
variants = {
{
arguments = {
{
name = "...",
type = "*",
description = "Strings (sets of characters) or numbers (character codes) to check for."
}
},
returns = {
{
name = "hasGlyphs",
type = "boolean",
description = "true if the Rasterizer can rasterize all of the supplied characters, false otherwise."
}
}
}
}
}
}
},
{
name = "SoundData",
summary = "An object that holds raw audio samples.",
description = "A SoundData stores raw audio samples that make up a sound file. You can use `Source` objects to play SoundData.",
key = "SoundData",
module = "lovr.data",
constructors = {
"lovr.data.newSoundData",
"AudioStream:decode",
"Microphone:getData"
},
methods = {
{
name = "getBitDepth",
summary = "Get the bit depth of the SoundData.",
description = "Returns the number of bits taken up by each sample in the SoundData. Higher bit depths mean the sound is higher quality and takes up more space. This is usually 8 or 16.",
key = "SoundData:getBitDepth",
module = "lovr.data",
related = {
"AudioStream:getBitDepth",
"Source:getBitDepth"
},
variants = {
{
arguments = {},
returns = {
{
name = "bitDepth",
type = "number",
description = "The size of each sample, in bits."
}
}
}
}
},
{
name = "getChannelCount",
summary = "Get the number of channels in the SoundData.",
description = "Returns the number of channels in the SoundData. Mono sounds have 1 channel and stereo sounds have 2 channels.",
key = "SoundData:getChannelCount",
module = "lovr.data",
notes = "It's important to keep in mind the channel count if you're using `SoundData:getSample` and `SoundData:setSample`. The SoundData stores its samples in an \"interleaved\" manner, meaning the samples from different channels are stored next to each other.\n\nIf you want to get the 3rd sample of the second channel of a stereo sound, you would use sample number 5, since samples start at zero and `(sample * channelCount) + channelIndex = 5`.",
variants = {
{
arguments = {},
returns = {
{
name = "channels",
type = "number",
description = "The number of channels."
}
}
}
},
related = {
"AudioStream:getChannelCount",
"Source:getChannelCount"
}
},
{
name = "getDuration",
summary = "Get the duration of the SoundData.",
description = "Returns the duration of the sound data in seconds.",
key = "SoundData:getDuration",
module = "lovr.data",
related = {
"SoundData:getSampleCount",
"AudioStream:getDuration",
"Source:getDuration"
},
variants = {
{
arguments = {},
returns = {
{
name = "duration",
type = "number",
description = "The duration of the sound."
}
}
}
}
},
{
name = "getSample",
summary = "Get a sample from the SoundData.",
description = "Returns a single sample from the SoundData. Sample indices start at 0, and the returned value will be between -1 and 1.",
key = "SoundData:getSample",
module = "lovr.data",
notes = "Note that samples for individual channels in stereo sounds are stored next to each other.",
variants = {
{
arguments = {
{
name = "index",
type = "number",
description = "The index of the sample to get."
}
},
returns = {
{
name = "value",
type = "number",
description = "A number indicating the value of the sample at the given index."
}
}
}
},
related = {
"SoundData:getSampleCount",
"SoundData:getSampleRate"
}
},
{
name = "getSampleCount",
summary = "Get the number of samples stored in the SoundData.",
description = "Returns the number of samples in the SoundData (per channel).",
key = "SoundData:getSampleCount",
module = "lovr.data",
related = {
"SoundData:getSample",
"SoundData:getChannelCount",
"Source:getDuration"
},
variants = {
{
arguments = {},
returns = {
{
name = "samples",
type = "number",
description = "The total number of channels per channel."
}
}
}
}
},
{
name = "getSampleRate",
summary = "Get the sample rate of the SoundData.",
description = "Returns the number of samples per second in the SoundData. This is usually a high number like 44100.",
key = "SoundData:getSampleRate",
module = "lovr.data",
related = {
"AudioStream:getSampleRate",
"Source:getSampleRate"
},
variants = {
{
arguments = {},
returns = {
{
name = "frequency",
type = "number",
description = "The number of samples per second in the SoundData."
}
}
}
}
},
{
name = "setSample",
summary = "Modify a sample in the SoundData.",
description = "Modify a single sample in the SoundData. Sample indices start at zero, and samples should be between -1 and 1.",
key = "SoundData:setSample",
module = "lovr.data",
notes = "Note that samples for individual channels in stereo sounds are stored next to each other.",
variants = {
{
arguments = {
{
name = "index",
type = "number",
description = "The index of the sample to set."
},
{
name = "value",
type = "number",
description = "The new value of the sample."
}
},
returns = {}
}
},
related = {
"SoundData:getSampleCount",
"SoundData:getSampleRate"
}
}
}
},
{
name = "TextureData",
summary = "An object that stores pixel data for Textures.",
description = "A TextureData stores raw 2D pixel info for `Texture`s. It has a width, height, and format. The TextureData can be initialized with the contents of an image file or it can be created with uninitialized contents. The supported image formats are `png`, `jpg`, `hdr`, `dds`, `ktx`, and `astc`.\n\nUsually you can just use Textures, but TextureData can be useful if you want to manipulate individual pixels, load Textures in a background thread, or use the FFI to efficiently access the raw image data.",
key = "TextureData",
module = "lovr.data",
constructors = {
"lovr.data.newTextureData",
"Canvas:newTextureData"
},
methods = {
{
name = "encode",
summary = "Encode the TextureData as png and write it to a file.",
description = "Encodes the TextureData to png and writes it to the specified file.",
key = "TextureData:encode",
module = "lovr.data",
variants = {
{
arguments = {
{
name = "filename",
type = "string",
description = "The file to write the png data to."
}
},
returns = {
{
name = "success",
type = "boolean",
description = "Whether or not the file was successfully written to."
}
}
}
}
},
{
name = "getDimensions",
summary = "Get the dimensions of the TextureData.",
description = "Returns the dimensions of the TextureData, in pixels.",
key = "TextureData:getDimensions",
module = "lovr.data",
related = {
"TextureData:getWidth",
"TextureData:getHeight",
"Texture:getDimensions"
},
variants = {
{
arguments = {},
returns = {
{
name = "width",
type = "number",
description = "The width of the TextureData, in pixels."
},
{
name = "height",
type = "number",
description = "The height of the TextureData, in pixels."
}
}
}
}
},
{
name = "getFormat",
summary = "Get the pixel format of the TextureData.",
description = "Returns the format of the TextureData.",
key = "TextureData:getFormat",
module = "lovr.data",
related = {
"TextureFormat",
"Texture:getFormat"
},
variants = {
{
arguments = {},
returns = {
{
name = "format",
type = "TextureFormat",
description = "The format of the TextureData."
}
}
}
}
},
{
name = "getHeight",
summary = "Get the height of the TextureData.",
description = "Returns the height of the TextureData, in pixels.",
key = "TextureData:getHeight",
module = "lovr.data",
related = {
"TextureData:getWidth",
"TextureData:getDimensions",
"Texture:getHeight"
},
variants = {
{
arguments = {},
returns = {
{
name = "height",
type = "number",
description = "The height of the TextureData, in pixels."
}
}
}
}
},
{
name = "getPixel",
summary = "Get the value of a pixel of the TextureData.",
description = "Returns the value of a pixel of the TextureData.",
key = "TextureData:getPixel",
module = "lovr.data",
notes = "The following texture formats are supported: `rgba`, `rgb`, `r32f`, `rg32f`, and `rgba32f`.",
variants = {
{
arguments = {
{
name = "x",
type = "number",
description = "The x coordinate of the pixel to get (0-indexed)."
},
{
name = "y",
type = "number",
description = "The y coordinate of the pixel to get (0-indexed)."
}
},
returns = {
{
name = "r",
type = "number",
description = "The red component of the pixel, from 0.0 to 1.0."
},
{
name = "g",
type = "number",
description = "The green component of the pixel, from 0.0 to 1.0."
},
{
name = "b",
type = "number",
description = "The blue component of the pixel, from 0.0 to 1.0."
},
{
name = "a",
type = "number",
description = "The alpha component of the pixel, from 0.0 to 1.0."
}
}
}
},
related = {
"TextureData:setPixel",
"Texture:replacePixels",
"TextureFormat"
}
},
{
name = "getWidth",
summary = "Get the width of the TextureData.",
description = "Returns the width of the TextureData, in pixels.",
key = "TextureData:getWidth",
module = "lovr.data",
related = {
"TextureData:getHeight",
"TextureData:getDimensions",
"Texture:getWidth"
},
variants = {
{
arguments = {},
returns = {
{
name = "width",
type = "number",
description = "The width of the TextureData, in pixels."
}
}
}
}
},
{
name = "paste",
summary = "Copy pixels from another TextureData to this one.",
description = "Copies a rectangle of pixels from one TextureData to this one.",
key = "TextureData:paste",
module = "lovr.data",
notes = "The two TextureData must have the same pixel format.\n\nCompressed TextureData cannot be copied.\n\nThe rectangle cannot go outside the dimensions of the source or destination textures.",
variants = {
{
arguments = {
{
name = "source",
type = "TextureData",
description = "The TextureData to copy pixels from."
},
{
name = "x",
type = "number",
description = "The x coordinate to paste to (0-indexed).",
default = "0"
},
{
name = "y",
type = "number",
description = "The y coordinate to paste to (0-indexed).",
default = "0"
},
{
name = "fromX",
type = "number",
description = "The x coordinate in the source to paste from (0-indexed).",
default = "0"
},
{
name = "fromY",
type = "number",
description = "The y coordinate in the source to paste from (0-indexed).",
default = "0"
},
{
name = "width",
type = "number",
description = "The width of the region to copy.",
default = "source:getWidth()"
},
{
name = "height",
type = "number",
description = "The height of the region to copy.",
default = "source:getHeight()"
}
},
returns = {}
}
},
related = {
"Texture:replacePixels",
"TextureData:getPixel",
"TextureData:setPixel"
}
},
{
name = "setPixel",
summary = "Set the value of a pixel of the TextureData.",
description = "Sets the value of a pixel of the TextureData.",
key = "TextureData:setPixel",
module = "lovr.data",
notes = "The following texture formats are supported: `rgba`, `rgb`, `r32f`, `rg32f`, and `rgba32f`.",
variants = {
{
arguments = {
{
name = "x",
type = "number",
description = "The x coordinate of the pixel to set (0-indexed)."
},
{
name = "y",
type = "number",
description = "The y coordinate of the pixel to set (0-indexed)."
},
{
name = "r",
type = "number",
description = "The red component of the pixel, from 0.0 to 1.0."
},
{
name = "g",
type = "number",
description = "The green component of the pixel, from 0.0 to 1.0."
},
{
name = "b",
type = "number",
description = "The blue component of the pixel, from 0.0 to 1.0."
},
{
name = "a",
type = "number",
description = "The alpha component of the pixel, from 0.0 to 1.0.",
default = "1.0"
}
},
returns = {}
}
},
related = {
"TextureData:getPixel",
"Texture:replacePixels",
"TextureFormat"
}
}
}
}
},
functions = {
{
name = "newAudioStream",
summary = "Create a new AudioStream.",
description = "Creates a new AudioStream. Right now, the only supported audio format is Ogg Vorbis (.ogg).",
key = "lovr.data.newAudioStream",
module = "lovr.data",
variants = {
{
arguments = {
{
name = "filename",
type = "string",
description = "The filename of the audio file to load."
},
{
name = "bufferSize",
type = "number",
description = "The size of the stream's audio buffer, in samples.",
default = "4096"
}
},
returns = {
{
name = "audioStream",
type = "AudioStream",
description = "The new AudioStream."
}
}
},
{
arguments = {
{
name = "blob",
type = "Blob",
description = "The Blob containing audio data to decode."
},
{
name = "bufferSize",
type = "number",
description = "The size of the stream's audio buffer, in samples.",
default = "4096"
}
},
returns = {
{
name = "audioStream",
type = "AudioStream",
description = "The new AudioStream."
}
}
}
}
},
{
name = "newBlob",
summary = "Create a new Blob.",
description = "Creates a new Blob.",
key = "lovr.data.newBlob",
module = "lovr.data",
related = {
"lovr.filesystem.newBlob"
},
variants = {
{
arguments = {
{
name = "size",
type = "number",
description = "The amount of data to allocate for the Blob, in bytes. All of the bytes will be filled with zeroes."
},
{
name = "name",
type = "string",
description = "A name for the Blob (used in error messages)",
default = "''"
}
},
returns = {
{
name = "blob",
type = "Blob",
description = "The new Blob."
}
}
},
{
arguments = {
{
name = "contents",
type = "string",
description = "A string to use for the Blob's contents."
},
{
name = "name",
type = "string",
description = "A name for the Blob (used in error messages)",
default = "''"
}
},
returns = {
{
name = "blob",
type = "Blob",
description = "The new Blob."
}
}
},
{
arguments = {
{
name = "source",
type = "Blob",
description = "A Blob to copy the contents from."
},
{
name = "name",
type = "string",
description = "A name for the Blob (used in error messages)",
default = "''"
}
},
returns = {
{
name = "blob",
type = "Blob",
description = "The new Blob."
}
}
}
}
},
{
name = "newModelData",
summary = "Create a new ModelData.",
description = "Loads a 3D model from a file. The supported 3D file formats are OBJ and glTF.",
key = "lovr.data.newModelData",
module = "lovr.data",
variants = {
{
arguments = {
{
name = "filename",
type = "string",
description = "The filename of the model to load."
}
},
returns = {
{
name = "modelData",
type = "ModelData",
description = "The new ModelData."
}
}
},
{
arguments = {
{
name = "blob",
type = "Blob",
description = "The Blob containing data for a model to decode."
}
},
returns = {
{
name = "modelData",
type = "ModelData",
description = "The new ModelData."
}
}
}
}
},
{
name = "newRasterizer",
summary = "Create a new Rasterizer.",
description = "Creates a new Rasterizer from a TTF file.",
key = "lovr.data.newRasterizer",
module = "lovr.data",
variants = {
{
description = "Create a Rasterizer for the default font included with LÖVR (Varela Round).",
arguments = {
{
name = "size",
type = "number",
description = "The resolution to render the fonts at, in pixels. Higher resolutions use more memory and processing power but may provide better quality results for some fonts/situations.",
default = "32"
}
},
returns = {
{
name = "rasterizer",
type = "Rasterizer",
description = "The new Rasterizer."
}
}
},
{
arguments = {
{
name = "filename",
type = "string",
description = "The filename of the font file to load."
},
{
name = "size",
type = "number",
description = "The resolution to render the fonts at, in pixels. Higher resolutions use more memory and processing power but may provide better quality results for some fonts/situations.",
default = "32"
}
},
returns = {
{
name = "rasterizer",
type = "Rasterizer",
description = "The new Rasterizer."
}
}
},
{
arguments = {
{
name = "blob",
type = "Blob",
description = "The Blob containing font data."
},
{
name = "size",
type = "number",
description = "The resolution to render the fonts at, in pixels. Higher resolutions use more memory and processing power but may provide better quality results for some fonts/situations.",
default = "32"
}
},
returns = {
{
name = "rasterizer",
type = "Rasterizer",
description = "The new Rasterizer."
}
}
}
}
},
{
name = "newSoundData",
summary = "Create a new SoundData.",
description = "Creates a new SoundData. You can pass a filename or Blob to decode, an existing AudioStream to decode audio samples from, or you can create an empty SoundData that can hold a certain number of samples.",
key = "lovr.data.newSoundData",
module = "lovr.data",
variants = {
{
arguments = {
{
name = "filename",
type = "string",
description = "The filename of the sound to decode."
}
},
returns = {
{
name = "soundData",
type = "SoundData",
description = "The new SoundData."
}
}
},
{
arguments = {
{
name = "samples",
type = "number",
description = "The total number of samples for each channel."
},
{
name = "sampleRate",
type = "number",
description = "The number of samples per second.",
default = "44100"
},
{
name = "bitDepth",
type = "number",
description = "The number of bits stored for each sample.",
default = "16"
},
{
name = "channels",
type = "number",
description = "The number of channels in the sound (1 for mono, 2 for stereo).",
default = "2"
}
},
returns = {
{
name = "soundData",
type = "SoundData",
description = "The new SoundData."
}
}
},
{
arguments = {},
returns = {
{
name = "soundData",
type = "SoundData",
description = "The new SoundData."
}
}
},
{
arguments = {
{
name = "blob",
type = "string",
description = "The Blob containing compressed sound data to decode."
}
},
returns = {
{
name = "soundData",
type = "SoundData",
description = "The new SoundData."
}
}
}
}
},
{
name = "newTextureData",
summary = "Create a new TextureData.",
description = "Creates a new TextureData. Image data can be loaded and decoded from an image file, or a raw block of pixels with a specified width, height, and format can be created.",
key = "lovr.data.newTextureData",
module = "lovr.data",
notes = "Right now the supported image file formats are png, jpg, hdr, dds (DXT1, DXT3, DXT5), ktx, and astc.",
variants = {
{
description = "Load image data from a file.",
arguments = {
{
name = "filename",
type = "string",
description = "The filename of the image to load."
},
{
name = "flip",
type = "boolean",
description = "Whether to vertically flip the image on load. This should be true for normal textures, and false for textures that are going to be used in a cubemap.",
default = "true"
}
},
returns = {
{
name = "textureData",
type = "TextureData",
description = "The new TextureData."
}
}
},
{
description = "Create an empty TextureData, initializing all pixel values to 0 (transparent black).",
arguments = {
{
name = "width",
type = "number",
description = "The width of the texture."
},
{
name = "height",
type = "number",
description = "The height of the texture."
},
{
name = "format",
type = "TextureFormat",
description = "The format of the texture's pixels.",
default = "rgba"
}
},
returns = {
{
name = "textureData",
type = "TextureData",
description = "The new TextureData."
}
}
},
{
description = "Decode image data from a Blob.",
arguments = {
{
name = "blob",
type = "Blob",
description = "The Blob containing image data to decode."
},
{
name = "flip",
type = "boolean",
description = "Whether to vertically flip the image on load. This should be true for normal textures, and false for textures that are going to be used in a cubemap.",
default = "true"
}
},
returns = {
{
name = "textureData",
type = "TextureData",
description = "The new TextureData."
}
}
}
}
}
},
enums = {}
},
{
name = "event",
tag = "modules",
summary = "Handles events from the operating system.",
description = "The `lovr.event` module handles events from the operating system.\n\nDue to its low-level nature, it's rare to use `lovr.event` in simple projects.",
key = "lovr.event",
enums = {},
examples = {
{
description = "Adding a custom event.",
code = "function lovr.load()\n lovr.handlers['customevent'] = function(a, b, c)\n print('custom event handled with args:', a, b, c)\n end\n\n lovr.event.push('customevent', 1, 2, 3)\nend"
}
},
functions = {
{
name = "clear",
summary = "Clear the event queue.",
description = "Clears the event queue, removing any unprocessed events.",
key = "lovr.event.clear",
module = "lovr.event",
variants = {
{
arguments = {},
returns = {}
}
}
},
{
name = "poll",
summary = "Iterate over unprocessed events in the queue.",
description = "This function returns a Lua iterator for all of the unprocessed items in the event queue. Each event consists of a name as a string, followed by event-specific arguments. This function is called in the default implementation of `lovr.run`, so it is normally not necessary to poll for events yourself.",
key = "lovr.event.poll",
module = "lovr.event",
variants = {
{
arguments = {},
returns = {
{
name = "iterator",
type = "function",
description = "The iterator function, usable in a for loop.",
arguments = {},
returns = {}
}
}
}
}
},
{
name = "pump",
summary = "Pump new events into the queue for processing.",
description = "Fills the event queue with unprocessed events from the operating system. This function should be called often, otherwise the operating system will consider the application unresponsive. This function is called in the default implementation of `lovr.run`.",
key = "lovr.event.pump",
module = "lovr.event",
related = {
"lovr.event.poll"
},
variants = {
{
arguments = {},
returns = {}
}
}
},
{
name = "push",
summary = "Manually push an event onto the queue.",
description = "Pushes an event onto the event queue. It will be processed the next time `lovr.event.poll` is called. For an event to be processed properly, there needs to be a function in the `lovr.handlers` table with a key that's the same as the event name.",
key = "lovr.event.push",
module = "lovr.event",
notes = "Only nil, booleans, numbers, strings, and LÖVR objects are supported types for event data.",
variants = {
{
arguments = {
{
name = "name",
type = "string",
description = "The name of the event."
},
{
name = "...",
type = "*",
description = "The arguments for the event. Currently, up to 4 are supported."
}
},
returns = {}
}
},
related = {
"lovr.event.poll",
"lovr.event.quit"
}
},
{
name = "quit",
summary = "Quit the application.",
description = "Pushes an event to quit or restart the application. An optional number can be passed to set the exit code for the application. An exit code of zero indicates normal termination, whereas a nonzero exit code indicates that an error occurred. Alternatively, the string 'restart' can be used to cause LÖVR to reload the project.",
key = "lovr.event.quit",
module = "lovr.event",
notes = "This function is equivalent to calling `lovr.event.push('quit', )`.\n\nThe program won't actually exit until the next time `lovr.event.poll` is called.\n\nThe `lovr.quit` callback will be called when the event is processed, which can be used to do any cleanup work. The callback can also return `false` to stop the quitting process.",
variants = {
{
arguments = {
{
name = "code",
type = "number",
description = "The exit code of the program.",
default = "0"
}
},
returns = {}
},
{
arguments = {
{
name = "'restart'",
type = "string",
description = "Restart instead of quitting."
}
},
returns = {}
}
},
related = {
"lovr.quit",
"lovr.event.poll"
}
}
},
objects = {},
notes = "You can define your own custom events by adding a function to the `lovr.handlers` table with a key of the name of the event you want to add. Then, push the event using `lovr.event.push`."
},
{
name = "filesystem",
tag = "modules",
summary = "Provides access to the filesystem.",
description = "The `lovr.filesystem` module provides access to the filesystem.",
key = "lovr.filesystem",
enums = {},
objects = {},
functions = {
{
name = "append",
summary = "Append content to the end of a file.",
description = "Appends content to the end of a file.",
key = "lovr.filesystem.append",
module = "lovr.filesystem",
notes = "If the file does not exist, it is created.",
variants = {
{
arguments = {
{
name = "filename",
type = "string",
description = "The file to append to."
},
{
name = "content",
type = "string",
description = "A string to write to the end of the file."
}
},
returns = {
{
name = "bytes",
type = "number",
description = "The number of bytes actually written to the file."
}
}
}
}
},
{
name = "createDirectory",
summary = "Create a directory.",
description = "Creates a directory in the save directory. Any parent directories that don't exist will also be created.",
key = "lovr.filesystem.createDirectory",
module = "lovr.filesystem",
variants = {
{
arguments = {
{
name = "path",
type = "string",
description = "The directory to create, recursively."
}
},
returns = {
{
name = "success",
type = "boolean",
description = "Whether the directory was created."
}
}
}
}
},
{
name = "getAppdataDirectory",
summary = "Get the application data directory.",
description = "Returns the application data directory. This will be something like:\n\n- `C:\\Users\\user\\AppData\\Roaming` on Windows.\n- `/home/user/.config` on Linux.\n- `/Users/user/Library/Application Support` on macOS.",
key = "lovr.filesystem.getAppdataDirectory",
module = "lovr.filesystem",
variants = {
{
arguments = {},
returns = {
{
name = "path",
type = "string",
description = "The absolute path to the appdata directory."
}
}
}
}
},
{
name = "getApplicationId",
summary = "Get the application ID.",
description = "Returns the platform-specific application ID, or `nil` if the current platform doesn't have one.\n\nCurrently only implemented on Android, where it returns the package name, e.g. `org.lovr.app`.",
key = "lovr.filesystem.getApplicationId",
module = "lovr.filesystem",
variants = {
{
arguments = {},
returns = {
{
name = "id",
type = "string",
description = "The application ID."
}
}
}
}
},
{
name = "getDirectoryItems",
summary = "Get a list of files in a directory.",
description = "Returns an unsorted table containing all files and folders in a single directory.",
key = "lovr.filesystem.getDirectoryItems",
module = "lovr.filesystem",
variants = {
{
arguments = {
{
name = "path",
type = "string",
description = "The directory."
}
},
returns = {
{
name = "table",
type = "items",
description = "A table with a string for each file and subfolder in the directory."
}
}
}
}
},
{
name = "getExecutablePath",
summary = "Get the path of the LÖVR executable.",
description = "Returns the absolute path of the LÖVR executable.",
key = "lovr.filesystem.getExecutablePath",
module = "lovr.filesystem",
variants = {
{
arguments = {},
returns = {
{
name = "path",
type = "string",
description = "The absolute path of the LÖVR executable, or `nil` if it is unknown."
}
}
}
}
},
{
name = "getIdentity",
summary = "Get the name of the save directory.",
description = "Returns the identity of the game, which is used as the name of the save directory. The default is `default`.",
key = "lovr.filesystem.getIdentity",
module = "lovr.filesystem",
variants = {
{
arguments = {},
returns = {
{
name = "identity",
type = "string",
description = "The name of the save directory, or `nil` if it isn't set."
}
}
}
}
},
{
name = "getLastModified",
summary = "Get the modification time of a file.",
description = "Returns when a file was last modified, since some arbitrary time in the past.",
key = "lovr.filesystem.getLastModified",
module = "lovr.filesystem",
variants = {
{
arguments = {
{
name = "path",
type = "string",
description = "The file to check."
}
},
returns = {
{
name = "time",
type = "number",
description = "The modification time of the file, in seconds, or `nil` if it's unknown."
}
}
}
}
},
{
name = "getRealDirectory",
summary = "Get the absolute path to a file.",
description = "Get the absolute path of the mounted archive containing a path in the virtual filesystem. This can be used to determine if a file is in the game's source directory or the save directory.",
key = "lovr.filesystem.getRealDirectory",
module = "lovr.filesystem",
variants = {
{
arguments = {
{
name = "path",
type = "string",
description = "The path to check."
}
},
returns = {
{
name = "realpath",
type = "string",
description = "The absolute path of the mounted archive containing `path`."
}
}
}
}
},
{
name = "getRequirePath",
summary = "Get the require path.",
description = "Returns the require path. The require path is a semicolon-separated list of patterns that LÖVR will use to search for files when they are `require`d. Any question marks in the pattern will be replaced with the module that is being required. It is similar to Lua\\'s `package.path` variable, but the main difference is that the patterns are relative to the virtual filesystem.\n\nFor the C require path, double question marks will be replaced by the name of the module with the operating system's native extension for shared libraries. For example, if you do `require('lib')` and the C require path is `??`, LÖVR will try to load `lib.dll` if you're on Windows or `lib.so` if you're on Linux.",
key = "lovr.filesystem.getRequirePath",
module = "lovr.filesystem",
notes = "The default reqiure path is '?.lua;?/init.lua;lua_modules/?.lua;lua_modules/?/init.lua'. The default C require path is '??'.",
variants = {
{
arguments = {},
returns = {
{
name = "path",
type = "string",
description = "The semicolon separated list of search patterns."
},
{
name = "cpath",
type = "string",
description = "The semicolon separated list of search patterns for C libraries."
}
}
}
}
},
{
name = "getSaveDirectory",
summary = "Get the location of the save directory.",
description = "Returns the absolute path to the save directory.",
key = "lovr.filesystem.getSaveDirectory",
module = "lovr.filesystem",
notes = "The save directory takes the following form:\n\n /LOVR/\n\nWhere `` is `lovr.filesystem.getAppdataDirectory` and `` is `lovr.filesystem.getIdentity` and can be customized using `lovr.conf`.",
variants = {
{
arguments = {},
returns = {
{
name = "path",
type = "string",
description = "The absolute path to the save directory."
}
}
}
},
related = {
"lovr.filesystem.getIdentity",
"lovr.filesystem.getAppdataDirectory"
}
},
{
name = "getSize",
summary = "Get the size of a file.",
description = "Returns the size of a file, in bytes.",
key = "lovr.filesystem.getSize",
module = "lovr.filesystem",
notes = "If the file does not exist, an error is thrown.",
variants = {
{
arguments = {
{
name = "file",
type = "string",
description = "The file."
}
},
returns = {
{
name = "size",
type = "number",
description = "The size of the file, in bytes."
}
}
}
}
},
{
name = "getSource",
summary = "Get the location of the project source.",
description = "Get the absolute path of the project's source directory or archive.",
key = "lovr.filesystem.getSource",
module = "lovr.filesystem",
variants = {
{
arguments = {},
returns = {
{
name = "path",
type = "string",
description = "The absolute path of the project's source, or `nil` if it's unknown."
}
}
}
}
},
{
name = "getUserDirectory",
summary = "Get the location of the user's home directory.",
description = "Returns the absolute path of the user's home directory.",
key = "lovr.filesystem.getUserDirectory",
module = "lovr.filesystem",
variants = {
{
arguments = {},
returns = {
{
name = "path",
type = "string",
description = "The absolute path of the user's home directory."
}
}
}
}
},
{
name = "getWorkingDirectory",
summary = "Get the current working directory.",
description = "Returns the absolute path of the working directory. Usually this is where the executable was started from.",
key = "lovr.filesystem.getWorkingDirectory",
module = "lovr.filesystem",
variants = {
{
arguments = {},
returns = {
{
name = "path",
type = "string",
description = "The current working directory, or `nil` if it's unknown."
}
}
}
}
},
{
name = "isDirectory",
summary = "Check whether a path is a directory.",
description = "Check if a path exists and is a directory.",
key = "lovr.filesystem.isDirectory",
module = "lovr.filesystem",
related = {
"lovr.filesystem.isFile"
},
variants = {
{
arguments = {
{
name = "path",
type = "string",
description = "The path to check."
}
},
returns = {
{
name = "isDirectory",
type = "boolean",
description = "Whether or not the path is a directory."
}
}
}
}
},
{
name = "isFile",
summary = "Check whether a path is a file.",
description = "Check if a path exists and is a file.",
key = "lovr.filesystem.isFile",
module = "lovr.filesystem",
related = {
"lovr.filesystem.isDirectory"
},
variants = {
{
arguments = {
{
name = "path",
type = "string",
description = "The path to check."
}
},
returns = {
{
name = "isFile",
type = "boolean",
description = "Whether or not the path is a file."
}
}
}
}
},
{
name = "isFused",
summary = "Check if the project is fused.",
description = "Returns whether the current project source is fused to the executable.",
key = "lovr.filesystem.isFused",
module = "lovr.filesystem",
variants = {
{
arguments = {},
returns = {
{
name = "fused",
type = "boolean",
description = "Whether or not the project is fused."
}
}
}
}
},
{
name = "load",
summary = "Load a file as Lua code.",
description = "Load a file containing Lua code, returning a Lua chunk that can be run.",
key = "lovr.filesystem.load",
module = "lovr.filesystem",
variants = {
{
arguments = {
{
name = "filename",
type = "string",
description = "The file to load."
}
},
returns = {
{
name = "chunk",
type = "function",
description = "The runnable chunk.",
arguments = {
{
name = "...",
type = "*"
}
},
returns = {
{
name = "...",
type = "*"
}
}
}
}
}
},
notes = "An error is thrown if the file contains syntax errors.",
examples = {
{
description = "Safely loading code:",
code = "local success, chunk = pcall(lovr.filesystem.load, filename)\nif not success then\n print('Oh no! There was an error: ' .. tostring(chunk))\nelse\n local success, result = pcall(chunk)\n print(success, result)\nend"
}
}
},
{
name = "mount",
summary = "Mount a directory or archive.",
description = "Mounts a directory or `.zip` archive, adding it to the virtual filesystem. This allows you to read files from it.",
key = "lovr.filesystem.mount",
module = "lovr.filesystem",
variants = {
{
arguments = {
{
name = "path",
type = "string",
description = "The path to mount."
},
{
name = "mountpoint",
type = "string",
description = "The path in the virtual filesystem to mount to.",
default = "'/'"
},
{
name = "append",
type = "boolean",
description = "Whether the archive will be added to the end or the beginning of the search path.",
default = "false"
},
{
name = "root",
type = "string",
description = "A subdirectory inside the archive to use as the root. If `nil`, the actual root of the archive is used.",
default = "nil"
}
},
returns = {
{
name = "success",
type = "boolean",
description = "Whether the archive was successfully mounted."
}
}
}
},
notes = "The `append` option lets you control the priority of the archive's files in the event of naming collisions.",
related = {
"lovr.filesystem.unmount"
},
examples = {
{
description = "Mount `data.zip` with a file `images/background.png`:",
code = "lovr.filesystem.mount('data.zip', 'assets')\nprint(lovr.filesystem.isFile('assets/images/background.png')) -- true"
}
}
},
{
name = "newBlob",
summary = "Create a new Blob from a file.",
description = "Creates a new Blob that contains the contents of a file.",
key = "lovr.filesystem.newBlob",
module = "lovr.filesystem",
related = {
"lovr.data.newBlob",
"Blob"
},
variants = {
{
arguments = {
{
name = "filename",
type = "string",
description = "The file to load."
}
},
returns = {
{
name = "blob",
type = "Blob",
description = "The new Blob."
}
}
}
}
},
{
name = "read",
summary = "Read a file.",
description = "Read the contents of a file.",
key = "lovr.filesystem.read",
module = "lovr.filesystem",
notes = "If the file does not exist or cannot be read, nil is returned.",
variants = {
{
arguments = {
{
name = "filename",
type = "string",
description = "The name of the file to read."
},
{
name = "bytes",
type = "number",
description = "The number of bytes to read (if -1, all bytes will be read).",
default = "-1"
}
},
returns = {
{
name = "contents",
type = "string",
description = "The contents of the file."
},
{
name = "bytes",
type = "number",
description = "The number of bytes read from the file."
}
}
}
}
},
{
name = "remove",
summary = "Remove a file or directory.",
description = "Remove a file or directory in the save directory.",
key = "lovr.filesystem.remove",
module = "lovr.filesystem",
notes = "A directory can only be removed if it is empty.",
variants = {
{
arguments = {
{
name = "path",
type = "string",
description = "The file or directory to remove."
}
},
returns = {
{
name = "success",
type = "boolean",
description = "Whether the path was removed."
}
}
}
}
},
{
name = "setIdentity",
summary = "Set the name of the save directory.",
description = "Set the name of the save directory.",
key = "lovr.filesystem.setIdentity",
module = "lovr.filesystem",
variants = {
{
arguments = {
{
name = "identity",
type = "string",
description = "The new name of the save directory."
}
},
returns = {}
}
}
},
{
name = "setRequirePath",
summary = "Set the require path.",
description = "Sets the require path. The require path is a semicolon-separated list of patterns that LÖVR will use to search for files when they are `require`d. Any question marks in the pattern will be replaced with the module that is being required. It is similar to Lua\\'s `package.path` variable, but the main difference is that the patterns are relative to the save directory and the project directory.\n\nFor the C require path, double question marks will be replaced by the name of the module with the operating system's native extension for shared libraries. For example, if you do `require('lib')` and the C require path is `??`, LÖVR will try to load `lib.dll` if you're on Windows or `lib.so` if you're on Linux.",
key = "lovr.filesystem.setRequirePath",
module = "lovr.filesystem",
notes = "The default reqiure path is '?.lua;?/init.lua;lua_modules/?.lua;lua_modules/?/init.lua'. The default C require path is '??'.",
variants = {
{
arguments = {
{
name = "path",
type = "string",
description = "An optional semicolon separated list of search patterns.",
default = "nil"
},
{
name = "cpath",
type = "string",
description = "An optional semicolon separated list of search patterns for C libraries.",
default = "nil"
}
},
returns = {}
}
}
},
{
name = "setSource",
summary = "Set the project source.",
description = "Sets the location of the project's source. This can only be done once, and is usually done internally.",
key = "lovr.filesystem.setSource",
module = "lovr.filesystem",
variants = {
{
arguments = {
{
name = "identity",
type = "string",
description = "The path containing the project's source."
}
},
returns = {}
}
}
},
{
name = "unmount",
summary = "Unmount a mounted archive.",
description = "Unmounts a directory or archive previously mounted with `lovr.filesystem.mount`.",
key = "lovr.filesystem.unmount",
module = "lovr.filesystem",
related = {
"lovr.filesystem.mount"
},
variants = {
{
arguments = {
{
name = "path",
type = "string",
description = "The path to unmount."
}
},
returns = {
{
name = "success",
type = "boolean",
description = "Whether the archive was unmounted."
}
}
}
}
},
{
name = "write",
summary = "Write to a file.",
description = "Write to a file.",
key = "lovr.filesystem.write",
module = "lovr.filesystem",
notes = "If the file does not exist, it is created.\n\nIf the file already has data in it, it will be replaced with the new content.",
variants = {
{
arguments = {
{
name = "filename",
type = "string",
description = "The file to write to."
},
{
name = "content",
type = "string",
description = "A string to write to the file."
}
},
returns = {
{
name = "bytes",
type = "number",
description = "The number of bytes written."
}
}
}
},
related = {
"lovr.filesystem.append",
"lovr.filesystem.read"
}
}
},
notes = "LÖVR programs can only write to a single directory, called the save directory. The location of the save directory is platform-specific:\n\n
\n\n`` should be a unique identifier for your app. It can be set either in `lovr.conf` or by using `lovr.filesystem.setIdentity`.\n\nAll filenames are relative to either the save directory or the directory containing the project source. Files in the save directory take precedence over files in the project."
},
{
name = "graphics",
tag = "modules",
summary = "Renders graphics.",
description = "The `lovr.graphics` module renders graphics to displays. Anything rendered using this module will automatically show up in the VR headset if one is connected, otherwise it will just show up in a window on the desktop.",
key = "lovr.graphics",
objects = {
{
name = "Canvas",
summary = "An offscreen render target.",
description = "A Canvas is also known as a framebuffer or render-to-texture. It allows you to render to a texture instead of directly to the screen. This lets you postprocess or transform the results later before finally rendering them to the screen.\n\nAfter creating a Canvas, you can attach Textures to it using `Canvas:setTexture`.",
key = "Canvas",
module = "lovr.graphics",
constructors = {
"lovr.graphics.newCanvas"
},
examples = {
{
description = "Apply a postprocessing effect (wave) using a Canvas and a fragment shader.",
code = "function lovr.load()\n lovr.graphics.setBackgroundColor(.1, .1, .1)\n canvas = lovr.graphics.newCanvas(lovr.headset.getDisplayDimensions())\n\n wave = lovr.graphics.newShader([[\n vec4 position(mat4 projection, mat4 transform, vec4 vertex) {\n return vertex;\n }\n ]], [[\n uniform float time;\n vec4 color(vec4 graphicsColor, sampler2D image, vec2 uv) {\n uv.x += sin(uv.y * 10 + time * 4) * .01;\n uv.y += cos(uv.x * 10 + time * 4) * .01;\n return graphicsColor * lovrDiffuseColor * vertexColor * texture(image, uv);\n }\n ]])\nend\n\nfunction lovr.update(dt)\n wave:send('time', lovr.timer.getTime())\nend\n\nfunction lovr.draw()\n -- Render the scene to the canvas instead of the headset.\n canvas:renderTo(function()\n lovr.graphics.clear()\n local size = 5\n for i = 1, size do\n for j = 1, size do\n for k = 1, size do\n lovr.graphics.setColor(i / size, j / size, k / size)\n local x, y, z = i - size / 2, j - size / 2, k - size / 2\n lovr.graphics.cube('fill', x, y, z, .5)\n end\n end\n end\n end)\n\n -- Render the canvas to the headset using a shader.\n lovr.graphics.setColor(1, 1, 1)\n lovr.graphics.setShader(wave)\n lovr.graphics.fill(canvas:getTexture())\n lovr.graphics.setShader()\nend"
}
},
notes = "Up to four textures can be attached to a Canvas and anything rendered to the Canvas will be broadcast to all attached Textures. If you want to do render different things to different textures, use the `multicanvas` shader flag when creating your shader and implement the `void colors` function instead of the usual `vec4 color` function. You can then assign different output colors to `lovrCanvas[0]`, `lovrCanvas[1]`, etc. instead of returning a single color. Each color written to the array will end up in the corresponding texture attached to the Canvas.",
methods = {
{
name = "getDepthTexture",
summary = "Get the depth buffer used by the Canvas.",
description = "Returns the depth buffer used by the Canvas as a Texture. If the Canvas was not created with a readable depth buffer (the `depth.readable` flag in `lovr.graphics.newCanvas`), then this function will return `nil`.",
key = "Canvas:getDepthTexture",
module = "lovr.graphics",
related = {
"lovr.graphics.newCanvas"
},
variants = {
{
arguments = {},
returns = {
{
name = "texture",
type = "Texture",
description = "The depth Texture of the Canvas."
}
}
}
}
},
{
name = "getDimensions",
summary = "Get the dimensions of the Canvas.",
description = "Returns the dimensions of the Canvas, its Textures, and its depth buffer.",
key = "Canvas:getDimensions",
module = "lovr.graphics",
notes = "The dimensions of a Canvas can not be changed after it is created.",
variants = {
{
arguments = {},
returns = {
{
name = "width",
type = "number",
description = "The width of the Canvas, in pixels."
},
{
name = "height",
type = "number",
description = "The height of the Canvas, in pixels."
}
}
}
},
related = {
"Canvas:getWidth",
"Canvas:getHeight"
}
},
{
name = "getHeight",
summary = "Get the height of the Canvas.",
description = "Returns the height of the Canvas, its Textures, and its depth buffer.",
key = "Canvas:getHeight",
module = "lovr.graphics",
notes = "The height of a Canvas can not be changed after it is created.",
variants = {
{
arguments = {},
returns = {
{
name = "height",
type = "number",
description = "The height of the Canvas, in pixels."
}
}
}
},
related = {
"Canvas:getWidth",
"Canvas:getDimensions"
}
},
{
name = "getMSAA",
summary = "Get the number of MSAA samples used by the Canvas.",
description = "Returns the number of multisample antialiasing samples to use when rendering to the Canvas. Increasing this number will make the contents of the Canvas appear more smooth at the cost of performance. It is common to use powers of 2 for this value.",
key = "Canvas:getMSAA",
module = "lovr.graphics",
notes = "All textures attached to the Canvas must be created with this MSAA value.",
variants = {
{
arguments = {},
returns = {
{
name = "samples",
type = "number",
description = "The number of MSAA samples."
}
}
}
},
related = {
"lovr.graphics.newCanvas",
"lovr.graphics.newTexture"
}
},
{
name = "getTexture",
summary = "Get the Textures attached to the Canvas.",
description = "Returns the set of Textures currently attached to the Canvas.",
key = "Canvas:getTexture",
module = "lovr.graphics",
notes = "Up to 4 Textures can be attached at once.",
variants = {
{
arguments = {},
returns = {
{
name = "...",
type = "Texture",
description = "One or more Textures attached to the Canvas."
}
}
}
}
},
{
name = "getWidth",
summary = "Get the width of the Canvas.",
description = "Returns the width of the Canvas, its Textures, and its depth buffer.",
key = "Canvas:getWidth",
module = "lovr.graphics",
notes = "The width of a Canvas can not be changed after it is created.",
variants = {
{
arguments = {},
returns = {
{
name = "width",
type = "number",
description = "The width of the Canvas, in pixels."
}
}
}
},
related = {
"Canvas:getHeight",
"Canvas:getDimensions"
}
},
{
name = "isStereo",
summary = "Check if the Canvas is stereo.",
description = "Returns whether the Canvas was created with the `stereo` flag. Drawing something to a stereo Canvas will draw it to two viewports in the left and right half of the Canvas, using transform information from two different eyes.",
key = "Canvas:isStereo",
module = "lovr.graphics",
related = {
"lovr.graphics.newCanvas",
"lovr.graphics.fill"
},
variants = {
{
arguments = {},
returns = {
{
name = "stereo",
type = "boolean",
description = "Whether the Canvas is stereo."
}
}
}
}
},
{
name = "newTextureData",
summary = "Create a new TextureData from a Canvas texture.",
description = "Returns a new TextureData containing the contents of a Texture attached to the Canvas.",
key = "Canvas:newTextureData",
module = "lovr.graphics",
related = {
"lovr.data.newTextureData",
"TextureData"
},
variants = {
{
arguments = {
{
name = "index",
type = "number",
description = "The index of the Texture to read from.",
default = "1"
}
},
returns = {
{
name = "textureData",
type = "TextureData",
description = "The new TextureData."
}
}
}
}
},
{
name = "renderTo",
summary = "Render to the Canvas using a function.",
description = "Renders to the Canvas using a function. All graphics functions inside the callback will affect the Canvas contents instead of directly rendering to the headset. This can be used in `lovr.update`.",
key = "Canvas:renderTo",
module = "lovr.graphics",
notes = "Make sure you clear the contents of the canvas before rendering by using `lovr.graphics.clear`. Otherwise there might be data in the canvas left over from a previous frame.\n\nAlso note that the transform stack is not modified by this function. If you plan on modifying the transform stack inside your callback it may be a good idea to use `lovr.graphics.push` and `lovr.graphics.pop` so you can revert to the previous transform afterwards.",
variants = {
{
arguments = {
{
name = "callback",
type = "function",
description = "The function to use to render to the Canvas.",
arguments = {
{
name = "...",
type = "*"
}
},
returns = {}
},
{
name = "...",
type = "*",
description = "Additional arguments to pass to the callback."
}
},
returns = {}
}
}
},
{
name = "setTexture",
summary = "Attach one or more Textures to the Canvas.",
description = "Attaches one or more Textures to the Canvas. When rendering to the Canvas, everything will be drawn to all attached Textures. You can attach different layers of an array, cubemap, or volume texture, and also attach different mipmap levels of Textures.",
key = "Canvas:setTexture",
module = "lovr.graphics",
variants = {
{
arguments = {
{
name = "...",
type = "*",
description = "One or more Textures to attach to the Canvas."
}
},
returns = {}
}
},
notes = "There are some restrictions on how textures can be attached:\n\n- Up to 4 textures can be attached at once.\n- Textures must have the same dimensions and multisample settings as the Canvas.\n\nTo specify layers and mipmaps to attach, specify them after the Texture. You can also optionally wrap them in a table.",
examples = {
{
description = "Various ways to attach textures to a Canvas.",
code = "canvas:setTexture(textureA)\ncanvas:setTexture(textureA, textureB) -- Attach two textures\ncanvas:setTexture(textureA, layer, mipmap) -- Attach a specific layer and mipmap\ncanvas:setTexture(textureA, layer, textureB, layer) -- Attach specific layers\ncanvas:setTexture({ textureA, layer, mipmap }, textureB, { textureC, layer }) -- Tables\ncanvas:setTexture({ { textureA, layer, mipmap }, textureB, { textureC, layer } })"
}
}
}
}
},
{
name = "Font",
summary = "A font used to render text.",
description = "A Font is an object created from a TTF file. It can be used to render text with `lovr.graphics.print`.",
key = "Font",
module = "lovr.graphics",
constructors = {
"lovr.graphics.newFont"
},
methods = {
{
name = "getAscent",
summary = "Get the ascent of the Font.",
description = "Returns the maximum distance that any glyph will extend above the Font's baseline. Units are generally in meters, see `Font:getPixelDensity`.",
key = "Font:getAscent",
module = "lovr.graphics",
related = {
"Font:getDescent",
"Rasterizer:getAscent"
},
variants = {
{
arguments = {},
returns = {
{
name = "ascent",
type = "number",
description = "The ascent of the Font."
}
}
}
}
},
{
name = "getBaseline",
summary = "Get the baseline of the Font.",
description = "Returns the baseline of the Font. This is where the characters \"rest on\", relative to the y coordinate of the drawn text. Units are generally in meters, see `Font:setPixelDensity`.",
key = "Font:getBaseline",
module = "lovr.graphics",
variants = {
{
arguments = {},
returns = {
{
name = "baseline",
type = "number",
description = "The baseline of the Font."
}
}
}
}
},
{
name = "getDescent",
summary = "Get the descent of the Font.",
description = "Returns the maximum distance that any glyph will extend below the Font's baseline. Units are generally in meters, see `Font:getPixelDensity` for more information. Note that due to the coordinate system for fonts, this is a negative value.",
key = "Font:getDescent",
module = "lovr.graphics",
variants = {
{
arguments = {},
returns = {
{
name = "descent",
type = "number",
description = "The descent of the Font."
}
}
}
}
},
{
name = "getHeight",
summary = "Get the height of a line of text.",
description = "Returns the height of a line of text. Units are in meters, see `Font:setPixelDensity`.",
key = "Font:getHeight",
module = "lovr.graphics",
related = {
"Rasterizer:getHeight"
},
variants = {
{
arguments = {},
returns = {
{
name = "height",
type = "number",
description = "The height of a rendered line of text."
}
}
}
}
},
{
name = "getLineHeight",
summary = "Get the line height of the Font.",
description = "Returns the current line height multiplier of the Font. The default is 1.0.",
key = "Font:getLineHeight",
module = "lovr.graphics",
related = {
"Font:getHeight",
"Rasterizer:getLineHeight"
},
variants = {
{
arguments = {},
returns = {
{
name = "lineHeight",
type = "number",
description = "The line height."
}
}
}
}
},
{
name = "getPixelDensity",
summary = "Get the pixel density of the Font.",
description = "Returns the current pixel density for the Font. The default is 1.0. Normally, this is in pixels per meter. When rendering to a 2D texture, the units are pixels.",
key = "Font:getPixelDensity",
module = "lovr.graphics",
variants = {
{
arguments = {},
returns = {
{
name = "pixelDensity",
type = "number",
description = "The current pixel density."
}
}
}
}
},
{
name = "getRasterizer",
summary = "Get the underlying Rasterizer.",
description = "Returns the underyling `Rasterizer` object for a Font.",
key = "Font:getRasterizer",
module = "lovr.graphics",
related = {
"Rasterizer",
"lovr.data.newRasterizer"
},
variants = {
{
arguments = {},
returns = {
{
name = "rasterizer",
type = "Rasterizer",
description = "The rasterizer."
}
}
}
}
},
{
name = "getWidth",
summary = "Measure a line of text.",
description = "Returns the width and line count of a string when rendered using the font, taking into account an optional wrap limit.",
key = "Font:getWidth",
module = "lovr.graphics",
notes = "To get the correct units returned, make sure the pixel density is set with\n `Font:setPixelDensity`.",
variants = {
{
arguments = {
{
name = "text",
type = "string",
description = "The text to get the width of."
},
{
name = "wrap",
type = "number",
description = "The width at which to wrap lines, or 0 for no wrap.",
default = "0"
}
},
returns = {
{
name = "width",
type = "number",
description = "The maximum width of any line in the text."
},
{
name = "lines",
type = "number",
description = "The number of lines in the wrapped text."
}
}
}
}
},
{
name = "hasGlyphs",
summary = "Check if a Font has a set of glyphs.",
description = "Returns whether the Font has a set of glyphs. Any combination of strings and numbers (corresponding to character codes) can be specified. This function will return true if the Font is able to render *all* of the glyphs.",
key = "Font:hasGlyphs",
module = "lovr.graphics",
notes = "It is a good idea to use this function when you're rendering an unknown or user-supplied string to avoid utterly embarrassing crashes.",
variants = {
{
arguments = {
{
name = "...",
type = "*",
description = "Strings or numbers to test."
}
},
returns = {
{
name = "has",
type = "boolean",
description = "Whether the Font has the glyphs."
}
}
}
},
related = {
"Rasterizer:hasGlyphs"
}
},
{
name = "setLineHeight",
summary = "Set the line height of the Font.",
description = "Sets the line height of the Font, which controls how far lines apart lines are vertically separated. This value is a ratio and the default is 1.0.",
key = "Font:setLineHeight",
module = "lovr.graphics",
related = {
"Font:getHeight",
"Rasterizer:getLineHeight"
},
variants = {
{
arguments = {
{
name = "lineHeight",
type = "number",
description = "The new line height."
}
},
returns = {}
}
}
},
{
name = "setPixelDensity",
summary = "Set the pixel density of the Font.",
description = "Sets the pixel density for the Font. Normally, this is in pixels per meter. When rendering to a 2D texture, the units are pixels.",
key = "Font:setPixelDensity",
module = "lovr.graphics",
variants = {
{
arguments = {
{
name = "pixelDensity",
type = "number",
description = "The new pixel density."
}
},
returns = {}
},
{
description = "Reset the pixel density to the default (`font:getRasterizer():getHeight()`).",
arguments = {},
returns = {}
}
}
}
}
},
{
name = "Material",
summary = "An object that controls texturing and shading.",
description = "A Material is an object used to control how objects appear, through coloring, texturing, and shading. The Material itself holds sets of colors, textures, and other parameters that are made available to Shaders.",
key = "Material",
module = "lovr.graphics",
constructors = {
"lovr.graphics.newMaterial"
},
methods = {
{
name = "getColor",
summary = "Get a color property of the Material.",
description = "Returns a color property for a Material. Different types of colors are supported for different lighting parameters. Colors default to `(1.0, 1.0, 1.0, 1.0)` and are gamma corrected.",
key = "Material:getColor",
module = "lovr.graphics",
related = {
"MaterialColor",
"lovr.graphics.setColor"
},
variants = {
{
arguments = {
{
name = "colorType",
type = "MaterialColor",
description = "The type of color to get.",
default = "'diffuse'"
}
},
returns = {
{
name = "r",
type = "number",
description = "The red component of the color."
},
{
name = "g",
type = "number",
description = "The green component of the color."
},
{
name = "b",
type = "number",
description = "The blue component of the color."
},
{
name = "a",
type = "number",
description = "The alpha component of the color."
}
}
}
}
},
{
name = "getScalar",
summary = "Get a scalar property of the Material.",
description = "Returns a numeric property of a Material. Scalar properties default to 1.0.",
key = "Material:getScalar",
module = "lovr.graphics",
related = {
"MaterialScalar"
},
variants = {
{
arguments = {
{
name = "scalarType",
type = "MaterialScalar",
description = "The type of property to get."
}
},
returns = {
{
name = "x",
type = "number",
description = "The value of the property."
}
}
}
}
},
{
name = "getTexture",
summary = "Get a texture for the Material.",
description = "Returns a texture for a Material. Several predefined `MaterialTexture`s are supported. Any texture that is `nil` will use a single white pixel as a fallback.",
key = "Material:getTexture",
module = "lovr.graphics",
related = {
"MaterialTexture"
},
variants = {
{
arguments = {
{
name = "textureType",
type = "MaterialTexture",
description = "The type of texture to get.",
default = "'diffuse'"
}
},
returns = {
{
name = "texture",
type = "Texture",
description = "The texture that is set, or `nil` if no texture is set."
}
}
}
}
},
{
name = "getTransform",
summary = "Get the transformation applied to texture coordinates.",
description = "Returns the transformation applied to texture coordinates of the Material.",
key = "Material:getTransform",
module = "lovr.graphics",
notes = "Although texture coordinates will automatically be transformed by the Material's transform, the material transform is exposed as the `mat3 lovrMaterialTransform` uniform variable in shaders, allowing it to be used for other purposes.",
variants = {
{
arguments = {},
returns = {
{
name = "ox",
type = "number",
description = "The texture coordinate x offset."
},
{
name = "oy",
type = "number",
description = "The texture coordinate y offset."
},
{
name = "sx",
type = "number",
description = "The texture coordinate x scale."
},
{
name = "sy",
type = "number",
description = "The texture coordinate y scale."
},
{
name = "angle",
type = "number",
description = "The texture coordinate rotation, in radians."
}
}
}
}
},
{
name = "setColor",
summary = "Set a color property of the Material.",
description = "Sets a color property for a Material. Different types of colors are supported for different lighting parameters. Colors default to `(1.0, 1.0, 1.0, 1.0)` and are gamma corrected.",
key = "Material:setColor",
module = "lovr.graphics",
related = {
"MaterialColor",
"lovr.graphics.setColor"
},
variants = {
{
arguments = {
{
name = "colorType",
type = "MaterialColor",
description = "The type of color to set.",
default = "'diffuse'"
},
{
name = "r",
type = "number",
description = "The red component of the color."
},
{
name = "g",
type = "number",
description = "The green component of the color."
},
{
name = "b",
type = "number",
description = "The blue component of the color."
},
{
name = "a",
type = "number",
description = "The alpha component of the color.",
default = "1.0"
}
},
returns = {}
},
{
arguments = {
{
name = "r",
type = "number",
description = "The red component of the color."
},
{
name = "g",
type = "number",
description = "The green component of the color."
},
{
name = "b",
type = "number",
description = "The blue component of the color."
},
{
name = "a",
type = "number",
description = "The alpha component of the color.",
default = "1.0"
}
},
returns = {}
},
{
arguments = {
{
name = "colorType",
type = "MaterialColor",
description = "The type of color to set.",
default = "'diffuse'"
},
{
name = "hex",
type = "number",
description = "A hexcode to use for the color (alpha is not supported)."
}
},
returns = {}
},
{
arguments = {
{
name = "hex",
type = "number",
description = "A hexcode to use for the color (alpha is not supported)."
}
},
returns = {}
}
}
},
{
name = "setScalar",
summary = "Set a scalar property of the Material.",
description = "Sets a numeric property of a Material. Scalar properties default to 1.0.",
key = "Material:setScalar",
module = "lovr.graphics",
related = {
"MaterialScalar"
},
variants = {
{
arguments = {
{
name = "scalarType",
type = "MaterialScalar",
description = "The type of property to set."
},
{
name = "x",
type = "number",
description = "The value of the property."
}
},
returns = {}
}
}
},
{
name = "setTexture",
summary = "Set a texture for the Material.",
description = "Sets a texture for a Material. Several predefined `MaterialTexture`s are supported. Any texture that is `nil` will use a single white pixel as a fallback.",
key = "Material:setTexture",
module = "lovr.graphics",
related = {
"MaterialTexture",
"lovr.graphics.newTexture"
},
variants = {
{
arguments = {
{
name = "textureType",
type = "MaterialTexture",
description = "The type of texture to set.",
default = "'diffuse'"
},
{
name = "texture",
type = "Texture",
description = "The texture to apply, or `nil` to use the default."
}
},
returns = {}
},
{
arguments = {
{
name = "texture",
type = "Texture",
description = "The texture to apply, or `nil` to use the default."
}
},
returns = {}
}
}
},
{
name = "setTransform",
summary = "Set the transformation applied to texture coordinates.",
description = "Sets the transformation applied to texture coordinates of the Material. This lets you offset, scale, or rotate textures as they are applied to geometry.",
key = "Material:setTransform",
module = "lovr.graphics",
notes = "Although texture coordinates will automatically be transformed by the Material's transform, the material transform is exposed as the `mat3 lovrMaterialTransform` uniform variable in shaders, allowing it to be used for other purposes.",
variants = {
{
arguments = {
{
name = "ox",
type = "number",
description = "The texture coordinate x offset."
},
{
name = "oy",
type = "number",
description = "The texture coordinate y offset."
},
{
name = "sx",
type = "number",
description = "The texture coordinate x scale."
},
{
name = "sy",
type = "number",
description = "The texture coordinate y scale."
},
{
name = "angle",
type = "number",
description = "The texture coordinate rotation, in radians."
}
},
returns = {}
}
}
}
}
},
{
name = "Mesh",
summary = "A drawable list of vertices.",
description = "A Mesh is a low-level graphics object that stores and renders a list of vertices.\n\nMeshes are really flexible since you can pack pretty much whatever you want in them. This makes them great for rendering arbitrary geometry, but it also makes them kinda difficult to use since you have to place each vertex yourself.\n\nIt's possible to batch geometry with Meshes too. Instead of drawing a shape 100 times, it's much faster to pack 100 copies of the shape into a Mesh and draw the Mesh once. Even storing just one copy in the Mesh and drawing that 100 times is usually faster.\n\nMeshes are also a good choice if you have an object that changes its shape over time.",
key = "Mesh",
module = "lovr.graphics",
constructors = {
"lovr.graphics.newMesh"
},
examples = {
{
description = "Draw a circle using a Mesh.",
code = "function lovr.load()\n local x, y, z = 0, 1, -2\n local radius = .3\n local points = 40\n\n -- A table to hold the Mesh data\n local vertices = {}\n\n for i = 0, points do\n local angle = i / points * 2 * math.pi\n local vx = x + math.cos(angle)\n local vy = y + math.sin(angle)\n table.insert(vertices, { vx, vy, z })\n end\n\n mesh = lovr.graphics.newMesh(vertices, 'fan')\nend\n\nfunction lovr.draw()\n mesh:draw()\nend"
}
},
notes = "Each vertex in a Mesh can hold several pieces of data. For example, you might want a vertex to keep track of its position, color, and a weight. Each one of these pieces of information is called a vertex **attribute**. A vertex attribute must have a name, a type, and a size. Here's what the \"position\" attribute would look like as a Lua table:\n\n { 'vPosition', 'float', 3 } -- 3 floats, one for x, y, and z\n\nEvery vertex in a Mesh must have the same set of attributes. We call this set of attributes the **format** of the Mesh, and it's specified as a simple table of attributes. For example, we could represent the format described above as:\n\n {\n { 'vPosition', 'float', 3 },\n { 'vColor', 'byte', 4 },\n { 'vWeight', 'int', 1 }\n }\n\nWhen creating a Mesh, you can give it any format you want, or use the default. The default Mesh format looks like this:\n\n {\n { 'lovrPosition', 'float', 3 },\n { 'lovrNormal', 'float', 3 },\n { 'lovrTexCoord', 'float', 2 }\n }\n\nGreat, so why do we go through the trouble of naming everything in our vertex and saying what type and size it is? The cool part is that we can access this data in a Shader. We can write a vertex Shader that has `in` variables for every vertex attribute in our Mesh:\n\n in vec3 vPosition;\n in vec4 vColor;\n in int vWeight;\n\n vec4 position(mat4 projection, mat4 transform, vec4 vertex) {\n // Here we can access the vPosition, vColor, and vWeight of each vertex in the Mesh!\n }\n\nSpecifying custom vertex data is really powerful and is often used for lighting, animation, and more!\n\nFor more on the different data types available for the attributes, see `AttributeType`.",
methods = {
{
name = "attachAttributes",
summary = "Attach attributes from another Mesh onto this one.",
description = "Attaches attributes from another Mesh onto this one. This can be used to share vertex data across multiple meshes without duplicating the data, and can also be used for instanced rendering by using the `divisor` parameter.",
key = "Mesh:attachAttributes",
module = "lovr.graphics",
notes = "The attribute divisor is a number used to control how the attribute data relates to instancing. If 0, then the attribute data is considered \"per vertex\", and each vertex will get the next element of the attribute's data. If the divisor 1 or more, then the attribute data is considered \"per instance\", and every N instances will get the next element of the attribute data.\n\nTo prevent cycles, it is not possible to attach attributes onto a Mesh that already has attributes attached to a different Mesh.",
variants = {
{
description = "Attach all attributes from the other mesh.",
arguments = {
{
name = "mesh",
type = "Mesh",
description = "The Mesh to attach attributes from."
},
{
name = "divisor",
type = "number",
description = "The attribute divisor for all attached attributes.",
default = "0"
}
},
returns = {}
},
{
arguments = {
{
name = "mesh",
type = "Mesh",
description = "The Mesh to attach attributes from."
},
{
name = "divisor",
type = "number",
description = "The attribute divisor for all attached attributes.",
default = "0"
},
{
name = "...",
type = "string",
description = "The names of attributes to attach from the other Mesh."
}
},
returns = {}
},
{
arguments = {
{
name = "mesh",
type = "Mesh",
description = "The Mesh to attach attributes from."
},
{
name = "divisor",
type = "number",
description = "The attribute divisor for all attached attributes.",
default = "0"
},
{
name = "attributes",
type = "table",
description = "A table of attribute names to attach from the other Mesh."
}
},
returns = {}
}
},
related = {
"Mesh:detachAttributes",
"Mesh:drawInstanced"
}
},
{
name = "detachAttributes",
summary = "Detach attributes that were attached from a different Mesh.",
description = "Detaches attributes that were attached using `Mesh:attachAttributes`.",
key = "Mesh:detachAttributes",
module = "lovr.graphics",
related = {
"Mesh:attachAttributes"
},
variants = {
{
description = "Detaches all attributes from the other mesh, by name.",
arguments = {
{
name = "mesh",
type = "Mesh",
description = "A Mesh. The names of all of the attributes from this Mesh will be detached."
}
},
returns = {}
},
{
arguments = {
{
name = "mesh",
type = "Mesh",
description = "A Mesh. The names of all of the attributes from this Mesh will be detached."
},
{
name = "...",
type = "string",
description = "The names of attributes to detach."
}
},
returns = {}
},
{
arguments = {
{
name = "mesh",
type = "Mesh",
description = "A Mesh. The names of all of the attributes from this Mesh will be detached."
},
{
name = "attributes",
type = "table",
description = "A table of attribute names to detach."
}
},
returns = {}
}
}
},
{
name = "draw",
summary = "Draw the Mesh.",
description = "Draws the contents of the Mesh.",
key = "Mesh:draw",
module = "lovr.graphics",
variants = {
{
arguments = {
{
name = "x",
type = "number",
description = "The x coordinate to draw the Mesh at.",
default = "0"
},
{
name = "y",
type = "number",
description = "The y coordinate to draw the Mesh at.",
default = "0"
},
{
name = "z",
type = "number",
description = "The z coordinate to draw the Mesh at.",
default = "0"
},
{
name = "scale",
type = "number",
description = "The scale to draw the Mesh at.",
default = "1"
},
{
name = "angle",
type = "number",
description = "The angle to rotate the Mesh around the axis of rotation, in radians.",
default = "0"
},
{
name = "ax",
type = "number",
description = "The x component of the axis of rotation.",
default = "0"
},
{
name = "ay",
type = "number",
description = "The y component of the axis of rotation.",
default = "1"
},
{
name = "az",
type = "number",
description = "The z component of the axis of rotation.",
default = "0"
},
{
name = "instances",
type = "number",
description = "The number of copies of the Mesh to draw.",
default = "1"
}
},
returns = {}
},
{
arguments = {
{
name = "transform",
type = "mat4",
description = "The transform to apply before drawing."
},
{
name = "instances",
type = "number",
description = "The number of copies of the Mesh to draw.",
default = "1"
}
},
returns = {}
}
}
},
{
name = "getDrawMode",
summary = "Get the draw mode of the Mesh.",
description = "Get the draw mode of the Mesh, which controls how the vertices are connected together.",
key = "Mesh:getDrawMode",
module = "lovr.graphics",
variants = {
{
arguments = {},
returns = {
{
name = "mode",
type = "DrawMode",
description = "The draw mode of the Mesh."
}
}
}
}
},
{
name = "getDrawRange",
summary = "Get the draw range of the Mesh.",
description = "Retrieve the current draw range for the Mesh. The draw range is a subset of the vertices of the Mesh that will be drawn.",
key = "Mesh:getDrawRange",
module = "lovr.graphics",
variants = {
{
arguments = {},
returns = {
{
name = "start",
type = "number",
description = "The index of the first vertex that will be drawn, or nil if no draw range is set."
},
{
name = "count",
type = "number",
description = "The number of vertices that will be drawn, or nil if no draw range is set."
}
}
}
}
},
{
name = "getMaterial",
summary = "Get the Material applied to the Mesh.",
description = "Get the Material applied to the Mesh.",
key = "Mesh:getMaterial",
module = "lovr.graphics",
variants = {
{
arguments = {},
returns = {
{
name = "material",
type = "Material",
description = "The current material applied to the Mesh."
}
}
}
}
},
{
name = "getVertex",
summary = "Get a single vertex in the Mesh.",
description = "Gets the data for a single vertex in the Mesh. The set of data returned depends on the Mesh's vertex format. The default vertex format consists of 8 floating point numbers: the vertex position, the vertex normal, and the texture coordinates.",
key = "Mesh:getVertex",
module = "lovr.graphics",
variants = {
{
arguments = {
{
name = "index",
type = "number",
description = "The index of the vertex to retrieve."
}
},
returns = {
{
name = "...",
type = "number",
description = "All attributes of the vertex."
}
}
}
}
},
{
name = "getVertexAttribute",
summary = "Get an attribute of a single vertex in the Mesh.",
description = "Returns the components of a specific attribute of a single vertex in the Mesh.",
key = "Mesh:getVertexAttribute",
module = "lovr.graphics",
notes = "Meshes without a custom format have the vertex position as their first attribute, the normal vector as the second attribute, and the texture coordinate as the third attribute.",
variants = {
{
arguments = {
{
name = "index",
type = "number",
description = "The index of the vertex to retrieve the attribute of."
},
{
name = "attribute",
type = "number",
description = "The index of the attribute to retrieve the components of."
}
},
returns = {
{
name = "...",
type = "number",
description = "The components of the vertex attribute."
}
}
}
}
},
{
name = "getVertexCount",
summary = "Get the number of vertices the Mesh can hold.",
description = "Returns the maximum number of vertices the Mesh can hold.",
key = "Mesh:getVertexCount",
module = "lovr.graphics",
notes = "The size can only be set when creating the Mesh, and cannot be changed afterwards.\n\nA subset of the Mesh's vertices can be rendered, see `Mesh:setDrawRange`.",
variants = {
{
arguments = {},
returns = {
{
name = "size",
type = "number",
description = "The number of vertices the Mesh can hold."
}
}
}
}
},
{
name = "getVertexFormat",
summary = "Get the vertex format of the Mesh.",
description = "Get the format table of the Mesh's vertices. The format table describes the set of data that each vertex contains.",
key = "Mesh:getVertexFormat",
module = "lovr.graphics",
variants = {
{
arguments = {},
returns = {
{
name = "format",
type = "table",
description = "The table of vertex attributes. Each attribute is a table containing the name of the attribute, the `AttributeType`, and the number of components."
}
}
}
}
},
{
name = "getVertexMap",
summary = "Get the current vertex map of the Mesh.",
description = "Returns the current vertex map for the Mesh. The vertex map is a list of indices in the Mesh, allowing the reordering or reuse of vertices.",
key = "Mesh:getVertexMap",
module = "lovr.graphics",
variants = {
{
arguments = {},
returns = {
{
name = "map",
type = "table",
description = "The list of indices in the vertex map, or `nil` if no vertex map is set."
}
}
},
{
arguments = {
{
name = "t",
type = "table",
description = "The table to fill with the vertex map."
}
},
returns = {
{
name = "map",
type = "table",
description = "The list of indices in the vertex map, or `nil` if no vertex map is set."
}
}
},
{
arguments = {
{
name = "blob",
type = "Blob",
description = "The Blob to fill with the vertex map data. It must be big enough to hold all of the indices."
}
},
returns = {}
}
}
},
{
name = "isAttributeEnabled",
summary = "Check if a vertex attribute is enabled.",
description = "Returns whether or not a vertex attribute is enabled. Disabled attributes won't be sent to shaders.",
key = "Mesh:isAttributeEnabled",
module = "lovr.graphics",
variants = {
{
arguments = {
{
name = "attribute",
type = "string",
description = "The name of the attribute."
}
},
returns = {
{
name = "enabled",
type = "boolean",
description = "Whether or not the attribute is enabled when drawing the Mesh."
}
}
}
}
},
{
name = "setAttributeEnabled",
summary = "Enable or disable a vertex attribute.",
description = "Sets whether a vertex attribute is enabled. Disabled attributes won't be sent to shaders.",
key = "Mesh:setAttributeEnabled",
module = "lovr.graphics",
variants = {
{
arguments = {
{
name = "attribute",
type = "string",
description = "The name of the attribute."
},
{
name = "enabled",
type = "boolean",
description = "Whether or not the attribute is enabled when drawing the Mesh."
}
},
returns = {}
}
}
},
{
name = "setDrawMode",
summary = "Change the draw mode of the Mesh.",
description = "Set a new draw mode for the Mesh.",
key = "Mesh:setDrawMode",
module = "lovr.graphics",
variants = {
{
arguments = {
{
name = "mode",
type = "DrawMode",
description = "The new draw mode for the Mesh."
}
},
returns = {}
}
}
},
{
name = "setDrawRange",
summary = "Set the draw range of the Mesh.",
description = "Set the draw range for the Mesh. The draw range is a subset of the vertices of the Mesh that will be drawn.",
key = "Mesh:setDrawRange",
module = "lovr.graphics",
variants = {
{
arguments = {
{
name = "start",
type = "number",
description = "The first vertex that will be drawn."
},
{
name = "count",
type = "number",
description = "The number of vertices that will be drawn."
}
},
returns = {}
},
{
description = "Remove the draw range, causing the Mesh to draw all of its vertices.",
arguments = {},
returns = {}
}
}
},
{
name = "setMaterial",
summary = "Apply a Material to the Mesh.",
description = "Applies a Material to the Mesh. This will cause it to use the Material's properties whenever it is rendered.",
key = "Mesh:setMaterial",
module = "lovr.graphics",
variants = {
{
arguments = {
{
name = "material",
type = "Material",
description = "The Material to apply."
}
},
returns = {}
}
}
},
{
name = "setVertex",
summary = "Update a single vertex in the Mesh.",
description = "Update a single vertex in the Mesh.",
key = "Mesh:setVertex",
module = "lovr.graphics",
variants = {
{
arguments = {
{
name = "index",
type = "number",
description = "The index of the vertex to set."
},
{
name = "...",
type = "number",
description = "The attributes of the vertex."
}
},
returns = {}
}
},
notes = "Any unspecified components will be set to 0.",
examples = {
{
description = "Set the position of a vertex:",
code = "function lovr.load()\n mesh = lovr.graphics.newMesh({\n { -1, 1, 0, 0, 0, 1, 0, 0 },\n { 1, 1, 0, 0, 0, 1, 1, 0 },\n { -1, -1, 0, 0, 0, 1, 0, 1 },\n { 1, -1, 0, 0, 0, 1, 1, 1 }\n }, 'strip')\n\n mesh:setVertex(2, { 7, 7, 7 })\n print(mesh:getVertex(2)) -- 7, 7, 7, 0, 0, 0, 0, 0\nend"
}
}
},
{
name = "setVertexAttribute",
summary = "Update a specific attribute of a single vertex in the Mesh.",
description = "Set the components of a specific attribute of a vertex in the Mesh.",
key = "Mesh:setVertexAttribute",
module = "lovr.graphics",
notes = "Meshes without a custom format have the vertex position as their first attribute, the normal vector as the second attribute, and the texture coordinate as the third attribute.",
variants = {
{
arguments = {
{
name = "index",
type = "number",
description = "The index of the vertex to update."
},
{
name = "attribute",
type = "number",
description = "The index of the attribute to update."
},
{
name = "...",
type = "number",
description = "Thew new components for the attribute."
}
},
returns = {}
}
}
},
{
name = "setVertexMap",
summary = "Set the vertex map of the Mesh.",
description = "Sets the vertex map. The vertex map is a list of indices in the Mesh, allowing the reordering or reuse of vertices.\n\nOften, a vertex map is used to improve performance, since it usually requires less data to specify the index of a vertex than it does to specify all of the data for a vertex.",
key = "Mesh:setVertexMap",
module = "lovr.graphics",
variants = {
{
arguments = {
{
name = "map",
type = "table",
description = "The new vertex map. Each element of the table is an index of a vertex."
}
},
returns = {}
},
{
description = "This variant is much faster than the previous one, but is harder to use.",
arguments = {
{
name = "blob",
type = "Blob",
description = "A Blob to use to update vertex data."
},
{
name = "size",
type = "number",
description = "The size of each element of the Blob, in bytes. Must be 2 or 4.",
default = "4"
}
},
returns = {}
}
}
},
{
name = "setVertices",
summary = "Update multiple vertices in the Mesh.",
description = "Updates multiple vertices in the Mesh.",
key = "Mesh:setVertices",
module = "lovr.graphics",
notes = "The start index plus the number of vertices in the table should not exceed the maximum size of the Mesh.",
variants = {
{
arguments = {
{
name = "vertices",
type = "table",
description = "The new set of vertices."
},
{
name = "start",
type = "number",
description = "The index of the vertex to start replacing at.",
default = "1"
},
{
name = "count",
type = "number",
description = "The number of vertices to replace. If nil, all vertices will be used.",
default = "nil"
}
},
returns = {}
}
}
}
}
},
{
name = "Model",
summary = "An asset imported from a 3D model file.",
description = "A Model is a drawable object loaded from a 3D file format. The supported 3D file formats are OBJ and glTF.",
key = "Model",
module = "lovr.graphics",
constructors = {
"lovr.graphics.newModel",
"lovr.headset.newModel"
},
examples = {
{
code = "local model\n\nfunction lovr.load()\n model = lovr.graphics.newModel('assets/model.gltf', 'assets/texture.png')\nend\n\nfunction lovr.draw()\n model:draw(0, 1, -1, 1, lovr.timer.getTime())\nend"
}
},
methods = {
{
name = "animate",
summary = "Apply an animation to the pose of the Model.",
description = "Applies an animation to the current pose of the Model.\n\nThe animation is evaluated at the specified timestamp, and mixed with the current pose of the Model using the alpha value. An alpha value of 1.0 will completely override the pose of the Model with the animation's pose.",
key = "Model:animate",
module = "lovr.graphics",
related = {
"Model:pose",
"Model:getAnimationCount",
"Model:getAnimationName",
"Model:getAnimationDuration"
},
examples = {
{
description = "Render an animated model, with a custom speed.",
code = "function lovr.load()\n model = lovr.graphics.newModel('model.gltf')\n shader = lovr.graphics.newShader('unlit', { flags = { animated = true } })\nend\n\nfunction lovr.draw()\n local speed = 1.0\n model:animate(1, lovr.timer.getTime() * speed)\n model:draw()\nend"
},
{
description = "Mix from one animation to another, as the trigger is pressed.",
code = "function lovr.load()\n model = lovr.graphics.newModel('model.gltf')\n shader = lovr.graphics.newShader('unlit', { flags = { animated = true } })\nend\n\nfunction lovr.draw()\n local t = lovr.timer.getTime()\n local mix = lovr.headset.getAxis('right', 'trigger')\n\n model:pose()\n model:animate(1, t)\n model:animate(2, t, mix)\n\n model:draw()\nend"
}
},
notes = "For animations to properly show up, use a Shader created with the `animated` flag set to `true`. See `lovr.graphics.newShader` for more.\n\nAnimations are always mixed in with the current pose, and the pose only ever changes by calling `Model:animate` and `Model:pose`. To clear the pose of a Model to the default, use `Model:pose(nil)`.",
variants = {
{
arguments = {
{
name = "name",
type = "string",
description = "The name of an animation."
},
{
name = "time",
type = "number",
description = "The timestamp to evaluate the keyframes at, in seconds."
},
{
name = "alpha",
type = "number",
description = "How much of the animation to mix in, from 0 to 1.",
default = "1"
}
},
returns = {}
},
{
arguments = {
{
name = "index",
type = "number",
description = "The index of an animation."
},
{
name = "time",
type = "number",
description = "The timestamp to evaluate the keyframes at, in seconds."
},
{
name = "alpha",
type = "number",
description = "How much of the animation to mix in, from 0 to 1.",
default = "1"
}
},
returns = {}
}
}
},
{
name = "draw",
summary = "Draw the Model.",
description = "Draw the Model.",
key = "Model:draw",
module = "lovr.graphics",
variants = {
{
arguments = {
{
name = "x",
type = "number",
description = "The x coordinate to draw the Model at.",
default = "0"
},
{
name = "y",
type = "number",
description = "The y coordinate to draw the Model at.",
default = "0"
},
{
name = "z",
type = "number",
description = "The z coordinate to draw the Model at.",
default = "0"
},
{
name = "scale",
type = "number",
description = "The scale to draw the Model at.",
default = "1"
},
{
name = "angle",
type = "number",
description = "The angle to rotate the Model around the axis of rotation, in radians.",
default = "0"
},
{
name = "ax",
type = "number",
description = "The x component of the axis of rotation.",
default = "0"
},
{
name = "ay",
type = "number",
description = "The y component of the axis of rotation.",
default = "1"
},
{
name = "az",
type = "number",
description = "The z component of the axis of rotation.",
default = "0"
},
{
name = "instances",
type = "number",
description = "The number of copies of the Model to draw.",
default = "1"
}
},
returns = {}
},
{
arguments = {
{
name = "transform",
type = "mat4",
description = "The transform to apply before drawing."
},
{
name = "instances",
type = "number",
description = "The number of copies of the Model to draw.",
default = "1"
}
},
returns = {}
}
}
},
{
name = "getAABB",
summary = "Get the Model's axis aligned bounding box.",
description = "Returns a bounding box that encloses the vertices of the Model.",
key = "Model:getAABB",
module = "lovr.graphics",
related = {
"Collider:getAABB"
},
variants = {
{
arguments = {},
returns = {
{
name = "minx",
type = "number",
description = "The minimum x coordinate of the box."
},
{
name = "maxx",
type = "number",
description = "The maximum x coordinate of the box."
},
{
name = "miny",
type = "number",
description = "The minimum y coordinate of the box."
},
{
name = "maxy",
type = "number",
description = "The maximum y coordinate of the box."
},
{
name = "minz",
type = "number",
description = "The minimum z coordinate of the box."
},
{
name = "maxz",
type = "number",
description = "The maximum z coordinate of the box."
}
}
}
}
},
{
name = "getAnimationCount",
summary = "Get the number of animations in the Model.",
description = "Returns the number of animations in the Model.",
key = "Model:getAnimationCount",
module = "lovr.graphics",
related = {
"Model:getAnimationName",
"Model:getAnimationDuration",
"Model:animate"
},
variants = {
{
arguments = {},
returns = {
{
name = "count",
type = "number",
description = "The number of animations in the Model."
}
}
}
}
},
{
name = "getAnimationDuration",
summary = "Get the duration of an animation in the Model.",
description = "Returns the duration of an animation in the Model, in seconds.",
key = "Model:getAnimationDuration",
module = "lovr.graphics",
related = {
"Model:getAnimationCount",
"Model:getAnimationName",
"Model:animate"
},
variants = {
{
arguments = {
name = {
type = "string",
description = "The name of the animation."
},
index = {
type = "number",
description = "The animation index."
}
},
returns = {
duration = {
type = "number",
description = "The duration of the animation, in seconds."
}
}
}
}
},
{
name = "getAnimationName",
summary = "Get the name of an animation in the Model.",
description = "Returns the name of one of the animations in the Model.",
key = "Model:getAnimationName",
module = "lovr.graphics",
related = {
"Model:getAnimationCount",
"Model:getAnimationDuration",
"Model:getMaterialName",
"Model:getNodeName"
},
variants = {
{
arguments = {
{
name = "index",
type = "number",
description = "The index of the animation to get the name of."
}
},
returns = {
{
name = "name",
type = "string",
description = "The name of the animation."
}
}
}
}
},
{
name = "getMaterial",
summary = "Get a Material from the Model.",
description = "Returns a Material loaded from the Model, by name or index.\n\nThis includes `Texture` objects and other properties like colors, metalness/roughness, and more.",
key = "Model:getMaterial",
module = "lovr.graphics",
related = {
"Model:getMaterialCount",
"Model:getMaterialName",
"Material"
},
variants = {
{
arguments = {
{
name = "name",
type = "string",
description = "The name of the Material to return."
}
},
returns = {
{
name = "material",
type = "Material",
description = "The material."
}
}
},
{
arguments = {
{
name = "index",
type = "number",
description = "The index of the Material to return."
}
},
returns = {
{
name = "material",
type = "Material",
description = "The material."
}
}
}
}
},
{
name = "getMaterialCount",
summary = "Get the number of materials in the Model.",
description = "Returns the number of materials in the Model.",
key = "Model:getMaterialCount",
module = "lovr.graphics",
related = {
"Model:getMaterialName",
"Model:getMaterial"
},
variants = {
{
arguments = {},
returns = {
{
name = "count",
type = "number",
description = "The number of materials in the Model."
}
}
}
}
},
{
name = "getMaterialName",
summary = "Get the name of a material in the Model.",
description = "Returns the name of one of the materials in the Model.",
key = "Model:getMaterialName",
module = "lovr.graphics",
related = {
"Model:getMaterialCount",
"Model:getAnimationName",
"Model:getNodeName"
},
variants = {
{
arguments = {
{
name = "index",
type = "number",
description = "The index of the material to get the name of."
}
},
returns = {
{
name = "name",
type = "string",
description = "The name of the material."
}
}
}
}
},
{
name = "getNodeCount",
summary = "Get the number of nodes in the Model.",
description = "Returns the number of nodes (bones) in the Model.",
key = "Model:getNodeCount",
module = "lovr.graphics",
related = {
"Model:getNodeName",
"Model:getNodePose",
"Model:pose"
},
variants = {
{
arguments = {},
returns = {
{
name = "count",
type = "number",
description = "The number of nodes in the Model."
}
}
}
}
},
{
name = "getNodeName",
summary = "Get the name of a node in the Model.",
description = "Returns the name of one of the nodes (bones) in the Model.",
key = "Model:getNodeName",
module = "lovr.graphics",
related = {
"Model:getNodeCount",
"Model:getAnimationName",
"Model:getMaterialName"
},
variants = {
{
arguments = {
{
name = "index",
type = "number",
description = "The index of the node to get the name of."
}
},
returns = {
{
name = "name",
type = "string",
description = "The name of the node."
}
}
}
}
},
{
name = "getNodePose",
summary = "Get the pose of a single node.",
description = "Returns the pose of a single node in the Model in a given `CoordinateSpace`.",
key = "Model:getNodePose",
module = "lovr.graphics",
notes = "For skinned nodes to render correctly, use a Shader created with the `animated` flag set to `true`. See `lovr.graphics.newShader` for more.",
variants = {
{
arguments = {
{
name = "name",
type = "string",
description = "The name of the node."
},
{
name = "space",
type = "CoordinateSpace",
description = "Whether the pose sould be returned relative to the node's parent or relative to the root node of the Model.",
default = "global"
}
},
returns = {
{
name = "x",
type = "number",
description = "The x position of the node."
},
{
name = "y",
type = "number",
description = "The y position of the node."
},
{
name = "z",
type = "number",
description = "The z position of the node."
},
{
name = "angle",
type = "number",
description = "The number of radians the node is rotated around its rotational axis."
},
{
name = "ax",
type = "number",
description = "The x component of the axis of rotation."
},
{
name = "ay",
type = "number",
description = "The y component of the axis of rotation."
},
{
name = "az",
type = "number",
description = "The z component of the axis of rotation."
}
}
},
{
arguments = {
{
name = "index",
type = "number",
description = "The node index."
},
{
name = "space",
type = "CoordinateSpace",
description = "Whether the pose sould be returned relative to the node's parent or relative to the root node of the Model.",
default = "global"
}
},
returns = {
{
name = "x",
type = "number",
description = "The x position of the node."
},
{
name = "y",
type = "number",
description = "The y position of the node."
},
{
name = "z",
type = "number",
description = "The z position of the node."
},
{
name = "angle",
type = "number",
description = "The number of radians the node is rotated around its rotational axis."
},
{
name = "ax",
type = "number",
description = "The x component of the axis of rotation."
},
{
name = "ay",
type = "number",
description = "The y component of the axis of rotation."
},
{
name = "az",
type = "number",
description = "The z component of the axis of rotation."
}
}
}
},
related = {
"Model:pose",
"Model:animate",
"Model:getNodeName",
"Model:getNodeCount"
}
},
{
name = "pose",
summary = "Set the pose of a single node, or clear the pose.",
description = "Applies a pose to a single node of the Model. The input pose is assumed to be relative to the pose of the node's parent. This is useful for applying inverse kinematics (IK) to a chain of bones in a skeleton.\n\nThe alpha parameter can be used to mix between the node's current pose and the input pose.",
key = "Model:pose",
module = "lovr.graphics",
notes = "For skinned nodes to render correctly, use a Shader created with the `animated` flag set to `true`. See `lovr.graphics.newShader` for more.",
variants = {
{
arguments = {
{
name = "name",
type = "string",
description = "The name of the node."
},
{
name = "x",
type = "number",
description = "The x position."
},
{
name = "y",
type = "number",
description = "The y position."
},
{
name = "z",
type = "number",
description = "The z position."
},
{
name = "angle",
type = "number",
description = "The angle of rotation around the axis, in radians."
},
{
name = "ax",
type = "number",
description = "The x component of the rotation axis."
},
{
name = "ay",
type = "number",
description = "The y component of the rotation axis."
},
{
name = "az",
type = "number",
description = "The z component of the rotation axis."
},
{
name = "alpha",
type = "number",
description = "How much of the pose to mix in, from 0 to 1.",
default = "1"
}
},
returns = {}
},
{
arguments = {
{
name = "index",
type = "number",
description = "The node index."
},
{
name = "x",
type = "number",
description = "The x position."
},
{
name = "y",
type = "number",
description = "The y position."
},
{
name = "z",
type = "number",
description = "The z position."
},
{
name = "angle",
type = "number",
description = "The angle of rotation around the axis, in radians."
},
{
name = "ax",
type = "number",
description = "The x component of the rotation axis."
},
{
name = "ay",
type = "number",
description = "The y component of the rotation axis."
},
{
name = "az",
type = "number",
description = "The z component of the rotation axis."
},
{
name = "alpha",
type = "number",
description = "How much of the pose to mix in, from 0 to 1.",
default = "1"
}
},
returns = {}
},
{
description = "Clear the pose of the Model.",
arguments = {},
returns = {}
}
},
related = {
"Model:getNodePose",
"Model:animate",
"Model:getNodeName",
"Model:getNodeCount"
}
}
}
},
{
name = "Shader",
summary = "A GLSL program used for low-level control over rendering.",
description = "Shaders are GLSL programs that transform the way vertices and pixels show up on the screen. They can be used for lighting, postprocessing, particles, animation, and much more. You can use `lovr.graphics.setShader` to change the active Shader.",
key = "Shader",
module = "lovr.graphics",
constructors = {
"lovr.graphics.newShader",
"lovr.graphics.newComputeShader"
},
related = {
"lovr.graphics.newComputeShader",
"lovr.graphics.setShader",
"lovr.graphics.getShader"
},
examples = {
{
description = "Set a simple shader that colors pixels based on vertex normals.",
code = "function lovr.load()\n lovr.graphics.setShader(lovr.graphics.newShader([[\n out vec3 vNormal; // This gets passed to the fragment shader\n\n vec4 position(mat4 projection, mat4 transform, vec4 vertex) {\n vNormal = lovrNormal;\n return projection * transform * vertex;\n }\n ]], [[\n in vec3 vNormal; // This gets passed from the vertex shader\n\n vec4 color(vec4 graphicsColor, sampler2D image, vec2 uv) {\n return vec4(vNormal * .5 + .5, 1.0);\n }\n ]]))\n\n model = lovr.graphics.newModel('model.gltf')\nend\n\nfunction lovr.draw()\n model:draw(x, y, z)\nend"
}
},
notes = "The GLSL version used is 430 on systems that support compute shaders and 150 otherwise. The version used for WebGL is 300 es.\n\nThe default vertex shader:\n\n vec4 position(mat4 projection, mat4 transform, vec4 vertex) {\n return projection * transform * vertex;\n }\n\nThe default fragment shader:\n\n vec4 color(vec4 graphicsColor, sampler2D image, vec2 uv) {\n return graphicsColor * lovrDiffuseColor * vertexColor * texture(image, uv);\n }\n\nAdditionally, the following headers are prepended to the shader source, giving you convenient access to a default set of uniform variables and vertex attributes.\n\nVertex shader header:\n\n in vec3 lovrPosition; // The vertex position\n in vec3 lovrNormal; // The vertex normal vector\n in vec2 lovrTexCoord;\n in vec4 lovrVertexColor;\n in vec3 lovrTangent;\n in uvec4 lovrBones;\n in vec4 lovrBoneWeights;\n in uint lovrDrawID;\n out vec2 texCoord;\n out vec4 vertexColor;\n out vec4 lovrColor;\n uniform mat4 lovrModel;\n uniform mat4 lovrView;\n uniform mat4 lovrProjection;\n uniform mat4 lovrTransform; // Model-View matrix\n uniform mat3 lovrNormalMatrix; // Inverse-transpose of lovrModel\n uniform mat3 lovrMaterialTransform;\n uniform float lovrPointSize;\n uniform mat4 lovrPose[48];\n uniform int lovrViewportCount;\n uniform int lovrViewID;\n const mat4 lovrPoseMatrix; // Bone-weighted pose\n const int lovrInstanceID; // Current instance ID\n\nFragment shader header:\n\n in vec2 texCoord;\n in vec4 vertexColor;\n in vec4 lovrColor;\n out vec4 lovrCanvas[gl_MaxDrawBuffers];\n uniform float lovrMetalness;\n uniform float lovrRoughness;\n uniform vec4 lovrDiffuseColor;\n uniform vec4 lovrEmissiveColor;\n uniform sampler2D lovrDiffuseTexture;\n uniform sampler2D lovrEmissiveTexture;\n uniform sampler2D lovrMetalnessTexture;\n uniform sampler2D lovrRoughnessTexture;\n uniform sampler2D lovrOcclusionTexture;\n uniform sampler2D lovrNormalTexture;\n uniform samplerCube lovrEnvironmentTexture;\n uniform int lovrViewportCount;\n uniform int lovrViewID;\n\n### Compute Shaders\n\nCompute shaders can be created with `lovr.graphics.newComputeShader` and run with `lovr.graphics.compute`. Currently, compute shaders are written with raw GLSL. There is no default compute shader, instead the `void compute();` function must be implemented.\n\nYou can use the `layout` qualifier to specify a local work group size:\n\n layout(local_size_x = X, local_size_y = Y, local_size_z = Z) in;\n\nAnd the following built in variables can be used:\n\n in uvec3 gl_NumWorkGroups; // The size passed to lovr.graphics.compute\n in uvec3 gl_WorkGroupSize; // The local work group size\n in uvec3 gl_WorkGroupID; // The current global work group\n in uvec3 gl_LocalInvocationID; // The current local work group\n in uvec3 gl_GlobalInvocationID; // A unique ID combining the global and local IDs\n in uint gl_LocalInvocationIndex; // A 1D index of the LocalInvocationID\n\nCompute shaders don't return anything but they can write data to `Texture`s or `ShaderBlock`s. To bind a texture in a way that can be written to a compute shader, declare the uniforms with a type of `image2D`, `imageCube`, etc. instead of the usual `sampler2D` or `samplerCube`. Once a texture is bound to an image uniform, you can use the `imageLoad` and `imageStore` GLSL functions to read and write pixels in the image. Variables in `ShaderBlock`s can be written to using assignment syntax.\n\nLÖVR handles synchronization of textures and shader blocks so there is no need to use manual memory barriers to synchronize writes to resources from compute shaders.",
methods = {
{
name = "getType",
summary = "Get the type of the Shader.",
description = "Returns the type of the Shader, which will be \"graphics\" or \"compute\".\n\nGraphics shaders are created with `lovr.graphics.newShader` and can be used for rendering with `lovr.graphics.setShader`. Compute shaders are created with `lovr.graphics.newComputeShader` and can be run using `lovr.graphics.compute`.",
key = "Shader:getType",
module = "lovr.graphics",
related = {
"ShaderType"
},
variants = {
{
arguments = {},
returns = {
{
name = "type",
type = "ShaderType",
description = "The type of the Shader."
}
}
}
}
},
{
name = "hasUniform",
summary = "Check if a Shader has a uniform variable.",
description = "Returns whether a Shader has a particular uniform variable.",
key = "Shader:hasUniform",
module = "lovr.graphics",
notes = "If a uniform variable is defined but unused in the shader, the shader compiler will optimize it out and the uniform will not report itself as present.",
variants = {
{
arguments = {
{
name = "uniform",
type = "string",
description = "The name of the uniform variable."
}
},
returns = {
{
name = "present",
type = "boolean",
description = "Whether the shader has the specified uniform."
}
}
}
}
},
{
name = "send",
summary = "Update a uniform variable in the Shader.",
description = "Updates a uniform variable in the Shader.",
key = "Shader:send",
module = "lovr.graphics",
variants = {
{
arguments = {
{
name = "uniform",
type = "string",
description = "The name of the uniform to update."
},
{
name = "value",
type = "*",
description = "The new value of the uniform."
}
},
returns = {}
}
},
notes = "The shader does not need to be active to update its uniforms.\n\nThe following type combinations are supported:\n\n
\n \n
\n
Uniform type
\n
LÖVR type
\n
\n \n \n
\n
float
\n
number
\n
\n
\n
int
\n
number
\n
\n
\n
vec2
\n
{ x, y }
\n
\n
\n
vec3
\n
{ x, y, z } or vec3
\n
\n
\n
vec4
\n
{ x, y, z, w }
\n
\n
\n
ivec2
\n
{ x, y }
\n
\n
\n
ivec3
\n
{ x, y, z }
\n
\n
\n
ivec4
\n
{ x, y, z, w }
\n
\n
\n
mat2
\n
{ x, ... }
\n
\n
\n
mat3
\n
{ x, ... }
\n
\n
\n
mat4
\n
{ x, ... } or mat4
\n
\n
\n
sampler
\n
Texture
\n
\n
\n
image
\n
Texture
\n
\n
\n\nUniform arrays can be wrapped in tables or passed as multiple arguments.\n\nTextures must match the type of sampler or image they are being sent to.\n\nThe following sampler (and image) types are currently supported:\n\n- `sampler2D`\n- `sampler3D`\n- `samplerCube`\n- `sampler2DArray`\n\nAn error is thrown if the uniform does not exist or is not used in the shader. The `Shader:hasUniform` function can be used to check if a uniform variable exists.\n\n`Blob`s can be used to pass arbitrary binary data to Shader variables.",
related = {
"ShaderBlock:send",
"Shader:sendBlock"
},
examples = {
{
description = "Updating a `vec3` uniform:",
code = "function lovr.load()\n shader = lovr.graphics.newShader([[\n uniform vec3 offset;\n vec4 position(mat4 projection, mat4 transform, vec4 vertex) {\n vertex.xyz += offset;\n return projection * transform * vertex;\n }\n ]], nil)\n\n shader:send('offset', { .3, .7, 0 })\nend"
}
}
},
{
name = "sendBlock",
summary = "Send a ShaderBlock to a Shader.",
description = "Sends a ShaderBlock to a Shader. After the block is sent, you can update the data in the block without needing to resend the block. The block can be sent to multiple shaders and they will all see the same data from the block.",
key = "Shader:sendBlock",
module = "lovr.graphics",
notes = "The Shader does not need to be active to send it a block.\n\nMake sure the ShaderBlock's variables line up with the block variables declared in the shader code, otherwise you'll get garbage data in the block. An easy way to do this is to use `ShaderBlock:getShaderCode` to get a GLSL snippet that is compatible with the block.",
variants = {
{
arguments = {
{
name = "name",
type = "string",
description = "The name of the block to send to."
},
{
name = "block",
type = "ShaderBlock",
description = "The ShaderBlock to associate with the specified block."
},
{
name = "access",
type = "UniformAccess",
description = "How the Shader will use this block (used as an optimization hint).",
default = "readwrite"
}
},
returns = {}
}
},
related = {
"Shader:send",
"ShaderBlock:send",
"ShaderBlock:getShaderCode",
"UniformAccess",
"ShaderBlock"
}
},
{
name = "sendImage",
summary = "Send a Texture to a Shader for writing.",
description = "Sends a Texture to a Shader for writing. This is meant to be used with compute shaders and only works with uniforms declared as `image2D`, `imageCube`, `image2DArray`, and `image3D`. The normal `Shader:send` function accepts Textures and should be used most of the time.",
key = "Shader:sendImage",
module = "lovr.graphics",
related = {
"Shader:send",
"ShaderBlock:send",
"ShaderBlock:getShaderCode",
"UniformAccess",
"ShaderBlock"
},
variants = {
{
arguments = {
{
name = "name",
type = "string",
description = "The name of the image uniform."
},
{
name = "slice",
type = "number",
description = "The slice of a cube, array, or volume texture to use, or `nil` for all slices.",
default = "nil"
},
{
name = "mipmap",
type = "number",
description = "The mipmap of the texture to use.",
default = "1"
},
{
name = "access",
type = "UniformAccess",
description = "Whether the image will be read from, written to, or both.",
default = "readwrite"
}
},
returns = {}
},
{
arguments = {
{
name = "name",
type = "string",
description = "The name of the image uniform."
},
{
name = "index",
type = "number",
description = "The array index to set."
},
{
name = "slice",
type = "number",
description = "The slice of a cube, array, or volume texture to use, or `nil` for all slices.",
default = "nil"
},
{
name = "mipmap",
type = "number",
description = "The mipmap of the texture to use.",
default = "1"
},
{
name = "access",
type = "UniformAccess",
description = "Whether the image will be read from, written to, or both.",
default = "readwrite"
}
},
returns = {}
}
}
}
}
},
{
name = "ShaderBlock",
summary = "A big ol' block of data that can be sent to a Shader.",
description = "ShaderBlocks are objects that can hold large amounts of data and can be sent to Shaders. It is common to use \"uniform\" variables to send data to shaders, but uniforms are usually limited to a few kilobytes in size. ShaderBlocks are useful for a few reasons:\n\n- They can hold a lot more data.\n- Shaders can modify the data in them, which is really useful for compute shaders.\n- Setting the data in a ShaderBlock updates the data for all Shaders using the block, so you\n don't need to go around setting the same uniforms in lots of different shaders.\n\nOn systems that support compute shaders, ShaderBlocks can optionally be \"writable\". A writable ShaderBlock is a little bit slower than a non-writable one, but shaders can modify its contents and it can be much, much larger than a non-writable ShaderBlock.",
key = "ShaderBlock",
module = "lovr.graphics",
constructors = {
"lovr.graphics.newShaderBlock"
},
examples = {
{
code = "function lovr.load()\n -- Create a ShaderBlock to store positions for 1000 models\n block = lovr.graphics.newShaderBlock('uniform', {\n modelPositions = { 'mat4', 1000 }\n }, { usage = 'static' })\n\n -- Write some random transforms to the block\n local transforms = {}\n for i = 1, 1000 do\n transforms[i] = lovr.math.mat4()\n local random, randomNormal = lovr.math.random, lovr.math.randomNormal\n transforms[i]:translate(randomNormal(8), randomNormal(8), randomNormal(8))\n transforms[i]:rotate(random(2 * math.pi), random(), random(), random())\n end\n block:send('modelPositions', transforms)\n\n -- Create the shader, injecting the shader code for the block\n shader = lovr.graphics.newShader(\n block:getShaderCode('ModelBlock') .. [[\n vec4 position(mat4 projection, mat4 transform, vec4 vertex) {\n return projection * transform * modelPositions[gl_InstanceID] * vertex;\n }\n ]])\n\n -- Bind the block to the shader\n shader:sendBlock('ModelBlock', block)\n model = lovr.graphics.newModel('monkey.obj')\nend\n\n-- Draw the model 1000 times, using positions from the shader block\nfunction lovr.draw()\n lovr.graphics.setShader(shader)\n model:draw(lovr.math.mat4(), 1000)\n lovr.graphics.setShader()\nend"
}
},
notes = "- A Shader can use up to 8 ShaderBlocks.\n- ShaderBlocks can not contain textures.\n- Some systems have bugs with `vec3` variables in ShaderBlocks. If you run into strange bugs,\n try switching to a `vec4` for the variable.",
methods = {
{
name = "getOffset",
summary = "Get the byte offset of a variable in the ShaderBlock.",
description = "Returns the byte offset of a variable in a ShaderBlock. This is useful if you want to manually send binary data to the ShaderBlock using a `Blob` in `ShaderBlock:send`.",
key = "ShaderBlock:getOffset",
module = "lovr.graphics",
related = {
"ShaderBlock:getSize",
"lovr.graphics.newShaderBlock"
},
variants = {
{
arguments = {
{
name = "field",
type = "string",
description = "The name of the variable to get the offset of."
}
},
returns = {
{
name = "offset",
type = "number",
description = "The byte offset of the variable."
}
}
}
}
},
{
name = "getShaderCode",
summary = "Get a GLSL string that defines the ShaderBlock in a Shader.",
description = "Before a ShaderBlock can be used in a Shader, the Shader has to have the block's variables defined in its source code. This can be a tedious process, so you can call this function to return a GLSL string that contains this definition. Roughly, it will look something like this:\n\n uniform