【发布时间】:2014-02-05 16:31:41
【问题描述】:
我正在一个 Web 查看器中工作,该查看器有许多渲染到同一页面的着色器程序。我正在添加另一个使用纹理渲染四边形的程序。四边形渲染得很好。纹理给我带来了问题。
Mesh.prototype.initTexture = function(ctx) {
this.texture = this.ctx.createTexture();
this.texture.image = new Image();
// ctx.bindTexture(this.ctx.TEXTURE_2D, this.texture);
// ctx.texImage2D(this.ctx.TEXTURE_2D, 0, this.ctx.RGBA, 1, 1, 0, this.ctx.RGBA, this.ctx.UNSIGNED_BYTE, new Uint8Array([255, 0, 0, 255])); // red
mesh.texture.image.onload = function () {
//Upon callback, 'this' is different, so we use the global variable for now
mesh.handleLoadedTexture(mesh.texture,mesh.texture.image);
}
this.texture.image.src = "/path/to/images/nehe.gif";
}
那是我的 initTexture 函数。我可以取消注释加载红色方块的两行(a la WebGL - wait for texture to load),然后纹理呈现为红色并且不再弹出错误,但我的纹理永远不会加载。纹理本身是我从 LearningWebGL 下载的可渲染纹理。我有一个演示下载表单,该站点在我的本地主机上运行良好,与该项目并行。
这里是handleLoadedTexture函数
Mesh.prototype.handleLoadedTexture = function(texture, image) {
mesh.ctx.bindTexture(mesh.ctx.TEXTURE_2D, texture);
mesh.ctx.pixelStorei(mesh.ctx.UNPACK_FLIP_Y_WEBGL, true);
mesh.ctx.texImage2D(mesh.ctx.TEXTURE_2D, 0, mesh.ctx.RGBA, this.ctx.RGBA, mesh.ctx.UNSIGNED_BYTE, image);
mesh.ctx.texParameteri(mesh.ctx.TEXTURE_2D, mesh.ctx.TEXTURE_MAG_FILTER, mesh.ctx.NEAREST);
mesh.ctx.texParameteri(mesh.ctx.TEXTURE_2D, mesh.ctx.TEXTURE_MIN_FILTER, mesh.ctx.NEAREST);
mesh.ctx.generateMipmap(mesh.ctx.TEXTURE_2D);
mesh.ctx.bindTexture(mesh.ctx.TEXTURE_2D, null);
}
然后我们在整个渲染管道中有调用这个渲染的块:
if (mesh != null) {
mesh = new Mesh();
ctx.useProgram(meshShader);
// I set the camera and projection matrices here
glCheck();
if(!mesh.vbo) {
mesh.loadGL(ctx);
}
if(!mesh.texture){
mesh.initTexture(ctx);
}
mesh.render(meshShader);
glCheck();
}
没有什么太革命性的了。
渲染函数:
Mesh.prototype.render = function(program) {
assert(this.vbo != null, "VBO is null");
assert(this.tcbo != null, "TCBO is null");
// Arguments here are (index, size, type, normalized(bool), stride, offset)
this.ctx.bindBuffer(this.ctx.ARRAY_BUFFER, this.vbo);
this.ctx.vertexAttribPointer(program.a.vertex, this.sizevertices, this.ctx.FLOAT, false, 0, 0);
this.ctx.bindBuffer(this.ctx.ARRAY_BUFFER, this.tcbo);
this.ctx.vertexAttribPointer(program.a.textureCoordinate, this.sizetexco, this.ctx.FLOAT, false, 0, 0);
this.ctx.activeTexture(this.ctx.TEXTURE0);
this.ctx.bindTexture(this.ctx.TEXTURE_2D, this.texture);
this.ctx.uniform1i(program.uSampler, 0);
this.ctx.drawArrays(this.ctx.TRIANGLE_STRIP, 0, this.numvertices);
render.glCheck();
}
顶点着色器:
varying vec2 vTextureCoord;
attribute vec3 vertex;
attribute vec2 textureCoordinate;
//other unrelated uniforms
void main(void) {
//position settings omitted
vTextureCoord = textureCoordinate;
}
片段着色器:
precision mediump float;
varying vec2 vTextureCoord;
uniform sampler2D uSampler;
void main(void) {
gl_FragColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t));
}
【问题讨论】:
-
如果你要使用最近邻缩小过滤器,那么调用
mesh.ctx.generateMipmap(mesh.ctx.TEXTURE_2D);是没有意义的。您所做的只是无缘无故地将纹理数据的大小增加了 33%。 -
嗯,我明白了。我想说那条线是在解决这个问题时留下来的。我删除了那条线,但是加载纹理的结果是一样的。不过感谢您的信息!
-
您确定调用了
handleLoadedTexture吗?您是否检查过(使用 Chrome 的 WebGL Inspector)纹理是否已加载到 WebGL? -
@virtualnobi 完全忽略了这个事实。好的。我仍然建议使用标志来检查某些内容,而不是将完整对象与某个值进行比较。
-
@AbstractAlgorithm 我不确定你的意思 - 我指的是一些基本的调试检查,以确保执行正确的代码并将纹理传输到 WebGL 空间......
标签: javascript opengl-es textures webgl