--- Require local mp = require("mp") --- Constants local SHADER_PARAM = [[ //!PARAM angle //!DESC Rotation angle in degrees //!TYPE float 0.0 ]] 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 = { angle = 0.0, shader = nil, gpu_next = false, } --- Functions local function shader_param() if state.gpu_next then return SHADER_PARAM else return "" end end local function shader_define() 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}, "=") 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 local shader = nil if state.angle ~= 0 then 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() end state.shader = shader end --- 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) --- 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)