項目遇到這個問題,找了好多網站都沒有找到例子,就研究了下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的值哦