OpenGL VBO drawing with multitexturing issue

I realize that OpenFrameworks doesn’t explicitly support multi-texturing (or at least the version I’m working with doesn’t). However I’m writing straight OpenGL where I need this kind of functionality. I’ve got the multitexturing working with a GLSL shader. But since the ofVbo object doesn’t handle multiple arrays of texture coordinates, I’m not using that. Right now, it works fine if I don’t bind any textures (although nothing’s textured then). But if I try to use texturing at all, the whole screen is only drawn white (presumably the last clear color). If I pass the textures in using immediate mode (without the VBO) then it’s also fine there. I can’t tell why there’s a problem.

Here’s the OpenGL:

  
// create vertex/normal/color/texcoord VBO  
glGenBuffersARB(1, &vboId);  
glBindBufferARB(GL_ARRAY_BUFFER_ARB, vboId);  
glBufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(vert_buf)+sizeof(norm_buf)+sizeof(col_buf)+sizeof(tex_buf), 0, GL_STREAM_DRAW);  
glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(vert_buf), vert_buf);  
glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, sizeof(vert_buf), sizeof(norm_buf), norm_buf);  
glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, sizeof(vert_buf)+sizeof(norm_buf), sizeof(col_buf), col_buf);  
glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, sizeof(vert_buf)+sizeof(norm_buf)+sizeof(col_buf), sizeof(tex_buf), tex_buf);  
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);  
  
// create geometry indices VBO  
glGenBuffersARB(1, &vboId2);  
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, vboId2);  
glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, sizeof(index_buf), index_buf, GL_STATIC_DRAW_ARB);  
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);  
  
// bind vertex/normal/color/texcoord VBO  
glBindBufferARB(GL_ARRAY_BUFFER_ARB, vboId);  
  
// enable vertex arrays  
glEnableClientState(GL_NORMAL_ARRAY);  
glEnableClientState(GL_COLOR_ARRAY);  
glEnableClientState(GL_VERTEX_ARRAY);  
  
// specify vertex and index arrays with their offsets  
glVertexPointer(3, GL_FLOAT, 0, 0);  
glNormalPointer(GL_FLOAT, 0, (void*)sizeof(vert_buf));  
glColorPointer(3, GL_FLOAT, 0, (void*)(sizeof(vert_buf)+sizeof(norm_buf)));  
  
// bind geometry indices VBO  
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, vboId2);  
glIndexPointer(GL_UNSIGNED_INT, 0, 0);  
  
// set the texture units  
GLvoid* start = (void*)(sizeof(vert_buf)+sizeof(norm_buf)+sizeof(col_buf));  
glClientActiveTexture(GL_TEXTURE0 + (GLuint)vid_regions[0].tex_id);	// same as GL_TEXTURE1  
glTexCoordPointer(2, GL_FLOAT, 0, start);  
glEnableClientState(GL_TEXTURE_COORD_ARRAY);  
glClientActiveTexture(GL_TEXTURE0 + (GLuint)vid_regions[1].tex_id);	// same as GL_TEXTURE2  
glTexCoordPointer(2, GL_FLOAT, 0, start);  
glEnableClientState(GL_TEXTURE_COORD_ARRAY);  
glClientActiveTexture(GL_TEXTURE0 + (GLuint)vid_regions[2].tex_id);	// same as GL_TEXTURE3  
glTexCoordPointer(2, GL_FLOAT, 0, start);  
glEnableClientState(GL_TEXTURE_COORD_ARRAY);  
glClientActiveTexture(GL_TEXTURE0 + noiseTexID);	// same as GL_TEXTURE4  
glTexCoordPointer(2, GL_FLOAT, 0, start);  
glEnableClientState(GL_TEXTURE_COORD_ARRAY);  
glClientActiveTexture(GL_TEXTURE0 + lutTexID);	// same as GL_TEXTURE5  
glTexCoordPointer(2, GL_FLOAT, 0, start);  
glEnableClientState(GL_TEXTURE_COORD_ARRAY);  
  
// draw VBOs  
glDrawElements(GL_TRIANGLES, 36*ROWS*COLS, GL_UNSIGNED_INT, 0);  
  
// disable arrays  
glDisableClientState(GL_VERTEX_ARRAY);  
glDisableClientState(GL_COLOR_ARRAY);  
glDisableClientState(GL_NORMAL_ARRAY);  
  
// disable texture arrays  
glClientActiveTexture(GL_TEXTURE0 + (GLuint)vid_regions[0].tex_id);  
glDisableClientState(GL_TEXTURE_COORD_ARRAY);  
glClientActiveTexture(GL_TEXTURE0 + (GLuint)vid_regions[1].tex_id);  
glDisableClientState(GL_TEXTURE_COORD_ARRAY);  
glClientActiveTexture(GL_TEXTURE0 + (GLuint)vid_regions[2].tex_id);  
glDisableClientState(GL_TEXTURE_COORD_ARRAY);  
glClientActiveTexture(GL_TEXTURE0 + noiseTexID);  
glDisableClientState(GL_TEXTURE_COORD_ARRAY);  
glClientActiveTexture(GL_TEXTURE0 + lutTexID);  
glDisableClientState(GL_TEXTURE_COORD_ARRAY);  
  
// unbind VBOs  
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);  
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);  

  
glClientActiveTexture(GL_TEXTURE0 + (GLuint)vid_regions[0].tex_id); // same as GL_TEXTURE1    
glTexCoordPointer(2, GL_FLOAT, 0, start);    
glEnableClientState(GL_TEXTURE_COORD_ARRAY);   

looks a little backwards. shouldn’t that be:

  
glClientActiveTextureARB(GL_TEXTURE1_ARB);  
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);  
    glTexCoordPointer(3, GL_FLOAT, 0, 0);  

Thanks for your reply.

The GL_TEXTURE0 + (GLuint)vid_regions[0].tex_id is correctly selecting a texture to pass to the shader. That works fine in immediate mode (but using glActiveTexture).

The texture pointer uses only 2 coordinates for UVs so it should be:

  
glEnableClientState(GL_TEXTURE_COORD_ARRAY);  

And as far as the order is concerned, I don’t think it matters in this case.

Of course, I tried that out anyway and it didn’t work. :confused:

Dang. Well, one final small thought, more of a shot in the dark really: looking at this http://www.gamedev.net/topic/543267-vbo-and-multi-texture/ might you try to call glEnable(GL_TEXTURE_2D) & glBindTexture(GL_TEXTURE_2D) for each texture.

Sorry I can’t be of more help than that

Thanks for your help.

I have tried that. Both before and after the VBO operations without success. It’s an elusive bug. I’ll post the solution, once I find it.

mmh, are you using ofTexture? cause it uses ARB textures not 2D ones. things like:

  
glEnable(GL_TEXTURE_2D)   

should be

  
glEnable(GL_TEXTURE_RECTANGLE_ARB)   

and everything related to textures in general. you can also try disabling ARB textures with

  
ofDisableArbTex();  

and the same in the shader side

The actual source of the problem here was that the VBO was being drawn to an FBO and I wasn’t resetting the client texture back to zero:

  
glClientActiveTexture(GL_TEXTURE0_ARB);  

Woops! Thanks for your help!