# help! my D3DXLoadSurfaceFromMemory doesn't work

## Recommended Posts

Yes, basically I just want to load a TGA image in the memory to the backbuffer, but I can get nothing except a black screen, can anyone help me out? here is my little render route
void render()
{
_render->BeginScene();

// pbmp is a pointer of my Bitmap class
_render->drawSurface(phm->pbmp->rawData());

_render->EndScene();
}

void DX9Render::drawSurface(void *pSurface)
{
if(!pSurface)
return;

LPDIRECT3DSURFACE9 pDstSurface = 0;
HRESULT hr = _pD3DDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &pDstSurface);
assert(SUCCEEDED(hr));

// yes, I garantee that the input image's size is the same as backbuffer
RECT rect = { 0, 0, _presentParams.BackBufferWidth - 1, _presentParams.BackBufferHeight - 1 };
hr = D3DXLoadSurfaceFromMemory(pDstSurface, 0, 0, pSurface, _presentParams.BackBufferFormat,
(_presentParams.BackBufferFormat == D3DFMT_A8R8G8B8 ? 4 : 3) * _presentParams.BackBufferWidth,
0, &rect, D3DX_FILTER_NONE, 0);

pDstSurface->Release();
}
[/code]

The code can run, however nothing shows on the screen, is there anything I missed? Thanks in advance :)



##### Share on other sites
That function expects the buffer you give it to contain only raw pixel data. If you want to load a TGA, you should use D3DXCreateTextureFromFile or D3DXCreateTextureFromFileInMemory to decode the TGA into a format D3D can understand. You can then use IDirect3DDevice9::StretchRect to just copy it over to the backbuffer.

##### Share on other sites
As an aside, you're never checking the return value of the function, so when it fails you don't notice. I'd be inclined to use the FAILED() macro to see if the return value is an error code, and if it is then return false or something (Make sure you release the backbuffer still), so the rest of your code can cope with it.

You could also do with using the Debug Runtimes, which will help you spot bugs like this.

##### Share on other sites
Quote:
 MJP:That function expects the buffer you give it to contain only raw pixel data.

I think the raw data is fine. Because before this I have used it to build a heightmap which is OK. To make is sure, I even write this:
// load image		phm->pbmp = new ico::Bitmap();		char errorMsg[256];		phm->pbmp->loadTGA("..\\media\\ps2.tga", errorMsg);		int width, height;		width = phm->pbmp->xSize();		height = phm->pbmp->ySize();		unsigned char* pData = (unsigned char*)phm->pbmp->rawData();                // load the same image into texture with the same format                 // of backbuffer		phm->pTex =	_render->createTextureFromFile(L"..\\media\\ps2.tga");		phm->pTex->getSize(width, height);			phm->heightInfo.resize(width * height, 0);		int pitch = 0;		void* pt = phm->pTex->lock(pitch);                // copy it back from tex		for(int y = 0; y < height; ++y)		    for(int x = 0; x < width; ++x)			{                             memcpy((void*)&pData[y * width + x],                                 (void*)(&((unsigned int*)pt)[y * pitch + x]), sizeof(unsigned int));			}		phm->pTex->unLock();

But, still a black screen. Any comment?

Quote:
 Evil Steve:As an aside, you're never checking the return value of the function

I checked, the return value hr is S_OK

##### Share on other sites
I think the problem maybe related to some d3ddevice config stuff, cause when I change the .tga to .bmp, nothing changes ...

##### Share on other sites
Now I have changed my drawSurface function to this, and everything is fine both with .bmp and .tga

void DX9Render::drawSurface(void *pSurface){	if(!pSurface)		return;	LPDIRECT3DSURFACE9 pDstSurface = 0;	HRESULT hr = _pD3DDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &pDstSurface);	assert(SUCCEEDED(hr));	RECT rect = { 0, 0, _presentParams.BackBufferWidth - 1, _presentParams.BackBufferHeight - 1 };	LPDIRECT3DSURFACE9 pSrcSurf = 0;	hr = _pD3DDevice->CreateOffscreenPlainSurface(640, 480, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &pSrcSurf, 0);	hr = D3DXLoadSurfaceFromMemory(pSrcSurf, 0, 0, pSurface, _presentParams.BackBufferFormat, 		(_presentParams.BackBufferFormat == D3DFMT_A8R8G8B8 ? 4 : 3) * _presentParams.BackBufferWidth,		0, &rect, D3DX_FILTER_NONE, 0);	assert(SUCCEEDED(hr));	hr = _pD3DDevice->StretchRect(pSrcSurf, 0, pDstSurface, 0, D3DTEXF_NONE);	pDstSurface->Release();	pSrcSurf->Release();}

It seems I have to load my raw data first to some mid-surface, then transfer to the backbuffer surface.
why can't I directly load the raw data to backbuffer surface? Could anyone give me some explanation, thanks ; )

## Create an account

Register a new account

• ### Forum Statistics

• Total Topics
628367
• Total Posts
2982284

• 10
• 9
• 13
• 24
• 11