如何从已创建的 WebGL 上下文中获取 WebGLProgram 对象?
How to obtain a WebGLProgram object from the already created WebGL context?
我想知道,如何从任何所需的 WebGL 上下文中获取任何 WebGL 程序实例 (WebGLProgram
)?
获取 WebGL 上下文不是问题。您正在使用 document.getElementsByTagName()
或 document.getElementById()
在当前页面的 DOM 中搜索 canvas 元素,如果您知道确切的 canvas id:
let canvas = document.getElementById( "canvasId" );
let context = canvas.getContext( "webgl" );
这里我们按照我的设想获取当前上下文,但是如果我想获取一些着色器参数或从已经 运行 vertex/fragment 着色器中获取某些值 - 我需要一个 WebGL 程序,与当前 WebGL 渲染上下文关联。
但我在 WebGL API 中找不到任何方法,例如 context.getAttachedProgram()
或 context.getActiveProgram()
。
那么如何获取用于渲染过程的活动WebGL程序呢?
也许,有一些特殊的 WebGL 参数?
gl.getParameter(gl.CURRENT_PROGRAM)。查看右侧的 https://www.khronos.org/files/webgl/webgl-reference-card-1_0.pdf 第 2 页。
无法从 WebGL 上下文中获取所有程序或任何其他资源。如果上下文已经存在,那么您可以做的最好的事情就是查看当前资源,例如 gl.getParameter(gl.CURRENT_PROGRAM)
等。
您可以做的是包装 WebGL 上下文
var allPrograms = [];
someContext.createProgram = (function(oldFunc) {
return function() {
// call the real createProgram
var prg = oldFunc.apply(this, arguments);
// if a program was created save it
if (prg) {
allPrograms.push(prg);
}
return prg;
};
}(someContext.createProgram));
当然,您还需要包装 gl.deleteProgram
以从所有程序的数组中删除内容。
someContext.deleteProgram = (function(oldFunc) {
return function(prg) {
// call the real deleteProgram
oldFunc.apply(this, arguments);
// remove the program from allPrograms
var ndx = allPrograms.indexOf(prg);
if (ndx >= 0) {
allPrograms.splice(ndx, 1);
}
};
}(someContext.deleteProgram));
这些是 WebGL Inspector and the WebGL Shader Editor Extension.
等使用的技术
如果您想包装所有上下文,您可以使用类似的技术来包装 getContext
。
HTMLCanvasElement.prototype.getContext = (function(oldFunc) {
return function(type) {
var ctx = oldFunc.apply(this, arguments);
if (ctx && (type === "webgl" || type === "experimental-webgl")) {
ctx = wrapTheContext(ctx);
}
return ctx;
};
}(HTMLCanvasElement.prototype.getContext));
我想知道,如何从任何所需的 WebGL 上下文中获取任何 WebGL 程序实例 (WebGLProgram
)?
获取 WebGL 上下文不是问题。您正在使用 document.getElementsByTagName()
或 document.getElementById()
在当前页面的 DOM 中搜索 canvas 元素,如果您知道确切的 canvas id:
let canvas = document.getElementById( "canvasId" );
let context = canvas.getContext( "webgl" );
这里我们按照我的设想获取当前上下文,但是如果我想获取一些着色器参数或从已经 运行 vertex/fragment 着色器中获取某些值 - 我需要一个 WebGL 程序,与当前 WebGL 渲染上下文关联。
但我在 WebGL API 中找不到任何方法,例如 context.getAttachedProgram()
或 context.getActiveProgram()
。
那么如何获取用于渲染过程的活动WebGL程序呢? 也许,有一些特殊的 WebGL 参数?
gl.getParameter(gl.CURRENT_PROGRAM)。查看右侧的 https://www.khronos.org/files/webgl/webgl-reference-card-1_0.pdf 第 2 页。
无法从 WebGL 上下文中获取所有程序或任何其他资源。如果上下文已经存在,那么您可以做的最好的事情就是查看当前资源,例如 gl.getParameter(gl.CURRENT_PROGRAM)
等。
您可以做的是包装 WebGL 上下文
var allPrograms = [];
someContext.createProgram = (function(oldFunc) {
return function() {
// call the real createProgram
var prg = oldFunc.apply(this, arguments);
// if a program was created save it
if (prg) {
allPrograms.push(prg);
}
return prg;
};
}(someContext.createProgram));
当然,您还需要包装 gl.deleteProgram
以从所有程序的数组中删除内容。
someContext.deleteProgram = (function(oldFunc) {
return function(prg) {
// call the real deleteProgram
oldFunc.apply(this, arguments);
// remove the program from allPrograms
var ndx = allPrograms.indexOf(prg);
if (ndx >= 0) {
allPrograms.splice(ndx, 1);
}
};
}(someContext.deleteProgram));
这些是 WebGL Inspector and the WebGL Shader Editor Extension.
等使用的技术如果您想包装所有上下文,您可以使用类似的技术来包装 getContext
。
HTMLCanvasElement.prototype.getContext = (function(oldFunc) {
return function(type) {
var ctx = oldFunc.apply(this, arguments);
if (ctx && (type === "webgl" || type === "experimental-webgl")) {
ctx = wrapTheContext(ctx);
}
return ctx;
};
}(HTMLCanvasElement.prototype.getContext));