原文地址:RGB数据通过D3DXCreateTexture创建纹理作者:归去来兮
事实上有时候我们只有纹理 RGB数据,并没有纹理文件,也就无法调用D3DXCreateTextureFromFile了。所以我就模拟通过D3DXCreateTexture创建纹理,纹理所需要的RGB数据通过GDI+的 CImage来读取一个文件(我们还是有一个纹理文件,我说了这里是为了模拟没有文件,只有RGB数据来创建纹理。所以这样是多此一举的,但是我们的重点不在于有没有纹理文件,在于只用RGB数据来渲染),获得其中的RGB信息。
先说一下D3D用RGB数据创建纹理的过程吧(几个关键的部分)
1)调用 D3DXCreateTexture函数,在我程序中这么调用的,imgWidth, imgHeight为像素的宽与高
D3DXCreateTexture(_device,imgWidth, imgHeight, D3DX_DEFAULT, D3DUSAGE_SOFTWAREPROCESSING, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &_d3dTexture);
2)填充纹理的RGB信息, 通过 D3DLOCKED_RECT这个数据结构,这个数据结构有两个数据,分别为pitch和pBits。 第一个成员表示一行数据占用的空间,第二个指向像素数据
D3DLOCKED_RECT d3d_lRect;
_d3dTexture->LockRect(0,&d3d_lRect,0,0)。
// 填充 d3d_lRect->pBits这块空间。
_d3dTexture->UnlockRect(0);
3)和D3DXCreateTextureFromFile创建纹理的渲染方式一样,渲染到屏幕。
这里有一个问题我用CImage 加载的是一个 24色的(2048*1024)位图图片,而D3DXCreateTexture 在填充数据时,得到的pitch为 8192 = 2048*4. 也就是说需要32色。所以这里就需要一个转换将24位变成32为,24色图片的RGB存放顺序从高位到低位为 R,G,B 转换成32为ARGB。也就是在每个像素的高位 添加一个 A。
for(int i=0;i
{
for(int j=0;j
{
p32Data[(i*imgWidth + j)*4] = pData[(i*imgWidth + j)*3];
p32Data[(i*imgWidth + j)*4 + 1] = pData[(i*imgWidth + j)*3 + 1];
p32Data[(i*imgWidth + j)*4 + 2] = pData[(i*imgWidth + j)*3 + 2];
p32Data[(i*imgWidth + j)*4 + 3] = 0xff;
}
}
这样就行了。
其实这个问题本来很小,但是也调试了我一天,其中一方面是对 D3D 不熟悉,另一方面不知道是不在状态还是马虎。不熟悉主要表现在
1) D3DXCreateTexture 中的 D3DFOMAT选项,其中有个 D3DFMT_R8G8B8,本以为这样的话应该就不用进行 24位转换为 32 位了。但是pitch 的值依旧为 8192 = 2048*4. 也就是说像素间隔还是 4 个字节。这个地方有点没搞懂
2)其它枚举参数的使用,在d3d中枚举类型的参数好多,相关文档介绍不多,让我试了好多次。