Sign in to follow this  
Moe Szyslack

Problem with Method

Recommended Posts

Hi, I have written a method in my sprite class which returns me the value for the sprite interface. CSprite.h: LPD3DXSPRITE m_pD3DSprite; CSprite.cpp CSprite::CSprite() { m_pD3DSprite = NULL; } LPD3DXSPRITE CSprite::GetD3DSprite() { return m_pD3DSprite; } In my main class I initialize the sprite interface and store m_pD3DSprite for rendering sprites in my game loop. CMain.cpp: VOID CMain::Initialize() { m_sprite.Initialize(); m_pD3DSprite = m_sprite.GetD3DSprite(); } VOID CMain::Render() { m_pD3DDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB( 0, 0, 0 ), 1.0f, 0 ); m_pD3DDevice->BeginScene(); m_pD3DSprite->Begin( D3DXSPRITE_ALPHABLEND ); m_menu.Draw(); <-- This causes the error message. Without this line everything works fine. m_pD3DSprite->End(); m_pD3DDevice->EndScene(); m_pD3DDevice->Present( NULL, NULL, NULL, NULL ); } In my menu class I need the sprite interface for making draw calls. CMenu.cpp: CMenu::CMenu() { m_pD3DSprite = NULL; m_pD3DSprite = m_sprite.GetD3DSprite(); } VOID CMenu::DrawMain() { m_pD3DSprite->Draw( ... ); } But everytime I use GetD3DSprite() in my menu class I get an acess violation at position 0x00000000. So why is it that GetD3DSprite() works in my main class but not in my menu class?

Share this post


Link to post
Share on other sites
Quote:
Original post by Moe Szyslack
But everytime I use GetD3DSprite() in my menu class I get an acess violation at position 0x00000000. So why is it that GetD3DSprite() works in my main class but not in my menu class?
Have you actually initialised the sprite pointer in your menu class? It looks to me like you have two ID3DXSprite interfaces, and you only initialise one (And you should really only have one for your entire app btw).

Share this post


Link to post
Share on other sites
As far as I could tell, m_pD3DSprite initialized in the main is not accessible by your Menu class. You'd have to make m_pD3DSprite static, or pass in the pointer to your menu constructor.

Share this post


Link to post
Share on other sites
Quote:
Original post by Moe Szyslack
But everytime I use GetD3DSprite() in my menu class I get an acess violation at position 0x00000000. So why is it that GetD3DSprite() works in my main class but not in my menu class?
Sounds like m_sprite (whatever it might be) is doing something will null pointers so somewhere you're not initialising a pointer properly.

If you post the actual code I'm sure someone can track it down. [smile]

In the meantime, based on the code you did post, it 'looks' like you're doing some rather quirky things, like 'Initialize' functions that are separate from your constructors, declaring global variables with an m_ prefix and using a macro instead of the good old void type.

As a separate note, shouldn't the menu class be responsible for calling Begin( D3DXSPRITE_ALPHABLEND )?

Share this post


Link to post
Share on other sites
Actually I'm initializing the sprtie interface in my sprite class.

CSprite.h:

class CSprite
{
public:
LPD3DXSPRITE GetD3DSprite();
...

private:
LPD3DXSPRITE m_pD3DSprite;
...
};

CSprite.cpp:

VOID CSprite::Initialize( LPDIRECT3DDEVICE9 pD3DDevice )
{
if( FAILED( D3DXCreateSprite( pD3DDevice, &m_pD3DSprite ) ) )
{
MessageBox( NULL, "CSprite::Initialize: D3DXCreateSprite() fehlgeschlagen.", "Error", NULL );
}

if( m_pD3DSprite == NULL )
{
MessageBox( NULL, "CSprite::Initialize: m_pD3DSprite == NULL.", "Error", NULL );
}
}

In my main class and my menu class I include the sprite class and use GetD3DSprite() to get the sprite interface.

Share this post


Link to post
Share on other sites
Quote:
Original post by Moe Szyslack
Actually I'm initializing the sprtie interface in my sprite class.

[snip]

In my main class and my menu class I include the sprite class and use GetD3DSprite() to get the sprite interface.
I'm confused. Where is m_sprite declared? If you have a separate copy of that in CMenu and CMain, you'll need each versions Initialize() function called. If you break to the debugger when you get the access violation, what is NULL? You could try adding some logging to check where the pointers are initialized.

Share this post


Link to post
Share on other sites
Quote:
Original post by dmatter
As a separate note, shouldn't the menu class be responsible for calling Begin( D3DXSPRITE_ALPHABLEND )?


I thought it wood be faster if I call only one time per frame Begin( D3DXSPRITE_ALPHABLEND ) and not everytime I draw a sprite. But if it makes no remarkable difference in speed I will change that.

Share this post


Link to post
Share on other sites
Quote:
Original post by Evil Steve
I'm confused. Where is m_sprite declared? If you have a separate copy of that in CMenu and CMain, you'll need each versions Initialize() function called. If you break to the debugger when you get the access violation, what is NULL? You could try adding some logging to check where the pointers are initialized.


m_sprite is declared in CMain and CMenu:


CMain.h:

#include "CSprite.h"

class CMain
{
private:
CSprite m_sprite;
...
};


CMenu.h:

#include "CSprite.h"

class CMenu
{
private:
CSprite m_sprite;
...
};

So, if I understand you right I have to call m_sprite.Initialize() in CMain and in CMenu?

Share this post


Link to post
Share on other sites
Quote:
Original post by Moe Szyslack
So, if I understand you right I have to call m_sprite.Initialize() in CMain and in CMenu?
Yes. You have two separate sprites there, so you need to initialize each one.

As I said though; it'd be more performant to have a single sprite instance instead of multiple ones.

Share this post


Link to post
Share on other sites
Ah ok, that explains that behaviour. But how can I achieve to have just one sprite interface? I thought I'm doing it already with initializing the sprite interface in my sprite class and passing the variable via the GetD3DSprite() method to any other class who needs it.

Share this post


Link to post
Share on other sites
Can't really solve this with the given code, but save yourself a lot of grief and just do this:


class Sprite
{
public:
// snip (but use the constructor instead of Initialise)

LPD3DXSPRITE GetSprite(){ return m_Sprite; }
};

class Menu
{
public:
// snip

void Render(Sprite &S){ LPD3DXSPRITE Temp=S.GetSprite(); DoStuffWithIt(Temp); }
};


Or in other words, stop trying to make the sprite pointer exist everywhere and just pass the parameters you need to the functions that use them.

Even better, hide the implementation detail of D3DXSprite behind a public interface in your Sprite class and use this interface everywhere else. But pass Sprite as a parameter to Menu's render function. Menu's SetOptionText() method (random example picked from air) does not need to access rendering stuff so should not have access to the rendering stuff.

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