Webgl 如何获得均匀变量的索引?

Webgl 如何获得均匀变量的索引?,webgl,Webgl,我目前正在编写一个自动生成统一设置器的函数,因此我需要统一变量的类型信息。现在的想法是使用存储在通过调用gl.getActiveUniform返回的对象中的数据类型,该方法期望统一的索引作为第二个参数,因此必须首先对其求值 但就我所见,通过传入变量的标识符,无法从WebGL接口检索统一的索引,对吗 当然有gl.getUniformLocation,但此方法返回的对象没有任何公共成员,它的唯一目的似乎是作为setter函数的参数传入-尽管它是提供统一索引信息的正确位置,不是吗 最后还有gl.get

我目前正在编写一个自动生成统一设置器的函数,因此我需要统一变量的类型信息。现在的想法是使用存储在通过调用
gl.getActiveUniform
返回的对象中的数据类型,该方法期望统一的索引作为第二个参数,因此必须首先对其求值

但就我所见,通过传入变量的标识符,无法从WebGL接口检索统一的索引,对吗

当然有
gl.getUniformLocation
,但此方法返回的对象没有任何公共成员,它的唯一目的似乎是作为setter函数的参数传入-尽管它是提供统一索引信息的正确位置,不是吗

最后还有
gl.getProgramParameter
,可以使用
gl.ACTIVE\u UNIFORMS
作为第二个参数调用它,但它只返回着色器中声明的一致性计数

所以,问题是,我必须自己提供变量索引值的信息,还是WebGL中有内置的功能来完成这项工作

编辑

嗯,有时候你看不到森林。显而易见的解决方案不是从变量名中获取索引值,而是从其索引中获取变量名,因为统一名称也是由
gl.getActiveUniform
返回的对象的成员

该过程将首先使用
gl.ACTIVE\u UNIFORMS
调用
gl.getProgramParameter
,以获取变量的计数,然后在每次迭代中循环调用
gl.getActiveUniform
。我认为这将是更优雅的解决方案


但是,尽管如此,如果有一种直接的方法可以通过名称获取单个制服的索引,那将是一件很有趣的事情…

你在编辑中提出的基本上就是我一直以来的做法。像这样:

function makeUniformSetters(program){
    var unifInfos = {};
    var uniformCount = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS);
    for (var i = 0; i < uniformCount; i++) {
        var info = gl.getActiveUniform(program, i);
        info.loc = gl.getUniformLocation(program, info.name);
        unifInfos[info.name] = info;
    }

    var unifSetters = {};
    Object.keys(unifInfos).forEach(function(k){
        unifSetters[k] = createUniformSetter(k);
    });


    function createUniformSetter(n){
        var info = unifInfos[n];
        if (info === undefined){
            console.log("program is not using uniform "+n);
            return function noOp(){};
        }

        var u = info;
        var loc = u.loc;
        var type = u.type;


        if (type === gl.FLOAT)
            return function(v){ gl.uniform1f(loc,v);};
        if (type === gl.FLOAT_VEC2)
            return function(v){ gl.uniform2fv(loc,v);};

        // etc
    }

    return unifSetters;
}
函数makeUniformSetters(程序){
var unifInfos={};
var uniformCount=gl.getProgramParameter(程序,gl.ACTIVE\u);
对于(变量i=0;i
然后您可以像这样使用它:
unifSetters[“u_viewProjection”](mat4)


我修改了代码以去除特定于引擎的部件,因此它可能无法100%开箱即用。但希望这个想法应该是清楚的。

你好,Wacław,非常感谢你的回答!这与我在此期间所写的非常接近。很高兴知道我走对了路最后…;-)