Sign in to follow this  

D3DXLoadSurfaceFromSurface is not working

This topic is 3723 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, I am new in the forum and in DirectX. After reading through the forum and articles, I decided to start making some tests with D3DXLoadSurfaceFromSurface, but the only thing that I get is a white screen. Can anyone tell me what I am doing wrong. I encapsulate all in a class CDirectDraw: CDirectDraw::CDirectDraw() { } CDirectDraw::~CDirectDraw() { destroyD3D(); } HRESULT CDirectDraw::initD3D(HWND hwnd_,BOOL bWindowed_) { hwnd=hwnd_; //CREATE Direct3D object if((lpdd=Direct3DCreate9(D3D_SDK_VERSION))==NULL) return E_FAIL; //SET DISPLAY MODE D3DDISPLAYMODE d3ddm; if(FAILED(lpdd->GetAdapterDisplayMode(D3DADAPTER_DEFAULT,&d3ddm))) return E_FAIL; RECT r_; GetWindowRect(hwnd,&r_); //PREPARE:SET FORMAT OF BACK BUFFER AND PRIMARY SURFACE D3DPRESENT_PARAMETERS d3dpp; ZeroMemory(&d3dpp,sizeof(d3dpp)); d3dpp.BackBufferCount=1; d3dpp.BackBufferWidth=r_.right-r_.left; d3dpp.BackBufferHeight=r_.bottom-r_.top; d3dpp.Windowed=bWindowed=bWindowed_; d3dpp.SwapEffect=D3DSWAPEFFECT_COPY; d3dpp.BackBufferFormat=d3ddm.Format; d3dpp.Flags=D3DPRESENTFLAG_LOCKABLE_BACKBUFFER; d3dpp.MultiSampleType=D3DMULTISAMPLE_NONE; d3dpp.MultiSampleQuality=0; d3dpp.EnableAutoDepthStencil=TRUE; d3dpp.AutoDepthStencilFormat=D3DFMT_D16; d3dpp.FullScreen_RefreshRateInHz=D3DPRESENT_RATE_DEFAULT; d3dpp.PresentationInterval=D3DPRESENT_INTERVAL_IMMEDIATE; d3dpp.hDeviceWindow=hwnd; return lpdd->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,hwnd,D3DCREATE_SOFTWARE_VERTEXPROCESSING,&d3dpp,&lpdddev); } void CDirectDraw::destroyD3D() { if(pBackBuffer) pBackBuffer->Release(); if(pTilesBuffer) pTilesBuffer->Release(); if(lpdddev!=NULL) lpdddev->Release(); if(lpdd!=NULL) lpdd->Release(); } HRESULT CDirectDraw::tileBuffer_init(UINT uiTiles_,UINT uiTileWidth_,UINT uiTileHeight_) { uiTiles=uiTiles_; uiTilesN=0; uiTileWidth=uiTileWidth_; uiTileHeight=uiTileHeight_; D3DDISPLAYMODE d3ddm; if(FAILED(lpdd->GetAdapterDisplayMode(D3DADAPTER_DEFAULT,&d3ddm))) return E_FAIL; return lpdddev->CreateOffscreenPlainSurface(uiTiles*uiTileWidth,uiTileHeight,d3ddm.Format,D3DPOOL_DEFAULT,&pTilesBuffer,NULL); } HRESULT CDirectDraw::tileBuffer_loadFile(LPCTSTR pSrcFile_) { RECT *pDestRect_=new RECT(); pDestRect_->left=uiTilesN*uiTileWidth; pDestRect_->top=0; pDestRect_->right=(uiTilesN+1)*uiTileWidth; pDestRect_->bottom=uiTileHeight; RECT *pSrcRect_=new RECT(); pSrcRect_->left=0; pSrcRect_->top=0; pSrcRect_->right=uiTileWidth; pSrcRect_->bottom=uiTileHeight; uiTilesN++; return D3DXLoadSurfaceFromFile(pTilesBuffer,NULL,pDestRect_,pSrcFile_,pSrcRect_,D3DX_FILTER_NONE,D3DCOLOR_ARGB(255,0,0,0),NULL); } void CDirectDraw::render() { if(lpdddev==NULL) return; lpdddev->Clear(0,NULL,D3DCLEAR_TARGET,D3DCOLOR_XRGB(255,0,0),1.0f,0); lpdddev->GetBackBuffer(0,0,D3DBACKBUFFER_TYPE_MONO,&pBackBuffer); RECT rSrc_,rDest_; rSrc_.top=0; rSrc_.left=0; rSrc_.right=uiTileWidth; rSrc_.bottom=uiTileHeight; rDest_.top=0; rDest_.left=0; rDest_.right=uiTileWidth; rDest_.bottom=uiTileHeight; D3DLOCKED_RECT rbSrc_,rbDest_; pTilesBuffer->LockRect(&rbSrc_,&rSrc_,D3DLOCK_READONLY); pBackBuffer->LockRect(&rbDest_,NULL,NULL); D3DXLoadSurfaceFromSurface(pBackBuffer,NULL,&rDest_,pTilesBuffer,NULL,&rSrc_,D3DX_FILTER_LINEAR,NULL); pBackBuffer->UnlockRect(); pTilesBuffer->UnlockRect(); lpdddev->BeginScene(); lpdddev->EndScene(); lpdddev->Present(NULL,NULL,NULL,NULL); } And in the callback function of the main window: case WM_CREATE: { cdd=new CDirectDraw(); cdd->initD3D(hwnd,FALSE); cdd->tileBuffer_init(3,130,65); cdd>tileBuffer_loadFile(TEXT("floor00.bmp")); cdd->render(); } Thanks!

Share this post


Link to post
Share on other sites
I don't see anything in the DXSDK docs that says you need to lock the source or destination surfaces when using DX3DLoadSurfaceFromSurface.

Try commenting out the Lock and Unlock calls to both surfaces surrounding the call.

Seems like a weird way to be rendering though. Can't you just load your image into a Texture instead and render it to the backbuffer via a vertex buffer and DrawPrimitive call? I believe surface copying is notoriously slow under Direct3D.

Share this post


Link to post
Share on other sites
Thanks EasilyConfused for you reply.

I commented the locks and unlocks but nothing happened.

I have read many comments saying that using textures is faster that surfaces, but I wonder if anyone has made a serious test.

It don’t look logical to me that using complex object is faster than simpler objects. I know textures functions are implemented in hardware, but surfaces are too, or not?

Share this post


Link to post
Share on other sites
Here's how I use D3DXLoadSurfaceFromSurface()

IDirect3DSurface9* screenSurface;
D3DLOCKED_RECT lockedRect;

pSurface->LockRect(&lockedRect, NULL, 0);

void *backBuffer = lockedRect.pBits;

// write whatever you want in backBuffer

pSurface->UnlockRect();

p_dx_Device->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &screenSurface);

