Sign in to follow this  
jhq

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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 ; )

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this