Code below allows you to wrap a texture using PBO. Works nice if you need to displace lets say an normal/elevation-map with fixed interval around the camera. So you can progressively insert the new areas.
void TextureOffset( uint32 resource, int dx, int dy )
{
const int sizePerPixel = 4; const int bytesPerPixel = 1;
const int colorFormat = GL_RGBA; int colorComponent = GL_UNSIGNED_BYTE;
int32 w; int32 h; uint32 pbo;
glBindTexture(GL_TEXTURE_2D, resource);
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &w);
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &h);
dx = (w + (dx % w)) % w;
dy = (h + (dy % h)) % h;
//Prepase source & destination regions...
int offetsx[] = { dx, 0, dx, 0 }, doffetsx[] = { 0, w - dx, 0, w - dx };
int offetsy[] = { dy, dy, 0, 0 }, doffetsy[] = { 0, 0, h - dy, h - dy };
int offetsw[] = { w, dx, w, dx }, doffetsw[] = { w - dx, w, w - dx, w };
int offetsh[] = { h, h, dy, dy }, doffetsh[] = { h - dy, h - dy, h, h };
for( int i = 0; i < 4; i++ ) offetsw[i] = offetsw[i] - offetsx[i], offetsh[i] = offetsh[i] - offetsy[i],
doffetsw[i] = doffetsw[i] - doffetsx[i], doffetsh[i] = doffetsh[i] - doffetsy[i];
glGenBuffersARB(1, &pbo);
glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, pbo);
glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB, w * h * sizePerPixel, 0x0, GL_DYNAMIC_COPY );
glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0x0);
glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, pbo);
glPixelStorei(GL_PACK_ROW_LENGTH, w ); glPixelStorei(GL_PACK_ALIGNMENT, bytesPerPixel);
glPixelStorei(GL_PACK_SKIP_PIXELS, 0 ), glPixelStorei(GL_PACK_SKIP_ROWS, 0);
glGetTexImage(GL_TEXTURE_2D, 0, colorFormat, colorComponent, (void*)0);
glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0);
glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, pbo);
glPixelStorei(GL_UNPACK_ROW_LENGTH, w ); glPixelStorei(GL_UNPACK_ALIGNMENT, bytesPerPixel);
for( int i = 0, offset = 0; i < 4; i++ )
glPixelStorei(GL_UNPACK_SKIP_PIXELS, doffetsx[i] ), glPixelStorei(GL_UNPACK_SKIP_ROWS, doffetsy[i]),
glTexSubImage2D(GL_TEXTURE_2D, 0, offetsx[i], offetsy[i], offetsw[i], offetsh[i], colorFormat, colorComponent, (void*)0 );
glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
glDeleteBuffersARB(1, &pbo);
glPixelStorei(GL_PACK_ROW_LENGTH, 0 ); glPixelStorei(GL_PACK_ALIGNMENT, 1);
glPixelStorei(GL_PACK_SKIP_PIXELS, 0 ), glPixelStorei(GL_PACK_SKIP_ROWS, 0);
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0 ); glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0 ), glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
glBindTexture(GL_TEXTURE_2D, 0);
}
Comments
Post a Comment