| ... | ... | @@ -4,6 +4,13 @@ local mp = require("mp") | 
| 4 | 4 |  | 
| 5 | 5 | --- Constants | 
| 6 | 6 |  | 
| 7 | +local SHADER_PARAM = [[ | |
| 8 | +//!PARAM angle | |
| 9 | +//!DESC Rotation angle in degrees | |
| 10 | +//!TYPE float | |
| 11 | +0.0 | |
| 12 | +]] | |
| 13 | + | |
| 7 | 14 | local SHADER_META = [[ | 
| 8 | 15 | //!HOOK MAINPRESUB | 
| 9 | 16 | //!DESC GPU rotate | 
| ... | ... | @@ -29,14 +36,31 @@ vec4 hook() | 
| 29 | 36 | --- State | 
| 30 | 37 |  | 
| 31 | 38 |  local state = { | 
| 32 | - angle = 0.0, | |
| 33 | - shader = nil, | |
| 39 | + angle = 0.0, | |
| 40 | + shader = nil, | |
| 41 | + gpu_next = false, | |
| 34 | 42 | } | 
| 35 | 43 |  | 
| 36 | 44 | --- Functions | 
| 37 | 45 |  | 
| 46 | +local function shader_param() | |
| 47 | + if state.gpu_next then | |
| 48 | + return SHADER_PARAM | |
| 49 | + else | |
| 50 | + return "" | |
| 51 | + end | |
| 52 | +end | |
| 53 | + | |
| 38 | 54 | local function shader_define() | 
| 39 | -    return table.concat({SHADER_DEFINE, state.angle}, " ") | |
| 55 | + if state.gpu_next then | |
| 56 | + return "" | |
| 57 | + else | |
| 58 | +        return table.concat({SHADER_DEFINE, state.angle}, " ") | |
| 59 | + end | |
| 60 | +end | |
| 61 | + | |
| 62 | +local function shader_opt() | |
| 63 | +    return table.concat({"angle", state.angle}, "=") | |
| 40 | 64 | end | 
| 41 | 65 |  | 
| 42 | 66 | local function remove() | 
| ... | ... | @@ -52,21 +76,44 @@ local function append(angle) | 
| 52 | 76 | state.angle = angle % 360 | 
| 53 | 77 | local shader = nil | 
| 54 | 78 | if state.angle ~= 0 then | 
| 55 | - shader = os.tmpname() | |
| 56 | -        mp.msg.debug("Writing", shader) | |
| 57 | - local file = io.open(shader, "w") | |
| 58 | -        file:write(table.concat({ | |
| 59 | - SHADER_META, | |
| 60 | - shader_define(), | |
| 61 | - SHADER_HOOK, | |
| 62 | - }, "\n")) | |
| 63 | - file:close() | |
| 64 | -        mp.commandv("change-list", "glsl-shaders", "append", shader) | |
| 79 | + if not state.gpu_next or not state.shader then | |
| 80 | + shader = os.tmpname() | |
| 81 | +            mp.msg.debug("Writing", shader) | |
| 82 | + local file = io.open(shader, "w") | |
| 83 | +            file:write(table.concat({ | |
| 84 | + shader_param(), | |
| 85 | + SHADER_META, | |
| 86 | + shader_define(), | |
| 87 | + SHADER_HOOK, | |
| 88 | + }, "\n")) | |
| 89 | + file:close() | |
| 90 | +            mp.commandv("change-list", "glsl-shaders", "append", shader) | |
| 91 | + end | |
| 92 | + if state.gpu_next then | |
| 93 | + shader = shader or state.shader | |
| 94 | +            mp.msg.debug("Setting shader opt") | |
| 95 | +            mp.commandv("change-list", "glsl-shader-opts", "append", shader_opt()) | |
| 96 | + end | |
| 97 | + end | |
| 98 | + if state.angle == 0 or not state.gpu_next then | |
| 99 | + remove() | |
| 65 | 100 | end | 
| 66 | - remove() | |
| 67 | 101 | state.shader = shader | 
| 68 | 102 | end | 
| 69 | 103 |  | 
| 104 | +--- Properties | |
| 105 | + | |
| 106 | +local function current_vo(_, vo) | |
| 107 | + local gpu_next = vo == "gpu-next" | |
| 108 | + if state.gpu_next ~= gpu_next then | |
| 109 | +        mp.msg.debug("gpu-next", gpu_next) | |
| 110 | + state.gpu_next = gpu_next | |
| 111 | + remove() | |
| 112 | + append(state.angle) | |
| 113 | + end | |
| 114 | +end | |
| 115 | +mp.observe_property("current-vo", "string", current_vo) | |
| 116 | + | |
| 70 | 117 | --- Events | 
| 71 | 118 |  | 
| 72 | 119 |  mp.register_event("shutdown", remove) | 
| ... | ... | @@ -50,16 +50,19 @@ end | 
| 50 | 50 |  | 
| 51 | 51 | local function append(angle) | 
| 52 | 52 | state.angle = angle % 360 | 
| 53 | - local shader = os.tmpname() | |
| 54 | -    mp.msg.debug("Writing", shader) | |
| 55 | - local file = io.open(shader, "w") | |
| 56 | -    file:write(table.concat({ | |
| 57 | - SHADER_META, | |
| 58 | - shader_define(), | |
| 59 | - SHADER_HOOK, | |
| 60 | - }, "\n")) | |
| 61 | - file:close() | |
| 62 | -    mp.commandv("change-list", "glsl-shaders", "append", shader) | |
| 53 | + local shader = nil | |
| 54 | + if state.angle ~= 0 then | |
| 55 | + shader = os.tmpname() | |
| 56 | +        mp.msg.debug("Writing", shader) | |
| 57 | + local file = io.open(shader, "w") | |
| 58 | +        file:write(table.concat({ | |
| 59 | + SHADER_META, | |
| 60 | + shader_define(), | |
| 61 | + SHADER_HOOK, | |
| 62 | + }, "\n")) | |
| 63 | + file:close() | |
| 64 | +        mp.commandv("change-list", "glsl-shaders", "append", shader) | |
| 65 | + end | |
| 63 | 66 | remove() | 
| 64 | 67 | state.shader = shader | 
| 65 | 68 | end | 
| ... | ... | @@ -50,17 +50,18 @@ end | 
| 50 | 50 |  | 
| 51 | 51 | local function append(angle) | 
| 52 | 52 | state.angle = angle % 360 | 
| 53 | - remove() | |
| 54 | - state.shader = os.tmpname() | |
| 55 | -    mp.msg.debug("Writing", state.shader) | |
| 56 | - local file = io.open(state.shader, "w") | |
| 53 | + local shader = os.tmpname() | |
| 54 | +    mp.msg.debug("Writing", shader) | |
| 55 | + local file = io.open(shader, "w") | |
| 57 | 56 |      file:write(table.concat({ | 
| 58 | 57 | SHADER_META, | 
| 59 | 58 | shader_define(), | 
| 60 | 59 | SHADER_HOOK, | 
| 61 | 60 | }, "\n")) | 
| 62 | 61 | file:close() | 
| 63 | -    mp.commandv("change-list", "glsl-shaders", "append", state.shader) | |
| 62 | +    mp.commandv("change-list", "glsl-shaders", "append", shader) | |
| 63 | + remove() | |
| 64 | + state.shader = shader | |
| 64 | 65 | end | 
| 65 | 66 |  | 
| 66 | 67 | --- Events | 
| 1 | 1 | new file mode 100644 | 
| ... | ... | @@ -0,0 +1,75 @@ | 
| 1 | +--- Require | |
| 2 | + | |
| 3 | +local mp = require("mp") | |
| 4 | + | |
| 5 | +--- Constants | |
| 6 | + | |
| 7 | +local SHADER_META = [[ | |
| 8 | +//!HOOK MAINPRESUB | |
| 9 | +//!DESC GPU rotate | |
| 10 | +//!BIND HOOKED | |
| 11 | +]] | |
| 12 | + | |
| 13 | +local SHADER_DEFINE = "#define angle" | |
| 14 | + | |
| 15 | +local SHADER_HOOK = [[ | |
| 16 | +vec4 hook() | |
| 17 | +{ | |
| 18 | + float rad = radians(angle); | |
| 19 | + float c = cos(rad); | |
| 20 | + float s = sin(rad); | |
| 21 | + mat2 rot = mat2(c, -s, s, c); | |
| 22 | + vec2 pos = rot * ((HOOKED_pos - 0.5) * HOOKED_size) * HOOKED_pt + 0.5; | |
| 23 | + if (!all(equal(pos, clamp(pos, 0.0, 1.0)))) | |
| 24 | + return vec4(0.0); | |
| 25 | + return HOOKED_tex(pos); | |
| 26 | +} | |
| 27 | +]] | |
| 28 | + | |
| 29 | +--- State | |
| 30 | + | |
| 31 | +local state = { | |
| 32 | + angle = 0.0, | |
| 33 | + shader = nil, | |
| 34 | +} | |
| 35 | + | |
| 36 | +--- Functions | |
| 37 | + | |
| 38 | +local function shader_define() | |
| 39 | +    return table.concat({SHADER_DEFINE, state.angle}, " ") | |
| 40 | +end | |
| 41 | + | |
| 42 | +local function remove() | |
| 43 | + if state.shader then | |
| 44 | +        mp.msg.debug("Removing", state.shader) | |
| 45 | +        mp.commandv("change-list", "glsl-shaders", "remove", state.shader) | |
| 46 | + os.remove(state.shader) | |
| 47 | + state.shader = nil | |
| 48 | + end | |
| 49 | +end | |
| 50 | + | |
| 51 | +local function append(angle) | |
| 52 | + state.angle = angle % 360 | |
| 53 | + remove() | |
| 54 | + state.shader = os.tmpname() | |
| 55 | +    mp.msg.debug("Writing", state.shader) | |
| 56 | + local file = io.open(state.shader, "w") | |
| 57 | +    file:write(table.concat({ | |
| 58 | + SHADER_META, | |
| 59 | + shader_define(), | |
| 60 | + SHADER_HOOK, | |
| 61 | + }, "\n")) | |
| 62 | + file:close() | |
| 63 | +    mp.commandv("change-list", "glsl-shaders", "append", state.shader) | |
| 64 | +end | |
| 65 | + | |
| 66 | +--- Events | |
| 67 | + | |
| 68 | +mp.register_event("shutdown", remove) | |
| 69 | + | |
| 70 | +--- Script messages | |
| 71 | + | |
| 72 | +local function set(angle) append(angle) end | |
| 73 | +local function add(angle) append(angle + state.angle) end | |
| 74 | +mp.register_script_message("set", set) | |
| 75 | +mp.register_script_message("add", add) |