Bind index 0 or get index 1
Return to home page
Comments Loading...
2009-01-08

There's been a distinct evolution in the API you use with OpenGL over the years. Originally, it was all this immediate mode stuff, where you'd send commands to the driver and it would render triangles on the screen for you. Next came the ability to have chunks of data on the client and send it to the server in bulk, you'd do this by giving the driver an array of vertices, an array of colours, an array of texture coordinates, an array of indexes, an array of.. well, an array of each kind of thing that existed in the fixed pipeline.

Now with OpenGL 3.0, there is no client state and no immediate mode, everything gets sent to the server and whether it ends up in RAM or VRAM is no longer your concern (although you can hint it or use lower level APIs to mold it the way you want).

This story is a story about how not all drivers are created equal. There are a number of people out there who love using OpenGL in VisualWorks, but only a handful of them have been game enough to try out the new 3.0 branch.

This is a story of one such brave individual, who helped me debug one of the harder and more confusing problems I've come up against so far trying to push VisualWorks - actually all of Cincom Smalltalk - in to the "new" age of OpenGL.

The fixed pipeline had these arrays. The arrays were assigned to slots that were processed by the vertex shader and fragment shader. You could program your own vertex shaders and fragment shaders - but you only had a set number of arrays you could access, the same ones from the fixed pipeline. That is, until generic attributes were added - you could now pass any array data you wanted to the card and process it.

The problem though, is that some drivers still expect a primary collection to iterate over. They expect variable index 0 to be bound. They expect variable index 0 to be filled with the primary vertex data, or gl_Vertex. When you define an attribute array in your vertex shader, it'll look something like this:

attribute vec4 myVertex;

When you set up the vertex shader program, you'll ask the driver for the index of 'myVertex' and it'll give you back a number. You can then use this number to bind an actual vertex buffer object. This is where the story got interesting. Mark Plas tried out the lessons that I've made for the OpenGL 3.0 stream - none of them drew anything.

At first, I thought perhaps OpenGL wasn't working at all, he'd get a blank black window and nothing else. He could change the clear colour to red and the window would go red. There were no errors setting up the window either (I'd previously gone through the OpenGL-Windows package and made it more paranoid wrt to setting up the window - just for this kind of debugging. However, in this case it did not help).

So OpenGL was working, but nothing was being drawn. Finally, after considerable thought and many caffeinated drinks, reading documentation, reading blog posts and chatting with the brains on the opengl irc channel, it struck me that if gl_Vertex expects to be in slot 0, perhaps none of our generic attributes are being bound to slot 0.

I had Mark check what the variable was being bound to - sure enough it was being bound at index 1, not index 0. So when we instructed the driver to render some of the content, it blissfully "optimized" the operation away because nothing was bound in to index 0.

I got Mark to try an alternate way of binding, where we specify what index the variable goes in to instead of letting the driver tell us - suddenly his OpenGL came to life and he could see the lessons.

Talk about your obscure bugs. This only happened because of the evolution of how OpenGL runs now versus how it ran before. It always expected to have index 0 bound and assumed that if it was not bound, there was no vertex data and thus nothing to render. This assumption is not true when we have generic attributes. I did not encounter this problem with my NVidia card or with my ATI card on my MacBook Pro - but Mark's Windows machine and the OpenGL driver it had most certainly did.

Thank you for your patient help debugging this problem Mark and I intend to have the fixes integrated in to the packages and lessons soon.

Listened to: Attacking Panthers from the album "Tomb Raider Underworld Deluxe Edition" by Colin O'Malley