bjorn 7 years ago
parent
commit
07ff9fd74d
99 changed files with 2168 additions and 275 deletions
  1. 742 47
      api/init.lua
  2. 37 0
      api/lovr/audio/Source/getCone.lua
  3. 0 0
      api/lovr/audio/Source/getDirection.lua
  4. 31 0
      api/lovr/audio/Source/getFalloff.lua
  5. 4 1
      api/lovr/audio/Source/getPosition.lua
  6. 25 0
      api/lovr/audio/Source/getVelocity.lua
  7. 21 0
      api/lovr/audio/Source/getVolumeLimits.lua
  8. 15 0
      api/lovr/audio/Source/isRelative.lua
  9. 37 0
      api/lovr/audio/Source/setCone.lua
  10. 0 0
      api/lovr/audio/Source/setDirection.lua
  11. 31 0
      api/lovr/audio/Source/setFalloff.lua
  12. 6 1
      api/lovr/audio/Source/setPosition.lua
  13. 15 0
      api/lovr/audio/Source/setRelative.lua
  14. 25 0
      api/lovr/audio/Source/setVelocity.lua
  15. 21 0
      api/lovr/audio/Source/setVolumeLimits.lua
  16. 30 0
      api/lovr/audio/getDopplerEffect.lua
  17. 1 1
      api/lovr/audio/getPosition.lua
  18. 27 0
      api/lovr/audio/getVelocity.lua
  19. 16 0
      api/lovr/audio/isSpatialized.lua
  20. 30 0
      api/lovr/audio/setDopplerEffect.lua
  21. 1 1
      api/lovr/audio/setPosition.lua
  22. 27 0
      api/lovr/audio/setVelocity.lua
  23. 17 0
      api/lovr/callbacks/conf.lua
  24. 23 0
      api/lovr/callbacks/controllerpressed.lua
  25. 23 0
      api/lovr/callbacks/controllerreleased.lua
  26. 28 0
      api/lovr/callbacks/errhand.lua
  27. 19 0
      api/lovr/callbacks/focus.lua
  28. 1 1
      api/lovr/callbacks/load.lua
  29. 1 0
      api/lovr/callbacks/run.lua
  30. 15 0
      api/lovr/filesystem/Blob/getFilename.lua
  31. 15 0
      api/lovr/filesystem/Blob/getPointer.lua
  32. 14 0
      api/lovr/filesystem/Blob/getSize.lua
  33. 19 0
      api/lovr/filesystem/Blob/getString.lua
  34. 11 0
      api/lovr/filesystem/Blob/init.lua
  35. 18 0
      api/lovr/filesystem/createDirectory.lua
  36. 15 0
      api/lovr/filesystem/getAppdataDirectory.lua
  37. 18 0
      api/lovr/filesystem/getDirectoryItems.lua
  38. 18 0
      api/lovr/filesystem/getLastModified.lua
  39. 12 0
      api/lovr/filesystem/getSaveDirectory.lua
  40. 18 0
      api/lovr/filesystem/getSize.lua
  41. 1 1
      api/lovr/filesystem/getUserDirectory.lua
  42. 12 0
      api/lovr/filesystem/isFused.lua
  43. 31 0
      api/lovr/filesystem/load.lua
  44. 43 0
      api/lovr/filesystem/mount.lua
  45. 25 0
      api/lovr/filesystem/newBlob.lua
  46. 19 0
      api/lovr/filesystem/remove.lua
  47. 21 0
      api/lovr/filesystem/unmount.lua
  48. 13 0
      api/lovr/getOS.lua
  49. 28 0
      api/lovr/graphics/BlendAlphaMode.lua
  50. 54 0
      api/lovr/graphics/BlendMode.lua
  51. 0 14
      api/lovr/graphics/Buffer/getDrawMode.lua
  52. 0 12
      api/lovr/graphics/Buffer/getTexture.lua
  53. 0 22
      api/lovr/graphics/Buffer/getVertex.lua
  54. 0 13
      api/lovr/graphics/Buffer/getVertexCount.lua
  55. 0 12
      api/lovr/graphics/Buffer/setDrawMode.lua
  56. 0 23
      api/lovr/graphics/BufferUsage.lua
  57. 15 0
      api/lovr/graphics/Font/getAscent.lua
  58. 15 0
      api/lovr/graphics/Font/getBaseline.lua
  59. 16 0
      api/lovr/graphics/Font/getDescent.lua
  60. 15 0
      api/lovr/graphics/Font/getHeight.lua
  61. 15 0
      api/lovr/graphics/Font/getPixelDensity.lua
  62. 27 0
      api/lovr/graphics/Font/getWidth.lua
  63. 15 0
      api/lovr/graphics/Font/setPixelDensity.lua
  64. 7 7
      api/lovr/graphics/Mesh/draw.lua
  65. 14 0
      api/lovr/graphics/Mesh/getDrawMode.lua
  66. 3 3
      api/lovr/graphics/Mesh/getDrawRange.lua
  67. 12 0
      api/lovr/graphics/Mesh/getTexture.lua
  68. 22 0
      api/lovr/graphics/Mesh/getVertex.lua
  69. 3 3
      api/lovr/graphics/Mesh/getVertexAttribute.lua
  70. 13 0
      api/lovr/graphics/Mesh/getVertexCount.lua
  71. 2 2
      api/lovr/graphics/Mesh/getVertexFormat.lua
  72. 3 3
      api/lovr/graphics/Mesh/getVertexMap.lua
  73. 21 21
      api/lovr/graphics/Mesh/init.lua
  74. 21 0
      api/lovr/graphics/Mesh/isAttributeEnabled.lua
  75. 19 0
      api/lovr/graphics/Mesh/setAttributeEnabled.lua
  76. 12 0
      api/lovr/graphics/Mesh/setDrawMode.lua
  77. 3 3
      api/lovr/graphics/Mesh/setDrawRange.lua
  78. 2 2
      api/lovr/graphics/Mesh/setTexture.lua
  79. 5 5
      api/lovr/graphics/Mesh/setVertex.lua
  80. 3 3
      api/lovr/graphics/Mesh/setVertexAttribute.lua
  81. 2 2
      api/lovr/graphics/Mesh/setVertexMap.lua
  82. 3 3
      api/lovr/graphics/Mesh/setVertices.lua
  83. 2 2
      api/lovr/graphics/MeshDrawMode.lua
  84. 23 0
      api/lovr/graphics/MeshUsage.lua
  85. 2 3
      api/lovr/graphics/Model/init.lua
  86. 2 2
      api/lovr/graphics/Texture/init.lua
  87. 25 0
      api/lovr/graphics/getBlendMode.lua
  88. 33 0
      api/lovr/graphics/getSystemLimits.lua
  89. 16 16
      api/lovr/graphics/newMesh.lua
  90. 2 3
      api/lovr/graphics/newModel.lua
  91. 9 0
      api/lovr/graphics/newSkybox.lua
  92. 24 9
      api/lovr/graphics/print.lua
  93. 3 0
      api/lovr/graphics/rotate.lua
  94. 2 0
      api/lovr/graphics/scale.lua
  95. 25 0
      api/lovr/graphics/setBlendMode.lua
  96. 0 28
      api/lovr/graphics/setProjection.lua
  97. 13 0
      api/lovr/headset/isMirrored.lua
  98. 13 0
      api/lovr/headset/setMirrored.lua
  99. 12 6
      guides/3D_Models.md

File diff suppressed because it is too large
+ 742 - 47
api/init.lua


+ 37 - 0
api/lovr/audio/Source/getCone.lua

@@ -0,0 +1,37 @@
+return {
+  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 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.
+  ]],
+  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.'
+    }
+  },
+  notes = [[
+    The default `innerAngle` for a Source is `0`.
+
+    The default `outerAngle` for a Source is `2 * math.pi`.
+
+    The default `outerVolume` for a Source is `0`.
+
+    Make sure to set the direction of a Source before setting its cone.
+  ]]
+}

+ 0 - 0
api/lovr/audio/Source/getOrientation.lua → api/lovr/audio/Source/getDirection.lua


+ 31 - 0
api/lovr/audio/Source/getFalloff.lua

@@ -0,0 +1,31 @@
+return {
+  summary = 'Get the falloff parameters for the Source.',
+  description = [[
+    Returns parameters that control how the volume of the Source falls of with distance.
+  ]],
+  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).
+      ]]
+    }
+  },
+  related = {
+    'Source:getVolumeLimits',
+    'Source:setVolumeLimits'
+  }
+}

+ 4 - 1
api/lovr/audio/Source/getPosition.lua

@@ -1,6 +1,9 @@
 return {
 return {
   summary = 'Get the position of the Source.',
   summary = 'Get the position of the Source.',
-  description = 'Returns the position of the Source in space.',
+  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.
+  ]],
   arguments = {},
   arguments = {},
   returns = {
   returns = {
     {
     {

+ 25 - 0
api/lovr/audio/Source/getVelocity.lua

@@ -0,0 +1,25 @@
+return {
+  summary = 'Get the velocity of the Source.',
+  description = [[
+    Returns the velocity of the Source, in meters per second.  This affects the doppler effect.
+  ]],
+  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.'
+    }
+  },
+  notes = 'The Source does not move based on its velocity.'
+}

+ 21 - 0
api/lovr/audio/Source/getVolumeLimits.lua

@@ -0,0 +1,21 @@
+return {
+  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.
+  ]],
+  arguments = {},
+  returns = {
+    {
+      name = 'min',
+      type = 'number',
+      description = 'The minimum volume of the Source.'
+    },
+    {
+      name = 'max',
+      type = 'number',
+      description = 'The maximum volume of the Source.'
+    }
+  }
+}

