This is the Texture::update code from the latest svn revision (it must have got put in right after the 9.00 beta 4 release...)
void Texture::update(const shared_ptr<PixelTransferBuffer>& src, int mipLevel, CubeFace face) {
alwaysAssertM(format()->openGLBaseFormat == src->format()->openGLBaseFormat,
"Data must have the same number of channels as the texture: this = " + format()->name() +
" src = " + src->format()->name());
const shared_ptr<GLPixelTransferBuffer>& glsrc = dynamic_pointer_cast<GLPixelTransferBuffer>(src);
glPushAttrib(GL_TEXTURE_BIT);
{
glBindTexture(openGLTextureTarget(), openGLID());
glPixelStorei(GL_PACK_ALIGNMENT, 1);
const GLint xoffset = 0;
const GLint yoffset = 0;
GLenum target = openGLTextureTarget();
if (isCubeMap()) {
target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + (int)face;
}
const void* ptr = NULL;
if (notNull(glsrc)) {
// Bind directly instead of invoking bindRead(); see below for discussion
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, glsrc->glBufferID());
// The pointer is an offset in this case
ptr = 0;
} else {
// Regular path
ptr = src->mapRead();
}
glTexSubImage2D
(target,
mipLevel,
xoffset,
yoffset,
src->width(),
src->height(),
src->format()->openGLBaseFormat,
src->format()->openGLDataFormat,
ptr);
if (notNull(glsrc)) {
// Creating the fence for this operation is VERY expensive because it causes a pipeline stall [on NVIDIA GPUs],
// so we directly unbind the buffer instead of creating a fence.
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, GL_NONE);
} else {
// We mapped the non-GL PTB, so unmap it
src->unmap();
}
}
glPopAttrib();
}