WCG MV

Saturday, March 03, 2007

SM's D3D Tutorial 2: Create Texture with User-defined Image Data

Usually we use D3DXCreateTextureFromFile() function to create a texture from external file, but how do we create it with user-defined image data? The way is as follows:
1. Create an empty texture:
LPDIRECT3DTEXTURE9 pTexture = NULL;
LPDIRECT3DSURFACE9 pRenderSurface = NULL;

D3DXCreateTexture(pDevice,
256, // width
256, // height
0, // number of mip levels(0 - a complete mipmap chain is created)
0, // usage
D3DFMT_A8R8G8B8, // format
D3DPOOL_MANAGED, // pool(cannot be D3DPOOL_DEFAULT here)
&pTexture);
2. Retrieve this texture surface level:
pTexture->GetSurfaceLevel(0, &pRenderSurface);
D3DSURFACE_DESC surfaceDesc;
pRenderSurface->GetDesc(&surfaceDesc);
3. Lock a rectangle on the surface:
D3DLOCKED_RECT lockedRect;
pRenderSurface->LockRect(&lockedRect, 0, 0); // entire surface

NOTE: This method cannot retrieve data from a surface that is is contained by a texture resource created with D3DUSAGE_RENDERTARGET because such a texture must be assigned to D3DPOOL_DEFAULT memory and is therefore not lockable. In this case, use instead GetRenderTargetData to copy texture data from device memory to system memory.
4. Retrieve and modify the surface's data :
DWORD* imageData = (DWORD*)lockedRect.pBits;
for(int i = 0; i < surfaceDesc.Height; i++)
{
for(int j = 0; j < surfaceDesc.Width; j++)
{
int index = i * (lockedRect.Pitch / 4) + j; // because pitch is in bytes, and 4 bytes per DWORD
imageData[index] = 0xffffff00;
}
}
5. Unlock the rectangle:
pRenderSurface->UnlockRect();

No comments: