我正试图在片段着色器中使用两个纹理,但无法让WebGL正确发送纹理。我可以一次发送一个,但当我试图同时发送两个时,我会变黑。我看到了其他一些多纹理的例子,但它们都涉及加载一组图像。
我想把一个视频加载到一个纹理中,把一个画布加载到第二个纹理中。我很确定我所有的着色器都很好,因为我只是从我写的一个c++opengl程序中移动它们。此外,我可以通过评论其中一个来分别显示视频或画布,但就像我上面提到的,它们加在一起似乎会引发错误。
这是我创建和填充纹理的代码片段。
var texture1 = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture1);
var texture2 = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture2);
gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MAG_FILTER, gl.NEAREST);
然后在我的抽奖循环中:
gl.texImage2D(gl.TEXTURE_2D,0,gl.RGBA,gl.RGBA,gl.UNSIGNED_BYTE, video);
var tex1loc = gl.getUniformLocation(program,"u_image");
gl.uniform1i(tex1loc, 0);
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, texture1);
gl.texImage2D(gl.TEXTURE_2D,0,gl.RGBA,gl.RGBA,gl.UNSIGNED_BYTE, canvas);
var tex2loc = gl.getUniformLocation(program, "u_image2");
gl.uniform1i(tex2loc, 1);
gl.activeTexture(gl.TEXTURE1);
gl.bindTexture(gl.TEXTURE_2D, texture2);
我还收到一条警告信息,上面写着:
GL_INVALID_ENUM:glActiveTexture:纹理为GL_FALSE
GL_INVALID_ENUM:glActiveTexture:纹理为GL_LINES
以及:
WebGL:drawArrays:绑定到纹理单元0的纹理不可渲染。它可能不是2的幂,并且具有不兼容的纹理过滤,或者不是"纹理完整"。或者纹理为带线性过滤的"浮点"或"半浮点"类型,而OES_Float_linear或OES_Half-Float_lineral扩展未启用。
触发警告的线路是:
gl.drawArrays(gl.TRIANGLES, 0,6);
提前感谢您的帮助!
gl.activeTexture
设置纹理单位所有其他纹理命令的效果。对于每个纹理单元,有2个结合点,TEXTURE_2D
和TEXTURE_CUBE_MAP
。
你可以把它想象成这个
gl = {
activeTextureUnit: 0,
textureUnits: [
{ TEXTURE_2D: null: TEXTURE_CUBE_MAP: null, },
{ TEXTURE_2D: null: TEXTURE_CUBE_MAP: null, },
{ TEXTURE_2D: null: TEXTURE_CUBE_MAP: null, },
...
],
};
gl.activeTexture
只是做这个
gl.activeTexture = function(unit) {
gl.activeTextureUnit = unit - gl.TEXTURE0;
};
gl.bindTexture
做这个
gl.bindTexture = function(bindPoint, texture) {
gl.textureUnits[gl.activeTextureUnit][bindPoint] = texture;
};
gl.texImage2D
和gl.texParamteri
查找像这样使用的纹理
gl.texImage2D = function(bindPoint, .....) {
var texture = gl.textureUnits[gl.activeTextureUnit][bindPoint];
// now do something with texture
因此,知道所有这些,代码的第一个问题是它创建了两个纹理,texture1
和texture2
,但随后它只为texture2
设置纹理参数,因为对gl.bindTexture
的第二个调用在其TEXTURE_2D
绑定点上设置了绑定到当前activeTexture
的纹理,然后gl.texParameteri
只对该纹理进行操作。
在绑定texture2
之前,它需要设置texture1
的参数。
类似地,绘制代码在调用gl.texImage2D
之前需要调用gl.activeTexture
和/或gl.bindTexture
,否则它在绑定到当前活动纹理单元上的绑定点TEXTURE_2D
的任何纹理上进行操作。
至于你关于gl.activeTexture
的警告,你确定你发布了所有与纹理相关的代码吗?如果你发布了所有这些警告,那么这些警告就没有多大意义,因为你对gl.activeTexture
的唯一调用看起来是有效的。
否则,关于单元0上的纹理不可渲染的另一个警告是因为您没有如上所述设置texture1
的参数。
所以,要明确的是,你的代码应该看起来像这个
var texture1 = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture1);
// you need to set parameters for texture1
gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MAG_FILTER, gl.NEAREST);
var texture2 = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture2);
gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MAG_FILTER, gl.NEAREST);
// these should be looked up at init time
var tex1loc = gl.getUniformLocation(program,"u_image");
var tex2loc = gl.getUniformLocation(program, "u_image2");
绘制循环:
// call active texture first
gl.activeTexture(gl.TEXTURE0);
// then bind a texture. This now binds texture1 to unit 0
gl.bindTexture(gl.TEXTURE_2D, texture1);
gl.texImage2D(gl.TEXTURE_2D,0,gl.RGBA,gl.RGBA,gl.UNSIGNED_BYTE, video);
gl.uniform1i(tex1loc, 0);
// call active texture first
gl.activeTexture(gl.TEXTURE1);
// then bind a texture. This now binds texture2 to unit 1
gl.bindTexture(gl.TEXTURE_2D, texture2);
gl.texImage2D(gl.TEXTURE_2D,0,gl.RGBA,gl.RGBA,gl.UNSIGNED_BYTE, canvas);
gl.uniform1i(tex2loc, 1);