DX9 Surfaces

Started by
9 comments, last by Buckeye 14 years, 6 months ago
hello, im just going through a typical book excersize, nothing fancy, but i just cant get it... the error i get is: Access violation reading location 0x000000c8


#define SPRITE_WIDTH 20
#define SPRITE_HEIGHT 20
#define SCREEN_WIDTH 640
#define SCREEN_HEIGHT 480

HINSTANCE hInst;
HWND wndHandle;

LPDIRECT3D9			pD3D;
 
LPDIRECT3DDEVICE9	pd3dDevice;

IDirect3DSurface9* Surface;

struct {
	RECT srcRect;
	// Position
	int posX, posY;
} spriteStruct[9];

////////////////
// Init Sprites

Surface = getSurfaceFromBitmap("test2.bmp");

	if (Surface == NULL)
		MessageBox(wndHandle, "Surface is null.", "FAILURE", NULL);
	for(int i=0; i< 10; i++)
	{
		spriteStruct.srcRect.top = 0;
		spriteStruct.srcRect.left = i * SPRITE_WIDTH;
		spriteStruct.srcRect.right = spriteStruct.srcRect.left + SPRITE_WIDTH;
		spriteStruct.srcRect.bottom = SPRITE_HEIGHT;

		spriteStruct.posX = rand()% SCREEN_WIDTH - SPRITE_WIDTH;
		spriteStruct.posY = rand()% SCREEN_HEIGHT - SPRITE_HEIGHT;
	}

// End Sprites
//////////////

//////////////
// Render code
	pd3dDevice->GetBackBuffer( 0,
					   0,
				         D3DBACKBUFFER_TYPE_MONO,
					   &backbuffer );

	RECT destRect;
	for (int i = 0; i < 10; i++ )
	{
		
		destRect.left = spriteStruct.posX;
		destRect.top = spriteStruct.posY;
		destRect.bottom = destRect.top + SPRITE_HEIGHT;
		destRect.right = destRect.left + SPRITE_WIDTH;

		HRESULT hResult;
		hResult = pd3dDevice->StretchRect( Surface,
							 &spriteStruct.srcRect,
							 backbuffer,
							 &destRect,
							 D3DTEXF_NONE );
		if(FAILED(hResult))
		{
			
			MessageBox(wndHandle, "Failed to draw surface to backbuffer.", "FAILURE", 0);
			if( Surface == NULL)
				MessageBox(wndHandle, "Surface was NULL.", "FAILURE", 0);
		}
	}

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

// End Render Code
//////////////////

//////////////////
// getSurface From Bitmap function

IDirect3DSurface9* surface;
	HRESULT hResult;
	D3DXIMAGE_INFO imageInfo;

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

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

	if(FAILED(hResult))
	{
		MessageBox(wndHandle, "Cant create surface.", "FAILURE", NULL);
		return NULL;
	}
	
	hResult = D3DXLoadSurfaceFromFile( surface,
									   NULL,
									   NULL,
									   filename.c_str(),
									   NULL,
									   D3DX_DEFAULT,
									   0,
									   NULL );
	if( FAILED( hResult ) )
	{
		MessageBox(wndHandle, "Cant Load surface.", "FAILURE", NULL);
		return NULL;
	}

	return surface;

// end function
////////////////


Advertisement
Quote:the error i get is: Access violation reading location 0x000000c8

Which line?

If you don't know, take a look at the FAQ and forum articles for turning on debugging. It's likely you've got some uninitialized variable, probably being used as a pointer somewhere in your code.

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

i honestly have no clue right now as to where the error is, i have checked everything i could see for a NULL value... and nothing i found shows up as null... its been a few hours, i think i'll grab some visine and check on this tomorrow. if anyone wants the full code here it is:
by the way, thank you Buck for your reply.

