在没有上下文的情况下访问 WebGL constants/enums
Access WebGL constants/enums without context
我觉得很奇怪,所有的WebGL常量都被定义为渲染上下文的成员。这意味着如果上下文被包装在某个库中,访问这些常量就会出现问题。
我有什么理由不能明确定义它们吗?或者,如果它们是实现定义的,也许是第一次创建上下文时,将所有枚举值写入某个全局对象?
基本上,我不想写 new renderer.Texture(renderer.gl.TEXTURE_2D)
或 new renderer.Texture("TEXTURE_2D")
,而是想写 new renderer.Texture(WebGL.TEXTURE_2D)
.
您可以自由地将它们定义为您自己的常量。事实上,它可能会使您的代码更快
const TEXTURE_2D = 0x0DE1
...
gl.bindTexture(TEXTURE_2D, someTexture);
完全没问题。而且,如果该代码是 运行 通过现代 JavaScript 压缩器,它将变成这个
gl.bindTexture(0x0DE1, someTexture);
这可以说会更快。比 gl.TEXTURE_2D
更快,因为使用 gl.TEXTURE_2D
JavaScript 引擎必须始终检查是否有人没有将 gl.TEXTURE_2D
分配给其他东西。比 TEXTURE_2D
快,因为即使是 const 变量也代表正在创建的东西,而 0x0DE1
绝对不会。
只是因为稍后我可能会收到一些问题,我上面关于速度的观点是 JavaScript 引擎必须在您每次调用时检查
gl.bindTexture(gl.TEXTURE2D, ...)
某处有人没有做
gl.TEXTURE_2D = 123
或属性getter
Object.defineProperty(gl, 'TEXTURE_2D', {
enumerable: true,
writable: false,
get() {
console.log('TEXTURE_2D was accessed at', (new Error()).stack));
return 0xDE1;
}
});
JavaScript 引擎无法假定 TEXTURE_2D
属性 未更改。每次都要检查。
至于 const
可能存在也可能没有一般速度差异,但是例如,如果我们创建一个函数 returns 像这样的函数
function makeFuncThatReturnsValue(value) {
const v = value;
return function() {
return v;
}
}
我们可以看到每次调用makeFuncThatReturnsValue
都会在闭包中创建并捕获一个新的v
。
直接使用文字不会有这个问题,不会创建任何东西。当然你不想直接使用文字,幻数是不好的,但如果你用现代压缩器编译你的 JavaScript 它会在适当的地方将任何 const
换成文字。
运行一个例子通过Google's closure compiler
代码:
const w = {
TEXTURE_2D: 0x0DE1,
};
gl.bindTexture(w.TEXTURE_2D, null);
gl.bindTexture(3553,null);
您可以使用 WebGLRenderingContext
和 WebGL2RenderingContext
访问它们,而无需创建上下文实例。例如:
console.log(WebGLRenderingContext.TEXTURE_2D); // 3553
我觉得很奇怪,所有的WebGL常量都被定义为渲染上下文的成员。这意味着如果上下文被包装在某个库中,访问这些常量就会出现问题。
我有什么理由不能明确定义它们吗?或者,如果它们是实现定义的,也许是第一次创建上下文时,将所有枚举值写入某个全局对象?
基本上,我不想写 new renderer.Texture(renderer.gl.TEXTURE_2D)
或 new renderer.Texture("TEXTURE_2D")
,而是想写 new renderer.Texture(WebGL.TEXTURE_2D)
.
您可以自由地将它们定义为您自己的常量。事实上,它可能会使您的代码更快
const TEXTURE_2D = 0x0DE1
...
gl.bindTexture(TEXTURE_2D, someTexture);
完全没问题。而且,如果该代码是 运行 通过现代 JavaScript 压缩器,它将变成这个
gl.bindTexture(0x0DE1, someTexture);
这可以说会更快。比 gl.TEXTURE_2D
更快,因为使用 gl.TEXTURE_2D
JavaScript 引擎必须始终检查是否有人没有将 gl.TEXTURE_2D
分配给其他东西。比 TEXTURE_2D
快,因为即使是 const 变量也代表正在创建的东西,而 0x0DE1
绝对不会。
只是因为稍后我可能会收到一些问题,我上面关于速度的观点是 JavaScript 引擎必须在您每次调用时检查
gl.bindTexture(gl.TEXTURE2D, ...)
某处有人没有做
gl.TEXTURE_2D = 123
或属性getter
Object.defineProperty(gl, 'TEXTURE_2D', {
enumerable: true,
writable: false,
get() {
console.log('TEXTURE_2D was accessed at', (new Error()).stack));
return 0xDE1;
}
});
JavaScript 引擎无法假定 TEXTURE_2D
属性 未更改。每次都要检查。
至于 const
可能存在也可能没有一般速度差异,但是例如,如果我们创建一个函数 returns 像这样的函数
function makeFuncThatReturnsValue(value) {
const v = value;
return function() {
return v;
}
}
我们可以看到每次调用makeFuncThatReturnsValue
都会在闭包中创建并捕获一个新的v
。
直接使用文字不会有这个问题,不会创建任何东西。当然你不想直接使用文字,幻数是不好的,但如果你用现代压缩器编译你的 JavaScript 它会在适当的地方将任何 const
换成文字。
运行一个例子通过Google's closure compiler
代码:
const w = {
TEXTURE_2D: 0x0DE1,
};
gl.bindTexture(w.TEXTURE_2D, null);
gl.bindTexture(3553,null);
您可以使用 WebGLRenderingContext
和 WebGL2RenderingContext
访问它们,而无需创建上下文实例。例如:
console.log(WebGLRenderingContext.TEXTURE_2D); // 3553