Sign in to follow this  
rekotc

UpdateSurface and Access Violation

Recommended Posts

hello everybody, i'm quite new to directX, i'm simply trying to load a .bmp in a surface, but it gives me back a memory access violation (Null pointer??) here is the code: const wchar_t* path = L"./mcgiver.mbmp"; D3DXIMAGE_INFO Info; D3DXGetImageInfoFromFile(path, &Info); g_pd3dDevice->CreateOffscreenPlainSurface(Info.Width, Info.Height, Info.Format, D3DPOOL_SYSTEMMEM, &Surface, NULL); D3DXLoadSurfaceFromFile(Surface, NULL, NULL, path,NULL, D3DX_FILTER_NONE, 0, NULL); if ( SUCCEEDED (g_pd3dDevice->BeginScene())) { IDirect3DSurface9 *BackBuffer = NULL; g_pd3dDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &BackBuffer); g_pd3dDevice->UpdateSurface(Surface, NULL, BackBuffer, NULL); g_pd3dDevice->EndScene(); } the error is at UpdateSurface(Surface, NULL, BackBuffer, NULL), and i'm sure it's because of the Surface object, but i cant understand why, this is the exact error: Unhandled exception at 0x743b65d0 in DX9GRAPHICS_1.exe: 0xC0000005: Access violation reading location 0x00000000. can u help me? :) thanks in advance

Share this post


Link to post
Share on other sites
You should be checking the return values for all of the functions which return any information you rely on. For example:

if(SUCCEEDED(g_pd3dDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &BackBuffer))
g_pd3dDevice->UpdateSurface(Surface, NULL, BackBuffer, NULL);


The Debug Runtimes will help you find out what's causing the error once you've diagnosed it.

Also, remember that you should be prepared for any D3D call to fail on the target platform, and should at least be able to shut down gracefully.

Share this post


Link to post
Share on other sites
ok i've found something...i think.., i added this lines ( i know maybe it's a stupid idea but i'm still learning everything)

if( D3DXGetImageInfoFromFile(path, &Info)!= D3D_OK )
{

int msgboxID = MessageBox(
NULL,
(LPCWSTR)L"something wrong here",
(LPCWSTR)L"Error",
MB_ICONWARNING
);

}

and actually the message box shows up, so at least i have a problem here, maybe something very stupid...like the path?, because i cant figure out something different, thanks again :)

Share this post


Link to post
Share on other sites
Quote:
Original post by rekotc
ok i've found something...i think.., i added this lines ( i know maybe it's a stupid idea but i'm still learning everything)

if( D3DXGetImageInfoFromFile(path, &Info)!= D3D_OK )
{

int msgboxID = MessageBox(
NULL,
(LPCWSTR)L"something wrong here",
(LPCWSTR)L"Error",
MB_ICONWARNING
);

}

and actually the message box shows up, so at least i have a problem here, maybe something very stupid...like the path?, because i cant figure out something different, thanks again :)
This:
if( D3DXGetImageInfoFromFile(path, &Info)!= D3D_OK )
Should be:
if(FAILED(D3DXGetImageInfoFromFile(path, &Info)))
Since there's 2 billion possible success codes, not just D3D_OK. For the actual problem, that function failing is usually caused by the path being invalid - again, the debug runtimes (Specifically d3dx9d.lib) will tell you exactly what the error is.

Share this post


Link to post
Share on other sites
mmm, i've chosen D3D_OK simply because i found this on the msdn website:

Return Values

If the function succeeds, the return value is D3D_OK. If the function fails, the return value can be the following: D3DERR_INVALIDCALL

anyway even with FAILED i have the same result, with the debug runtimes i get :


Direct3D9: (ERROR) :This format is not supported for offscreen plain surfaces. CreateOffscreenPlainSurface fails.
Direct3D9: (ERROR) :NULL surface interface specified. UpdateSurface fails
Direct3D9: (ERROR) :This format is not supported for offscreen plain surfaces. CreateOffscreenPlainSurface fails.
Direct3D9: (ERROR) :NULL surface interface specified. UpdateSurface fails
The program '[1636] DX9GRAPHICS_1.exe: Native' has exited with code 0 (0x0).

Share this post


Link to post
Share on other sites
also...i'm an idiot.....it couldnt find the picture because i wrote .mbmp instead of .bmp, now the message box doesnt show up, but i still get the same errors

Share this post


Link to post
Share on other sites
The path you're using is a relative path to the current directory. Just to be sure, try changing your path to a full path including the drive, directories, etc.

For instance, const wchar_t* path = L"c:/projects/myprojects/mcgiver.bmp";

Share this post


Link to post
Share on other sites
thanks for the answers, i changed it to C:/mcgiver.bmp, (after having moved the file there :P) but it doesnt work, i really cant figure out the problem..sorry i'm still a beginner

Share this post


Link to post
Share on other sites
still no solutions.....i checked the content of the Info object and it's ok, it keeps all the informations about my mcgiver.bmp, so the path is correct, but i have problems with this CreateOffscreenPlainSurface function, the object &Surface is still NULL, but everything seems ready to work!....:(

Share this post


