问题描述
由于某些原因,在移动Safari上似乎无法渲染到帧缓冲区,然后从缓冲区渲染到屏幕。我没有机会查看桌面Safari,但是我的Firefox可以很好地显示Microsoft徽标,在我的手机上我只能看到边框:
const dmnsn = [800,600],glCtx = twgl.getContext(document.createElement("canvas")),imgLc =
"https://upload.wikimedia.org/wikipedia/commons/b/b6/Microsoft_logo_%281987%29.svg";
var bfInf = twgl.primitives.createXYQuadBufferInfo(glCtx),pgInf = twgl.createProgramInfo(glCtx,["vs","fs"]),imgTx = twgl.createTexture(glCtx,{ src: imgLc },tstSB),scnBf = twgl.createFramebufferInfo(glCtx,[{ wrap: glCtx.REPEAT}],dmnsn[0],dmnsn[1]);
function plcCv() {
document.body.append(glCtx.canvas);
glCtx.canvas.width = dmnsn[0];
glCtx.canvas.height = dmnsn[1];
}
function drwTx(tx,fbi,fy) {
twgl.bindFramebufferInfo(glCtx,fbi);
twgl.drawObjectList(glCtx,[
{
programInfo: pgInf,bufferInfo: bfInf,uniforms: { u_texture: tx,u_flipy: fy }
}
]);
}
function tstSB() {
plcCv();
drwTx(imgTx,scnBf,true);
drwTx(scnBf.attachments[0],null,false);
}
html{
height:100%;
}
body{
margin:0;
height:100%;
display: flex;
align-items: center;
justify-content: center;
}
canvas{
border-style:solid;
}
<script id="vs" type="x-shader/x-vertex">
attribute vec4 position;
attribute vec2 texcoord;
uniform bool u_flipy;
varying vec2 v_texcoord;
void main() {
if(u_flipy) {
v_texcoord = vec2(texcoord.x,1.0 - texcoord.y);
} else {
v_texcoord = texcoord;
}
gl_Position = position;
}
</script>
<script id="fs" type="x-shader/x-fragment">
precision mediump float;
varying vec2 v_texcoord;
uniform sampler2D u_texture;
void main() {
gl_FragColor=texture2D(u_texture,v_texcoord);
}
</script>
<script src="https://twgljs.org/dist/4.x/twgl-full.min.js"></script>
我知道绘制SVG只是实验性的,但是在移动Safari上似乎也可以正常工作。
解决方法
检查我看到的Safari中的错误
WebGL:drawElements:绑定到纹理单元0的纹理不可渲染。它可能不是2的幂,并且具有不兼容的纹理过滤或不是“纹理完整”的,或者是具有线性过滤功能且未启用相关的float / half-float线性扩展的float / half-float类型。>
要找出问题所在的纹理,请使用webgl-lint并添加这些行
const ext = glCtx.getExtension('GMAN_debug_helper');
const tagObject = ext ? ext.tagObject.bind(ext) : () => {};
tagObject(imgTx,'imgTx');
tagObject(scnBf.attachments[0],'colorAttach');
然后我收到此错误
drawElements(TRIANGLES,6,UNSIGNED_SHORT,0)中的错误:统一采样器2D引用的纹理单元0上的纹理WebGLTexture(“ colorAttach”)u_texture无法渲染:纹理的width(800)不是2的幂和height( 600)不是2的幂,但是TEXTURE_WRAP_S(REPEAT)不是CLAMP_TO_EDGE,而TEXTURE_WRAP_T(REPEAT)不是CLAMP_TO_EDGE。 使用WebGLProgram(“ unnamed ”)作为当前程序 绑定了默认的顶点数组
问题是twgl.getContext
在Chrome / Firefox上返回WebGL2,但在Safari上仅返回WebGL1(尚不支持WebGL2)
我添加了此webgl-helper以禁用WebGL2,并且在Chrome中出现了相同的错误。
如果您始终只想使用WebGL1,则不要使用twgl.getContext
。
否则,您可以修复它,更改twgl.createFramebufferInfo
的行以设置与WebGL1兼容的参数
scnBf = twgl.createFramebufferInfo(glCtx,[{ }],dmnsn[0],dmnsn[1]);
IIRC twgl中createFramebufferInfo的默认值为wrap: CLAMP_TO_EDGE
,minMag: LINEAR
const dmnsn = [800,600],glCtx = twgl.getContext(document.createElement("canvas")),imgLc =
"https://upload.wikimedia.org/wikipedia/commons/b/b6/Microsoft_logo_%281987%29.svg";
var bfInf = twgl.primitives.createXYQuadBufferInfo(glCtx),pgInf = twgl.createProgramInfo(glCtx,["vs","fs"]),imgTx = twgl.createTexture(glCtx,{ src: imgLc },tstSB),scnBf = twgl.createFramebufferInfo(glCtx,dmnsn[1]);
function plcCv() {
document.body.append(glCtx.canvas);
glCtx.canvas.width = dmnsn[0];
glCtx.canvas.height = dmnsn[1];
}
function drwTx(tx,fbi,fy) {
twgl.bindFramebufferInfo(glCtx,fbi);
twgl.drawObjectList(glCtx,[
{
programInfo: pgInf,bufferInfo: bfInf,uniforms: { u_texture: tx,u_flipy: fy }
}
]);
}
function tstSB() {
plcCv();
drwTx(imgTx,scnBf,true);
drwTx(scnBf.attachments[0],null,false);
}
html{
height:100%;
}
body{
margin:0;
height:100%;
display: flex;
align-items: center;
justify-content: center;
}
canvas{
border-style:solid;
}
<script id="vs" type="x-shader/x-vertex">
attribute vec4 position;
attribute vec2 texcoord;
uniform bool u_flipy;
varying vec2 v_texcoord;
void main() {
if(u_flipy) {
v_texcoord = vec2(texcoord.x,1.0 - texcoord.y);
} else {
v_texcoord = texcoord;
}
gl_Position = position;
}
</script>
<script id="fs" type="x-shader/x-fragment">
precision mediump float;
varying vec2 v_texcoord;
uniform sampler2D u_texture;
void main() {
gl_FragColor=texture2D(u_texture,v_texcoord);
}
</script>
<script src="https://twgljs.org/dist/4.x/twgl-full.min.js"></script>