gpt4 book ai didi

javascript - copyTexImage2D — GL 错误 :GL_INVALID_OPERATION : glCopyTexImage2D:

转载 作者:行者123 更新时间:2023-12-03 07:13:13 32 4
gpt4 key购买 nike

我正在尝试弄清楚如何使用gl.copyTexImage2D功能。我有以下代码(虽然不方便):

//--------- SETUP (not important) ---------------

//I use budo package to easily run browserify
var createContext = require('webgl-context');
var createShader = require('gl-shader');

//↓ here is webgl setup usual routine, using floats and simple one-triangle vertex shader
var gl = createContext({width: 2, height: 2});
gl.getExtension('OES_texture_float');
gl.getExtension('OES_texture_float_linear');

var shader = createShader(gl, `
precision mediump float;
attribute vec2 position;
varying vec2 uv;
void main (void) {
gl_Position = vec4(position, 0, 1);
uv = vec2(position.x * 0.5 + 0.5, position.y * 0.5 + 0.5);
}
`, `
precision mediump float;
uniform sampler2D image;
varying vec2 uv;
void main (void) {
gl_FragColor = texture2D(image, uv);
}
`);

//fullscreen triangle
var buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([-1, -1, -1, 3, 3, -1]), gl.STATIC_DRAW);
shader.attributes.position.pointer();

//textures
var outTexture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, outTexture);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
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.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 2, 2, 0, gl.RGBA, gl.FLOAT, new Float32Array([1,1,1,1, 0,0,0,1, 0,0,0,1, 0,0,0,1]));

var sourceTexture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, sourceTexture);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
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.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 2, 2, 0, gl.RGBA, gl.FLOAT, new Float32Array([0,0,0,1, 1,1,1,1, 0,0,0,1, 0,0,0,1]));


//--------------- MAIN PART (important) ---------------

//then I setup custom framebuffer ↓
var framebuffer = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, outTexture, 0);

gl.bindTexture(gl.TEXTURE_2D, sourceTexture);
gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
gl.drawArrays(gl.TRIANGLES, 0, 3);

//here ↓ I am expecting to copy framebuffer’s output, which is `outTexture`, to `sourceTexture`
gl.bindTexture(gl.TEXTURE_2D, sourceTexture);
gl.copyTexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 0, 0, w, h, 0);

//then I try to render shader again, with it’s own output as input
gl.drawArrays(gl.TRIANGLES, 0, 3);

//when I try to read pixels here ↓ I get the error below
gl.readPixels(0, 0, w, h, gl.RGBA, gl.FLOAT, pixels);

错误:[.CommandBufferContext]GL错误:GL_INVALID_OPERATION:glCopyTexImage2D:

无法弄清楚我做错了什么。

最佳答案

该错误来自 gl.copyTexImage2D,而不是来自 gl.readPixels。在调用 gl.readPixels 之前您看不到它的原因是因为 WebGL 是一种命令驱动语言。命令只有在出于各种原因必须执行时才会执行。 gl.flush 将强制在某个时刻执行命令。 gl.readPixels 还强制执行命令,因为需要使用命令的结果来读取像素。

至于错误,您需要提供更多代码。代码按原样通过 gl.copyTexImage2D 工作,这意味着您从中得到的错误与您未显示的某些代码有关。要么你创建了错误的纹理,要么是 w 和 h 或时髦的值或其他什么

我自己在下面尝试了一下,它有效,但指出了另一个错误。您无法在 WebGL 中使用 gl.readPixels 读取 float 。切换到 UNSIGNED_BYTE 有效

var gl = document.getElementById("c").getContext("webgl");
var w = 300;
var h = 150;

var programInfo = twgl.createProgramInfo(gl, ["vs", "fs"]);
gl.useProgram(programInfo.program);

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 renderable npot texture
function createRenderableTexture(gl, w, h) {
var tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, w, h, 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.LINEAR);
return tex;
}

var outTexture = createRenderableTexture(gl, w, h);
var framebuffer = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, outTexture, 0);

// render something to it
gl.clearColor(0,1,0,1); // green
gl.clear(gl.COLOR_BUFFER_BIT);

// copy the framebuffer to the texture
var sourceTexture = createRenderableTexture(gl, w, h)
gl.copyTexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 0, 0, w, h, 0);

// draw to canvas
gl.bindFramebuffer(gl.FRAMEBUFFER, null);

// clear to red
gl.clearColor(1,0,0,1);
gl.clear(gl.COLOR_BUFFER_BIT);

// Since we cleared to red and the texture is filled with green
// the result should be green
gl.drawArrays(gl.TRIANGLES, 0, 6);

var pixels = new Uint8Array(w * h * 4);
gl.readPixels(0, 0, w, h, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
log("pixel 0: "
+ pixels[0] + ","
+ pixels[1] + ","
+ pixels[2] + ","
+ pixels[3]);

function log(msg) {
var div = document.createElement("pre");
div.appendChild(document.createTextNode(msg));
document.body.appendChild(div);
}
<script src="https://twgljs.org/dist/twgl.min.js"></script>
<script id="vs" type="notjs">
attribute vec4 position;
varying vec2 v_uv;

void main() {
gl_Position = position;
v_uv = position.xy * 0.5 + 0.5;
}
</script>
<script id="fs" type="notjs">
precision mediump float;

varying vec2 v_uv;
uniform sampler2D u_texture;

void main() {
gl_FragColor = texture2D(u_texture, v_uv);
}
</script>
<canvas id="c"></canvas>

另一方面,FLOAT 纹理不应该起作用。他们为我工作,但据我所知,这是我系统上的错误,而不是你的系统。

具体来说,WebGL 默认情况下不允许使用 FLOAT 纹理。您可以通过启用 OES_texture_float 扩展来打开它们,但 that extension specifically says

  1. Should CopyTexImage2D, CopyTexSubImage{2D|3D} be supported for textures with half-float and float channels?

    RESOLUTION: No.

I filed a bug for Chrome

您可以尝试通过自己实现 copyTexImage2D 来解决该问题。基本上将要作为源纹理复制的纹理附加到某些着色器和四边形。将要复制到的纹理附加到帧缓冲区对象。由于它是 FLOAT 纹理,您需要调用 checkFramebufferStatus 并检查它返回 FRAMEBUFFER_COMPLETE 以确保您的 GPU/驱动程序实际上支持浮点纹理作为附件。然后使用简单的着色器绘制四边形,有效地将纹理从 src 复制到 dst。

关于javascript - copyTexImage2D — GL 错误 :GL_INVALID_OPERATION : glCopyTexImage2D:,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36539955/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com