Quellcode durchsuchen

Fix Hud, Mesh samples on Oculus Mobile

- Hud example was crashing on lovr.mouse load, now it checks for lovr.mouse compatibility before loading it and prints a nice error message if not
- Mesh example was failing to build because it was inadequately strict about types of literals
- Also improved comments in Mesh example
- Also added credit to myself in Mesh and Postprocessing examples, since I did originally contribute these
mcc vor 6 Jahren
Ursprung
Commit
b88b392ade
4 geänderte Dateien mit 57 neuen und 30 gelöschten Zeilen
  1. 11 1
      examples/Hud/main.lua
  2. 41 27
      examples/Mesh/main.lua
  3. 1 0
      examples/Mesh/shader.lua
  4. 4 2
      examples/Postprocessing/main.lua

+ 11 - 1
examples/Hud/main.lua

@@ -4,7 +4,12 @@
 -- Sample contributed by andi mcc
 
 local shader = require 'shader'
-lovr.mouse = require 'mouse'    -- Note: Requires LuaJIT
+
+-- In order for lovr.mouse to work, and therefore for this example to work,
+-- we must be using LuaJIT and we must be using GLFW (ie: we can't be on Oculus Mobile)
+if type(jit) == 'table' and lovr.headset.getDriver() ~= "oculusmobile" then
+	lovr.mouse = require 'mouse'
+end
 
 local mirror = lovr.mirror              -- Backup lovr.mirror before it is overwritten
 local font = lovr.graphics.newFont(36)  -- Font appropriate for screen-space usage
@@ -136,4 +141,9 @@ function lovr.draw()
 		local gray = grid[x][y]
 		if gray then floorbox(x,y,gray) end
 	end end
+
+	if not lovr.mouse then -- If you can't click, you can't create any blocks
+		lovr.graphics.setShader(nil)
+		lovr.graphics.print('This example only works on a desktop computer.', 0, 1.7, -3, .2)
+	end
 end

+ 41 - 27
examples/Mesh/main.lua

@@ -1,8 +1,10 @@
 -- This demo renders four examples of mesh drawing:
 -- A plain mesh (one triangle, white)
--- A mesh with a vertex map (a cube, magenta)
+-- A mesh with a vertex map, in other words indexed triangles (a cube, magenta)
 -- An instanced mesh with its size controlled by gl_InstanceID and an equation (512 cubes animated, cyan)
 -- An instanced mesh with its size controlled by an attached attribute (512 cubes with random sizes, yellow)
+--
+-- Sample contributed by andi mcc
 
 local fragmentShader = require("shader")
 
@@ -12,15 +14,17 @@ local mesh1Program, mesh3Program, mesh4Program
 local gridSize = 8
 local gridSizeCubed = gridSize*gridSize*gridSize
 
+-- This reproduces the simple shader from the Physics example, but in the vertex shader
+-- the mesh coordinate is run through a customized function first.
 -- Call this function with a string containing a glsl function preTransform()
--- Which maps world space coordinates to world space coordinates.
+-- which maps world space coordinates to world space coordinates to construct a shader.
 local function makeShader(prefix)
   return lovr.graphics.newShader(prefix .. [[
 out vec3 lightDirection;
 out vec3 normalDirection;
 out vec3 vertexPosition;
 
-vec3 lightPosition = vec3(10, 10, 3);
+vec3 lightPosition = vec3(10., 10., 3.);
 
 vec4 position(mat4 projection, mat4 transform, vec4 _vertex) {
   vec4 vertex = preTransform(_vertex);
@@ -37,21 +41,21 @@ vec4 position(mat4 projection, mat4 transform, vec4 _vertex) {
 ]], fragmentShader)
 end
 
--- This "standard" program is the same as the standard light shader from the other examples-- it does nothing.
-local mesh1Program = makeShader("vec4 preTransform(vec4 v) { return v; }")
-
 local animate = 0
 
 function lovr.load()
   lovr.graphics.setCullingEnabled(true)
 
---  mesh1Program()
+  -- This "standard" program is the same as the standard light shader from the other examples-- it does nothing.
+  mesh1Program = makeShader("vec4 preTransform(vec4 v) { return v; }")
 
+  -- This mesh is a single triangle
   mesh1 = lovr.graphics.newMesh({{ 'lovrPosition', 'float', 3 }, { 'lovrNormal', 'float', 3 }}, 3, 'triangles')
-  mesh1:setVertices({{0,0,0, 0,0,1}, {1,0,0, 0,0,1}, {0,1,0, 0,0,1}}) -- A triangle
+  mesh1:setVertices({{0,0,0, 0,0,1}, {1,0,0, 0,0,1}, {0,1,0, 0,0,1}})
 
+  -- This mesh is a cube
   mesh2 = lovr.graphics.newMesh({{ 'lovrPosition', 'float', 3 }, { 'lovrNormal', 'float', 3 }}, 24, 'triangles')
-  local mesh2Vertices = { -- Coordinates for mesh 2 (a cube)
+  local mesh2Vertices = {
     {0,0,0, 0,0,-1}, -- Face front
     {0,1,0, 0,0,-1},
     {1,1,0, 0,0,-1},
@@ -83,8 +87,8 @@ function lovr.load()
     {0,0,1, 0,-1,0}
   }
 
-  -- This cube covers the space 0..1, so it's centered at (0.5, 0.5, 0.5).
-  -- Edit the first three coordinates of each vertex to center it at (0,0,0):
+  -- The cube specified above covers the space 0..1, so it's centered at (0.5, 0.5, 0.5). That's not right.
+  -- Let's edit the first three coordinates of each vertex to center it at (0,0,0):
   for _, v in ipairs(mesh2Vertices) do
     for i=1,3 do
       v[i] = v[i] - 0.5
@@ -93,7 +97,8 @@ function lovr.load()
 
   mesh2:setVertices(mesh2Vertices)
 
-  local mesh2Indexes = { -- Indexes for mesh 2
+  -- Indices to draw the faces of the cube out of triangles
+  local mesh2Indexes = {
     1,  2,  3,  1,  3,  4,  -- Face front
     5,  6,  7,  5,  7,  8,  -- Face top
     9,  10,  11, 9,  11, 12, -- Face right
@@ -104,36 +109,45 @@ function lovr.load()
 
   mesh2:setVertexMap(mesh2Indexes)
 
+  -- This program draws many "instances" of a single model (in this example, a cube, but it could be anything)
+  -- but uses the instance ID to recenter the model so that the various copies pack the volume of a cube.
+  -- The model is resized according to a uniform and a little equation to make them wave nicely.
   mesh3Program = makeShader([[
   uniform int gridSize;
   uniform float animate;
   vec4 preTransform(vec4 v) {
-    int x = gl_InstanceID % gridSize;
-    int y = (gl_InstanceID / gridSize) % gridSize;
-    int z = (gl_InstanceID / gridSize) / gridSize;
-    float cubeSize = (sin(x + y + z + animate) + 1) / 2;
-    return v * vec4(cubeSize,cubeSize,cubeSize,1) + vec4(x,y,z,0) - vec4(gridSize, gridSize, gridSize, 0)/2;
+    int instance = lovrInstanceID;
+    int x = instance % gridSize;
+    int y = (instance / gridSize) % gridSize;
+    int z = (instance / gridSize) / gridSize;
+    float cubeSize = (sin(float(x + y + z) + animate) + 1.) / 2.;
+    return v * vec4(cubeSize,cubeSize,cubeSize,1) + vec4(x,y,z,0.) - vec4(gridSize, gridSize, gridSize, 0.)/2.;
   }
   ]])
   mesh3Program:send("gridSize", gridSize)
 
+  -- This is exactly like the last program-- many instances of one model, packed into a cube volume.
+  -- The difference is instead of the size being set by a single uniform, we'll pass in a list of sizes.
+  -- We only have to pass in the cube mesh once, and it matches a copy of the cube for each size in the list.
   mesh4Program = makeShader([[
   uniform int gridSize;
   in float cubeSize;
   vec4 preTransform(vec4 v) {
-    int x = gl_InstanceID % gridSize;
-    int y = (gl_InstanceID / gridSize) % gridSize;
-    int z = (gl_InstanceID / gridSize) / gridSize;
-    return v * vec4(cubeSize,cubeSize,cubeSize,1) + vec4(x,y,z,0) - vec4(gridSize, gridSize, gridSize, 0)/2;
+    int instance = lovrInstanceID;
+    int x = instance % gridSize;
+    int y = (instance / gridSize) % gridSize;
+    int z = (instance / gridSize) / gridSize;
+    return v * vec4(cubeSize,cubeSize,cubeSize,1.) + vec4(x,y,z,0.) - vec4(gridSize, gridSize, gridSize, 0.)/2.;
   }
   ]])
   mesh4Program:send("gridSize", gridSize)
 
+  -- Here we make an alternate version of mesh 2 (the cube) with the size list attached.
   mesh4 = lovr.graphics.newMesh({}, 24, 'triangles')
   mesh4Instance = lovr.graphics.newMesh({{'cubeSize', 'float', 1}}, gridSizeCubed, 'points')
   local mesh4Vertices = {}
-  for i=1,gridSizeCubed do
-    table.insert(mesh4Vertices, {math.random()})
+  for i=1,gridSizeCubed do                       -- Hmm, what sizes should we use?
+    table.insert(mesh4Vertices, {math.random()}) -- Let's just make them random.
   end
   mesh4Instance:setVertices(mesh4Vertices)
   mesh4:setVertexMap(mesh2Indexes)
@@ -148,20 +162,20 @@ end
 function lovr.draw(eye)
   lovr.graphics.setShader(mesh1Program)
 
-  lovr.graphics.push()
+  lovr.graphics.push() -- White triangle
   lovr.graphics.setColor(1,1,1)
   lovr.graphics.translate(0, 0, -2)
   mesh1:draw(0,0,0)
   lovr.graphics.pop()
 
-  lovr.graphics.push()
+  lovr.graphics.push() -- Magenta cube
   lovr.graphics.setColor(1,0,1)
   lovr.graphics.rotate(1 * math.pi/2, 0, 1, 0)
   lovr.graphics.translate(0, 0, -2)
   mesh2:draw(0,0,0)
   lovr.graphics.pop()
 
-  lovr.graphics.setShader(mesh3Program)
+  lovr.graphics.setShader(mesh3Program) -- Cyan cubes with size animated by uniform
   lovr.graphics.setColor(0,1,1)
   lovr.graphics.push()
   lovr.graphics.rotate(2 * math.pi/2, 0, 1, 0)
@@ -171,7 +185,7 @@ function lovr.draw(eye)
   mesh2:draw(lovr.math.mat4(), gridSizeCubed)
   lovr.graphics.pop()
 
-  lovr.graphics.setShader(mesh4Program)
+  lovr.graphics.setShader(mesh4Program) -- Yellow cubes with size specified by mesh4
   lovr.graphics.setColor(1,1,0)
   lovr.graphics.push()
   lovr.graphics.rotate(3 * math.pi/2, 0, 1, 0)

+ 1 - 0
examples/Mesh/shader.lua

@@ -1,3 +1,4 @@
+-- Copy of fragment shader from Physics example
 return [[
 in vec3 lightDirection;
 in vec3 normalDirection;

+ 4 - 2
examples/Postprocessing/main.lua

@@ -1,6 +1,8 @@
 -- This demo renders a scene to a canvas, then renders the canvas to screen filtered through a shader.
--- Set this to false to see the scene with no postprocessing.
-local useCanvas = true
+--
+-- Sample contributed by andi mcc
+
+local useCanvas = true -- Set this to false to see the scene with no postprocessing.
 
 -- A shader program consists of a vertex shader (which describes how to transform polygons)
 -- and a fragment shader (which describes how to color pixels).