纹理操作
2010-05-27 18:24:03| 分类: DirectX 3D学习|举报|字号 订阅
在d3d8中,创建纹理的方法有:
1、D3DXCreateTexture ()
2、D3DXCreateTextureFromFile ()
3、D3DXCreateTextureFromFileEx ()
4、D3DXCreateTextureFromFileInMemory ()
5、D3DXCreateTextureFromFileInMemoryEx ()
6、D3DXCreateTextureFromResource ()
7、D3DXCreateTextureFromResourceEx ()
其中只有第1种是可以用自定义的纹理图片的格式(要自己编写文件读取函数,大部分游戏都是自定义格式的,很少有人直接用bmp,tag,png等末经压缩的文件,容量大不说,而且容易被别人盗用),那么现在问题出现了,用函数D3DXCreateTexture () 创建纹理的方法如下:
LPDIRECT3DDEVICE8 m_pd3dDevice;
LPDIRECT3DTEXTURE8 pTexture;
//其它初始化代码略,直接跳到创建纹理处
//读取图象(这是我自定义的格式*.shp),Load_Image(...)函数是自己写的
if (!Load_Image(&image, "com280001.SHP "))
return;
HRESULT hr;
//创建纹理表面
hr = D3DXCreateTexture(m_pd3dDevice, image.m_Width, image.m_Height, 0, 0, D3DFMT_R5G6B5, D3DPOOL_MANAGED, &pTexture);
if(FAILED(hr))
{
MessageBox(NULL, "Cannot create texture! ", "ERROR ",MB_OK);
return;
}
D3DSURFACE_DESC pDesc;
pTexture-> GetLevelDesc(0, &pDesc );
D3DLOCKED_RECT d3dlr;
//锁定纹理表面
pTexture-> LockRect( 0, &d3dlr, 0, 0 );
WORD * pDst = (WORD *)d3dlr.pBits;
int DPitch = d3dlr.Pitch> > 1;
//逐个象素扫描并写进纹理表面
for (int y=0; y <m_Height; ++y){
for (int x=0; x <m_Width; ++x)
{
pDst[y*DPitch + x] = image.buffer[y*shp.width + x];
}
}
//解锁
pTexture-> UnlockRect (0);
//释放图片占用的资源
Unload_Image(&image);
到这里纹理已成功创建了,但还有一个问题:如何设定颜色关键字(即colorkey)?
用D3DXCreateTextureFromFileEx ()
或D3DXCreateTextureFromFileInMemoryEx ()
或D3DXCreateTextureFromResourceEx ()
这些函数可以设定colorkey,但只能用指定的几种格式文件如bmp、tga等。
象我这种用自定义的文件格式的话如何设定colorkey?
colorkey其实是surface的属性,只不过大部分texture都只有一个surface,(cube,Mip有多个,但colorkey的设置一般也一样),所以D3DX中有一些简化的用法。
要达到你的目标可以用IDirect3DTexture9::GetSurfaceLevel(0)获得第一个表面然后设置colorkey,或者你可以先在内存里把你的格式写成位图(反正都需要这一步),然后再用D3DXCreateTextureFromFileInMemoryEx () 。
我可不是高手,说错了别介意。
//有一种笨方法:
//创建两个纹理,一个用于显示,设为txture1,一个用于存放图片,设为texture2,
LPDIRECT3DTEXTURE8 texture1;
LPDIRECT3DTEXTURE8 texture2;
//创建texture1(略)详细见上面,不过要注意象素格式不能设为R5G6B5,而是一定要带有alpha值的,否则ColorKey没有用。我用的是A1R5G5B5格式。
//创建texture2并将图片载入texture2(略)详细见上面,象素格式必须对应你的图片象素的格式。我的图片象素格式是R5G6B5。
//再创建两个表面:分别用来指向两个纹理的surface;
LPDIRECT3DSURFACE8 surface1;
LPDIRECT3DSURFACE8 surface2;
//用来指向两个纹理的surface
texture1-> GetSurfaceLevel(0, &surface1);
texture2-> GetSurfaceLevel(0, &surface2);
//然后用函数D3DXLoadSurfaceFromSurface()把surface2复制到surface1
D3DXLoadSurfaceFromSurface(surface1,
NULL,
NULL,
surface2,
NULL,
NULL,
D3DX_DEFAULT,
ColorKey);
//然后自己指定参数中的ColorKey,就可以在渲染中使用texture1了。贴出来的图片果然是背景透明。
这是我想出的笨方法,谁有更好的方法的话,望指教!