Skip to main content
GameDev.net gamedev.net
🔒 Locked

D3D9 Textures...

Started by stu_pidd_cow Mar 10, 2009 at 1:16 PM 2 replies 850+ views
Original Post
stu_pidd_cow
stu_pidd_cow
So I'm trying to get familiar with the basics of Direct3D 9.0c by doing simple 2D stuff, but I'm having trouble loading textures. When I run my program, it crashes and the debugger says it's on a line that (I think) is fine. Here's the source:


// ###################### HEADER ######################

struct SPRITE_INFO
{
	SPRITE_INFO();
	~SPRITE_INFO();

	short Texture;
	D3DXVECTOR3* Position;
	D3DCOLOR Color;

	void SetColor( WORD r, WORD g, WORD b );
	void SetPosition( float x, float y, float z );
};

struct TEXTURE
{
	TEXTURE( IDirect3DDevice9* Device, LPCSTR Filename, float Dim_X, float Dim_Y );
	~TEXTURE();

	IDirect3DTexture9* Texture;
	D3DXVECTOR3* Center;
};

class SPRITE
{
public:
	SPRITE();
	SPRITE( IDirect3DDevice9* Dev );
	~SPRITE();

	ID3DXSprite* Sprite;

	std::vector<TEXTURE> Texture;
	std::vector<SPRITE_INFO> SpriteInfo;
	
	
	void SetDevice( IDirect3DDevice9* Dev );
	void OnLostDevice();
	void OnResetDevice();
	void AddTexture( LPCSTR Filename, float Dim_X, float Dim_Y );
	void Draw();

private:
	IDirect3DDevice9* Device;
	bool inited : 1;
};

// ###################### SPRITE_INFO ######################

SPRITE_INFO::SPRITE_INFO()
{
	// Default color
	Position = new D3DXVECTOR3( 0.0f, 0.0f, 0.0f );
	SetColor( 255, 255, 255 );
};

SPRITE_INFO::~SPRITE_INFO()
{
	delete Position;
};

void SPRITE_INFO::SetColor( WORD r, WORD g, WORD b )
{
	Color = D3DCOLOR_XRGB( r, g, b );
};

void SPRITE_INFO::SetPosition( float x, float y, float z )
{
	*Position = D3DXVECTOR3( x, y, z );
};


// ###################### TEXTURE ######################

TEXTURE::TEXTURE( IDirect3DDevice9* Device, LPCSTR Filename, float Dim_X, float Dim_Y )
{
	Center = new D3DXVECTOR3( Dim_X, Dim_Y, 0.0f);
	HR( D3DXCreateTextureFromFile( Device, Filename, &Texture ) );
};

TEXTURE::~TEXTURE()
{
	ReleaseCOM( Texture ); // DEBUGGER SAYS THIS IS WRONG!!!!!!!!!!!!!!!
	delete Center;
};


// ###################### SPRITE ######################

SPRITE::SPRITE()
{
	inited = false;
};

SPRITE::SPRITE( IDirect3DDevice9* Dev )
{
	inited = false;
	SetDevice( Dev );
};

SPRITE::~SPRITE()
{
	ReleaseCOM( Sprite );
};

void SPRITE::SetDevice( IDirect3DDevice9* Dev )
{
	if ( !inited )
	{
		inited = true;
		Device = Dev;
		HR( D3DXCreateSprite( Device, &Sprite ) );
	}
};

void SPRITE::OnLostDevice()
{
	HR( Sprite->OnLostDevice() );
};

void SPRITE::OnResetDevice()
{
	// Call the onResetDevice of other objects.
	HR( Sprite->OnResetDevice() );

	// This code sets texture filters, which helps to smooth out distortions
	// when you scale a texture.  
	HR( Device->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR ) );
	HR( Device->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR ) );
	HR( Device->SetSamplerState( 0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR ) );
	
	// The following code specifies an alpha test and reference value.
	HR( Device->SetRenderState(D3DRS_ALPHAREF, 10 ) );
	HR( Device->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATER ) );

	// The following code is used to setup alpha blending.
	HR( Device->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE ) );
	HR( Device->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 ) );
	HR( Device->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA ) );
	HR( Device->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA ) );

	// Indicates that we are using 2D texture coordinates.
	HR( Device->SetTextureStageState( 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2 ) );
};

void SPRITE::AddTexture( LPCSTR Filename, float Dim_X, float Dim_Y )
{
	Texture.push_back( TEXTURE( Device, Filename, Dim_X, Dim_Y ) );
};

void SPRITE::Draw()
{
	// Clear the back buffer and depth buffer.
	HR( Sprite->Begin( D3DXSPRITE_OBJECTSPACE | D3DXSPRITE_DONOTMODIFY_RENDERSTATE ) );
	
	for ( unsigned short i = 0 ; i < SpriteInfo.size() ; i++ )
	{
		HR( Sprite->Draw( Texture.at( i ).Texture, NULL, Texture.at( i ).Center, SpriteInfo.at( i ).Position, SpriteInfo.at( i ).Color ) );
	}

	HR( Sprite->End() );
};

// ########################

// THIS IS HOW I US IT:
	SPRITE testsprite;
	testsprite.SetDevice( gd3dDevice );
	testsprite.AddTexture( "test.bmp", 128.0f, 128.0f );
	testsprite.SpriteInfo.push_back( SPRITE_INFO() );
	testsprite.SpriteInfo.at(1).SetPosition( 0.0f, 0.0f, 10.0f);
	testsprite.Draw();



Sorry about the length, but the whole thing could be wrong. Am I going about this the wrong way of am I missing something simple? Thanks a bunch! [Edited by - stu_pidd_cow on March 10, 2009 1:42:06 PM]
SiCrane
SiCrane
One problem is that your classes don't seem to obey the rule of three. Also, you might want to mention which line your program is crashing on.
stu_pidd_cow
stu_pidd_cow
Haha, yeah, I forgot the most important part. All fixed now.
sirob
sirob
Yeah, SiCrane was dead on here even before you added which line is failing. You're releasing textures too many times, since you don't addref in TEXTURE's copy constructor but you Release() on the destructor. std::vector is of course calling the copy constructor.

I'd recommend you use CComPtr to handle your COM objects for you. While this issue was due to an error you made, using CComPtr would have protected you from it (though not from other bugs that might arise).

Hope this helps.
Sirob Yes.» - status: Work-O-Rama.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.