Quellcode durchsuchen

Partially completed mirror HUD example

mcc vor 6 Jahren
Ursprung
Commit
5572b88563
3 geänderte Dateien mit 274 neuen und 0 gelöschten Zeilen
  1. 119 0
      examples/Hud/main.lua
  2. 116 0
      examples/Hud/mouse.lua
  3. 39 0
      examples/Hud/shader.lua

+ 119 - 0
examples/Hud/main.lua

@@ -0,0 +1,119 @@
+-- Sample contributed by andi mcc
+
+local shader = require 'shader'
+lovr.mouse = require 'mouse'
+
+local mirror = lovr.mirror
+local font = lovr.graphics.newFont(48)
+font:setFlipEnabled(true)
+font:setPixelDensity(1)
+
+local triangle = lovr.graphics.newMesh(
+	{{ 'lovrPosition', 'float', 3 }, { 'lovrNormal', 'float', 3 }},
+	{{0,-1,0, 0,0,1}, {0.75,1,0, 0,0,1}, {-0.75,1,0, 0,0,1}},
+	'triangles', 'static'
+	)
+
+-- Constants
+local pixwidth = lovr.graphics.getWidth()
+local pixheight = lovr.graphics.getHeight()
+local aspect = pixwidth/pixheight
+local height = 2
+local width = aspect*2
+local topmargin = 0.2
+local cells = 7
+local gridheight = (height-topmargin*2)
+local gridspan = gridheight/2
+local cellheight = gridheight/cells
+local cellspan = cellheight/2
+local bannedcell = math.ceil(cells/2)
+local towerscalexz = 2
+local towerscaley = 3
+
+local matrix = lovr.math.mat4():orthographic(-aspect, aspect, -1, 1, -64, 64)
+
+local grid = {}
+for x=1,cells do grid[x] = {} end
+
+function lovr.load()
+	lovr.handlers['mousepressed'] = function(x,y)
+		local inx = x * width / pixwidth - width/2
+		local iny = y * height / pixheight - height/2
+		local gridorigin = -gridspan - cellheight
+		local gx = (inx - gridorigin) / cellheight
+		local gy = (iny - gridorigin) / cellheight
+		print('mouse:', pixwidth, pixheight, x, y, inx, iny, gx, gy)
+		local fx = math.floor(gx)
+		local fy = math.floor(gy)
+		if fx >= 1 and fy >= 1 and fx <= cells and fy <= cells
+		   and not (fx == bannedcell and fy == bannedcell) then
+			if grid[fx][fy] then
+				grid[fx][fy] = nil
+			else
+				grid[fx][fy] = lovr.math.random()
+			end
+		end
+	end
+end
+
+function drawGrid()
+	for _x=1,cells do for _y=1,cells do
+		local x = -gridspan + _x * cellheight - cellspan
+		local y = -gridspan + _y * cellheight - cellspan
+
+		local gray = grid[_x][_y]
+		if gray then
+			lovr.graphics.setColor(gray,gray,gray,1)
+			lovr.graphics.plane('fill', x, y, 0, cellheight, cellheight)
+		end
+	end end
+
+	lovr.graphics.setColor(1,1,1,1)
+	for _x=0,cells do for _y=0,cells do
+		local x = -gridspan + _x * cellheight
+		local y = -gridspan + _y * cellheight
+		lovr.graphics.line(-gridspan, y, 0, gridspan, y, 0)
+		lovr.graphics.line(x, -gridspan, 0, x, gridspan, 0)
+	end end
+
+	lovr.graphics.push()
+	local x, y, z, angle, ax, ay, az = lovr.headset.getPose()
+	-- Equation from: http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToEuler/index.htm
+	local s = math.sin(angle);
+	local c = math.cos(angle);
+	local t = 1-c;
+	local xzangle = math.atan2(ay*s - ax*az*t , 1 - (ay*ay + az*az) * t);
+	lovr.graphics.setColor(1,0,0,1)
+	lovr.graphics.translate(x / towerscalexz, z / towerscalexz, 0)
+	lovr.graphics.scale(cellheight*0.5*0.75)
+	lovr.graphics.rotate(-xzangle, 0, 0, 1)
+	triangle:draw()
+	lovr.graphics.pop()
+end
+
+function lovr.mirror()
+	mirror()
+	--lovr.graphics.clear()
+	lovr.graphics.setShader(nil)
+	lovr.graphics.origin()
+	lovr.graphics.setDepthTest(nil)
+	lovr.graphics.setProjection(matrix)
+	drawGrid()
+end
+
+function floorbox(_x,_y,gray)
+	local x = -gridspan + _x * cellheight - cellspan
+	local z = -gridspan + _y * cellheight - cellspan
+	local height = gray * towerscaley
+	lovr.graphics.box('fill', x*towerscalexz, height/2, z*towerscalexz, cellheight*towerscalexz, height, cellheight*towerscalexz)
+end
+
+function lovr.draw()
+	lovr.graphics.setDepthTest('lequal', true)
+	lovr.graphics.setShader(shader)
+	lovr.graphics.setColor(0,1,1)
+	for x=1,cells do for y=1,cells do
+		local gray = grid[x][y]
+		if gray then floorbox(x,y,gray) end
+	end end
+end

