【发布时间】:2016-05-20 15:32:52
【问题描述】:
我正在尝试将图像从 2d 画布绘制到 webgl 画布。
如果我使用:
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);
,它可以正常工作并成功渲染图像,但如果我使用:
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, c.width, c.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, dataTypedArray);
,它只是显示一个黑屏。
这是我的代码:
顶点着色器
attribute vec2 a_position;
uniform vec2 u_resolution;
uniform mat3 u_matrix;
varying vec2 v_texCoord;
void main() {
gl_Position = vec4(u_matrix * vec3(a_position, 1), 1);
v_texCoord = a_position;
}
片段着色器
precision mediump float;
// our texture
uniform sampler2D u_image;
// the texCoords passed in from the vertex shader.
varying vec2 v_texCoord;
void main() {
gl_FragColor = texture2D(u_image, v_texCoord);
}
Javascript
window.onload = main;
var buffer = null;
function main() {
var image = new Image();
image.src = "images/GL.jpg"
image.onload = function() {
render(image);
}
}
function render(image) {
var c = document.getElementById("c");
c.width = window.innerWidth*0.90;
c.height = window.innerHeight*0.90;
var context = c.getContext('2d');
context.drawImage(image, 0, 0);
var imageData = context.getImageData(0,0,image.width,image.height);
buffer = imageData.data.buffer; // ArrayBuffer
var canvas = document.getElementById("canvas");
canvas.width = window.innerWidth*0.90;
canvas.height = window.innerHeight*0.90;
//Get A WebGL context
var gl = getWebGLContext(canvas);
if (!gl) {
return;
}
// setup GLSL program
var program = createProgramFromScripts(gl, ["2d-vertex-shader", "2d-fragment-shader"]);
gl.useProgram(program);
// look up where the vertex data needs to go.
var positionLocation = gl.getAttribLocation(program, "a_position");
// look up uniform locations
var u_imageLoc = gl.getUniformLocation(program, "u_image");
var u_matrixLoc = gl.getUniformLocation(program, "u_matrix");
// provide texture coordinates for the rectangle.
var positionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
0.0, 0.0,
1.0, 0.0,
0.0, 1.0,
0.0, 1.0,
1.0, 0.0,
1.0, 1.0]), gl.STATIC_DRAW);
gl.enableVertexAttribArray(positionLocation);
gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, 0, 0);
var texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture);
// Set the parameters so we can render any size image.
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);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
// Upload the image into the texture.
var dataTypedArray = new Uint8Array(buffer);
//gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);
textureFromPixelArray(gl, buffer, gl.RGBA, canvas.width, canvas.height);
var dstX = 20;
var dstY = 30;
var dstWidth = canvas.width;
var dstHeight = canvas.height;
// convert dst pixel coords to clipspace coords
var clipX = dstX / gl.canvas.width * 2 - 1;
var clipY = dstY / gl.canvas.height * -2 + 1;
var clipWidth = dstWidth / gl.canvas.width * 2;
var clipHeight = dstHeight / gl.canvas.height * -2;
// build a matrix that will stretch our
// unit quad to our desired size and location
gl.uniformMatrix3fv(u_matrixLoc, false, [
clipWidth, 0, 0,
0, clipHeight, 0,
clipX, clipY, 1,
]);
// Draw the rectangle.
gl.drawArrays(gl.TRIANGLES, 0, 6);
}
function textureFromPixelArray(gl, dataArray, type, width, height) {
var dataTypedArray = new Uint8Array(dataArray); // Don't need to do this if the data is already in a typed array
var texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.texImage2D(gl.TEXTURE_2D, 0, type, width, height, 0, type, gl.UNSIGNED_BYTE, dataTypedArray);
// Other texture setup here, like filter modes and mipmap generation
console.log(dataTypedArray);
return texture;
}
【问题讨论】:
-
dataTypedArray 长什么样子?在此处发布。
-
对我来说,图像的大小看起来很奇怪。您从上下文中读取 [image.width, image.height] 纹素到图像数据中,然后告诉 gl 图像的大小为 [canvas.width, canvas.height]。
-
如何将
dataTypedArray传递到您的textureFromPixelArray方法中。截至目前dataTypedArray是您的render方法的本地,因此在textureFromPixelArray中不可见。在非严格模式下,这将导致undefined被传递,这将使 texImage2D 用黑色填充纹理。 -
不,我现在得到了答案,实际上我没有使用正确的高度和宽度,BDL 的评论在上面是正确的。谢谢
-
抱歉,我明白了。
标签: javascript glsl webgl