0

I want to switch between shader programs runtime, with a fixed VBO array.

I thik I need no more than the following functions with fixed vertex attributes index (I want 0 for position, 1 for texture coordinates)

glEnableVertexAttribArray
glVertexAttribPointer
glGetAttribLocation
glBindAttribLocation

I have wired up everything, but nothing has drawn to the FBO. If I use vertex attribute index (in glVertexAttribPointer) that has been located from the program, then it works fine, but I cannot use it with fixed attributes index.

Can somebody show me a brief sample code that shows me the right usage/execution order of the functions above?

Is there any missing step?

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
Geri Borbás
  • 15,810
  • 18
  • 109
  • 172
  • 3
    -1: "Can somebody show me a brief sample code that shows me the right usage/execution order of the functions above?" This is a terrible thing to ask. The only way you wouldn't know what order those functions go in is if you didn't know what they *do*. So you need to ask how these functions *work*; otherwise, you're just copy-and-paste coding. – Nicol Bolas Apr 21 '12 at 10:02
  • @Nicol: Things like this - http://www.opengl.org/sdk/docs/man/xhtml/glBindAttribLocation.xml - are really good, but tells me nothin' about the execution order. – Geri Borbás Apr 21 '12 at 10:50
  • I really know what glBindAttribLocation do, but when it not works just because I used it after linking my program, then I have no idea where to go. – Geri Borbás Apr 21 '12 at 10:51
  • Ok, +1 for you, I've found it in the documentation. :) Posted another answer. – Geri Borbás Apr 21 '12 at 10:53

2 Answers2

3

The point is: glBindAttribLocation must be called before link the program.

glBindAttribLocation(program, ATTRIBUTE_POSITION, "position");
glBindAttribLocation(program, ATTRIBUTE_TEXTURE_COORDINATES, "textureCoordinates");      
glLinkProgram(program);

Then you can use attribute array function with fixed indices, like:

glEnableVertexAttribArray(ATTRIBUTE_POSITION);
glEnableVertexAttribArray(ATTRIBUTE_TEXTURE_COORDINATES);    
glVertexAttribPointer(ATTRIBUTE_POSITION, 2, GL_FLOAT, GL_FALSE, _positionStride, (void*)0);    
glVertexAttribPointer(ATTRIBUTE_TEXTURE_COORDINATES, 2, GL_FLOAT, GL_FALSE, _positionStride, (void*)_textureCoordinatesOffset);  

Where indices are just simple integers, as:

//Vertex attributes.
enum 
{
    ATTRIBUTE_POSITION,            //0
    ATTRIBUTE_TEXTURE_COORDINATES  //1
};

It works now. So I don't have to call glVertexAttribPointer before every draw call.

Riot
  • 15,723
  • 4
  • 60
  • 67
Geri Borbás
  • 15,810
  • 18
  • 109
  • 172
0

As the doc says (http://www.opengl.org/sdk/docs/man/xhtml/glBindAttribLocation.xml):

Attribute variable name-to-generic attribute index bindings for a program object can be explicitly assigned at any time by calling glBindAttribLocation. Attribute bindings do not go into effect until glLinkProgram is called. After a program object has been linked successfully, the index values for generic attributes remain fixed (and their values can be queried) until the next link command occurs.

Applications are not allowed to bind any of the standard OpenGL vertex attributes using this command, as they are bound automatically when needed. Any attribute binding that occurs after the program object has been linked will not take effect until the next time the program object is linked.

Geri Borbás
  • 15,810
  • 18
  • 109
  • 172