带有 gnome 扩展的 ClutterShaderEffect
ClutterShaderEffect with gnome extension
我的项目的目的是实现一个着色器并将其附加到舞台上。我想要使用 JS gnome 扩展系统对整个屏幕进行变形。 (我在 C 中完成并重新编译 gnome,但我想使用一种不需要任何编译的技术)。
然后,我正在寻找实现并将自定义 ShaderEffect 附加到舞台。
我试着用下面的代码来做,但整个屏幕都冻结了:
fx = new Clutter.ShaderEffect({
shader_type: Clutter.ShaderType.FRAGMENT_SHADER });
fx.set_shader_source(shader);
fx.set_uniform_value('height', this._actor.get_height());
fx.set_uniform_value('width', this._actor.get_width());
this._actor.add_effect_with_name('shader', fx);
this._actor = global.stage。这是有效的,但屏幕冻结。所以我阅读了文档并发现了这个 Doc link:
Implementing a ClutterOffscreenEffect
Creating a sub-class of ClutterOffscreenEffect requires, in case of overriding the ClutterEffect virtual functions, to chain up to the ClutterOffscreenEffect's implementation.
On top of the ClutterEffect's virtual functions, ClutterOffscreenEffect also provides a ClutterOffscreenEffectClass.paint_target() function, which encapsulates the effective painting of the texture that contains the result of the offscreen redirection.
但是我应该如何在 JS 中做到这一点?
const ClutterShaderEffectCustom = new Lang.Class({
Name : 'ClutterShaderEffectCustom',
Extends : Clutter.ShaderEffect,
_init : function(shader_type, actor, shaderSource) {
// some stuff
},
paint_target : function() {
// TODO but how ? :/
}
});
因为我有一些 C 文件在做,但我不知道如何在 JS 中实现它。非官方 JS 文档没有帮助。
我还尝试了 Clutter.Shader 的其他方法:
fx = new Clutter.Shader();
fx.set_fragment_source(shader, shader.lenght);
fx.set_uniform('height', this._actor.get_height());
fx.set_uniform('width', this._actor.get_width());
this._actor.set_shader(fx);
但是着色器只应用于孩子,而不是舞台。 this._actor = global.stage。这是使用第二种方法的结果的概述。我的着色器正在复制纹理,只是为了 test.But 为什么只在图标上而不是在整个屏幕上,因为我将它附加到舞台上?
我使用以下源代码修复了我的非刷新问题:
myFunction : function() {
fx = new Clutter.ShaderEffect({
shader_type: Clutter.ShaderType.FRAGMENT_SHADER });
fx.set_shader_source(shader);
fx.set_uniform_value('height', this._actor.get_height());
fx.set_uniform_value('width', this._actor.get_width());
this._actor.add_effect_with_name('shader', fx);
this._timeline = new Clutter.Timeline({ duration: 1, repeat_count: -1 });
this._timeline.connect('new-frame', Lang.bind(this, this._newFrame));
this._timeline.start();
}
_newFrame: function() {
this._actor.scale_y = 1.0;
}
我的项目的目的是实现一个着色器并将其附加到舞台上。我想要使用 JS gnome 扩展系统对整个屏幕进行变形。 (我在 C 中完成并重新编译 gnome,但我想使用一种不需要任何编译的技术)。
然后,我正在寻找实现并将自定义 ShaderEffect 附加到舞台。 我试着用下面的代码来做,但整个屏幕都冻结了:
fx = new Clutter.ShaderEffect({
shader_type: Clutter.ShaderType.FRAGMENT_SHADER });
fx.set_shader_source(shader);
fx.set_uniform_value('height', this._actor.get_height());
fx.set_uniform_value('width', this._actor.get_width());
this._actor.add_effect_with_name('shader', fx);
this._actor = global.stage。这是有效的,但屏幕冻结。所以我阅读了文档并发现了这个 Doc link:
Implementing a ClutterOffscreenEffect Creating a sub-class of ClutterOffscreenEffect requires, in case of overriding the ClutterEffect virtual functions, to chain up to the ClutterOffscreenEffect's implementation. On top of the ClutterEffect's virtual functions, ClutterOffscreenEffect also provides a ClutterOffscreenEffectClass.paint_target() function, which encapsulates the effective painting of the texture that contains the result of the offscreen redirection.
但是我应该如何在 JS 中做到这一点?
const ClutterShaderEffectCustom = new Lang.Class({
Name : 'ClutterShaderEffectCustom',
Extends : Clutter.ShaderEffect,
_init : function(shader_type, actor, shaderSource) {
// some stuff
},
paint_target : function() {
// TODO but how ? :/
}
});
因为我有一些 C 文件在做,但我不知道如何在 JS 中实现它。非官方 JS 文档没有帮助。
我还尝试了 Clutter.Shader 的其他方法:
fx = new Clutter.Shader();
fx.set_fragment_source(shader, shader.lenght);
fx.set_uniform('height', this._actor.get_height());
fx.set_uniform('width', this._actor.get_width());
this._actor.set_shader(fx);
但是着色器只应用于孩子,而不是舞台。 this._actor = global.stage。这是使用第二种方法的结果的概述。我的着色器正在复制纹理,只是为了 test.But 为什么只在图标上而不是在整个屏幕上,因为我将它附加到舞台上?
我使用以下源代码修复了我的非刷新问题:
myFunction : function() {
fx = new Clutter.ShaderEffect({
shader_type: Clutter.ShaderType.FRAGMENT_SHADER });
fx.set_shader_source(shader);
fx.set_uniform_value('height', this._actor.get_height());
fx.set_uniform_value('width', this._actor.get_width());
this._actor.add_effect_with_name('shader', fx);
this._timeline = new Clutter.Timeline({ duration: 1, repeat_count: -1 });
this._timeline.connect('new-frame', Lang.bind(this, this._newFrame));
this._timeline.start();
}
_newFrame: function() {
this._actor.scale_y = 1.0;
}