2014/09/18
(转载自:http://blog.sina.com.cn/s/blog_57bf2c59010008gm.html)
如果一个图象文件比较大的话(比如4000*4000),纹理无法从文件中读出全部的图象,当然这个具体的大小是根据显示硬件而有差别的。这时候可以用表面载入文件,然后再把表面的内容复制到纹理中。
需要用到的方法:
CreateTexture,
CreateOffscreenPlainSurf ace,
D3DXGetImageInfoFromFile ,
D3DXLoadSurfaceFromFile,
GetSurfaceLevel,
SetRenderTarget,
UpdateSurface
下面是关键代码片段:
LPDIRECT3DSURFACE9 srcSurface=NULL;
LPDIRECT3DSURFACE9 backbuffer=NULL;
LPDIRECT3DTEXTURE9 pStateTexture=NULL;
D3DXIMAGE_INFO Info;
//得到图片文件信息到Info
if(D3D_OK!=(D3DXGetImageInfoFromFile("kongfu1.png", &Info)))
{
MessageBox(NULL,"得到图象信息错误!","LOAD PIC ERROR",MB_OK);
}
//创建纹理
if(D3D_OK!=(g_pd3dDevice->CreateTexture(
350,//宽
350,//高
1,//纹理级别,不使用多重纹理时候为1
D3DUSAGE_RENDERTARGET,//创建的纹理为可渲染对象(复制纹理必须),内存
//必须为D3DPOOL_DEFAULT
D3DFMT_A8R8G8B8,//带ALPHA通道的32位像素样式
D3DPOOL_DEFAULT,//在显存中创建
&pStateTexture,//目标纹理
NULL//保留,为NULL
)))
{
MessageBox(NULL,"纹理初始化错误!","LOAD PIC ERROR",MB_OK);
}
//创建离屏表面
if(D3D_OK!=(g_pd3dDevice->CreateOffscreenPlainSurface(Info.Width,//宽
Info.Height,//高
D3DFMT_A8R8G8B8,//带ALPHA通道的32位像素样式
D3DPOOL_SYSTEMMEM,//在系统内存中创建表面
&srcSurface, //目标表面
NULL//保留,设为NULL
)))
{
MessageBox(NULL,"创建表面错误!","LOAD PIC ERROR",MB_OK);
}
//加载文件图片到表面
if(D3D_OK!=(D3DXLoadSurfaceFromFile(
srcSurface,//目标表面
NULL,//目标调色板
NULL,//目标矩形,NULL为加载整个表面
"kongfu1.png",//文件
NULL,//源矩形,NULL为复制整个图片
D3DX_FILTER_NONE,//过滤
D3DCOLOR_XRGB(0,0,0),//透明色
NULL//源图像信息
)))
{
MessageBox(NULL,"表面装载错误!","LOAD PIC ERROR",MB_OK);
}
//得到纹理表面,一个纹理可以看作很多表面组成。得到最上面的一个。
if(D3D_OK!=(pStateTexture->GetSurfaceLevel(0,&backbuffer)))
{
MessageBox(NULL,"纹理装载错误!","LOAD PIC ERROR",MB_OK);
}
//设置渲染目标为上面得到的文理表面
g_pd3dDevice->SetRenderTarget(0,backbuffer);
//从srcSurface表面复制rect矩形内数据到渲染目标表面
//注意几点:源表面必须创建在D3DPOOL_SYSTEMMEM系统内存中
// 目标表面必须创建在D3DPOOL_DEFAULT显示内存中
// 表面的FORMAT必须相同,矩形区域大小必须相同
if(D3D_OK!=(g_pd3dDevice->UpdateSurface(
srcSurface,//源表面
&rect,//源矩形
backbuffer,//目标纹理表面
NULL//目标矩形
)))
{
MessageBox(NULL,"纹理更新错误!","LOAD PIC ERROR",MB_OK);
}
//得到正常渲染缓冲表面
g_pd3dDevice->GetBackBuffer(0,0,D3DBACKBUFFER_TYPE_MONO,&backbuffer);
//设置正常渲染缓冲表面为渲染目标表面
g_pd3dDevice->SetRenderTarget(0,backbuffer);