Link to post
Share on other sites
YEAH :D.....i "solved" it....i tried with different pictures..that mcgiver.bmp is the problem...i tried with some .jpg pics and it works fine, but no one of my .bmp files can be loaded....they all give me back a

Direct3D9: (ERROR) :This format is not supported for offscreen plain surfaces. CreateOffscreenPlainSurface fails.

i cant understand why, isnt it the right way of loading bmp files?

(anyway even a 1600x1200 jpg file cant be loaded, with error
Direct3D9: (ERROR) :pRect doesn't fit inside the surface , i think it's too big no?)

thanks :)

Share this post


Link to post
Share on other sites
Quote:
Original post by Evil Steve
This:
if( D3DXGetImageInfoFromFile(path, &Info)!= D3D_OK )
Should be:
if(FAILED(D3DXGetImageInfoFromFile(path, &Info)))
Since there's 2 billion possible success codes, not just D3D_OK. For the actual problem, that function failing is usually caused by the path being invalid - again, the debug runtimes (Specifically d3dx9d.lib) will tell you exactly what the error is.


The documentation specifically says that it will return D3D_OK on success, why in the world would you consider this to be incorrect?

Share this post


Link to post
Share on other sites
Quote:
Original post by marius1930
The documentation specifically says that it will return D3D_OK on success, why in the world would you consider this to be incorrect?
Because all HRESULT values contain 2 billion possible success codes and 2 billion possible failure codes, with the top bit being set to indicate failure.
Just because the documentation says it will return D3D_OK doesn't mean that it'll always return that in future - for instance, in a future SDK version it may return S_FALSE (Which is still success, but not D3D_OK) to indicate that the image was loaded, just in a different format.

Quote:
Original post by rekotc
Direct3D9: (ERROR) :This format is not supported for offscreen plain surfaces. CreateOffscreenPlainSurface fails.

i cant understand why, isnt it the right way of loading bmp files?
BMP files are almost always 24-bit, and I bet your card doesn't support 24-bit textures (Usually only 32-bit or 16-bit are supported). The options are:
1. Save the BMP as a 32-bit BMP (Some image editing software allows this).
2. Force the format to D3DFMT_X8R8G8B8 (Assuming D3DXLoadSurfaceFromFile can convert, I'm not entirely sure on this).
Also, for reference - it's usually preferable to load the image as a texture (Using D3DXCreateTextureFromFileEx), and then render it as a textured quad (Which will also let you do alpha blending, rotation, and so on) - although one thing at a time [smile].

Quote:
Original post by marius1930
(anyway even a 1600x1200 jpg file cant be loaded, with error
Direct3D9: (ERROR) :pRect doesn't fit inside the surface , i think it's too big no?)
The documentation for UpdateSurface states: "No stretching or shrinking is allowed (the rects must be the same size)" - I assume that means you can't update a surface using source surface that is larger than the dest surface in that case.

Share this post


Link to post
Share on other sites
ok thank you very much :), just the last question, i still dont understand when you say "you can't update a surface using source surface that is larger than the dest surface in that case", i created a new Surface and i allocated enough memory for that file using the Info object to know about the image size and color depth, so i thought the Surface object was big enough for that jpg, then i simply called UpdateSurface to copy the Surface to the BackBuffer. I cant understand what is wrong (i'm simply trying to follow a book about direct3d :))

Share this post


Link to post
Share on other sites
As Evil Steve said, it appears that UpdateSurface requires that both buffer RECTs be the same size. If the backbuffer isn't exactly the same size as the loaded image, you get an error return. You're specifying NULL for the rect sizes, so it defaults to the full size of each buffer.

Try setting the RECT parameters in the buffer call.

If the source is smaller than the destination, use the size of the source buffer for both RECT parameters.

If the destination is smaller then the source, use the size of the destination buffer.

Share this post


Link to post
Share on other sites
Quote:
Original post by Buckeye
Try setting the RECT parameters in the buffer call.

mmm.....i cant understand how to do it, i understood that i have to set the size of source and destination, but i cant find out how

Share this post


Link to post
Share on other sites
I've never done it but the documentation seems clear enough. You too can try looking at the SDK docs!

HRESULT IDirect3DDevice9::UpdateSurface(
IDirect3DSurface9* pSourceSurface,
CONST RECT* pSourceRect,
IDirect3DSurface9* pDestinationSurface,
CONST POINT* pDestinationPoint
);

Instead of setting pSourceRect and pDestinationPoint to NULL (which you do), create a CONST RECT sized to be as small as or smaller than the source and destination sizes. You can get the sizes of the surfaces with

HRESULT IDirect3DSurface9::GetDesc(
D3DSURFACE_DESC * pDesc
);

The D3DSURFACE_DESC has the width and height of the surface. Use the smaller of the 2 widths and the smaller of the 2 heights. One may be from the source and one from the destination, or both width and height from just one of the two. Use those smaller values to set the RECT values.

You also need to create a CONST POINT of (0,0) for the 4th parameter.

You may see just a part of the texture filling the destination, the whole texture filling just a part of the destination, or part of the texture filling part of the destination. The entire texture will only fill the background if the texture is exactly the right size.

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