#include "GlobalIncs.h"#define SPRITE_WIDTH 20#define SPRITE_HEIGHT 20#define SCREEN_WIDTH 640#define SCREEN_HEIGHT 480HINSTANCE hInst;HWND wndHandle;LPDIRECT3D9			pD3D; LPDIRECT3DDEVICE9	pd3dDevice;IDirect3DSurface9* Surface;bool initWindow( HINSTANCE hInstance );bool initDirect3D();IDirect3DSurface9* getSurfaceFromBitmap(string filename);bool initSprites(void);void Render();void ShutDown();LRESULT CALLBACK WndProc( HWND, UINT, WPARAM, LPARAM);struct {	RECT srcRect;	// Position	int posX, posY;} spriteStruct[9];int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,				   LPTSTR lpCmdLine, int nCmdShow ){	// Init Window	if( !initWindow( hInstance ) )	{		MessageBox(wndHandle, "Cant Create the window!", "FAILURE", NULL);		return false;	}	if( !initDirect3D( ) )	{		MessageBox(wndHandle, "Cant Start DirectX!", "FAILURE", NULL);		return false;	}	if (!initSprites() )	{		MessageBox(wndHandle, "Sprites failed to initialize!", "FAILURE", NULL);		return false;	}	MSG msg;	ZeroMemory( &msg, sizeof( msg ) );	while( msg.message!=WM_QUIT )	{		if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE) )		{			TranslateMessage( &msg );			DispatchMessage( &msg );		}		else		{			// Recieve( ); // Later network implementation			// Input( );			Render( );		}	}		ShutDown();	return (int) msg.wParam;}bool initWindow( HINSTANCE hInstance ){	WNDCLASSEX wcex;	wcex.cbClsExtra	= 0;	wcex.cbSize = sizeof(WNDCLASSEX);	wcex.cbWndExtra = 0;	wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);	wcex.hCursor = LoadCursor( NULL, IDC_ARROW );	wcex.hIcon = 0;	wcex.hIconSm= 0;	wcex.hInstance = hInstance;	wcex.lpfnWndProc = (WNDPROC)WndProc;	wcex.lpszClassName = "GameApp";	wcex.lpszMenuName = NULL;	wcex.style = CS_HREDRAW | CS_VREDRAW;	RegisterClassEx(&wcex);	wndHandle= CreateWindow(		"GameApp",		"GameApp",		WS_EX_TOPMOST | WS_POPUP | WS_VISIBLE, // one of two things for Full screen		// Replace above line with WS_OVERLAPPEDWINDOW for normal window		CW_USEDEFAULT,		CW_USEDEFAULT,		640,		480,		NULL,		NULL,		hInstance,		NULL );	if(!wndHandle)		return false;	ShowWindow(wndHandle, SW_SHOW);	UpdateWindow(wndHandle);	return true;}bool initDirect3D(void){	pD3D = NULL;	pd3dDevice = NULL;		if( NULL == ( pD3D = Direct3DCreate9( D3D_SDK_VERSION ) ) )		return false;	// Fill PresentParams Struct	D3DPRESENT_PARAMETERS d3dpp;	ZeroMemory ( &d3dpp, sizeof( d3dpp) );	d3dpp.Windowed = FALSE;	d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;	d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8;	d3dpp.BackBufferCount = 1;	d3dpp.BackBufferHeight = 480;	d3dpp.BackBufferWidth = 640;	d3dpp.hDeviceWindow = wndHandle;	if ( FAILED( pD3D->CreateDevice( D3DADAPTER_DEFAULT,		D3DDEVTYPE_REF,		wndHandle,		D3DCREATE_SOFTWARE_VERTEXPROCESSING,		&d3dpp,		&pd3dDevice ) ) )	{		return false;	}	return true;}void Render(){	IDirect3DSurface9* backbuffer = NULL;		if (Surface == NULL)		MessageBox(wndHandle, "Surface is null.", "FAILURE", NULL);	if( NULL == pd3dDevice )		return;	pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET,		D3DCOLOR_XRGB( 0, 0, 255 ), 1.0f, 0 );	pd3dDevice->GetBackBuffer( 0,							   0,							   D3DBACKBUFFER_TYPE_MONO,							   &backbuffer );		for (int i = 0; i < 10; i++ )	{		RECT destRect;		destRect.left = spriteStruct.posX;		destRect.top = spriteStruct.posY;		destRect.bottom = destRect.top + SPRITE_HEIGHT;		destRect.right = destRect.left + SPRITE_WIDTH;		if(Surface == NULL)			MessageBox(wndHandle, "surface is null.", "Failure", 0);		HRESULT hResult;		hResult = pd3dDevice->StretchRect( Surface,							 &spriteStruct.srcRect,							 backbuffer,							 &destRect,							 D3DTEXF_NONE );		if(FAILED(hResult))		{			MessageBox(wndHandle, "Failed to draw surface to backbuffer.", "FAILURE", 0);			if( Surface == NULL)				MessageBox(wndHandle, "Surface was NULL.", "FAILURE", 0);		}	}	pd3dDevice->Present( NULL, NULL, NULL, NULL);}LRESULT CALLBACK WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){	switch(message)	{	case WM_DESTROY:		PostQuitMessage(0);		break;	}	return DefWindowProc(hWnd, message, wParam, lParam);}void ShutDown(){	if ( Surface != NULL )		Surface->Release();	if ( pd3dDevice != NULL )		pd3dDevice->Release();	if( pD3D != NULL )		pD3D->Release();}IDirect3DSurface9* getSurfaceFromBitmap(string filename){	IDirect3DSurface9* surface;	HRESULT hResult;	D3DXIMAGE_INFO imageInfo;	hResult = D3DXGetImageInfoFromFile(filename.c_str(), &imageInfo);	if(FAILED(hResult))	{		MessageBox(wndHandle, "Can not obtain file info for surface bitmap.", "Failure", NULL);		return NULL;	}	hResult = pd3dDevice->CreateOffscreenPlainSurface( imageInfo.Width,										imageInfo.Height,										D3DFMT_X8R8G8B8,										D3DPOOL_DEFAULT,										&Surface,										NULL);	if(FAILED(hResult))	{		MessageBox(wndHandle, "Cant create surface.", "FAILURE", NULL);		return NULL;	}		hResult = D3DXLoadSurfaceFromFile( surface,									   NULL,									   NULL,									   filename.c_str(),									   NULL,									   D3DX_DEFAULT,									   0,									   NULL );	if( FAILED( hResult ) )	{		MessageBox(wndHandle, "Cant Load surface.", "FAILURE", NULL);		return NULL;	}	if( surface == NULL )		MessageBox(wndHandle, "surface is NOT being returned.", "Failure", NULL);	return surface;}bool initSprites(void){	for(int i=0; i< 10; i++)	{		spriteStruct.srcRect.top = 0;		spriteStruct.srcRect.left = i * SPRITE_WIDTH;		spriteStruct.srcRect.right = spriteStruct.srcRect.left + SPRITE_WIDTH;		spriteStruct.srcRect.bottom = SPRITE_HEIGHT;		spriteStruct.posX = rand()% SCREEN_WIDTH - SPRITE_WIDTH;		spriteStruct.posY = rand()% SCREEN_HEIGHT - SPRITE_HEIGHT;	}	return true;}


