项目遇到这个问题,找了好多网站都没有找到例子,就研究了下Directx SDK,除了直接读取支持Volume Texture的文件以外,还是可以直接从2D Texture转换来的,当然没有像OpenGL这么方便,一个函数搞定。
1. 创建VolumeTexture,这个不用说了,用的是D3DXCreateVolumeTexture.
2. 我们的2D Texture是像这个样子滴。Volume Texture长宽高是16x16x16。我们希望能把这个16x256的2D Texture分切。Opengl就直接调用glTexImage3D就可以了哈,最后一个data的buffer就是这个2D的资源buffer.
3. Ok有了volume texture,有了buffer,下一步就是把这个buffer填充到volume texture中了,d3d也有很多填充方法哈,这里我们用的是D3DXFillVolumeTexture。
最重要是第二个参数,这个是函数指针,实现如下:
void WINAPI FillFuncVolume(D3DXVECTOR4 * value, const D3DXVECTOR3 * texcoord,
const D3DXVECTOR3* texelsize, void* data)
{
Vector3i boxSize( (int)(1.0/texelsize->x), (int)(1.0/texelsize->y), (int)(1.0/texelsize->z));
int index = (int)( (boxSize[1]-1) * texcoord->y + 0.5) * boxSize[0] * boxSize[2] +
(int)( (boxSize[0]-1) * texcoord->x + 0.5) * boxSize[0] +
(int)( (boxSize[2]-1) * texcoord->z + 0.5);
u8* dataPtr = (u8*)(data);
u8* color = dataPtr + (int)(index * 4);
value->x = (float)((*(color))/256.0);
value->y = (float)((*(color + 1))/256.0);
value->z = (float)((*(color + 2))/256.0);
value->w = 1.0;
}
这个函数的功能就是,通过VolumeTexture的采样坐标texcoord去找data buffer中的值,然后赋给颜色value。
大家都知道2Dtexture的buffer都是一行一行写到buffer中去的噻,texelsize是指每个像素是多大,比如我们的texture是16x16x16,这个texelsize的值就是三个1/16=0.0625,通过texelsize我们就知道volume texture的大小了。
index就是找到buffer中对应的位置,2D texture用的是R8G8B8A8,所以要乘个4才是最终的buffer中的位置哈。
PS: volume texture 的采样不要忘记设置D3DSAMP_ADDRESSW的值哦