Explorar o código

Add Debugg/FPS_Controls example;

bjorn %!s(int64=5) %!d(string=hai) anos
pai
achega
628815fcb1

+ 5 - 0
examples/Debugging/FPS_Controls/conf.lua

@@ -0,0 +1,5 @@
+function lovr.conf(t)
+  t.modules.headset = false
+  t.window.width = 800
+  t.window.height = 600
+end

+ 151 - 0
examples/Debugging/FPS_Controls/lovr-keyboard.lua

@@ -0,0 +1,151 @@
+local ffi = require 'ffi'
+local C = ffi.os == 'Windows' and ffi.load('glfw3') or ffi.C
+
+ffi.cdef [[
+  typedef struct GLFWwindow GLFWwindow;
+  typedef void(*GLFWkeyfun)(GLFWwindow*, int, int, int, int);
+
+  GLFWwindow* glfwGetCurrentContext(void);
+  int glfwGetKey(GLFWwindow* window, int key);
+  GLFWkeyfun glfwSetKeyCallback(GLFWwindow* window, GLFWkeyfun callback);
+]]
+
+local window = C.glfwGetCurrentContext()
+
+local keymap = {
+  ['space'] = 32,
+  ['\''] = 39,
+  [','] = 44,
+  ['-'] = 45,
+  ['.'] = 46,
+  ['/'] = 47,
+
+  ['0'] = 48,
+  ['1'] = 49,
+  ['2'] = 50,
+  ['3'] = 51,
+  ['4'] = 52,
+  ['5'] = 53,
+  ['6'] = 54,
+  ['7'] = 55,
+  ['8'] = 56,
+  ['9'] = 57,
+
+  [';'] = 59,
+  ['='] = 61,
+
+  ['a'] = 65,
+  ['b'] = 66,
+  ['c'] = 67,
+  ['d'] = 68,
+  ['e'] = 69,
+  ['f'] = 70,
+  ['g'] = 71,
+  ['h'] = 72,
+  ['i'] = 73,
+  ['j'] = 74,
+  ['k'] = 75,
+  ['l'] = 76,
+  ['m'] = 77,
+  ['n'] = 78,
+  ['o'] = 79,
+  ['p'] = 80,
+  ['q'] = 81,
+  ['r'] = 82,
+  ['s'] = 83,
+  ['t'] = 84,
+  ['u'] = 85,
+  ['v'] = 86,
+  ['w'] = 87,
+  ['x'] = 88,
+  ['y'] = 89,
+  ['z'] = 90,
+
+  ['['] = 91,
+  ['\\'] = 92,
+  [']'] = 93,
+  ['`'] = 96,
+
+  ['escape'] = 256,
+  ['return'] = 257,
+  ['enter'] = 257,
+  ['tab'] = 258,
+  ['backspace'] = 259,
+  ['insert'] = 260,
+  ['delete'] = 261,
+  ['right'] = 262,
+  ['left'] = 263,
+  ['down'] = 264,
+  ['up'] = 265,
+  ['pageup'] = 266,
+  ['pagedown'] = 267,
+  ['home'] = 268,
+  ['end'] = 269,
+  ['capslock'] = 280,
+  ['scrolllock'] = 281,
+  ['numlock'] = 282,
+  ['printscreen'] = 283,
+  ['pause'] = 284,
+
+  ['f1'] = 290,
+  ['f2'] = 291,
+  ['f3'] = 292,
+  ['f4'] = 293,
+  ['f5'] = 294,
+  ['f6'] = 295,
+  ['f7'] = 296,
+  ['f8'] = 297,
+  ['f9'] = 298,
+  ['f10'] = 299,
+  ['f11'] = 300,
+  ['f12'] = 301,
+
+  ['kp0'] = 320,
+  ['kp1'] = 321,
+  ['kp2'] = 322,
+  ['kp3'] = 323,
+  ['kp4'] = 324,
+  ['kp5'] = 325,
+  ['kp6'] = 326,
+  ['kp7'] = 327,
+  ['kp8'] = 328,
+  ['kp9'] = 329,
+  ['kp.'] = 330,
+  ['kp/'] = 331,
+  ['kp*'] = 332,
+  ['kp-'] = 333,
+  ['kp+'] = 334,
+  ['kpenter'] = 335,
+  ['kp='] = 336,
+
+  ['lshift'] = 340,
+  ['lctrl'] = 341,
+  ['lalt'] = 342,
+  ['lgui'] = 343,
+  ['rshift'] = 344,
+  ['rctrl'] = 345,
+  ['ralt'] = 346,
+  ['rgui'] = 347,
+  ['menu'] = 348
+}
+
+for k, v in pairs(keymap) do
+  keymap[v] = k
+end
+
+local keyboard = {}
+
+function keyboard.isDown(key, ...)
+  if not key then return false end
+  local keycode = keymap[key]
+  assert(keycode and type(keycode) == 'number', 'Unknown key: ' .. key)
+  return C.glfwGetKey(window, keycode) == 1 or keyboard.isDown(...)
+end
+
+C.glfwSetKeyCallback(window, function(window, key, scancode, action, mods)
+  if action ~= 2 and keymap[key] then
+    lovr.event.push(action > 0 and 'keypressed' or 'keyreleased', keymap[key])
+  end
+end)
+
+return keyboard