+ 15 - 0
api/lovr/audio/Source/isRelative.lua

@@ -0,0 +1,15 @@
+return {
+  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 direction are all relative to the audio listener.
+  ]],
+  arguments = {},
+  returns = {
+    {
+      name = 'relative',
+      type = 'boolean',
+      description = 'Whether or not the Source is relative.'
+    }
+  }
+}

+ 37 - 0
api/lovr/audio/Source/setCone.lua

@@ -0,0 +1,37 @@
+return {
+  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.
+  ]],
+  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 = {},
+  notes = [[
+    The default `innerAngle` for a Source is `0`.
+
+    The default `outerAngle` for a Source is `2 * math.pi`.
+
+    The default `outerVolume` for a Source is `0`.
+
+    Make sure to set the direction of a Source before setting its cone.
+  ]]
+}

+ 0 - 0
api/lovr/audio/Source/setOrientation.lua → api/lovr/audio/Source/setDirection.lua


+ 31 - 0
api/lovr/audio/Source/setFalloff.lua

@@ -0,0 +1,31 @@
+return {
+  summary = 'Set the falloff parameters for the Source.',
+  description = [[
+    Sets parameters that control how the volume of the Source falls of with distance.
+  ]],
+  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 = {},
+  related = {
+    'Source:getVolumeLimits',
+    'Source:setVolumeLimits'
+  }
+}

+ 6 - 1
api/lovr/audio/Source/setPosition.lua

@@ -1,6 +1,11 @@
 return {
 return {
   summary = 'Set the position of the Source.',
   summary = 'Set the position of the Source.',
-  description = 'Sets the position of the Source in space.',
+  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.
+
+    Only mono sources can be positioned.
+  ]],
   arguments = {
   arguments = {
     {
     {
       name = 'x',
       name = 'x',

+ 15 - 0
api/lovr/audio/Source/setRelative.lua

@@ -0,0 +1,15 @@
+return {
+  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 direction are all relative to the audio listener.
+  ]],
+  arguments = {
+    {
+      name = 'relative',
+      type = 'boolean',
+      description = 'Whether or not the Source is relative.'
+    }
+  },
+  returns = {}
+}

+ 25 - 0
api/lovr/audio/Source/setVelocity.lua

@@ -0,0 +1,25 @@
+return {
+  summary = 'Set the velocity of the Source.',
+  description = [[
+    Sets the velocity of the Source, in meters per second.  This affects the doppler effect.
+  ]],
+  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 = {},
+  notes = 'The Source does not move based on its velocity.'
+}

+ 21 - 0
api/lovr/audio/Source/setVolumeLimits.lua

@@ -0,0 +1,21 @@
+return {
+  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.
+  ]],
+  arguments = {
+    {
+      name = 'min',
+      type = 'number',
+      description = 'The minimum volume of the Source.'
+    },
+    {
+      name = 'max',
+      type = 'number',
+      description = 'The maximum volume of the Source.'
+    }
+  },
+  returns = {}
+}

+ 30 - 0
api/lovr/audio/getDopplerEffect.lua

@@ -0,0 +1,30 @@
+return {
+  tag = 'listener',
+  summary = 'Get the doppler effect settings.',
+  description = [[
+    Returns the parameters for the doppler effect.  The speed of sound and the intensity of the
+    effect can be controlled.
+
+    The doppler effect changes the pitch of Sources based on their relative velocity to the
+    listener.
+  ]],
+  arguments = {},
+  returns = {
+    {
+      name = 'factor',
+      type = 'number',
+      description = 'How intense the doppler factor is.'
+    },
+    {
+      name = 'speedOfSound',
+      type = 'number',
+      description = 'The speed of virtual sound, in meters per second.'
+    }
+  },
+  related = {
+    'lovr.audio.getVelocity',
+    'lovr.audio.setVelocity',
+    'Source:getVelocity',
+    'Source:setVelocity'
+  }
+}

+ 1 - 1
api/lovr/audio/getPosition.lua