D3DXLoadSurfaceFromSurface(screenSurface, 0, &destRect, pSurface, 0, NULL, D3DX_FILTER_NONE , 0);

screenSurface->Release();

p_dx_Device->Present(NULL, NULL, NULL, NULL);


Hope this helps.



Edit: Oh yes, I almost forgot to say what's pSurface:
IDirect3DSurface9* pSurface;
p_dx_Device->CreateOffscreenPlainSurface(BUFFER_WIDTH, BUFFER_HEIGHT, D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &pSurface, NULL)

Share this post


Link to post
Share on other sites
Thanks Ais.

I did it like this and it worked when the destRect=NULL. But when I send any valid destRect, D3DXLoadSurfaceFromSurface fails. Any ideas?

HRESULT hResult;
D3DXIMAGE_INFO imageInfo;

hResult = D3DXGetImageInfoFromFile(filename, &imageInfo);
if(FAILED(hResult))
return NULL;

IDirect3DSurface9 *surface;

hResult = pd3dDevice->CreateOffscreenPlainSurface( imageInfo.Width,
imageInfo.Height,
D3DFMT_X8R8G8B8,
D3DPOOL_DEFAULT,
&surface,
NULL);

if(FAILED(hResult))
return NULL;

hResult = D3DXLoadSurfaceFromFile(surface, NULL, NULL, filename, NULL, D3DX_DEFAULT, 0, NULL);

if(FAILED(hResult))
return NULL;

IDirect3DSurface9 *pBackBuffer;

hResult = pd3dDevice->GetBackBuffer(0,0,D3DBACKBUFFER_TYPE_MONO,&pBackBuffer);

if(FAILED(hResult))
return NULL;

int width;
int x = GetSystemMetrics(SM_CXSCREEN);
int y = GetSystemMetrics(SM_CYSCREEN);

if(imageInfo.Width<GetSystemMetrics(SM_CXSCREEN))
width = imageInfo.Width;
else
width = GetSystemMetrics(SM_CXSCREEN);

int height;
if(imageInfo.Height<GetSystemMetrics(SM_CYSCREEN))
height = imageInfo.Height;
else
height = GetSystemMetrics(SM_CYSCREEN);

RECT rSourface;
rSourface.top = 0;
rSourface.left = 0;
rSourface.right = width;
rSourface.bottom = height;


pd3dDevice->Clear(0,
NULL,
D3DCLEAR_TARGET,
D3DCOLOR_XRGB(0,0,0),
0.5f,
0);

hResult = D3DXLoadSurfaceFromSurface(pBackBuffer, NULL, NULL, surface, NULL, &rSourface, D3DX_FILTER_NONE, 0xFF000000);

if(FAILED(hResult))
return NULL;

pd3dDevice->Present(NULL,NULL,NULL,NULL);


Also, is anyone shure that textures are faster that surfeces, has anyone test it?

Share this post


Link to post
Share on other sites
Quote:
Original post by ofreyre
I did it like this and it worked when the destRect=NULL. But when I send any valid destRect, D3DXLoadSurfaceFromSurface fails. Any ideas?
What error code does it return (Print it out as an 8 digit hex number if you don't know what code it is, or use DXGetErrorString())? Also, install the debug runtimes (DirectX control pannel, in the Windows control pannel in older SDKs, in the start menu DirectX SDK directory for newer SDKs), then you'll get told exactly what the error is in your debug output.

Quote:
Original post by ofreyre
Also, is anyone shure that textures are faster that surfeces, has anyone test it?
They will be, almost certainly. D3DXLoadSurfaceFromSurface() is probably extremely slow, and doing 2D work on the GPU is a really bad idea. It's much better to use textures and render quads instead, that way you also get stuff like rotation and alpha blending for free, which you don't get when using surfaces like that.

A little off-topic, but surfaces themselfs aren't slow, it's how you're using them. GetBackBuffer() stalls the GPU and then you force it to wait for the CPU to upload the data from the source surface. With textures, that can all be done async.

Share this post


Link to post
Share on other sites

This topic is 3723 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

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