+ 158 - 0
examples/Debugging/FPS_Controls/lovr-mouse.lua

@@ -0,0 +1,158 @@
+local ffi = require 'ffi'
+local C = ffi.os == 'Windows' and ffi.load('glfw3') or ffi.C
+
+ffi.cdef [[
+  enum {
+    GLFW_CURSOR = 0x00033001,
+    GLFW_CURSOR_NORMAL = 0x00034001,
+    GLFW_CURSOR_HIDDEN = 0x00034002,
+    GLFW_CURSOR_DISABLED = 0x00034003,
+    GLFW_ARROW_CURSOR = 0x00036001,
+    GLFW_IBEAM_CURSOR = 0x00036002,
+    GLFW_CROSSHAIR_CURSOR = 0x00036003,
+    GLFW_HAND_CURSOR = 0x00036004,
+    GLFW_HRESIZE_CURSOR = 0x00036005,
+    GLFW_VRESIZE_CURSOR = 0x00036006
+  };
+
+  typedef struct {
+    int width;
+    int height;
+    unsigned char* pixels;
+  } GLFWimage;
+
+  typedef struct GLFWcursor GLFWcursor;
+  typedef struct GLFWwindow GLFWwindow;
+  typedef void(*GLFWmousebuttonfun)(GLFWwindow*, int, int, int);
+  typedef void(*GLFWcursorposfun)(GLFWwindow*, double, double);
+  typedef void(*GLFWscrollfun)(GLFWwindow*, double, double);
+
+  GLFWwindow* glfwGetCurrentContext(void);
+  void glfwGetInputMode(GLFWwindow* window, int mode);
+  void glfwSetInputMode(GLFWwindow* window, int mode, int value);
+  void glfwGetCursorPos(GLFWwindow* window, double* x, double* y);
+  void glfwSetCursorPos(GLFWwindow* window, double x, double y);
+  GLFWcursor* glfwCreateCursor(const GLFWimage* image, int xhot, int yhot);
+  GLFWcursor* glfwCreateStandardCursor(int kind);
+  void glfwSetCursor(GLFWwindow* window, GLFWcursor* cursor);
+  int glfwGetMouseButton(GLFWwindow* window, int button);
+  void glfwGetWindowSize(GLFWwindow* window, int* width, int* height);
+  GLFWmousebuttonfun glfwSetMouseButtonCallback(GLFWwindow* window, GLFWmousebuttonfun callback);
+  GLFWcursorposfun glfwSetCursorPosCallback(GLFWwindow* window, GLFWcursorposfun callback);
+  GLFWcursorposfun glfwSetScrollCallback(GLFWwindow* window, GLFWscrollfun callback);
+]]
+
+local window = C.glfwGetCurrentContext()
+
+local mouse = {}
+
+-- LÖVR uses framebuffer scale for everything, but glfw uses window scale for events.
+-- It is necessary to convert between the two at all boundaries.
+function mouse.getScale()
+  local x, _ = ffi.new('int[1]'), ffi.new('int[1]')
+  C.glfwGetWindowSize(window, x, _)
+  return lovr.graphics.getWidth() / x[0]
+end
+
+function mouse.getX()
+  local x = ffi.new('double[1]')
+  C.glfwGetCursorPos(window, x, nil)
+  return x[0] * mouse.getScale()
+end
+
+function mouse.getY()
+  local y = ffi.new('double[1]')
+  C.glfwGetCursorPos(window, nil, y)
+  return y[0] * mouse.getScale()
+end
+
+function mouse.getPosition()
+  local x, y = ffi.new('double[1]'), ffi.new('double[1]')
+  local scale = mouse.getScale()
+  C.glfwGetCursorPos(window, x, y)
+  return x[0] * scale, y[0] * scale
+end
+
+function mouse.setX(x)
+  local y = mouse.getY()
+  local scale = mouse.getScale()
+  C.glfwSetCursorPos(window, x / scale, y / scale)
+end
+
+function mouse.setY(y)
+  local x = mouse.getX()
+  local scale = mouse.getScale()
+  C.glfwSetCursorPos(window, x / scale, y / scale)
+end
+
+function mouse.setPosition(x, y)
+  local scale = mouse.getScale()
+  C.glfwSetCursorPos(window, x / scale, y / scale)
+end
+
+function mouse.isDown(button, ...)
+  if not button then return false end
+  return C.glfwGetMouseButton(window, button - 1) > 0 or mouse.isDown(...)
+end
+
+function mouse.getRelativeMode()
+  return C.glfwGetInputMode(window, C.GLFW_CURSOR) == C.GLFW_CURSOR_DISABLED
+end
+
+function mouse.setRelativeMode(enable)
+  C.glfwSetInputMode(window, C.GLFW_CURSOR, enable and C.GLFW_CURSOR_DISABLED or C.GLFW_CURSOR_NORMAL)
+end
+
+function mouse.newCursor(source, hotx, hoty)
+  if type(source) == 'string' or tostring(source) == 'Blob' then
+    source = lovr.data.newTextureData(source, false)
+  else
+    assert(tostring(source) == 'TextureData', 'Bad argument #1 to newCursor (TextureData expected)')
+  end
+  local image = ffi.new('GLFWimage', source:getWidth(), source:getHeight(), source:getPointer())
+  return C.glfwCreateCursor(image, hotx or 0, hoty or 0)
+end
+
+function mouse.getSystemCursor(kind)
+  local kinds = {
+    arrow = C.GLFW_ARROW_CURSOR,
+    ibeam = C.GLFW_IBEAM_CURSOR,
+    crosshair = C.GLFW_CROSSHAIR_CURSOR,
+    hand = C.GLFW_HAND_CURSOR,
+    sizewe = C.GLFW_HRESIZE_CURSOR,
+    sizens = C.GLFW_VRESIZE_CURSOR
+  }
+  assert(kinds[kind], string.format('Unknown cursor %q', tostring(kind)))
+  return C.glfwCreateStandardCursor(kinds[kind])
+end
+
+function mouse.setCursor(cursor)
+  C.glfwSetCursor(window, cursor)
+end
+
+C.glfwSetMouseButtonCallback(window, function(target, button, action, mods)
+  if target == window then
+    local x, y = mouse.getPosition()
+    lovr.event.push(action > 0 and 'mousepressed' or 'mousereleased', x, y, button + 1, false)
+  end
+end)
+
+local px, py = mouse.getPosition()
+C.glfwSetCursorPosCallback(window, function(target, x, y)
+  if target == window then
+    local scale = mouse.getScale()
+    x = x * scale
+    y = y * scale
+    lovr.event.push('mousemoved', x, y, x - px, y - py, false)
+    px, py = x, y
+  end
+end)
+
+C.glfwSetScrollCallback(window, function(target, x, y)
+  if target == window then
+    local scale = mouse.getScale()
+    lovr.event.push('wheelmoved', x * scale, y * scale)
+  end
+end)
+
+return mouse

