Texture from surface

Started by
5 comments, last by lone_ranger 21 years, 2 months ago
I am developing a top-down racing game with VC++ and directx 8.1.I have a tile map image and i load it as a surface in my program.Now, i want to create textures form this surface(one texture per tile type) but i can not find any directX function doing this is in Microsoft''s documentation.Can anyone help me?
Virtus junxit, mors non separabit
Advertisement
I was looking for the same functionality a week ago: making a texture from a surface. I didn''t find anything, but rather just switched to just load the images with D3DXCreateTextureFromFile(). Could you do the same?

Mind you though, I had straaaange random scaling problems on my sprites using this function. After a bit of testing, I resolved the problem by first calling D3DXGetImageInfoFromFile(), and then rather use D3DXCreateTextureFromFileEx() with the info i had.

Two atoms walk into a bar, the first one says: "Oh no, I have lost an electron!". The other one asks: "Are you shure?", and the first one replies: "I''m positive!"
Real programmers don't comment their code, it was hard to write, it should be hard to understand
may be you can copy the rectangle your want to texture, from surface, by yourself?
Hi, I had the same problem recently then someone came up with the solution (thx Rich [Microsoft Direct3D MVP])

Simply use the D3DXLoadSurfaceFromSurface on your texture.

I know this look like repeating unnecessary steps just to get a texture but when you want to create a texture from a surface, the easiest way I found was to get a surface from the texture, perform a surface to surface copy and copy the surface back to the texture. There might be some other way, faster or optimized, but to me this was the most comprehensible for now.

In our case here is some steps :

1- you need a texture, empty or already filled we don''t care
2- create and load an image (bitmap) on your surface
3- get a surface from your texture (ie level 0) **This is where I think most people are havig problem**
4- call D3DXLoadSurfaceFromSurface
5- It might depends how you want to play with your new surface, but you might lock your surface and copy it to a texture (you need to do this to render a surface to a triangle...)

// We suppose you have a valid texture created. IT could be empty or filled with data.// Create and load a file to your first surfaceLPDIRECT3DSURFACE9 surface = NULL;D3DXIMAGE_INFO info;hr = m_pD3DDevice->CreateOffscreenPlainSurface(32,32, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT,&surface,NULL);hr = D3DXLoadSurfaceFromFile(surface, NULL,NULL, "base3.bmp", NULL,D3DX_DEFAULT,D3DCOLOR_XRGB(0,0,0),&info);// This is the fun part.  Get a surface from the texture you want to copy *to*. You will load your first surface to this second surface which is basically a pointer to your texture.LPDIRECT3DSURFACE9 tempSurf;m_pMeshTextures[0]->GetSurfaceLevel(0,&tempSurf);// Load the first surface to the texture (second surface)D3DXLoadSurfaceFromSurface(tempSurf,NULL,NULL,surface,NULL,NULL,D3DX_FILTER_NONE,0);// Finally, copy your new surface to your texture.  I do that by locking my surface, copying it to my texture, unlocking and so on...surface->LockRect(&rect,NULL,0);surface->UnlockRect();[\code]    
yes but how i do this handing?:

// We suppose you have a valid texture created. IT could be empty or filled with data.
// Create and load a file to your first surface
quote:Original post by Link
yes but how i do this handing?:

// We suppose you have a valid texture created. IT could be empty or filled with data.
// Create and load a file to your first surface


You mean creating the target texture?

In my particular case I use :
LPDIRECT3DTEXTURE9 texture = NULL;
hr = D3DXCreateTexture(m_pD3DDevice,32,32,D3DX_DEFAULT,
0,D3DFMT_X8R8G8B8,D3DPOOL_MANAGED,&texture);

Since you cannot (or at least I did not find a way to) copy a surface to texture directly, you must get a surface pointer from your texture. You do that with the GetSurfaceLevel function. Then you copy surfaces with D3DXLoadSurfaceFromSurface.

Frankski


HRESULT CreateTextureFromSurface(LPDIRECT3DSURFACE8 pSurface, RECT* pSrcRect,
RECT* pDestRect,
LPDIRECT3DTEXTURE8* ppTexture)
{
int width, height;
RECT Src;
D3DSURFACE_DESC surfDesc;
DXTEST( pSurface->GetDesc(&surfDesc) );
if( !pSrcRect ){
width = surfDesc.Width;
height = surfDesc.Height;
Src.left = Src.top = 0;
Src.right = width;
Src.bottom = height;
}
else{
width = pSrcRect->right - pSrcRect->left; // + 1;
height = pSrcRect->bottom - pSrcRect->top; // + 1;
Src = *pSrcRect;
}

DXTEST( D3DXCreateTexture(g_pD3DDevice, width, height,
1, 0, surfDesc.Format, D3DPOOL_DEFAULT, ppTexture) );

// Retrieve the surface image of the texture.
LPDIRECT3DSURFACE8 pTexSurface;
LPDIRECT3DTEXTURE8 pTexture = *ppTexture;
DXTEST( pTexture->GetLevelDesc(0, &surfDesc) );
DXTEST( pTexture->GetSurfaceLevel(0, &pTexSurface) );

// Create a clean surface to clear the texture with.
LPDIRECT3DSURFACE8 pCleanSurface;
D3DLOCKED_RECT lockRect;
DXTEST( g_pD3DDevice->CreateImageSurface(
surfDesc.Width, surfDesc.Height, surfDesc.Format, &pCleanSurface) );
DXTEST( pCleanSurface->LockRect(&lockRect, NULL, 0) );
memset((BYTE*)lockRect.pBits, 0, surfDesc.Height * lockRect.Pitch);
DXTEST( pCleanSurface->UnlockRect() );

DXTEST( g_pD3DDevice->CopyRects(pCleanSurface, NULL, 0,
pTexSurface, NULL) );
pCleanSurface->Release();

// Copy the image to the texture.
POINT destPoint = { 0, 0 };
DXTEST( g_pD3DDevice->CopyRects(pSurface, &Src, 1,
pTexSurface, &destPoint) );
pTexSurface->Release();

return S_OK;
}

This topic is closed to new replies.

Advertisement