gl.texImage2D适用于Image,但不适用于ImageData
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了gl.texImage2D适用于Image,但不适用于ImageData相关的知识,希望对你有一定的参考价值。
当我使用gl.texImage2D
与javascript的Image
对象指定像素数据时,我有一个正确渲染的纹理。但是,如果我将Image
渲染到离屏画布上,然后从中拉出ImageData
对象,然后将其反馈给gl.texImage2D
,纹理无法正确绘制。当我检查ImageData
对象时,像素数据是正确的。 gl.texImage2D
与Image
对象有什么不同,而不是ImageData
对象?
图像只是32位,每个组件8位,RGBA。我的片段着色器获取并期望这些组件作为[0,1]
中的值。可能是因为当我传入ImageData
对象时,我的着色器现在让它们在[0,255]
范围内?我将不得不测试这个假设。无论如何,我完全失败了。
编辑:经过多次努力,我发现OpenGL和着色器管道的东西没有任何问题。我面临的问题与从Image到ImageData的转换有关。这是一些代码......
let perm_image = new Image();
...
let canvas = document.createElement('canvas');
let context = canvas.getContext('2d');
canvas.width = perm_image.width;
canvas.height = perm_image.height;
context.drawImage(perm_image, 0, 0);
let perm_image_data = context.getImageData(0, 0, perm_image.width, perm_image.height);
我已将返回的图像数据与实际图像数据进行比较,而缓冲区的第一部分看起来是正确的,其余部分是错误的。我以前做过这个检查,但是很快停了下来。
无论如何,我要四处寻找,看看如何更改/修复上面的代码。
最终编辑:我决定放弃。我知道没有防弹方法可以从JS Image
对象中获取原始的,未经改变的RGBA数据,我认为发明该死的对象的人完全失败了。我要做的就是不使用PNG文件,而是使用我自己的二进制格式。
似乎为我工作。也许比较一下,看看你的做法可能与众不同?
const img = new Image();
img.addEventListener('load', render);
img.crossOrigin = "";
img.src = "https://i.imgur.com/ZKMnXce.png";
function render() {
const vs = `
attribute vec4 position;
void main() {
gl_PointSize = 80.0;
gl_Position = position;
}
`;
const fs = `
precision mediump float;
uniform sampler2D tex;
void main() {
gl_FragColor = texture2D(tex, gl_PointCoord);
}
`;
const gl = document.querySelector("canvas").getContext("webgl");
const program = twgl.createProgram(gl, [vs, fs]);
const positionLoc = gl.getAttribLocation(program, "position");
const ctx = document.createElement("canvas").getContext("2d");
ctx.canvas.width = img.width;
ctx.canvas.height = img.height;
ctx.fillStyle = '#FFF'
ctx.drawImage(img, 0, 0);
ctx.font = "bold 48px sans-serif";
ctx.fillText("imageData", 10, 200);
const imgData = ctx.getImageData(0, 0, img.width, img.height);
ctx.drawImage(img, 0, 0);
ctx.fillText("canvas", 10, 200);
gl.useProgram(program);
createTextureAndDraw(img, -.6);
createTextureAndDraw(ctx.canvas, 0);
createTextureAndDraw(imgData, .6);
function createTextureAndDraw(src, x) {
const tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex);
{
const level = 0;
const internalFormat = gl.RGBA;
const width = 1;
const height = 1;
const border = 0;
const format = gl.RGBA;
const type = gl.UNSIGNED_BYTE;
gl.texImage2D(gl.TEXTURE_2D, level, internalFormat,
format, type, src);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_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.vertexAttrib1f(positionLoc, x);
const primitiveType = gl.POINTS;
const offset = 0;
const count = 1;
gl.drawArrays(primitiveType, offset, count);
}
}
<script src="https://twgljs.org/dist/4.x/twgl.min.js"></script>
<canvas></canvas>
以上是关于gl.texImage2D适用于Image,但不适用于ImageData的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 texSubImage2D 在 webgl 中显示精灵?