+ 57 - 0
examples/Debugging/FPS_Controls/main.lua

@@ -0,0 +1,57 @@
+lovr.keyboard = require 'lovr-keyboard'
+lovr.mouse = require 'lovr-mouse'
+
+function lovr.load()
+  lovr.mouse.setRelativeMode(true)
+
+  camera = {
+    transform = lovr.math.newMat4(),
+    position = lovr.math.newVec3(),
+    movespeed = 10,
+    pitch = 0,
+    yaw = 0
+  }
+end
+
+function lovr.update(dt)
+  local velocity = vec4()
+
+  if lovr.keyboard.isDown('w', 'up') then
+    velocity.z = -1
+  elseif lovr.keyboard.isDown('s', 'down') then
+    velocity.z = 1
+  end
+
+  if lovr.keyboard.isDown('a', 'left') then
+    velocity.x = -1
+  elseif lovr.keyboard.isDown('d', 'right') then
+    velocity.x = 1
+  end
+
+  if #velocity > 0 then
+    velocity:normalize()
+    velocity:mul(camera.movespeed * dt)
+    camera.position:add(camera.transform:mul(velocity).xyz)
+  end
+
+  camera.transform:identity()
+  camera.transform:translate(0, 1.7, 0)
+  camera.transform:translate(camera.position)
+  camera.transform:rotate(camera.yaw, 0, 1, 0)
+  camera.transform:rotate(camera.pitch, 1, 0, 0)
+end
+
+function lovr.draw()
+  lovr.graphics.push()
+  lovr.graphics.transform(mat4(camera.transform):invert())
+  lovr.graphics.setColor(0xff0000)
+  lovr.graphics.cube('fill', 0, 1.7, -3, .5, lovr.timer.getTime())
+  lovr.graphics.setColor(0xffffff)
+  lovr.graphics.plane('fill', 0, 0, 0, 10, 10, math.pi / 2, 1, 0, 0)
+  lovr.graphics.pop()
+end
+
+function lovr.mousemoved(x, y, dx, dy)
+  camera.pitch = camera.pitch - dy * .001
+  camera.yaw = camera.yaw - dx * .001
+end