1
votes

I'm currently using a VBO to draw a series of cubes in OpenGL using a GLSL shader that performs multitexturing (with 5 textures). It works fine if I don't pass the textures in. 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.

Code:

// 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);

Note: the creation of the VBOs is called during the initial setup phase. The drawing happens in a drawing GLUT routine.

1
Maybe you should post the shader code. And your "set the texture units" seems very wrong. If the coordinates are the same for all the texture units you shouldn't have to pass them multiple times.Jonathan

1 Answers

0
votes

Try resetting your texture level back to 0:

glClientActiveTexture(GL_TEXTURE0);

It's not uncommon for weirdness to happen when the active texture level isn't reset (say if you're using FBOs, etc).

It might also be helpful to set your clear colour to something other than black/white/transparent to see if the screen is being drawn with the clear colour or if you're somehow seeing a texel stretched or something else.