我用这种方式创建了一个纹理:
var tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex);
gl.texParameteri(...
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, w, h, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
然后我尝试将当前帧缓冲区中的子数据复制到其中:
gl.copyTexSubImage2D(gl.TEXTURE_2D, 0, ox, oy, sx, sy, w, h);
它不会第一次复制任何内容。纹理仍为空(包含零)。
当我第二次调用copyTexSubImage2D时,它可以正常工作。如果子区域的大小对应于纹理的大小,它也是第一次起作用。
我想避免在开始时发送实际数据(花费太长时间)并且复制比我需要的更大的区域也需要太长时间。
是预期的行为,还是Chromes WebGL中的错误?还有其他解决方案吗?
答案 0 :(得分:0)
让我们进行测试
var gl = twgl.getWebGLContext(document.getElementById("c"));
var programInfo = twgl.createProgramInfo(gl, ["vs", "fs"]);
var greenProgramInfo = twgl.createProgramInfo(gl, ["vs", "green-fs"]);
var arrays = {
position: [-1, -1, 0, 1, -1, 0, -1, 1, 0, -1, 1, 0, 1, -1, 0, 1, 1, 0],
};
var bufferInfo = twgl.createBufferInfoFromArrays(gl, arrays);
twgl.setBuffersAndAttributes(gl, programInfo, bufferInfo);
// make a texture for a framebuffer
var fbtex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, fbtex);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 256, 256, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
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);
// create a framebuffer and attach the texture
var fb = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, fbtex, 0);
// clear texture to green
//gl.clearColor(0, 1, 0, 1);
//gl.clear(gl.COLOR_BUFFER_BIT);
// Just to make sure let's render green instead of clear to green. (both work for me though)
gl.useProgram(greenProgramInfo.program);
twgl.drawBufferInfo(gl, gl.TRIANGLES, bufferInfo);
// now make a texture
var tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 256, 256, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
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);
// copy part of the fbtexture to it
// target, level, xoffset, yoffset, x, y, width, height
gl.copyTexSubImage2D(gl.TEXTURE_2D, 0, 10, 20, 30, 40, 50, 60);
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
// now clear to red
gl.clearColor(1, 0, 0, 1);
gl.clear(gl.COLOR_BUFFER_BIT);
// Now render with the texture
gl.useProgram(programInfo.program);
var uniforms = {
u_texture: tex,
};
twgl.setUniforms(programInfo, uniforms);
twgl.drawBufferInfo(gl, gl.TRIANGLES, bufferInfo);

canvas { border: 1px solid black; }

<script src="//twgljs.org/dist/twgl-full.min.js"></script>
<script id="vs" type="notjs">
attribute vec4 position;
varying vec2 v_texcoord;
void main() {
gl_Position = position;
v_texcoord = position.xy * 0.5 + 0.5;
}
</script>
<script id="fs" type="notjs">
precision mediump float;
uniform sampler2D u_texture;
varying vec2 v_texcoord;
void main() {
gl_FragColor = texture2D(u_texture, v_texcoord);
}
</script>
<script id="green-fs" type="notjs">
precision mediump float;
varying vec2 v_texcoord;
void main() {
gl_FragColor = vec4(0,1,0,1);
}
</script>
<div>If this works there should be a white (transparent) canvas with a green rectangle inside.</div>
<canvas id="c"></canvas>
&#13;
似乎适合我。它不适合你吗?