如何正确使用Clutter.ShaderEffect.set_uniform_value()?

How to use Clutter.ShaderEffect.set_uniform_value() properly?

我正在尝试将 uniform float 设置为 Clutter.ShaderEffect。如果将浮点数传递给 set_uniform_value(),这会很有效。但是,当您传递整数 Number 时,会抛出 OpenGL 错误(1282,无效操作)。在这种情况下,实现似乎假定制服实际上是 int 类型。这是一个最小的例子:

const {Clutter, GObject} = imports.gi;

Clutter.init(null);

let stage  = new Clutter.Stage({width: 200, height: 200});
let shader = new Clutter.ShaderEffect({shader_type: Clutter.ShaderType.FRAGMENT_SHADER});

shader.set_shader_source(`
  uniform float value;

  void main(void) {
    cogl_color_out = vec4(value, 0, 0, 1);
  }
`);

// This creates the OpenGL Error.
// shader.set_uniform_value('value', 1);

// This works however:
shader.set_uniform_value('value', 0.999);

stage.add_effect(shader);

stage.connect('destroy', () => Clutter.main_quit());
stage.show();

Clutter.main();

那么如何强制 set_uniform_value() 将该值解释为浮点数?阅读文档 (https://gjs-docs.gnome.org/clutter6~6_api/clutter.shadereffect#method-set_uniform_value),我假设我可以通过 GObject.Value - 可能像这样:

let value = new GObject.Value();
value.init(GObject.TYPE_FLOAT);
value.set_float(1.0);
shader.set_uniform_value('value', value);

但这会产生错误 Invalid uniform of type 'GValue' for name 'value'。也许我现在有一个 GObject.Value 包含一个 GObject.Value 包含一个 GObject.TYPE_FLOAT?

如果有人找这个问题,我有答案:

https://gjs-docs.gnome.org/clutter7~7_api/clutter.shadereffect#method-set_uniform_value 值 - 一个 GObject.Value GObject.TYPE_FLOAT for float

在 gjs GTK 中 Javascript 他们有 https://gjs-docs.gnome.org/clutter7~7_api/clutter.value_set_shader_float

value_set_shader_float(value,[float]) 方法 - 必须使用 %CLUTTER_TYPE_SHADER_FLOAT.

初始化值

并且在 Javascript 版本的 GTK 中,他们没有任何方法来初始化 CLUTTER_TYPE_SHADER_FLOATGObject.TYPE_FLOAT

解决方法是:

function make_float(val) {
    return Math.floor(val)==val?val+0.000001:val;
}

自 GJS 1.68.0 (GNOME 40) 起,传递 GObject.Value 有效:

let value = new GObject.Value();
value.init(GObject.TYPE_FLOAT);
value.set_float(1);
shader.set_uniform_value('value', value);