@@ -1,7 +1,7 @@
 return {
 return {
   tag = 'listener',
   tag = 'listener',
   summary = 'Get the position of the listener.',
   summary = 'Get the position of the listener.',
-  description = 'Returns the position of the virtual audio listener.',
+  description = 'Returns the position of the virtual audio listener, in meters.',
   arguments = {},
   arguments = {},
   returns = {
   returns = {
     {
     {

+ 27 - 0
api/lovr/audio/getVelocity.lua

@@ -0,0 +1,27 @@
+return {
+  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.
+  ]],
+  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.'
+    }
+  },
+  notes = 'The audio listener does not move based on its velocity.'
+}

+ 16 - 0
api/lovr/audio/isSpatialized.lua

@@ -0,0 +1,16 @@
+return {
+  tag = 'listener',
+  summary = 'Check if audio is spatialized.',
+  description = [[
+    Returns whether or not audio is currently spatialized with HRTFs.  Spatialized audio is much
+    more immersive.
+  ]],
+  arguments = {},
+  returns = {
+    {
+      name = 'spatialized',
+      type = 'boolean',
+      description = 'Whether or not audio is spatialized.'
+    }
+  }
+}

+ 30 - 0
api/lovr/audio/setDopplerEffect.lua

@@ -0,0 +1,30 @@
+return {
+  tag = 'listener',
+  summary = 'Set the doppler effect.',
+  description = [[
+    Sets parameters for the doppler effect.  The speed of sound and the intensity of the
+    effect can be controlled.
+
+    The doppler effect changes the pitch of Sources based on their relative velocity to the
+    listener.
+  ]],
+  arguments = {
+    {
+      name = 'factor',
+      type = 'number',
+      description = 'How intense the doppler factor is.'
+    },
+    {
+      name = 'speedOfSound',
+      type = 'number',
+      description = 'The speed of virtual sound, in meters per second.'
+    }
+  },
+  returns = {},
+  related = {
+    'lovr.audio.getVelocity',
+    'lovr.audio.setVelocity',
+    'Source:getVelocity',
+    'Source:setVelocity'
+  }
+}

+ 1 - 1
api/lovr/audio/setPosition.lua

@@ -1,7 +1,7 @@
 return {
 return {
   tag = 'listener',
   tag = 'listener',
   summary = 'Set the position of the listener.',
   summary = 'Set the position of the listener.',
-  description = 'Sets the position of the virtual audio listener.',
+  description = 'Sets the position of the virtual audio listener, in meters.',
   arguments = {
   arguments = {
     {
     {
       name = 'x',
       name = 'x',

+ 27 - 0
api/lovr/audio/setVelocity.lua

@@ -0,0 +1,27 @@
+return {
+  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.
+  ]],
+  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 = {},
+  notes = 'The audio listener does not move based on its velocity.'
+}

+ 17 - 0
api/lovr/callbacks/conf.lua

@@ -17,6 +17,20 @@ return {
           type = 'string',
           type = 'string',
           description = 'A unique label for this project.'
           description = 'A unique label for this project.'
         },
         },
+        {
+          name = 'headset',
+          type = 'table',
+          description = 'Configuration for the headset.',
+          table = {
+            {
+              name = 'mirrored',
+              type = 'boolean',
+              description = [[
+                Whether the desktop window should display a mirror of what's in the headset.
+              ]]
+            }
+          }
+        },
         {
         {
           name = 'modules',
           name = 'modules',
           type = 'table',
           type = 'table',
@@ -74,6 +88,9 @@ return {
           -- Set the project identity
           -- Set the project identity
           t.identity = 'default'
           t.identity = 'default'
 
 
+          -- Headset settings
+          t.headset.mirror = true -- Mirror the headset to the desktop
+
           -- Enable or disable different modules
           -- Enable or disable different modules
           t.modules.audio = true
           t.modules.audio = true
           t.modules.event = true
           t.modules.event = true

+ 23 - 0
api/lovr/callbacks/controllerpressed.lua

@@ -0,0 +1,23 @@
+return {
+  tag = 'callbacks',
+  summary = 'Called when a Controller button is pressed.',
+  description = 'This callback is called when a button on a Controller is pressed.',
+  arguments = {
+    {
+      name = 'controller',
+      type = 'Controller',
+      description = 'The new controller object.'
+    },
+    {
+      name = 'button',
+      type = 'ControllerButton',
+      description = 'The button that was pressed.'
+    }
+  },
+  returns = {},
+  related = {
+    'lovr.controllerreleased',
+    'Controller:isDown',
+    'ControllerButton'
+  }
+}

+ 23 - 0
api/lovr/callbacks/controllerreleased.lua

@@ -0,0 +1,23 @@
+return {
+  tag = 'callbacks',
+  summary = 'Called when a Controller button is released.',
+  description = 'This callback is called when a button on a Controller is released.',
+  arguments = {
+    {
+      name = 'controller',
+      type = 'Controller',
+      description = 'The new controller object.'
+    },
+    {
+      name = 'button',
+      type = 'ControllerButton',
+      description = 'The button that was released.'
+    }
+  },
+  returns = {},
+  related = {
+    'lovr.controllerpressed',
+    'Controller:isDown',
+    'ControllerButton'
+  }
+}

+ 28 - 0
api/lovr/callbacks/errhand.lua

@@ -0,0 +1,28 @@
+return {
+  tag = 'callbacks',
+  summary = 'Called when an error occurs.',
+  description = [[
+    The `lovr.errhand` callback is run whenever an error occurs.  It receives a single string
+    parameter containing the error message.
+
+    The program exits after this callback returns.
+
+    A default error handler is supplied that renders the error message as text in a loop.
+  ]],
+  arguments = {
+    {
+      name = 'message',
+      type = 'string',
+      description = 'The error message.'
+    }
+  },
+  returns = {},
+  example = [[
+    function lovr.errhand(message)
+      print('ohh NOOOO!', message)
+    end
+  ]],
+  related = {
+    'lovr.quit'
+  }
+}

+ 19 - 0
api/lovr/callbacks/focus.lua

@@ -0,0 +1,19 @@
+return {
+  tag = 'callbacks',
+  summary = 'Called when the application gets or loses focus.',
+  description = [[
+    The `lovr.focus` callback is called whenever the application acquires or loses focus (for
+    example, when opening or closing the Steam dashboard).  The callback receives a single argument,
+    focused, which is a boolean indicating whether or not the application is now focused.  It may
+    make sense to pause the game or reduce visual fidelity when the application loses focus.
+  ]],
+  arguments = {
+    {
+      name = 'focused',
+      type = 'boolean',
+      description = 'Whether the program is now focused.'
+    }
+  },
+  returns = {},
+  related = {}
+}

+ 1 - 1
api/lovr/callbacks/load.lua

@@ -17,7 +17,7 @@ return {
     function lovr.load(args)
     function lovr.load(args)
       model = lovr.graphics.newModel('cena.fbx')
       model = lovr.graphics.newModel('cena.fbx')
       texture = lovr.graphics.newTexture('cena.png')
       texture = lovr.graphics.newTexture('cena.png')
-      levelGeometry = lovr.graphics.newBuffer(1000)
+      levelGeometry = lovr.graphics.newMesh(1000)
       effects = lovr.graphics.newShader('vert.glsl', 'frag.glsl')
       effects = lovr.graphics.newShader('vert.glsl', 'frag.glsl')
       loadLevel(1)
       loadLevel(1)
     end
     end

+ 1 - 0
api/lovr/callbacks/run.lua

@@ -33,6 +33,7 @@ return {
             if lovr.headset and lovr.headset.isPresent() then
             if lovr.headset and lovr.headset.isPresent() then
               lovr.audio.setPosition(lovr.headset.getPosition())
               lovr.audio.setPosition(lovr.headset.getPosition())
               lovr.audio.setOrientation(lovr.headset.getOrientation())
               lovr.audio.setOrientation(lovr.headset.getOrientation())
+              lovr.audio.setVelocity(lovr.headset.getVelocity())
             end
             end
           end
           end
 
 

+ 15 - 0
api/lovr/filesystem/Blob/getFilename.lua

@@ -0,0 +1,15 @@
+return {
+  summary = 'Get the file the Blob was loaded from.',
+  description = [[
+    Returns the name of the file used to load the Blob, or the custom name given to it when it was
+    created.
+  ]],
+  arguments = {},
+  returns = {
+    {
+      name = 'filename',
+      type = 'string',
+      description = 'The name of the Blob.'
+    }
+  }
+}

+ 15 - 0
api/lovr/filesystem/Blob/getPointer.lua

@@ -0,0 +1,15 @@
+return {
+  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!
+  ]],
+  arguments = {},
+  returns = {
+    {
+      name = 'pointer',
+      type = 'userdata',
+      description = 'A pointer to the data.'
+    }
+  }
+}

+ 14 - 0
api/lovr/filesystem/Blob/getSize.lua

@@ -0,0 +1,14 @@
+return {
+  summary = 'Get the size of the Blob\'s data.',
+  description = [[
+    Returns the size of the Blob's contents, in bytes.
+  ]],
+  arguments = {},
+  returns = {
+    {
+      name = 'bytes',
+      type = 'number',
+      description = 'The size of the Blob, in bytes.'
+    }
+  }
+}

+ 19 - 0
api/lovr/filesystem/Blob/getString.lua

@@ -0,0 +1,19 @@
+return {
+  summary = 'Get the Blob\'s contents as a string.',
+  description = 'Returns a binary string containing the Blob\'s data.',
+  arguments = {},
+  returns = {
+    {
+      name = 'data',
+      type = 'string',
+      description = 'The Blob\'s data.'
+    }
+  },
+  example = {
+    description = 'Manually copy a file using Blobs:',
+    code = [[
+      blob = lovr.filesystem.newBlob('image.png')
+      lovr.filesystem.write('copy.png', blob:getString())
+    ]]
+  }
+}

+ 11 - 0
api/lovr/filesystem/Blob/init.lua

@@ -0,0 +1,11 @@
+return {
+  summary = 'A loaded file object.',
+  description = [[
+    A Blob is an object that loads and holds the contents of a file.  It can be passed to most
+    functions that take filename arguments, like `lovr.graphics.newModel` or `lovr.audio.newSource`.
+    Loading many objects this way is often faster because the file data only needs to be read once
+    and can be reused.  It can also be useful if file data is retrieved from some non-filesystem
+    source, such as a network request.
+  ]],
+  constructor = 'lovr.filesystem.newBlob'
+}

+ 18 - 0
api/lovr/filesystem/createDirectory.lua

@@ -0,0 +1,18 @@
+return {
+  summary = 'Create a directory.',
+  description = 'Creates a directory in the save directory.',
+  arguments = {
+    {
+      name = 'path',
+      type = 'string',
+      description = 'The directory to create.'
+    }
+  },
+  returns = {
+    {
+      name = 'success',
+      type = 'boolean',
+      description = 'Whether the directory was created.'
+    }
+  }
+}

+ 15 - 0
api/lovr/filesystem/getAppdataDirectory.lua

@@ -0,0 +1,15 @@
+return {
+  summary = 'Get the application data directory.',
+  description = [[
+    Returns the application data directory.  This will be something like `C:\Users\user\AppData` on
+    Windows, or `/Users/user/Library/Application Support` on macOS.
+  ]],
+  arguments = {},
+  returns = {
+    {
+      name = 'path',
+      type = 'string',
+      description = 'The absolute path to the appdata directory.'
+    }
+  }
+}

+ 18 - 0
api/lovr/filesystem/getDirectoryItems.lua

@@ -0,0 +1,18 @@
+return {
+  summary = 'Get a list of files in a directory..',
+  description = 'Returns an unsorted table containing all files and subfolders in a directory.',
+  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.'
+    }
+  }
+}

+ 18 - 0
api/lovr/filesystem/getLastModified.lua

@@ -0,0 +1,18 @@
+return {
+  summary = 'Get the modification time of a file.',
+  description = 'Returns when a file was last modified.',
+  arguments = {
+    {
+      name = 'file',
+      type = 'string',
+      description = 'The file.'
+    }
+  },
+  returns = {
+    {
+      name = 'time',
+      type = 'number',
+      description = 'The time when the file was last modified, in seconds.'
+    }
+  }
+}

+ 12 - 0
api/lovr/filesystem/getSaveDirectory.lua

@@ -0,0 +1,12 @@
+return {
+  summary = 'Get the location of the save directory.',
+  description = 'Returns the absolute path to the save directory.',
+  arguments = {},
+  returns = {
+    {
+      name = 'path',
+      type = 'string',
+      description = 'The absolute path to the save directory.'
+    }
+  }
+}

+ 18 - 0
api/lovr/filesystem/getSize.lua

@@ -0,0 +1,18 @@
+return {
+  summary = 'Get the size of a file.',
+  description = 'Returns the size of a file, in bytes.',
+  arguments = {
+    {
+      name = 'file',
+      type = 'string',
+      description = 'The file.'
+    }
+  },
+  returns = {
+    {
+      name = 'size',
+      type = 'number',
+      description = 'The size of the file, in bytes.'
+    }
+  }
+}

+ 1 - 1
api/lovr/filesystem/getUserDirectory.lua

@@ -1,6 +1,6 @@
 return {
 return {
   summary = 'Get the location of the user\'s home directory.',
   summary = 'Get the location of the user\'s home directory.',
-  description = 'Get the absolute path of the user\'s home directory.',
+  description = 'Returns the absolute path of the user\'s home directory.',
   arguments = {},
   arguments = {},
   returns = {
   returns = {
     {
     {

+ 12 - 0
api/lovr/filesystem/isFused.lua

@@ -0,0 +1,12 @@
+return {
+  summary = 'Check if the project is fused.',
+  description = 'Returns whether the current project source is fused to the executable.',
+  arguments = {},
+  returns = {
+    {
+      name = 'fused',
+      type = 'boolean',
+      description = 'Whether or not the project is fused.'
+    }
+  }
+}

+ 31 - 0
api/lovr/filesystem/load.lua

@@ -0,0 +1,31 @@
+return {
+  summary = 'Load a file as Lua code.',
+  description = 'Load a file containing Lua code, returning a Lua chunk that can be run.',
+  arguments = {
+    {
+      name = 'filename',
+      type = 'string',
+      description = 'The file to load.'
+    }
+  },
+  returns = {
+    {
+      name = 'chunk',
+      type = 'function',
+      description = 'The runnable chunk.'
+    }
+  },
+  notes = 'An error is thrown if the file contains syntax errors.',
+  example = {
+    description = 'Safely loading code:',
+    code = [[
+      local success, chunk = pcall(lovr.filesystem.load, filename)
+      if not success then
+        print('Oh no! There was an error: ' .. tostring(chunk))
+      else
+        local success, result = pcall(chunk)
+        print(success, result)
+      end
+    ]]
+  }
+}

+ 43 - 0
api/lovr/filesystem/mount.lua

@@ -0,0 +1,43 @@
+return {
+  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.
+  ]],
+  arguments = {
+    {
+      name = 'path',
+      type = 'string',
+      description = 'The path to mount.'
+    },
+    {
+      name = 'mountpoint',
+      type = 'string',
+      default = [['/']],
+      description = 'The path in the virtual filesystem to mount to.'
+    },
+    {
+      name = 'append',
+      type = 'boolean',
+      default = 'false',
+      description = [[
+        Whether the archive will be added to the end or the beginning of the search path.
+      ]]
+    }
+  },
+  returns = {},
+  notes = [[
+    The `append` option lets you control the priority of the archive's files in the event of naming
+    collisions.
+  ]],
+  example = {
+    description = 'Mount `data.zip` with a file `images/background.png`:',
+    code = [[
+      lovr.filesystem.mount('data.zip', 'assets')
+      print(lovr.filesystem.exists('assets/images/background.png')) -- true
+    ]]
+  },
+  related = {
+    'lovr.filesystem.unmount'
+  }
+}

+ 25 - 0
api/lovr/filesystem/newBlob.lua

@@ -0,0 +1,25 @@
+return {
+  summary = 'Create a new Blob.',
+  description = 'Creates a new Blob from a file.',
+  arguments = {
+    filename = {
+      type = 'string',
+      description = 'The file to load.'
+    },
+    str = {
+      type = 'string',
+      description = 'A string containing the Blob\'s contents.'
+    },
+    name = {
+      type = 'string',
+      description = 'A name for the Blob (used in error messages)',
+    }
+  },
+  returns = {
+    {
+      name = 'blob',
+      type = 'Blob',
+      description = 'The new Blob.'
+    }
+  }
+}

+ 19 - 0
api/lovr/filesystem/remove.lua

@@ -0,0 +1,19 @@
+return {
+  summary = 'Remove a file or directory.',
+  description = 'Remove a file or directory in the save directory.',
+  arguments = {
+    {
+      name = 'path',
+      type = 'string',
+      description = 'The file or folder to remove..'
+    }
+  },
+  returns = {
+    {
+      name = 'success',
+      type = 'boolean',
+      description = 'Whether the path was removed.'
+    }
+  },
+  notes = 'A directory can only be removed if it is empty.'
+}

+ 21 - 0
api/lovr/filesystem/unmount.lua

@@ -0,0 +1,21 @@
+return {
+  summary = 'Unmount a mounted archive.',
+  description = 'Unmounts a directory or archive previously mounted with `lovr.filesystem.mount`.',
+  arguments = {
+    {
+      name = 'path',
+      type = 'string',
+      description = 'The path to unmount.'
+    }
+  },
+  returns = {
+    {
+      name = 'success',
+      type = 'boolean',
+      description = 'Whether the archive was unmounted.'
+    }
+  },
+  related = {
+    'lovr.filesystem.mount'
+  }
+}

+ 13 - 0
api/lovr/getOS.lua

@@ -0,0 +1,13 @@
+return {
+  tag = 'system',
+  summary = 'Get the current operating system.',
+  description = 'Returns the current operating system.',
+  arguments = {},
+  returns = {
+    {
+      name = 'os',
+      type = 'string',
+      description = 'Either "windows" or "macOS".'
+    }
+  }
+}

+ 28 - 0
api/lovr/graphics/BlendAlphaMode.lua

@@ -0,0 +1,28 @@
+return {
+  summary = 'Different ways of blending alpha.',
+  description = 'Different ways the alpha channel of pixels affects blending.',
+  values = {
+    {
+      name = 'alphamultiply',
+      description = 'Color channel values are multiplied by the alpha channel during blending.'
+    },
+    {
+      name = 'premultiplied',
+      description = [[
+        Color channels are not multiplied by the alpha channel.  This should be used if the pixels
+        being drawn have already been blended, or "pre-multiplied", by the alpha channel.
+      ]]
+    }
+  },
+  notes = [[
+    The premultiplied mode should be used if pixels being drawn have already been blended, or
+    "pre-multiplied", by the alpha channel.  This happens when rendering a framebuffer that contains
+    pixels with transparent alpha values, since the stored color values have already been faded by
+    alpha and don't need to be faded a second time with the alphamultiply blend mode.
+  ]],
+  related = {
+    'BlendMode',
+    'lovr.graphics.getBlendMode',
+    'lovr.graphics.setBlendMode'
+  }
+}

+ 54 - 0
api/lovr/graphics/BlendMode.lua

@@ -0,0 +1,54 @@
+return {
+  summary = 'Different blend modes.',
+  description = [[
+    Blend modes control how overlapping pixels are blended together, similar to layers in Photoshop.
+  ]],
+  values = {
+    {
+      name = 'alpha',
+      description = 'Normal blending where the alpha value controls how the colors are blended.'
+    },
+    {
+      name = 'add',
+      description = 'The incoming pixel color is added to the destination pixel color.'
+    },
+    {
+      name = 'subtract',
+      description = 'The incoming pixel color is subtracted from the destination pixel color.'
+    },
+    {
+      name = 'multiply',
+      description = [[
+        The color channels from the two pixel values are multiplied together to produce a result.
+      ]]
+    },
+    {
+      name = 'lighten',
+      description = [[
+        The maximum value from each color channel is used, resulting in a lightening effect.
+      ]]
+    },
+    {
+      name = 'darken',
+      description = [[
+        The minimum value from each color channel is used, resulting in a darkening effect.
+      ]]
+    },
+    {
+      name = 'screen',
+      description = [[
+        The opposite of multiply: The pixel values are inverted, multiplied, and inverted again,
+        resulting in a lightening effect.
+      ]]
+    },
+    {
+      name = 'replace',
+      description = 'The incoming pixel replaces the destination pixel.'
+    }
+  },
+  related = {
+    'BlendAlphaMode',
+    'lovr.graphics.getBlendMode',
+    'lovr.graphics.setBlendMode'
+  }
+}

+ 0 - 14
api/lovr/graphics/Buffer/getDrawMode.lua

@@ -1,14 +0,0 @@
-return {
-  summary = 'Get the draw mode of the Buffer.',
-  description = [[
-    Get the draw mode of the Buffer, which controls how the vertices are connected together.
-  ]],
-  arguments = {},
-  returns = {
-    {
-      name = 'mode',
-      type = 'BufferDrawMode',
-      description = 'The draw mode of the buffer.'
-    }
-  }
-}

+ 0 - 12
api/lovr/graphics/Buffer/getTexture.lua

@@ -1,12 +0,0 @@
-return {
-  summary = 'Get the Texture applied to the Buffer.',
-  description = 'Get the Texture applied to the Buffer.',
-  arguments = {},
-  returns = {
-    {
-      name = 'texture',
-      type = 'Texture',
-      description = 'The current texture applied to the Buffer.'
-    }
-  }
-}

+ 0 - 22
api/lovr/graphics/Buffer/getVertex.lua

@@ -1,22 +0,0 @@
-return {
-  summary = 'Get a single vertex in the Buffer.',
-  description = [[
-    Gets the data for a single vertex in the Buffer.  The set of data returned depends on the
-    Buffer's vertex format.  The default vertex format consists of 8 floating point numbers: the
-    vertex position, the vertex normal, and the texture coordinates.
-  ]],
-  arguments = {
-    {
-      name = 'index',
-      type = 'number',
-      description = 'The index of the vertex to retrieve.'
-    }
-  },
-  returns = {
-    {
-      name = '...',
-      type = 'number',
-      description = 'All attributes of the vertex.'
-    }
-  }
-}

+ 0 - 13
api/lovr/graphics/Buffer/getVertexCount.lua

@@ -1,13 +0,0 @@
-return {
-  summary = 'Get the number of vertices the Buffer can hold.',
-  description = 'Returns the maximum number of vertices the Buffer can hold.',
-  arguments = {},
-  returns = {
-    {
-      name = 'size',
-      type = 'number',
-      description = 'The number of vertices the Buffer can hold.'
-    }
-  },
-  notes = 'The size can only be set when creating the Buffer, and cannot be changed afterwards.'
-}

+ 0 - 12
api/lovr/graphics/Buffer/setDrawMode.lua

@@ -1,12 +0,0 @@
-return {
-  summary = 'Change the draw mode of the Buffer.',
-  description = 'Set a new draw mode for the Buffer.',
-  arguments = {
-    {
-      name = 'mode',
-      type = 'BufferDrawMode',
-      description = 'The new draw mode for the Buffer.'
-    }
-  },
-  returns = {}
-}

+ 0 - 23
api/lovr/graphics/BufferUsage.lua

@@ -1,23 +0,0 @@
-return {
-  summary = 'How a Buffer is going to be updated.',
-  description = [[
-    Buffers can have a usage hint, describing how they are planning on being updated.  Setting the
-    usage hint allows the graphics driver optimize how it handles the data in the Buffer.
-  ]],
-  values = {
-    {
-      name = 'static',
-      description = 'The buffer contents will rarely change.'
-    },
-    {
-      name = 'dynamic',
-      description = 'The buffer contents will change often.'
-    },
-    {
-      name = 'stream',
-      description = [[
-        The buffer contents will change constantly, potentially multiple times each frame.
-      ]]
-    }
-  }
-}

+ 15 - 0
api/lovr/graphics/Font/getAscent.lua

@@ -0,0 +1,15 @@
+return {
+  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`.
+  ]],
+  arguments = {},
+  returns = {
+    {
+      name = 'ascent',
+      type = 'number',
+      description = 'The ascent of the Font.'
+    }
+  }
+}

+ 15 - 0
api/lovr/graphics/Font/getBaseline.lua

@@ -0,0 +1,15 @@
+return {
+  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`.
+  ]],
+  arguments = {},
+  returns = {
+    {
+      name = 'baseline',
+      type = 'number',
+      description = 'The baseline of the Font.'
+    }
+  }
+}

+ 16 - 0
api/lovr/graphics/Font/getDescent.lua

@@ -0,0 +1,16 @@
+return {
+  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.
+  ]],
+  arguments = {},
+  returns = {
+    {
+      name = 'descent',
+      type = 'number',
+      description = 'The descent of the Font.'
+    }
+  }
+}

+ 15 - 0
api/lovr/graphics/Font/getHeight.lua

@@ -0,0 +1,15 @@
+return {
+  summary = 'Get the height of a line of text.',
+  description = [[
+    Returns the height of a line of text, in meters.  Units are in meters, see
+    `Font:setPixelDensity`.
+  ]],
+  arguments = {},
+  returns = {
+    {
+      name = 'height',
+      type = 'number',
+      description = 'The height of a rendered line of text.'
+    }
+  }
+}

+ 15 - 0
api/lovr/graphics/Font/getPixelDensity.lua

@@ -0,0 +1,15 @@
+return {
+  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.
+  ]],
+  arguments = {},
+  returns = {
+    {
+      name = 'pixelDensity',
+      type = 'number',
+      description = 'The current pixel density.'
+    }
+  }
+}

+ 27 - 0
api/lovr/graphics/Font/getWidth.lua

@@ -0,0 +1,27 @@
+return {
+  summary = 'Get the width of a line of text.',
+  description = [[
+    Returns the width of a string when rendered using the font, with an optional wrap.  To get the
+    correct units returned, make sure the pixel density is set with `Font:setPixelDensity`.
+  ]],
+  arguments = {
+    {
+      name = 'text',
+      type = 'string',
+      description = 'The text to get the width of.'
+    },
+    {
+      name = 'wrap',
+      type = 'number',
+      default = '0',
+      description = 'The width at which to wrap lines, or 0 for no wrap.'
+    }
+  },
+  returns = {
+    {
+      name = 'width',
+      type = 'number',
+      description = 'The maximum width of any line in the text.'
+    }
+  }
+}

+ 15 - 0
api/lovr/graphics/Font/setPixelDensity.lua

@@ -0,0 +1,15 @@
+return {
+  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.
+  ]],
+  arguments = {
+    {
+      name = 'pixelDensity',
+      type = 'number',
+      description = 'The new pixel density.'
+    }
+  },
+  returns = {}
+}

+ 7 - 7
api/lovr/graphics/Buffer/draw.lua → api/lovr/graphics/Mesh/draw.lua

@@ -1,31 +1,31 @@
 return {
 return {
-  summary = 'Draw the Buffer.',
-  description = 'Draws the contents of the Buffer.',
+  summary = 'Draw the Mesh.',
+  description = 'Draws the contents of the Mesh.',
   arguments = {
   arguments = {
     x = {
     x = {
       type = 'number',
       type = 'number',
       default = '0',
       default = '0',
-      description = 'The x coordinate to draw the Buffer at.'
+      description = 'The x coordinate to draw the Mesh at.'
     },
     },
     y = {
     y = {
       type = 'number',
       type = 'number',
       default = '0',
       default = '0',
-      description = 'The y coordinate to draw the Buffer at.'
+      description = 'The y coordinate to draw the Mesh at.'
     },
     },
     z = {
     z = {
       type = 'number',
       type = 'number',
       default = '0',
       default = '0',
-      description = 'The z coordinate to draw the Buffer at.'
+      description = 'The z coordinate to draw the Mesh at.'
     },
     },
     scale = {
     scale = {
       type = 'number',
       type = 'number',
       default = '1',
       default = '1',
-      description = 'The scale to draw the Buffer at.'
+      description = 'The scale to draw the Mesh at.'
     },
     },
     angle = {
     angle = {
       type = 'number',
       type = 'number',
       default = '0',
       default = '0',
-      description = 'The angle to rotate the Buffer around its axis of rotation.'
+      description = 'The angle to rotate the Mesh around its axis of rotation.'
     },
     },
     ax = {
     ax = {
       type = 'number',
       type = 'number',

+ 14 - 0
api/lovr/graphics/Mesh/getDrawMode.lua

@@ -0,0 +1,14 @@
+return {
+  summary = 'Get the draw mode of the Mesh.',
+  description = [[
+    Get the draw mode of the Mesh, which controls how the vertices are connected together.
+  ]],
+  arguments = {},
+  returns = {
+    {
+      name = 'mode',
+      type = 'MeshDrawMode',
+      description = 'The draw mode of the Mesh.'
+    }
+  }
+}

+ 3 - 3
api/lovr/graphics/Buffer/getDrawRange.lua → api/lovr/graphics/Mesh/getDrawRange.lua

@@ -1,8 +1,8 @@
 return {
 return {
-  summary = 'Get the draw range of the Buffer.',
+  summary = 'Get the draw range of the Mesh.',
   description = [[
   description = [[
-    Retrieve the current draw range for the buffer.  The draw range is a subset of the vertices of
-    the buffer that will be drawn.
+    Retrieve the current draw range for the Mesh.  The draw range is a subset of the vertices of the
+    Mesh that will be drawn.
   ]],
   ]],
   arguments = {},
   arguments = {},
   returns = {
   returns = {

+ 12 - 0
api/lovr/graphics/Mesh/getTexture.lua

@@ -0,0 +1,12 @@
+return {
+  summary = 'Get the Texture applied to the Mesh.',
+  description = 'Get the Texture applied to the Mesh.',
+  arguments = {},
+  returns = {
+    {
+      name = 'texture',
+      type = 'Texture',
+      description = 'The current texture applied to the Mesh.'
+    }
+  }
+}

+ 22 - 0
api/lovr/graphics/Mesh/getVertex.lua

@@ -0,0 +1,22 @@
+return {
+  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.
+  ]],
+  arguments = {
+    {
+      name = 'index',
+      type = 'number',
+      description = 'The index of the vertex to retrieve.'
+    }
+  },
+  returns = {
+    {
+      name = '...',
+      type = 'number',
+      description = 'All attributes of the vertex.'
+    }
+  }
+}

+ 3 - 3
api/lovr/graphics/Buffer/getVertexAttribute.lua → api/lovr/graphics/Mesh/getVertexAttribute.lua

@@ -1,6 +1,6 @@
 return {
 return {
-  summary = 'Get an attribute of a single vertex in the Buffer.',
-  description = 'Get the components of a specific attribute of a single vertex in the Buffer.',
+  summary = 'Get an attribute of a single vertex in the Mesh.',
+  description = 'Get the components of a specific attribute of a single vertex in the Mesh.',
   arguments = {
   arguments = {
     {
     {
       name = 'index',
       name = 'index',
@@ -21,7 +21,7 @@ return {
     }
     }
   },
   },
   notes = [[
   notes = [[
-    Buffers without a custom format have the vertex position as their first attribute, the normal
+    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.
     vector as the second attribute, and the texture coordinate as the third attribute.
   ]]
   ]]
 }
 }

+ 13 - 0
api/lovr/graphics/Mesh/getVertexCount.lua

@@ -0,0 +1,13 @@
+return {
+  summary = 'Get the number of vertices the Mesh can hold.',
+  description = 'Returns the maximum number of vertices the Mesh can hold.',
+  arguments = {},
+  returns = {
+    {
+      name = 'size',
+      type = 'number',
+      description = 'The number of vertices the Mesh can hold.'
+    }
+  },
+  notes = 'The size can only be set when creating the Mesh, and cannot be changed afterwards.'
+}

+ 2 - 2
api/lovr/graphics/Buffer/getVertexFormat.lua → api/lovr/graphics/Mesh/getVertexFormat.lua

@@ -1,7 +1,7 @@
 return {
 return {
-  summary = 'Get the vertex format of the Buffer.',
+  summary = 'Get the vertex format of the Mesh.',
   description = [[
   description = [[
-    Get the format table of the Buffer's vertices.  The format table describes the set of data that
+    Get the format table of the Mesh's vertices.  The format table describes the set of data that
     each vertex contains.
     each vertex contains.
   ]],
   ]],
   arguments = {},
   arguments = {},

+ 3 - 3
api/lovr/graphics/Buffer/getVertexMap.lua → api/lovr/graphics/Mesh/getVertexMap.lua

@@ -1,8 +1,8 @@
 return {
 return {
-  summary = 'Get the current vertex map of the Buffer.',
+  summary = 'Get the current vertex map of the Mesh.',
   description = [[
   description = [[
-    Returns the current vertex map for the buffer.  The vertex map is a list of indices in the
-    buffer, allowing the reordering or reuse of vertices.
+    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.
   ]],
   ]],
   arguments = {},
   arguments = {},
   returns = {
   returns = {

+ 21 - 21
api/lovr/graphics/Buffer/init.lua → api/lovr/graphics/Mesh/init.lua

@@ -1,29 +1,29 @@
 return {
 return {
   summary = 'A drawable list of vertices.',
   summary = 'A drawable list of vertices.',
   description = [[
   description = [[
-    A Buffer is a low-level graphics object that stores and renders a list of vertices.
+    A Mesh is a low-level graphics object that stores and renders a list of vertices.
 
 
-    Buffers 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.
+    Meshes 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.
 
 
-    It's possible to batch geometry with Buffers too.  Instead of drawing a shape 100 times, it's
-    much faster to pack 100 copies of the shape into a Buffer and draw the Buffer once.
+    It'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.
 
 
-    Buffers are also a good choice if you have a mesh that changes its shape over time.
+    Meshes are also a good choice if you have a mesh that changes its shape over time.
   ]],
   ]],
-  constructor = 'lovr.graphics.newBuffer',
+  constructor = 'lovr.graphics.newMesh',
   notes = [[
   notes = [[
-    Each vertex in a buffer 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
+    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
     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:
     what the "position" attribute would look like as a Lua table:
 
 
         { 'vPosition', 'float', 3 } -- 3 floats for x, y, and z
         { 'vPosition', 'float', 3 } -- 3 floats for x, y, and z
 
 
-    Every vertex in a Buffer must have the same set of attributes.  We call this set of attributes
-    the **format** of the Buffer, and it's specified as a simple table of attributes.  For example,
-    we could represent the format described above as:
+    Every 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:
 
 
         {
         {
           { 'vPosition', 'float', 3 },
           { 'vPosition', 'float', 3 },
@@ -31,8 +31,8 @@ return {
           { 'vWeight',   'int',   1 }
           { 'vWeight',   'int',   1 }
         }
         }
 
 
-    When creating a Buffer, you can give it any format you want, or use the default.  The default
-    Buffer format looks like this:
+    When creating a Mesh, you can give it any format you want, or use the default.  The default Mesh
+    format looks like this:
 
 
         {
         {
           { 'lovrPosition', 'float', 3 },
           { 'lovrPosition', 'float', 3 },
@@ -42,28 +42,28 @@ return {
 
 
     Great, so why do we go through the trouble of naming everything in our vertex and saying what
     Great, 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
     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 Buffer:
+    vertex Shader that has `in` variables for every vertex attribute in our Mesh:
 
 
         in vec3 vPosition;
         in vec3 vPosition;
         in vec4 vColor;
         in vec4 vColor;
         in int vWeight;
         in int vWeight;
 
 
         vec4 position(mat4 projection, mat4 transform, vec4 vertex) {
         vec4 position(mat4 projection, mat4 transform, vec4 vertex) {
-          // Here we can access the vPosition, vColor, and vWeight of each vertex in the buffer!
+          // Here we can access the vPosition, vColor, and vWeight of each vertex in the Mesh!
         }
         }
 
 
     Specifying custom vertex data is really powerful and is often used for lighting, animation, and
     Specifying custom vertex data is really powerful and is often used for lighting, animation, and
     more!
     more!
   ]],
   ]],
   example = {
   example = {
-    description = 'Draw a circle using a Buffer.',
+    description = 'Draw a circle using a Mesh.',
     code = [[
     code = [[
       function lovr.load()
       function lovr.load()
         local x, y, z = 0, 1, -2
         local x, y, z = 0, 1, -2
         local radius = .3
         local radius = .3
         local points = 40
         local points = 40
 
 
-        -- A table to hold the Buffer data
+        -- A table to hold the Mesh data
         local vertices = {}
         local vertices = {}
 
 
         for i = 0, points do
         for i = 0, points do
@@ -73,11 +73,11 @@ return {
           table.insert(vertices, { vx, vy, z })
           table.insert(vertices, { vx, vy, z })
         end
         end
 
 
-        buffer = lovr.graphics.newBuffer(vertices, 'fan')
+        mesh = lovr.graphics.newMesh(vertices, 'fan')
       end
       end
 
 
       function lovr.draw()
       function lovr.draw()
-        buffer:draw()
+        mesh:draw()
       end
       end
     ]]
     ]]
   }
   }

+ 21 - 0
api/lovr/graphics/Mesh/isAttributeEnabled.lua

@@ -0,0 +1,21 @@
+return {
+  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.
+  ]],
+  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.'
+    }
+  }
+}

+ 19 - 0
api/lovr/graphics/Mesh/setAttributeEnabled.lua

@@ -0,0 +1,19 @@
+return {
+  summary = 'Enable or disable a vertex attribute.',
+  description = [[
+    Sets whether a vertex attribute is enabled.  Disabled attributes won't be sent to shaders.
+  ]],
+  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 = {}
+}

+ 12 - 0
api/lovr/graphics/Mesh/setDrawMode.lua

@@ -0,0 +1,12 @@
+return {
+  summary = 'Change the draw mode of the Mesh.',
+  description = 'Set a new draw mode for the Mesh.',
+  arguments = {
+    {
+      name = 'mode',
+      type = 'MeshDrawMode',
+      description = 'The new draw mode for the Mesh.'
+    }
+  },
+  returns = {}
+}

+ 3 - 3
api/lovr/graphics/Buffer/setDrawRange.lua → api/lovr/graphics/Mesh/setDrawRange.lua

@@ -1,8 +1,8 @@
 return {
 return {
-  summary = 'Set the draw range of the Buffer.',
+  summary = 'Set the draw range of the Mesh.',
   description = [[
   description = [[
-    Set the draw range for the Buffer.  The draw range is a subset of the vertices of the buffer
-    that will be drawn.
+    Set the draw range for the Mesh.  The draw range is a subset of the vertices of the Mesh that
+    will be drawn.
   ]],
   ]],
   arguments = {
   arguments = {
     {
     {

+ 2 - 2
api/lovr/graphics/Buffer/setTexture.lua → api/lovr/graphics/Mesh/setTexture.lua

@@ -1,6 +1,6 @@
 return {
 return {
-  summary = 'Apply a Texture to the Buffer.',
-  description = 'Applies a Texture to the Buffer.',
+  summary = 'Apply a Texture to the Mesh.',
+  description = 'Applies a Texture to the Mesh.',
   arguments = {
   arguments = {
     {
     {
       name = 'texture',
       name = 'texture',

+ 5 - 5
api/lovr/graphics/Buffer/setVertex.lua → api/lovr/graphics/Mesh/setVertex.lua

@@ -1,6 +1,6 @@
 return {
 return {
-  summary = 'Update a single vertex in the Buffer.',
-  description = 'Update a single vertex in the Buffer.',
+  summary = 'Update a single vertex in the Mesh.',
+  description = 'Update a single vertex in the Mesh.',
   arguments = {
   arguments = {
     index = {
     index = {
       type = 'number',
       type = 'number',
@@ -34,15 +34,15 @@ return {
     description = 'Set the position of a vertex:',
     description = 'Set the position of a vertex:',
     code = [[
     code = [[
       function lovr.load()
       function lovr.load()
-        buffer = lovr.graphics.newBuffer({
+        mesh = lovr.graphics.newMesh({
           { -1, 1, 0,  0, 0, 1,  0, 0 },
           { -1, 1, 0,  0, 0, 1,  0, 0 },
           { 1, 1, 0,  0, 0, 1,  1, 0 },
           { 1, 1, 0,  0, 0, 1,  1, 0 },
           { -1, -1, 0,  0, 0, 1,  0, 1 },
           { -1, -1, 0,  0, 0, 1,  0, 1 },
           { 1, -1, 0,  0, 0, 1,  1, 1 }
           { 1, -1, 0,  0, 0, 1,  1, 1 }
         }, 'strip')
         }, 'strip')
 
 
-        buffer:setVertex(2, { 7, 7, 7 })
-        print(buffer:getVertex(2)) -- 7, 7, 7, 0, 0, 0, 0, 0
+        mesh:setVertex(2, { 7, 7, 7 })
+        print(mesh:getVertex(2)) -- 7, 7, 7, 0, 0, 0, 0, 0
       end
       end
     ]]
     ]]
   }
   }

+ 3 - 3
api/lovr/graphics/Buffer/setVertexAttribute.lua → api/lovr/graphics/Mesh/setVertexAttribute.lua

@@ -1,6 +1,6 @@
 return {
 return {
-  summary = 'Update a specific attribute of a single vertex in the Buffer.',
-  description = 'Set the components of a specific attribute of a vertex in the Buffer.',
+  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.',
   arguments = {
   arguments = {
     {
     {
       name = 'index',
       name = 'index',
@@ -20,7 +20,7 @@ return {
   },
   },
   returns = {},
   returns = {},
   notes = [[
   notes = [[
-    Buffers without a custom format have the vertex position as their first attribute, the normal
+    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.
     vector as the second attribute, and the texture coordinate as the third attribute.
   ]]
   ]]
 }
 }

+ 2 - 2
api/lovr/graphics/Buffer/setVertexMap.lua → api/lovr/graphics/Mesh/setVertexMap.lua

@@ -1,7 +1,7 @@
 return {
 return {
-  summary = 'Set the vertex map of the Buffer.',
+  summary = 'Set the vertex map of the Mesh.',
   description = [[
   description = [[
-    Sets the vertex map.  The vertex map is a list of indices in the buffer, allowing the reordering
+    Sets the vertex map.  The vertex map is a list of indices in the Mesh, allowing the reordering
     or reuse of vertices.
     or reuse of vertices.
 
 
     Often, a vertex map is used to improve performance, since it usually requires less data to
     Often, a vertex map is used to improve performance, since it usually requires less data to

+ 3 - 3
api/lovr/graphics/Buffer/setVertices.lua → api/lovr/graphics/Mesh/setVertices.lua

@@ -1,6 +1,6 @@
 return {
 return {
-  summary = 'Update multiple vertices in the Buffer.',
-  description = 'Update multiple vertices in the Buffer.',
+  summary = 'Update multiple vertices in the Mesh.',
+  description = 'Update multiple vertices in the Mesh.',
   arguments = {
   arguments = {
     {
     {
       name = 'vertices',
       name = 'vertices',
@@ -10,6 +10,6 @@ return {
   },
   },
   returns = {},
   returns = {},
   notes = [[
   notes = [[
-    The number of vertices in the table should not exceed the maximum size of the Buffer.
+    The number of vertices in the table should not exceed the maximum size of the Mesh.
   ]]
   ]]
 }
 }

+ 2 - 2
api/lovr/graphics/BufferDrawMode.lua → api/lovr/graphics/MeshDrawMode.lua

@@ -1,7 +1,7 @@
 return {
 return {
-  summary = 'Different ways buffers can be drawn.',
+  summary = 'Different ways Mesh objects can be drawn.',
   description = [[
   description = [[
-    Buffers are lists of arbitrary vertices.  These vertices can be drawn in a few different ways,
+    Meshes are lists of arbitrary vertices.  These vertices can be drawn in a few different ways,
     leading to different results.
     leading to different results.
   ]],
   ]],
   values = {
   values = {

+ 23 - 0
api/lovr/graphics/MeshUsage.lua

@@ -0,0 +1,23 @@
+return {
+  summary = 'How a Mesh is going to be updated.',
+  description = [[
+    Meshes can have a usage hint, describing how they are planning on being updated.  Setting the
+    usage hint allows the graphics driver optimize how it handles the data in the Mesh.
+  ]],
+  values = {
+    {
+      name = 'static',
+      description = 'The Mesh contents will rarely change.'
+    },
+    {
+      name = 'dynamic',
+      description = 'The Mesh contents will change often.'
+    },
+    {
+      name = 'stream',
+      description = [[
+        The Mesh contents will change constantly, potentially multiple times each frame.
+      ]]
+    }
+  }
+}

+ 2 - 3
api/lovr/graphics/Model/init.lua

@@ -1,9 +1,8 @@
 return {
 return {
   summary = 'An asset imported from a 3D model file.',
   summary = 'An asset imported from a 3D model file.',
   description = [[
   description = [[
-    A Model is a drawable object loaded from a 3D file format.  Most common 3D file formats are
-    supported, such as `3ds`, `blend`, `dae`, `fbx`, `stl`, `obj`, and `glTF`.  Models will use
-    normals and texture coordinates, if provided.
+    A Model is a drawable object loaded from a 3D file format.  The supported 3D file formats are
+    `obj`, `fbx`, and collada.  Models will use normals and texture coordinates, if provided.
 
 
     The following advanced features are not supported yet: animations, materials, and vertex colors.
     The following advanced features are not supported yet: animations, materials, and vertex colors.
   ]],
   ]],

+ 2 - 2
api/lovr/graphics/Texture/init.lua

@@ -1,7 +1,7 @@
 return {
 return {
-  summary = 'An image that can be applied to Buffers and Models.',
+  summary = 'An image that can be applied to Meshes and Models.',
   description = [[
   description = [[
-    A Texture is an image that can be applied to `Model`s and `Buffer`s.  Supported file formats
+    A Texture is an image that can be applied to `Model`s and `Mesh`s.  Supported file formats
     include `.png`, `.jpg`, `.tga`, and `.bmp`.
     include `.png`, `.jpg`, `.tga`, and `.bmp`.
   ]],
   ]],
   constructor = 'lovr.graphics.newTexture'
   constructor = 'lovr.graphics.newTexture'

+ 25 - 0
api/lovr/graphics/getBlendMode.lua

@@ -0,0 +1,25 @@
+return {
+  tag = 'graphicsState',
+  summary = 'Get the blend mode.',
+  description = [[
+    Returns the current blend mode.  The blend mode controls how each pixel's color is blended with
+    the previous pixel's color when drawn.
+  ]],
+  arguments = {},
+  returns = {
+    {
+      name = 'blend',
+      type = 'BlendMode',
+      description = 'The current blend mode.'
+    },
+    {
+      name = 'alphaBlend',
+      type = 'BlendAlphaMode',
+      description = 'The current alpha blend mode.'
+    }
+  },
+  related = {
+    'BlendMode',
+    'BlendAlphaMode'
+  }
+}

+ 33 - 0
api/lovr/graphics/getSystemLimits.lua

@@ -0,0 +1,33 @@
+return {
+  tag = 'graphicsState',
+  summary = 'Get capabilities of the graphics card.',
+  description = [[
+    Returns information about the capabilities of the graphics card, such as the maximum texture
+    size or the amount of supported antialiasing.
+  ]],
+  arguments = {},
+  returns = {
+    {
+      name = 'limits',
+      type = 'table',
+      description = 'The table of limits.',
+      table = {
+        {
+          name = 'pointsize',
+          type = 'number',
+          description = 'The maximum size of points, in pixels.'
+        },
+        {
+          name = 'texturesize',
+          type = 'number',
+          description = 'The maximum width or height of textures, in pixels.'
+        },
+        {
+          name = 'texturemsaa',
+          type = 'number',
+          description = 'The maximum MSAA value supported by `lovr.graphics.newTexture`.'
+        }
+      }
+    }
+  }
+}

+ 16 - 16
api/lovr/graphics/newBuffer.lua → api/lovr/graphics/newMesh.lua

@@ -1,24 +1,24 @@
 return {
 return {
   tag = 'graphicsObjects',
   tag = 'graphicsObjects',
-  summary = 'Create a new Buffer.',
+  summary = 'Create a new Mesh.',
   description = [[
   description = [[
-    Creates a new Buffer.  You must specify either the capacity for the Buffer or an initial set of
+    Creates a new Mesh.  You must specify either the capacity for the Mesh or an initial set of
     vertex data.  The draw mode and usage hint can also optionally be specified.
     vertex data.  The draw mode and usage hint can also optionally be specified.
   ]],
   ]],
   arguments = {
   arguments = {
     size = {
     size = {
       type = 'number',
       type = 'number',
-      description = 'The maximum number of vertices the Buffer can store.'
+      description = 'The maximum number of vertices the Mesh can store.'
     },
     },
     mode = {
     mode = {
-      type = 'BufferDrawMode',
+      type = 'MeshDrawMode',
       default = [['triangles']],
       default = [['triangles']],
-      description = 'How the Buffer will render its vertices.'
+      description = 'How the Mesh will render its vertices.'
     },
     },
     usage = {
     usage = {
-      type = 'BufferUsage',
+      type = 'MeshUsage',
       default = [['dynamic']],
       default = [['dynamic']],
-      description = 'How the Buffer will be updated.'
+      description = 'How the Mesh will be updated.'
     },
     },
     vertices = {
     vertices = {
       type = 'table',
       type = 'table',
@@ -30,32 +30,32 @@ return {
     }
     }
   },
   },
   returns = {
   returns = {
-    buffer = {
-      type = 'Buffer',
-      description = 'The new Buffer.'
+    mesh = {
+      type = 'Mesh',
+      description = 'The new Mesh.'
     }
     }
   },
   },
   variants = {
   variants = {
     {
     {
       arguments = { 'size', 'mode', 'usage' },
       arguments = { 'size', 'mode', 'usage' },
-      returns = { 'buffer' }
+      returns = { 'mesh' }
     },
     },
     {
     {
       arguments = { 'vertices', 'mode', 'usage' },
       arguments = { 'vertices', 'mode', 'usage' },
-      returns = { 'buffer' }
+      returns = { 'mesh' }
     },
     },
     {
     {
       description = [[
       description = [[
         These variants accept a custom vertex format.  For more info, see the <a
         These variants accept a custom vertex format.  For more info, see the <a
-        data-key="Buffer">`Buffer`</a> page.
+        data-key="Mesh">`Mesh`</a> page.
       ]],
       ]],
       arguments = { 'format', 'size', 'mode', 'usage' },
       arguments = { 'format', 'size', 'mode', 'usage' },
-      returns = { 'buffer' }
+      returns = { 'mesh' }
     },
     },
     {
     {
       arguments = { 'format', 'vertices', 'mode', 'usage' },
       arguments = { 'format', 'vertices', 'mode', 'usage' },
-      returns = { 'buffer' }
+      returns = { 'mesh' }
     }
     }
   },
   },
-  notes = 'Once created, the size of the Buffer can\'t be changed.'
+  notes = 'Once created, the size of the Mesh can\'t be changed.'
 }
 }

+ 2 - 3
api/lovr/graphics/newModel.lua

@@ -2,9 +2,8 @@ return {
   tag = 'graphicsObjects',
   tag = 'graphicsObjects',
   summary = 'Create a new Model.',
   summary = 'Create a new Model.',
   description = [[
   description = [[
-    Creates a new Model from a file.  Most common 3D file formats are supported, such as `3ds`,
-    `blend`, `dae`, `fbx`, `stl`, `obj`, and `glTF`.  Models use normals and texture coordinates,
-    if provided.
+    Creates a new Model from a file.  The supported 3D file formats are `obj`, `fbx`, and collada.
+    Models use normals and texture coordinates, if provided.
 
 
     The following features are not supported yet: animations, materials, vertex colors.
     The following features are not supported yet: animations, materials, vertex colors.
   ]],
   ]],

+ 9 - 0
api/lovr/graphics/newSkybox.lua

@@ -30,6 +30,10 @@ return {
     images = {
     images = {
       type = 'table',
       type = 'table',
       description = 'A table containing 6 images, as described above.'
       description = 'A table containing 6 images, as described above.'
+    },
+    image = {
+      type = 'string',
+      description = 'A filename for an equirectangular image to load.'
     }
     }
   },
   },
   returns = {
   returns = {
@@ -46,6 +50,11 @@ return {
     {
     {
       arguments = { 'images' },
       arguments = { 'images' },
       returns = { 'skybox' }
       returns = { 'skybox' }
+    },
+    {
+      description = 'Creates a Skybox from a single equirectangular image.',
+      arguments = { 'image' },
+      returns = { 'skybox' }
     }
     }
   }
   }
 }
 }

+ 24 - 9
api/lovr/graphics/print.lua

@@ -27,16 +27,10 @@ return {
       description = 'The z coordinate of the center of the text.'
       description = 'The z coordinate of the center of the text.'
     },
     },
     {
     {
-      name = 'w',
+      name = 'scale',
       type = 'number',
       type = 'number',
-      default = 0,
-      description = 'The maximum width of each line, in meters.  Use zero for unlimited.'
-    },
-    {
-      name = 'h',
-      type = 'number',
-      default = .1,
-      description = 'The height of each line, in meters.'
+      default = 1,
+      description = 'The scale of the text.'
     },
     },
     {
     {
       name = 'angle',
       name = 'angle',
@@ -61,6 +55,27 @@ return {
       type = 'number',
       type = 'number',
       default = 0,
       default = 0,
       description = 'The z component of the axis of rotation.'
       description = 'The z component of the axis of rotation.'
+    },
+    {
+      name = 'wrap',
+      type = 'number',
+      default = '0',
+      description = [[
+        The maximum width of each line, in meters (affected by `scale`).  Set to 0 or `nil` for no
+        wrapping.
+      ]]
+    },
+    {
+      name = 'halign',
+      type = 'HorizontalAlign',
+      default = [['center']],
+      description = 'The horizontal alignment.'
+    },
+    {
+      name = 'valign',
+      type = 'VerticalAlign',
+      default = [['middle']],
+      description = 'The vertical alignment.'
     }
     }
   },
   },
   returns = {},
   returns = {},

+ 3 - 0
api/lovr/graphics/rotate.lua

@@ -16,16 +16,19 @@ return {
     {
     {
       name = 'ax',
       name = 'ax',
       type = 'number',
       type = 'number',
+      default = '0',
       description = 'The x component of the axis of rotation.'
       description = 'The x component of the axis of rotation.'
     },
     },
     {
     {
       name = 'ay',
       name = 'ay',
       type = 'number',
       type = 'number',
+      default = '1',
       description = 'The y component of the axis of rotation.'
       description = 'The y component of the axis of rotation.'
     },
     },
     {
     {
       name = 'az',
       name = 'az',
       type = 'number',
       type = 'number',
+      default = '0',
       description = 'The z component of the axis of rotation.'
       description = 'The z component of the axis of rotation.'
     }
     }
   },
   },

+ 2 - 0
api/lovr/graphics/scale.lua

@@ -17,11 +17,13 @@ return {
     {
     {
       name = 'y',
       name = 'y',
       type = 'number',
       type = 'number',
+      default = 'x',
       description = 'The amount to scale on the y axis.'
       description = 'The amount to scale on the y axis.'
     },
     },
     {
     {
       name = 'z',
       name = 'z',
       type = 'number',
       type = 'number',
+      default = 'x',
       description = 'The amount to scale on the z axis.'
       description = 'The amount to scale on the z axis.'
     }
     }
   },
   },

+ 25 - 0
api/lovr/graphics/setBlendMode.lua

@@ -0,0 +1,25 @@
+return {
+  tag = 'graphicsState',
+  summary = 'Set the blend mode.',
+  description = [[
+    Sets the blend mode.  The blend mode controls how each pixel's color is blended with the
+    previous pixel's color when drawn.
+  ]],
+  arguments = {
+    {
+      name = 'blend',
+      type = 'BlendMode',
+      description = 'The blend mode.'
+    },
+    {
+      name = 'alphaBlend',
+      type = 'BlendAlphaMode',
+      description = 'The alpha blend mode.'
+    }
+  },
+  returns = {},
+  related = {
+    'BlendMode',
+    'BlendAlphaMode'
+  }
+}

+ 0 - 28
api/lovr/graphics/setProjection.lua

@@ -1,28 +0,0 @@
-return {
-  tag = 'graphicsState',
-  summary = 'Set the camera projection.',
-  description = [[
-    Sets the camera projection.  The projection settings define the camera frustum: How wide of a
-    field of view the camera has and how far away the near and far clipping planes are.  If an
-    object is outside of this field of view, closer than the near clipping plane, or further away
-    than the far clipping plane, then it will not be rendered.
-  ]],
-  arguments = {
-    {
-      name = 'near',
-      type = 'number',
-      description = 'How far away the near clipping plane is, in meters.'
-    },
-    {
-      name = 'far',
-      type = 'number',
-      description = 'How far away the far clipping plane is, in meters.'
-    },
-    {
-      name = 'fov',
-      type = 'number',
-      description = 'The vertical field of view of the camera, in radians.'
-    }
-  },
-  returns = {}
-}

+ 13 - 0
api/lovr/headset/isMirrored.lua

@@ -0,0 +1,13 @@
+return {
+  tag = 'headset',
+  summary = 'Check if the headset is mirrored to the desktop.',
+  description = 'Returns whether or not the headset display is mirrored to the desktop window.',
+  arguments = {},
+  returns = {
+    {
+      name = 'mirrored',
+      type = 'boolean',
+      description = 'Whether or not the headset is mirrored to the desktop.'
+    }
+  }
+}

+ 13 - 0
api/lovr/headset/setMirrored.lua

@@ -0,0 +1,13 @@
+return {
+  tag = 'headset',
+  summary = 'Set whether the headset is mirrored to the desktop.',
+  description = 'Returns whether or not the headset display is mirrored to the desktop window.',
+  arguments = {
+    {
+      name = 'mirror',
+      type = 'boolean',
+      description = 'Whether or not the headset should be mirrored to the desktop.'
+    }
+  },
+  returns = {}
+}

+ 12 - 6
guides/3D_Models.md

@@ -14,7 +14,7 @@ To load a model into LÖVR, we can use the `lovr.graphics.newModel` function.  I
 the name of the model file and returns an object representing the model.
 the name of the model file and returns an object representing the model.
 
 
 ```
 ```
-model = lovr.graphics.newModel('duck.dae')
+model = lovr.graphics.newModel('assets/duck.dae')
 ```
 ```
 
 
 Create the Texture
 Create the Texture
@@ -23,7 +23,7 @@ Create the Texture
 Creating textures is really similar to creating models:
 Creating textures is really similar to creating models:
 
 
 ```
 ```
-texture = lovr.graphics.newTexture('duck.png')
+texture = lovr.graphics.newTexture('assets/duck.png')
 ```
 ```
 
 
 We can apply a texture to a model using `Model:setTexture`.  The colon syntax in Lua is used when
 We can apply a texture to a model using `Model:setTexture`.  The colon syntax in Lua is used when
@@ -33,6 +33,13 @@ you're calling a function on an object.
 model:setTexture(texture)
 model:setTexture(texture)
 ```
 ```
 
 
+It is also possible to create and set the texture while creating the model, using the second
+parameter to `lovr.graphics.newModel`:
+
+```
+model = lovr.graphics.newModel('assets/duck.dae', 'assets/duck.png')
+```
+
 Rendering the Model
 Rendering the Model
 ---
 ---
 
 
@@ -52,8 +59,7 @@ Here's the complete program for loading and rendering a 3D model:
 
 
 ```
 ```
 function lovr.load()
 function lovr.load()
-  model = lovr.graphics.newModel('model.obj')
-  model:setTexture(lovr.graphics.newTexture('texture.png'))
+  model = lovr.graphics.newModel('assets/model.obj', 'assets/texture.png')
 end
 end
 
 
 function lovr.draw()
 function lovr.draw()
@@ -61,8 +67,8 @@ function lovr.draw()
 end
 end
 ```
 ```
 
 
-I combined the calls to `lovr.graphics.newTexture` and `model:setTexture`, and I left out the
-rotation parameters from `model:draw` for simplicity.
+The rotation parameters for `model:draw` were left out for simplicity.  The model and texture were
+put in a folder called `assets`.
 
 
 That's all there is to it!  Next we'll (finally!) talk about our first VR topic:
 That's all there is to it!  Next we'll (finally!) talk about our first VR topic:
 <a data-key="Controllers">Controllers</a>.
 <a data-key="Controllers">Controllers</a>.

Some files were not shown because too many files changed in this diff