+ 116 - 0
examples/Hud/mouse.lua

@@ -0,0 +1,116 @@
+-- Source: https://github.com/bjornbytes/lovr-mouse/
+-- Source: c2f704db2463e05c453580b80b26200d5dd508a9
+
+local ffi = require 'ffi'
+local C = ffi.os == 'Windows' and ffi.load('glfw3') or ffi.C
+
+ffi.cdef [[
+  typedef enum {
+    GLFW_CURSOR = 0x00033001,
+    GLFW_CURSOR_NORMAL = 0x00034001,
+    GLFW_CURSOR_HIDDEN = 0x00034002,
+    GLFW_CURSOR_DISABLED = 0x00034003
+  } Constants;
+
+  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);
+  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 = {}
+
+-- Lovr 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()
+  C.glfwSetCursorPos(window, x/scale, y/scale)
+end
+
+function mouse.setPosition(x, y)
+  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
+
+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

+ 39 - 0
examples/Hud/shader.lua

@@ -0,0 +1,39 @@
+return lovr.graphics.newShader([[
+out vec3 lightDirection;
+out vec3 normalDirection;
+
+vec3 lightPosition = vec3(0, 10, 3);
+
+vec4 position(mat4 projection, mat4 transform, vec4 vertex) {
+  vec4 vVertex = transform * vec4(lovrPosition, 1.);
+  vec4 vLight = lovrView * vec4(lightPosition, 1.);
+
+  lightDirection = normalize(vec3(vLight - vVertex));
+  normalDirection = normalize(lovrNormalMatrix * lovrNormal);
+
+  return projection * transform * vertex;
+}
+]], [[
+in vec3 lightDirection;
+in vec3 normalDirection;
+
+vec3 cAmbient = vec3(.25);
+vec3 cDiffuse = vec3(.75);
+vec3 cSpecular = vec3(.35);
+
+vec4 color(vec4 graphicsColor, sampler2D image, vec2 uv) {
+  float diffuse = max(dot(normalDirection, lightDirection), 0.);
+  float specular = 0.;
+
+  if (diffuse > 0.) {
+    vec3 r = reflect(lightDirection, normalDirection);
+    vec3 viewDirection = normalize(-vec3(gl_FragCoord));
+
+    float specularAngle = max(dot(r, viewDirection), 0.);
+    specular = pow(specularAngle, 5.);
+  }
+
+  vec3 cFinal = pow(clamp(vec3(diffuse) * cDiffuse + vec3(specular) * cSpecular, cAmbient, vec3(1.)), vec3(.4545));
+  return vec4(cFinal, 1.) * graphicsColor * texture(image, uv);
+}
+]])