Reputation: 25
I'm learning WebGL and stuck in understanding how to pass data to attributes.
drawArrays: no buffer is bound to enabled attribute this is a warning that I get, but if I disable one vertexAttrib
gl.disableVertexAttribArray(positionAttributeLocation)
, this warning disappears, but I still don't have anything on a screen.
What am I doing wrong?
This is my shaders.
const vsSource = `
attribute vec4 a_position;
attribute vec4 a_color;
varying vec4 v_color;
void main() {
gl_Position = a_position;
v_color = a_color;
}
`;
const fsSource = `
precision mediump float;
varying vec4 v_color;
void main() {
gl_FragColor = v_color;
}
`;
Next my steps: 1) get gl context
const canvas = document.querySelector('#glCanvas');
gl = canvas.getContext('webgl');
2) create shaders
function createShader(type, source) {
var shader = gl.createShader(type); // create shader
gl.shaderSource(shader, source); // set to shader his code
gl.compileShader(shader); // compile shader
var success = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
if (success) {
return shader;
}
console.log(gl.getShaderInfoLog(shader));
gl.deleteShader(shader);
}
const vShader = createShader(gl.VERTEX_SHADER, vsSource)
const fShader = createShader(gl.FRAGMENT_SHADER, fsSource)
3) Create a program and attach shaders, link them
var program = gl.createProgram();
checkGlError()
gl.attachShader(program, vShader);
gl.attachShader(program, fShader);
gl.linkProgram(program);
if ( !gl.getProgramParameter(program, gl.LINK_STATUS) ) {
var info = gl.getProgramInfoLog(program);
throw 'Could not compile WebGL program. \n\n' + info;
}
4) Get references to attributes
var positionAttributeLocation = gl.getAttribLocation(program, "a_position");
var colorAttributeLocation = gl.getAttribLocation(program, "a_color");
5) create buffers and bind data
var positionBuffer = gl.createBuffer()
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer)
setRectangle(gl)
var colorBuffer = gl.createBuffer()
gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer)
setColors(gl)
function setRectangle(gl) {
let x = randomFloat()
let y = randomFloat()
let width = randomFloat()
let height = randomFloat()
let x1 = x;
let x2 = x + width;
let y1 = y;
let y2 = y + height;
let positions = [
x1, y1,
x2, y1,
x1, y2,
x1, y2,
x2, y1,
x2, y2
]
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW)
}
function setColors(gl) {
var r1 = Math.random();
var b1 = Math.random();
var g1 = Math.random();
var r2 = Math.random();
var b2 = Math.random();
var g2 = Math.random();
gl.bufferData(
gl.ARRAY_BUFFER,
new Float32Array(
[ r1, b1, g1, 1,
r1, b1, g1, 1,
r1, b1, g1, 1,
r2, b2, g2, 1,
r2, b2, g2, 1,
r2, b2, g2, 1]),
gl.STATIC_DRAW);
}
6) Draw scene
gl.viewport(0,0,gl.canvas.width,gl.canvas.height)
gl.clearColor(78/255.0,159/255.0,255/255.0,1.0)
gl.clear(gl.COLOR_BUFFER_BIT)
gl.useProgram(program)
gl.enableVertexAttribArray(positionAttributeLocation)
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer)
var size = 2
var type = gl.FLOAT
var normalize = false
var stride = 0
var offset = 0
gl.vertexAttribPointer(
positionBuffer,
size,
type,
normalize,
stride,
offset)
gl.enableVertexAttribArray(colorAttributeLocation)
gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer)
var size = 4
var type = gl.FLOAT
var normalize = false
var stride = 0
var offset = 0
gl.vertexAttribPointer(
colorBuffer,
size,
type,
normalize,
stride,
offset)
let verticiesCounter = 6;
var drawingOffset = 0;
gl.drawArrays(gl.TRIANGLES, drawingOffset , verticiesCounter)
Upvotes: 2
Views: 841
Reputation: 210908
The first parameter of vertexAttribPointer
has to be the index of the generic vertex attribute and not a buffer object.
Note, vertexAttribPointer
specifies the data for a generic vertex attribute, so the index has to be specified somewhere.
If a named buffer object is bound to the target ARRAY_BUFFER
, then the data in this buffer are the data source.
See OpenGL ES glVertexAttribPointer
and WebGL Specification; 5.13.10 Uniforms and attributes
This means you have to change your code like this:
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer)
gl.vertexAttribPointer(
positionAttributeLocation, // instead of positionBuffer
size,
type,
normalize,
stride,
offset)
.....
gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer)
gl.vertexAttribPointer(
colorAttributeLocation, // instead of colorBuffer
size,
type,
normalize,
stride,
offset)
Upvotes: 2