i dont expect anyone to read through this all.. but if you like a challenge it should keep you busy for a few minutes. im going to continue working on it and checking the forums.
Very seriously - you'll save yourself hours if you just enable Debug runtime to see where the error may be occurring.

Also, are you using some version of Visual Studio? If so, then you can easily determine the line where the error occurred by going into debugging when you get the error dialog. Then bring up the call stack window and double click on the first line in the window that's in one of your code modules. It'll open the cpp file (if it's not already open) and point to the exact line.

EDIT: a quick look at your code - you never create or load the surface, you only init the sprite structures. Your problem may be that you don't initialize Surface to NULL. In your render function, you test Surface==NULL but it may not be NULL. So, in StretchRect, you use an invalid Surface pointer. Just a guess.

EDIT2: FYI - don't know how you plan to enhance your app in the future, but, in general, you should use "while PeekMessage" rather than "if(PeekMessage)"

[Edited by - Buckeye on October 10, 2009 11:20:22 PM]

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

You have a global variable Surface, and a local variable surface, and in one call you use the local variable, with a lower case 's', when loading your surface.

Then again you don't seem to use that function anyway. I pasted your code into VC++ 2008 and it runs fine for me, only crashes on exit when you try to release Surface which doesn't exist. Make sure to set all your variables to NULL to start with, and then make sure you actually call all your init functions. There's no call to getSurfaceFromBitmap in your code for example.
i tested the pd3dDevice variable in the Render() method against a null value, and it turns out to be null... which explains why my screen doesnt draw as a blue color the way its supposed to...
First, it might be easier if you setup for a windowed application, not fullscreen. The way you've got your code written, you're going to run into trouble if the desktop doesn't match your creation parameters.

Second, initialize all your global variables to 0 or NULL.

Then, set breakpoints at the beginning of each of your initxxx functions. Step through each line and check values to see if they're correct.

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

Okay. i got the error right about here now, pd3dDevice isnt null, imageInfo is fine, surface isnt null, it gets a value of 0xcccccccc but the error shows up at the last parameter (when i click break there is an arrow pointing to NULL, specificly.
        hResult = pd3dDevice->CreateOffscreenPlainSurface(              imageInfo.Width,	     imageInfo.Height,	     D3DFMT_X8R8G8B8,             D3DPOOL_DEFAULT,	     &surface,	     NULL);	if(FAILED(hResult))	{		MessageBox(wndHandle, "Cant create surface.", "FAILURE", NULL);		return 0;	}
The arrow pointing to NULL in the function call is standard. It's pointing to the end of the line in the file where the error occurred.

Because you get a memory access error for that function call, it appears that, although the device is not null, it's invalid, iceman. If the device were valid for that call, and something were wrong with one of the parameters, you'd get an error return (bad HRESULT) rather than a memory access error.

Did you call initDirect3D() before you called getSurfaceFromBitmap()? It appears that the device hasn't been initialized.

Again, always initialize your variables to 0 or NULL to aid in debugging like so:
HINSTANCE hInst = NULL;HWND wndHandle = NULL;LPDIRECT3D9 pD3D = NULL;LPDIRECT3DDEVICE9 pd3dDevice = NULL;IDirect3DSurface9* Surface = NULL;

I know you set d3d and the device to NULL in the initDirect3D call, but, if you initialize them as suggested, it'll be easier to determine errors. For instance, if you do that, and you're stepping through your code, you'll probably see a NULL value where it shouldn't be - like in the line of code that caused your memory error! Then it would be obvious that you hadn't init'd it.

The 0xcccccccc value for surface is what happens to be in memory for the variable "surface." AGAIN (you listening?) initialize variables like this to NULL before you use them. In this case it (probably) isn't causing the problem but get into the habit.

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

okay,

surface was initialized to null, along with all other pointers.
and i know that 0xcccccccc is a value, as to why i even mentioned that, i dont know.........

now with a change to my initDirect3D() function...

bool initDirect3D(void){	if( NULL == ( pD3D = Direct3DCreate9( D3D_SDK_VERSION ) ) )		return false;	// Fill PresentParams Struct	D3DPRESENT_PARAMETERS d3dpp;	ZeroMemory ( &d3dpp, sizeof( d3dpp) );	d3dpp.Windowed = TRUE;	d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;	d3dpp.BackBufferFormat = D3DFMT_R8G8B8; // use D3DFMT_X8R8G8B8 for full screen	d3dpp.BackBufferCount = 1;	d3dpp.BackBufferHeight = SCREEN_HEIGHT;	d3dpp.BackBufferWidth = SCREEN_WIDTH;	d3dpp.hDeviceWindow = wndHandle;	if ( FAILED( pD3D->CreateDevice( D3DADAPTER_DEFAULT,		D3DDEVTYPE_HAL,		wndHandle,		D3DCREATE_HARDWARE_VERTEXPROCESSING,		&d3dpp,		&pd3dDevice ) ) )	{		return false;	}	return true;}


... it finally tells me that direct3d cant initialize when i call it in main() like so:

if( !initDirect3D( ) )	{		MessageBox(wndHandle, "Cant Start DirectX!", "FAILURE", NULL);		return false;	}

This topic is closed to new replies.

Advertisement