I am trying to use texture bricking for my volume rendering application. The whole volume data is divided into 3D bricks of smaller dimensions so that they can fit into the texture memory. Also since I am using Linear filtering I get a black border between the two bricks if I dont use an extra voxel from the neighborhood. Thus in short every brick is made up of its own data plus a adjacent voxels along the border.
Given this, Now I am facing a problem where I can no longer use glTexSubImage3D to replace one texture brick with another. I use this function because all bricks can not be loaded completely in the small amount of texture memory available. But the glTexSubImage3D doesnt take the border size as the parameter. My border is of size 1 and my data is also of appropriate size(actual size + 2 /for borders/). Also if i just give the actual size in the widht, height and depth parameters of SubImage3D I get incorrect results. Consequently I had to use glTexImage3DEXT in place of the SubImage3D but that slows down my application quite a bit.
Can someone please suggest an alternative.
Specifically My question is :
How to use glTexSubImage3D to replace a 3D texture with border of size 1 with another 3D texture with border of size 1?
This will replace the black border by something visually better, still not as much as real borders :
If this is not enough, try to use emulate border texels. With different texcoords : instead of range [0,1] use something like [ 1.0/texwidth , 1.0-1.0/texwidth} , and make sure that left texels of tex A are the sames as right texels of tex B.
Not sure if it can work though.
EDIT: fixed 2D to 3D
Thanks a lot ZbuffeR. The GL_CLAMP_TO_EDGE solved my problem. It achieves almost the same effect as with the borders.
Regarding TexSubImage border download you need to set the correct offset parameters.
To include the borders set offsets to -1 and the sizes to texels + 2 * border.
E.g. a full 4x4 2D texture + border starts at (-1, -1) with 6x6 size:
glTexSubImage2D(GL_TEXTURE_2D, 0, -1, -1, 6, 6, format, type, pixels);
Thanks a lot for this info Relic. I would never have guessed that, even if now I find the negative offset very logical.
… Missed it completely, but it is actually suggested in the ERRORS part of the API doc for glTexSubImage :
GL_INVALID_VALUE is generated if xoffset < -b, (xoffset + width) > (w - b), ... b is the border width of the texture image being modified ...
If the volume needs to be accurately interpolated, you cannot use clamp to edge, since no interpolation occurs at the edge. The solution is to overlap your bricks by a single voxel instead of using the border. This will also result in better performance as border calculations are not usually optimized in hardware. Instead of using texture coordinates from [0,1] your coordinates would then be from [1/size, (size -1)/size]. Clamp to edge only works for a pseudo volume in which the final image is not significant. For more precise purposes (ie. medical visualization), you will want to use the above algorithm.