John Smith's Blog

Ramblings (mostly) about technical stuff

gl.enableVertexAttribArray() gotcha

Posted by John Smith on

Another post mainly in the hope that I might save someone else the wasted time and head-scratching I spent in fixing this...

I've been continuing playing with WebGL, and as well as experimenting with new (to me) functionality, in parallel I've started building up a library to tidy up the repetitious boilerplate that has been largely common to all my experiments to date. Until now, this has been a fairly mundane and trouble-free job, but I managed to cause myself a lot of pain and anguish last night, when some of my library code wasn't completely right.

I had a vertex buffer that contained 4 elements per vertex, a three-element (x,y,z) coordinate, and a single-element greyscale value. On initial run-through, the coordinates were rendered correctly, but the greyscale value was not at all how I expected. Rather than coming out in a shade of grey, my pixels were being rendered as white.

As far as I could tell, the code to push the vertex data through to OpenGL was fine, and not really any different to a number of earlier successful experiments: gl.bindBuffer(gl.ARRAY_BUFFER, bottomFace.vertexPositionBuffer); gl.vertexAttribPointer(shaderProgram.attributes["aVertexPosition"], 3, // vec3 - (x, y, z) gl.FLOAT, false, (4*4), // total size of 'vertex-input' aka stride 0); // offset within 'vertex-input' gl.vertexAttribPointer(shaderProgram.attributes["aVertexGreyness"], 1, // float gl.FLOAT, false, (4*4), // total size of 'vertex-input' aka stride 12); // offset within 'vertex-input' gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, bottomFace.vertexIndexBuffer); gl.drawElements(gl.TRIANGLES, bottomFace.vertexIndexBuffer.numItems, gl.UNSIGNED_SHORT, 0); I've had problems with this sort of code before, so started fiddling with the arguments to the second gl.vertexAttribPointer() to see if I could provoke it into doing something that would give some insight into what was going wrong, but it steadfastly refused to render anything differently.

One thing that was curious, was swapping the ordering of the two attribute declarations in the vertex shader. As expected, this caused the attribute index values to flip between 0 and 1, but also this seemed to be passed through to the shader, causing my pixels to render as either black or white.

Chrome's WebGL inspector didn't show anything unusual, and indicated that my vertex array had the expected values, so I was at a bit of a loss. Eventually I started hacking around with some older working code, to find out where things were going wrong, and stumbled across the cause.

It transpired that when I was initially getting my attribute index values, I wasn't also enabling them as vertex attribute arrays - or rather, this was happening for the (x,y,z) coordinate attribute (thanks to some legacy code that I thought wasn't getting called), but not for the greyscale attribute. Updating my attribute initialization code fixed the problem: for (var i=0; i<attrNames.length; i++) { attrDict[attrNames[i]] = gl.getAttribLocation(shaderProgram, attrNames[i]); gl.enableVertexAttribArray(attrDict[attrNames[i]]); // THIS LINE ADDED }

No errors are caused by not calling gl.enableVertexAttribArray(), and I don't currently know of any reason why you wouldn't want an attribute enabled, but without this rather boring line, you get mysterious failures as I unfortunately found out :-(

About this blog

This blog (mostly) covers technology and software development.

Note: I've recently ported the content from my old blog hosted on Google App Engine using some custom code I wrote, to a static site built using Pelican. I've put in place various URL manipulation rules in the webserver config to try to support the old URLs, but it's likely that I've missed some (probably meta ones related to pagination or tagging), so apologies for any 404 errors that you get served.

RSS icon, courtesy of www.feedicons.com RSS feed for this blog

About the author

I'm a software developer who's worked with a variety of platforms and technologies over the past couple of decades, but for the past 7 or so years I've focussed on web development. Whilst I've always nominally been a "full-stack" developer, I feel more attachment to the back-end side of things.

I'm a web developer for a London-based equities exchange. I've worked at organizations such as News Corporation and Google and BATS Global Markets. Projects I've been involved in have been covered in outlets such as The Guardian, The Telegraph, the Financial Times, The Register and TechCrunch.

Twitter | LinkedIn | GitHub | My CV | Mail

Popular tags

Other sites I've built or been involved with

Work

Most of these have changed quite a bit since my involvement in them...

Personal/fun/experimentation