Jump to content
  • Advertisement
Sign in to follow this  
iceman90289

DX9 Surfaces

This topic is 3351 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

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
////////////////


Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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 480

HINSTANCE 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.

Share this post


Link to post
Share on other sites
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]

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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...

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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;
}

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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;
}


Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!