scripts/gpu_rotate.lua
ca63b185
 --- Require
 
 local mp = require("mp")
 
 --- Constants
 
44d727d0
 local SHADER_PARAM = [[
 //!PARAM angle
 //!DESC Rotation angle in degrees
 //!TYPE float
 0.0
 ]]
 
ca63b185
 local SHADER_META = [[
 //!HOOK MAINPRESUB
 //!DESC GPU rotate
 //!BIND HOOKED
 ]]
 
 local SHADER_DEFINE = "#define angle"
 
 local SHADER_HOOK = [[
 vec4 hook()
 {
     float rad = radians(angle);
     float c   = cos(rad);
     float s   = sin(rad);
     mat2  rot = mat2(c, -s, s, c);
     vec2  pos = rot * ((HOOKED_pos - 0.5) * HOOKED_size) * HOOKED_pt + 0.5;
     if (!all(equal(pos, clamp(pos, 0.0, 1.0))))
         return vec4(0.0);
     return HOOKED_tex(pos);
 }
 ]]
 
 --- State
 
 local state = {
44d727d0
     angle    = 0.0,
     shader   = nil,
     gpu_next = false,
ca63b185
 }
 
 --- Functions
 
44d727d0
 local function shader_param()
     if state.gpu_next then
         return SHADER_PARAM
     else
         return ""
     end
 end
 
ca63b185
 local function shader_define()
44d727d0
     if state.gpu_next then
         return ""
     else
         return table.concat({SHADER_DEFINE, state.angle}, " ")
     end
 end
 
 local function shader_opt()
     return table.concat({"angle", state.angle}, "=")
ca63b185
 end
 
 local function remove()
     if state.shader then
         mp.msg.debug("Removing", state.shader)
         mp.commandv("change-list", "glsl-shaders", "remove", state.shader)
         os.remove(state.shader)
         state.shader = nil
     end
 end
 
 local function append(angle)
     state.angle = angle % 360
b79e4588
     local shader = nil
     if state.angle ~= 0 then
44d727d0
         if not state.gpu_next or not state.shader then
             shader = os.tmpname()
             mp.msg.debug("Writing", shader)
             local file = io.open(shader, "w")
             file:write(table.concat({
                 shader_param(),
                 SHADER_META,
                 shader_define(),
                 SHADER_HOOK,
             }, "\n"))
             file:close()
             mp.commandv("change-list", "glsl-shaders", "append", shader)
         end
         if state.gpu_next then
             shader = shader or state.shader
             mp.msg.debug("Setting shader opt")
             mp.commandv("change-list", "glsl-shader-opts", "append", shader_opt())
         end
     end
     if state.angle == 0 or not state.gpu_next then
         remove()
b79e4588
     end
9ac9e7c4
     state.shader = shader
ca63b185
 end
 
44d727d0
 --- Properties
 
 local function current_vo(_, vo)
     local gpu_next = vo == "gpu-next"
     if state.gpu_next ~= gpu_next then
         mp.msg.debug("gpu-next", gpu_next)
         state.gpu_next = gpu_next
         remove()
         append(state.angle)
     end
 end
 mp.observe_property("current-vo", "string", current_vo)
 
ca63b185
 --- Events
 
 mp.register_event("shutdown", remove)
 
 --- Script messages
 
 local function set(angle) append(angle)               end
 local function add(angle) append(angle + state.angle) end
 mp.register_script_message("set", set)
 mp.register_script_message("add", add)