【发布时间】:2018-11-18 08:47:46
【问题描述】:
我正在尝试在 webgl 中的三角形上加载单个纹理。这是我的代码。我没有收到错误,但有 2 个警告,我无法找出原因,警告是:
INVALID_VALUE: enableVertexAttribArray: index out of range
INVALID_VALUE: vertexAttribPointer: index out of range
程序应该加载给定的纹理并显示矩形。 我正在关注here 的教程。可能的原因是什么?这里是JSBIN OUTPUT
var canvas = document.createElement('canvas')
canvas.width = window.innerWidth
canvas.height = window.innerHeight
document.body.appendChild(canvas)
// Create a canvas webgl context as a base to draw upon
var gl = canvas.getContext('webgl')
// Clear canvas with any color you want
gl.clearColor(0.75, 0.85, 0.8, 1.0)
gl.clear(gl.COLOR_BUFFER_BIT)
// webgl pipeline need 2 shaders 1) vertex shader & fragment shader
// crate a vertex shader & compile it
var vertexShader = gl.createShader(gl.VERTEX_SHADER)
gl.shaderSource(vertexShader, [
'attribute vec2 a_texcoord;',
'varying vec2 v_texcoord;',
'attribute vec2 position;',
'void main() {',
'gl_Position = vec4(position, 0.0, 1.0);',
'v_texcoord = a_texcoord;',
'}'
].join('\n'))
gl.compileShader(vertexShader)
if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) {
console.error('ERROR compiling vertex shader!', gl.getShaderInfoLog(vertexShader));
}
// create a fragment shader & compile it
var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER)
gl.shaderSource(fragmentShader, [
'precision mediump float;',
'varying vec2 v_texcoord;',
'uniform sampler2D u_texture;',
'void main() {',
' gl_FragColor = texture2D(u_texture, v_texcoord);',
'}'
].join('\n'))
gl.compileShader(fragmentShader)
if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) {
console.error('ERROR compiling fragment shader!',
gl.getShaderInfoLog(fragmentShader));
}
// Create a program that will be offloaded to the GPU
var program = gl.createProgram()
// Attach vertex shader & fragment shaders to the the program
gl.attachShader(program, vertexShader)
gl.attachShader(program, fragmentShader)
// Link program
// gl.linkProgram(program)
gl.linkProgram(program);
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
console.error('ERROR linking program!', gl.getProgramInfoLog(program));
}
gl.validateProgram(program);
if (!gl.getProgramParameter(program, gl.VALIDATE_STATUS)) {
console.error('ERROR validating program!', gl.getProgramInfoLog(program));
}
// Define vertex positions as float32 array elemnets
var vertices = new Float32Array([
-0.5, -0.5,
0.5, -0.5,
0.0, 0.5
]);
// Create buffer where data will be stored
var buffer = gl.createBuffer()
// Mark the given buffer as current/active buffer
gl.bindBuffer(gl.ARRAY_BUFFER, buffer)
// Add data to the active buffer
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW)
const colors = [
1, 0.5, 1.0, 1.0, // white
0, 1.0, 0.3, 1.0, // red
0.0, 0.0, 0.8, 1.0, // green
];
const colorBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW);
// Tell webgl to use the progr that we created
gl.useProgram(program)
gl.bindBuffer(gl.ARRAY_BUFFER, buffer)
// Get location of the attribute `position` defined in our shader program
program.position = gl.getAttribLocation(program, 'position')
gl.enableVertexAttribArray(program.position)
gl.vertexAttribPointer(program.position, 2, gl.FLOAT, false, 0, 0)
var texcoordLocation = gl.getAttribLocation(program, "a_texcoords");
var Texbuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, Texbuffer);
gl.enableVertexAttribArray(texcoordLocation);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
// We'll supply texcoords as floats.
gl.vertexAttribPointer(texcoordLocation, 2, gl.FLOAT, false, 0, 0);
var texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture);
// Fill the texture with a 1x1 blue pixel.
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE,
new Uint8Array([0, 0, 255, 255]));
// Asynchronously load an image
var image = new Image();
image.src = "tex.jpg";
image.addEventListener('load', function() {
// Now that the image has loaded make copy it to the texture.
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA,gl.UNSIGNED_BYTE, image);
gl.generateMipmap(gl.TEXTURE_2D);
});
gl.drawArrays(gl.TRIANGLES, 0, vertices.length / 2)
【问题讨论】:
标签: javascript html5-canvas webgl