WebGL无报错无法渲染图片,TypeScript开发2D游戏纹理显示失败
存在的问题及修复方案
1. 顶点属性名不匹配
你顶点着色器中定义的输入属性名为a_position,但初始化时获取属性位置的代码传入的是a_pos,二者名称不一致导致WebGL无法读取顶点数据,无法绘制图形。
修复:修改属性获取代码的入参即可
this.a_posLoc = this.gl.getAttribLocation(this.program,"a_position");
2. 缺少纹理相关配置
你没有显式给片元着色器的纹理采样器u_image绑定纹理单元,绘制前也没有重新绑定要使用的纹理对象,导致着色器无法读取纹理数据。
3. 未确认图片加载状态
如果调用绘制时图片还没有加载完成,此时img元素的宽高为0,上传的纹理内容为空,也会导致绘制结果为空。
4. 顶点属性配置可能被覆盖
如果项目中还有其他绘制逻辑修改了ARRAY_BUFFER绑定或顶点属性指针配置,仅在构造函数中配置一次顶点属性会导致后续绘制时数据读取错误。
修正后的drawImage代码
public drawImage(tex: HTMLImageElement, x: number, y: number): void{ // 先校验图片加载状态 if (!tex.complete || tex.naturalWidth === 0) { return } const width = tex.width; const height = tex.height; this.glUtil.resizeCanvasToDisplaySize(this.gl); this.gl.useProgram(this.program); // 重新绑定顶点缓冲区,配置顶点属性 this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.positionBuffer); this.gl.enableVertexAttribArray(this.a_posLoc); this.gl.vertexAttribPointer(this.a_posLoc, 2, this.gl.FLOAT, false, 0, 0); // 绑定纹理、上传纹理数据 this.gl.bindTexture(this.gl.TEXTURE_2D, this.plainTex); this.gl.texImage2D(this.gl.TEXTURE_2D, 0, this.gl.RGBA, this.gl.RGBA, this.gl.UNSIGNED_BYTE, tex); // 给纹理采样器绑定0号纹理单元(WebGL默认激活的就是0号单元) this.gl.uniform1i(this.u_imageLoc, 0); const clipX = x / this.gl.canvas.width * 2 - 1; const clipY = y / this.gl.canvas.height * -2 + 1; const clipWidth = width / this.gl.canvas.width * 2; const clipHeight = height / this.gl.canvas.height * -2; this.gl.uniformMatrix3fv(this.u_matrixLoc, false, [ clipWidth, 0, 0, 0, clipHeight, 0, clipX, clipY, 1, ]); this.gl.drawArrays(this.gl.TRIANGLES, 0, 6); }
图片加载逻辑优化
确保图片加载完成后再调用绘制:
this.temptex = document.getElementById('imagee') as HTMLImageElement; const draw = () => this.imageRender.drawImage(this.temptex,0,0); this.temptex.complete ? draw() : this.temptex.onload = draw;
排查技巧
如果修改后还是没有内容,可以先把片元着色器的输出改成固定颜色验证顶点逻辑是否正常:
void main() { gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); }
如果能看到红色矩形,说明顶点部分逻辑正常,问题出在纹理相关配置;如果看不到,再回头检查顶点属性、矩阵计算等逻辑。
内容的提问来源于stack exchange,提问作者Akshay_VK
相关产品推荐
相关产品推荐

