1 Replies - 5995 Views - Last Post: 14 February 2012 - 11:06 PM Rate Topic: -----

#1 bear(NP)  Icon User is offline

  • D.I.C Head

Reputation: 2
  • View blog
  • Posts: 144
  • Joined: 18-February 09

DirectX9, Sprite not displaying

Posted 11 February 2012 - 08:33 PM

Hey guys- I'm just starting out in DirectX 9 (2D for now ;) ) and I can't seem to display a sprite from my source. I'm running VS2010, and I'm displaying/running without any problems. I have the .bmp in the same directory as my .sln, and it's in the "Resource Files" within my sln in VS2010

here's the source (heavily commented, but taken from shreds I could find)

If anybody knows of some good DirectX 9 2D tutorials, I would really appreciate it if they posted the links :D

Main.cpp
/* PacChief, a game that attempts to show some of Halo 3's AI Tree
 * @author ***
 * Last modified: 05 February 2012
 *
 * Notes for getting this running:
 * built using Feb 2011 build of DX9.0c, need to include lib(x86) & include directories
 */

#define DIRECTINPUT_VERSION 0x0800


//includes / namespaces
#include <Windows.h>
#include <WindowsX.h>
#include <MMSystem.h>
#include <d3d9.h>
#include <d3dx9.h>
#include <dinput.h>
#include <list>
#include "resource.h"
#include "sprite.h"
using namespace std;

//Prototypes
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
HRESULT WinInit(HINSTANCE hInst, int nCmdShow, HWND* phWnd, HACCEL* phAccel);
LRESULT CALLBACK MainWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
HRESULT GameStart(HWND hWnd);
HRESULT GameMain(HWND hWnd);
HRESULT InitDirect3D(HWND hWnd, BOOL bWindowed);
void    GameOver(void);
void    FreeDirect3D(void);
HRESULT InitDirectInput(HWND hWnd);
void    FreeDirectInput(void);
void    InitializeSprites(void);
HRESULT DisplayFrame();

//Macros
#define SAFE_DELETE(p)  { if(p) { delete (p);     (p)=NULL; } }
#define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } }
#define KEYDOWN(name,key) (name[key] & 0x80)

//Global vars
HWND                 g_hWnd       = NULL;
LPDIRECT3D9          g_pD3D       = NULL;
LPDIRECT3DDEVICE9    g_pd3dDevice = NULL;
LPDIRECTINPUT8       g_lpdi       = NULL;
LPDIRECTINPUTDEVICE8 g_pKeyboard  = NULL;

RECT g_rcWindow;

BOOL g_bWindowed = true;
BOOL g_bActive = false;

DWORD g_dwLastFireTick  = 0;

double g_dElapsedTime;
double g_dCurTime;
double g_dLastTime;
double g_dAnimationTimer = 0.0;

	//sprite linked list
typedef list<CSprite> SPRITELIST;
SPRITELIST g_SpriteList;
SPRITELIST::iterator g_sprite_i;
SPRITELIST::iterator g_sprite_j;
SPRITELIST::iterator g_sprite_k;

/*
 * WinMain(): entry point of game, inits / calls everything
 hInst: "handle to an instance", 32bit int that IDs a prgm, 
 hPrevInst: handle to a previous instance; if there's multiplce copes of the same app open, 
      this contains a handle to the last instance created
 lpCmdLine: long pntr to a string containing cmd used to run prgm, can check for special params
 nCmdShow: indicates how window should appear when created (minimized, max, normal, background, etc.)
      View possible values: Table 2.1: http://www.directxtutorial.com/Tutorial9/A-Win32/dx9A2.aspx#still
 */
int APIENTRY WinMain( HINSTANCE hInstance,
					  HINSTANCE hPrevInstance,
					  LPSTR     pCmdLine,
					  int       nCmdShow){
	//this struct holds Windows even messages
	MSG msg;
	//the handle for the window, filled by a function
	HWND hWnd;
	//Hardware acceleration; ?
	HACCEL hAccel;

	//???
	memset(&msg, 0, sizeof(msg));

	//int window
	WinInit(hInstance, nCmdShow, &hWnd, &hAccel);

	//start window
	GameStart(hWnd);

	/*
	//wait for the next message in teh queue, store the result in msg
	//can't use this because no time to wait for a new message; should just check and continue
	while(GetMessage(&msg, NULL, 0, 0)){
		//while their are messages to process (always, unless end of prgm) -> translate and dispatch them ->
		//to my WindowProc, because wc.lpfnWndProc = WindowProc
		//WindowProc listens for some messages, handles them, passes rest to defaultWindowProc()
	*/

	//enter main loop
	while(true){
		//check to see if any messages are witing in the queue
			//PeekMessage(LPMSG, HWND, UINT msgFilterMin, UINT msgFilterMax, UINT removeMsg [remove it?] )
		if( PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE) ){
            if( 0 == GetMessage(&msg, NULL, 0, 0 ) ){
                // WM_QUIT was posted, so exit
                return (int)msg.wParam;
            }

            // Translate and dispatch the message
            if( 0 == TranslateAccelerator(hWnd, hAccel, &msg) ){
                TranslateMessage(&msg); 
                DispatchMessage(&msg);
            }
        }else{
			if(g_bActive){
				//move the sprites, by blting them to the back buffer, then flip|blt to back buff to primary buff
				g_dCurTime = timeGetTime();
				g_dElapsedTime = ((g_dCurTime - g_dLastTime) * 0.001);
				g_dLastTime = g_dCurTime;

				if(FAILED(GameMain(hWnd))){
					MessageBox(hWnd, TEXT("GAMEMAIN() FAILED.")
						TEXT("The game will now exit."), TEXT("PrototypeX"),
						MB_IConerror | MB_OK);
					return FALSE;
				}
			}else{
				//go to sleep if we have nothing to do
				WaitMessage();
			}
		}
	}

	/* OLD, KEEP FOR OWN NOTES
	//create a "hello world" message box, has a return int stating what value was pressed
						  //see Table 2.4 for a full listing: http://www.directxtutorial.com/Tutorial9/A-Win32/dx9A2.aspx#still
	MessageBox(NULL, //HWND: "handle to a window", no window to launch from, so use the desktop via NULL
		       L"Hello World", //long pointer to a string: the content of the message
			   L"Just another Hello World program!", //long pointer to a string: the title of the message box
			   MB_ICONEXCLAMATION | MB_OK); //UINT: unisigned int, use with a logical or to display icons and buttons
	                                        // see table 2.2 and 2.3 for a full listing http://www.directxtutorial.com/Tutorial9/A-Win32/dx9A2.aspx#still


	//return 0 to Windows
	return 0;
	*/
}

/*
 * Init the game's window
 */
HRESULT WinInit( HINSTANCE hInst, int nCmdShow, HWND *phWnd, HACCEL *phAccel ){
	//this struct holds info for the window class
	WNDCLASSEX wc;
	HWND hWnd;
	HACCEL hAccel;

	//clear out the window class for use
	ZeroMemory(&wc, sizeof(WNDCLASSEX));

	//fill in the struct with the needed info
	wc.cbSize = sizeof(WNDCLASSEX);
	wc.lpszClassName = TEXT("SNAKE_GAME_CLASS");
	wc.style = CS_HREDRAW | CS_VREDRAW;
	wc.lpfnWndProc = MainWndProc;
	wc.hInstance = hInst;
	wc.hCursor = LoadCursor(NULL, IDC_ARROW);
	wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
	wc.cbClsExtra = 0;
	wc.cbWndExtra = 0;

	//register the window class
	if(RegisterClassEx(&wc) == 0)
		return E_FAIL;

	//load keyboard accelerators
	hAccel = LoadAccelerators(hInst, MAKEINTRESOURCE(IDR_MAIN_ACCEL)); //IDR found in resource.h

	//calc proper size for window given client ox 640x480 (given in resource.h)
	DWORD dwFrameWidth = GetSystemMetrics(SM_CXSIZEFRAME);
	DWORD dwFrameHeight = GetSystemMetrics(SM_CYSIZEFRAME);
	DWORD dwMenuHeight = GetSystemMetrics(SM_CYMENU);
	DWORD dwCaptionHeight = GetSystemMetrics(SM_CYCAPTION);
	DWORD dwWindowWidth = SCREEN_WIDTH + dwFrameWidth * 2;
	DWORD dwWindowHeight = SCREEN_HEIGHT + dwFrameHeight * 2 + 
							dwMenuHeight + dwCaptionHeight;

	//create the window and use the result as the handle
	DWORD dwStyle = WS_OVERLAPPEDWINDOW & ~WS_MAXIMIZEBOX; //???
	hWnd = CreateWindowEx(0,
						  L"SNAKE_GAME_CLASS", //name of the window class
						  L"Snake Game v1.0", //title of the window
						  dwStyle, //window style, can take out min/max buttons, etc.
						  CW_USEDEFAULT, //x-position of the window
						  CW_USEDEFAULT, //y-position of the window
						  dwWindowWidth, //width of the window
						  dwWindowHeight, //height of the window
						  NULL, //we have no parent window, so NULL
						  NULL, //we aren't using menus, so NULL
						  hInst, //application handle
						  NULL); //used with multi windows, NULL

	//if window failed to init, say so
	if(hWnd == NULL)
		return E_FAIL;

	//display the window on the screen
	ShowWindow(hWnd, nCmdShow);
	UpdateWindow(hWnd);

	//save window size&pos for switching modes
	GetWindowRect(hWnd, &g_rcWindow);

	*phWnd = hWnd;
	*phAccel = hAccel;

	return S_OK;
}

//this is the main message handler for the program
LRESULT CALLBACK MainWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){
	//sort through and find what code to run for the message given
	switch(message){
		case WM_COMMAND:
			switch(LOWORD(wParam)){
			case IDM_TOGGLEFULLSCREEN:
				//TODO
				return 0L;
			case IDM_EXIT:
				//received key/menu cmd to exit app
				PostMessage(hWnd, WM_CLOSE, 0, 0);
				return 0L;
			}
			break;
		case WM_GETMINMAXINFO:
			{
				//don't allow window resizing (fix size of window to 800x600
				MINMAXINFO* pMinMax = (MINMAXINFO*) lParam;

				DWORD dwFrameWidth = GetSystemMetrics(SM_CXSIZEFRAME);
				DWORD dwFrameHeight = GetSystemMetrics(SM_CYSIZEFRAME);
				DWORD dwMenuHeight = GetSystemMetrics(SM_CYMENU);
				DWORD dwCaptionHeight = GetSystemMetrics(SM_CYCAPTION);

				pMinMax->ptMinTrackSize.x = SCREEN_WIDTH + dwFrameWidth * 2;
				pMinMax->ptMinTrackSize.y = SCREEN_HEIGHT + dwFrameHeight *2 +
											dwMenuHeight + dwCaptionHeight;

				pMinMax->ptMaxTrackSize.x = pMinMax->ptMinTrackSize.x;
				pMinMax->ptMaxTrackSize.y = pMinMax->ptMinTrackSize.y;
			}
			return 0L;
		case WM_SIZE:
            // Check to see if we are losing our window...
            if( SIZE_MAXHIDE == wParam || SIZE_MINIMIZED == wParam )
                g_bActive = FALSE;
            else
                g_bActive = TRUE;
            break;
		case WM_SETCURSOR:
			//hide the cursor if in full screen
			if(!g_bWindowed){
				SetCursor(NULL);
				return true;
			}
			break;

		case WM_EXITMENULOOP:
			//do nothing for now
			break;

		case WM_EXITSIZEMOVE:
			//do nothing for now
			break;

		case WM_SYSCOMMAND:
			//prevent moving/sizign and power loss in full screen mode
			switch(wParam){
				case SC_MOVE:
				case SC_SIZE:
				case SC_MAXIMIZE:
				case SC_MONITORPOWER:
					if(!g_bWindowed)
						return true;
			}
			break;

		case WM_ACTIVATE:
			if(WA_INACTIVE != wParam && g_pKeyboard){
				//make sure device is acquired if gaining focus
				g_pKeyboard->Acquire();
			}
			break;

		//this message is read when the window is closed
		case WM_DESTROY:{
				//close the application entierely
				GameOver();
				PostQuitMessage(0);
				return 0L;
			} break;
	}

	//Handle any messages the switch didn't
	return DefWindowProc(hWnd, message, wParam, lParam);
}

/*
 * Init all direct 3D
 */
HRESULT InitDirect3D(HWND hWnd, BOOL bWindowed){
	g_pD3D = Direct3DCreate9(D3D_SDK_VERSION);

	D3DCAPS9 d3dCaps;
	g_pD3D->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &d3dCaps);

	D3DDISPLAYMODE d3ddm;
	g_pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm);

	D3DPRESENT_PARAMETERS d3dpp;
	ZeroMemory(&d3dpp, sizeof(d3dpp));

	if(bWindowed == true){
		d3dpp.Windowed = true;
		d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
		d3dpp.BackBufferFormat = d3ddm.Format;
	}else{
		d3dpp.Windowed = false;
		d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
		d3dpp.BackBufferWidth = SCREEN_WIDTH;
		d3dpp.BackBufferHeight = SCREEN_HEIGHT;
		d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8;
	}

	d3dpp.EnableAutoDepthStencil = true;
	d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
	d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; //don't sync to vert retrace
	d3dpp.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;

	g_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
						D3DCREATE_SOFTWARE_VERTEXPROCESSING,
						&d3dpp, &g_pd3dDevice);

	D3DXMATRIX matProj;
	D3DXMatrixPerspectiveFovLH(&matProj, D3DXToRadian(45.0f),
								SCREEN_WIDTH / SCREEN_HEIGHT, 0.1f, 100.0f);
	g_pd3dDevice->SetTransform(D3DTS_PROJECTION, &matProj);

	g_pd3dDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
	g_pd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);

	return S_OK;
}

/*
 * init the DirX input vars
 */
void FreeDirectInput(void){
	//unacquire device, incase app exited while device still acquired
	if(g_pKeyboard)
		g_pKeyboard->Unacquire();
	//release any DirIn objs
	SAFE_RELEASE(g_pKeyboard);
	SAFE_RELEASE(g_lpdi);
}

/*
 * Init directX's input
 */
HRESULT InitDirectInput(HWND hWnd){
	HRESULT hr;

	FreeDirectInput();

	//create DirIn obj
	if(FAILED(hr = DirectInput8Create(GetModuleHandle(NULL), DIRECTINPUT_VERSION,
		IID_IDirectInput8, (VOID**)&g_lpdi, NULL)))
		return hr;

	//grab interface to sys keyboard device
	if(FAILED(hr = g_lpdi->CreateDevice(GUID_SysKeyboard, &g_pKeyboard, NULL)))
		return hr;

	//set data format to a predefined "keyboard" format
	//a format specifies what to do with the controls specified
	//this tells DirIn that a 256 byte array will be passed to IDirectInputDevice::GetDeviceState
	if(FAILED(hr = g_pKeyboard->SetDataFormat(&c_dfDIKeyboard)))
		return hr;

	//set cooperative level
	hr = g_pKeyboard->SetCooperativeLevel(hWnd, DISCL_NOWINKEY | DISCL_NONEXCLUSIVE | DISCL_FOREGROUND);

	if(hr == DIERR_UNSUPPORTED){
		FreeDirectInput();
		MessageBox(hWnd, TEXT("SetCooperativeLevel() returned DIERR_UNSUPPORTED.\n")
			TEXT("FOR security reasons, background exclusive keyboard\n")
			TEXT("access is not allowed."), TEXT("PrototypeX"), MB_OK);
		return S_OK;
	}

	if(FAILED(hr))
		return hr;

	//acquire the new device
	g_pKeyboard->Acquire();

	return S_OK;
}

/*
 * create each sprite, set their properties & loads them into the linked list
 */
void InitializeSprites(void){
	CSprite sprite;
	int i = 0;

	sprite.zeroSpriteValues();
	sprite.m_nID            = 555;
	strcpy( sprite.m_chType, "player");
	strcpy( sprite.m_chSpriteTextureName, "player.bmp");
	sprite.m_nWidth         = 32;
	sprite.m_nHeight        = 32;
	sprite.m_fPosition_x    = 0;
	sprite.m_fPosition_y    = 256;
	sprite.m_bActive        = true;
	sprite.m_bSingleFrame   = true;
	sprite.m_nFrameWidth    = 32;
	sprite.m_nFrameHeight   = 32;

	g_SpriteList.push_back(sprite);
}


/*
 * GameStart(), oversees init of DX3D functions
 */
HRESULT GameStart(HWND hWnd){
	HRESULT hr;

	//init all surfaces needed
	if(FAILED(hr = InitDirect3D(hWnd, g_bWindowed)))
		return hr;
	if(FAILED(hr = InitDirectInput(hWnd)))
		return hr;

	InitializeSprites();

	g_dwLastFireTick = timeGetTime();

	return S_OK;
}

VOID GameOver(){
	//FreeDirect3D(); //DO LATER ???
    //FreeDirectInput();

    for( g_sprite_i = g_SpriteList.begin(); g_sprite_i != g_SpriteList.end(); ++g_sprite_i )
        g_sprite_i->releaseMemory();

    // Cleanup the STL generated linked list
    g_SpriteList.erase( g_SpriteList.begin(), g_SpriteList.end() );
}

/*
 * Call each function for input/collisions/score/display for the game
 */
HRESULT GameMain(HWND hWnd){
	g_dAnimationTimer += g_dElapsedTime;

	if(g_dAnimationTimer >= 0.016)
		g_dAnimationTimer = 0.0; //target of 60FPS (1/60th of a second) reached, render new frame
	else
		return S_OK; //it's too early to change, return now and render nothing

	//collect user input and move the player
	//MovePlayer();

	//move the game sprites
	//MoveSprites();

	//check for collision
	//CheckCollisions();

	//assign the score
	//ComputeScore();

	//display the sprites
	DisplayFrame();

	return S_OK;
}

/*
 * Display a single frame (the sprites)
 */
HRESULT DisplayFrame(){
	HRESULT hr;

	//clear the primary buffer
	g_pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,
							D3DCOLOR_COLORVALUE(0.0f, 0.0f, 0.0f, 1.0f), 1.0f, 0);

	g_pd3dDevice->BeginScene();

	g_pd3dDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
	g_pd3dDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);

	for(g_sprite_i = g_SpriteList.begin(); g_sprite_i != g_SpriteList.end(); ++g_sprite_i)
		g_sprite_i->drawSprite(g_pd3dDevice);

	g_pd3dDevice->EndScene();

	if(FAILED(hr = g_pd3dDevice->Present(NULL, NULL, NULL, NULL)))
		return hr;

	return S_OK;
}



Sprite.cpp
/*
 * function definitions for CSprite class
 *
 */

#include "sprite.h"

/*
 * CSprite Constructor
 */
CSprite::CSprite():
m_pSpriteTexture( NULL ),
m_pD3DXSprite( NULL ),
m_nWidth( 0 ),
m_nHeight( 0 ),
m_nID( 0 ),
m_nState( 0 ),
m_fPosition_x( 0.0f ),
m_fPosition_y( 0.0f ),
m_fVelocity_x( 0.0f ),
m_fVelocity_y( 0.0f ),
m_bVisible( true ),
m_bCollide( true ),
m_bAutoAnimate( true ),
m_bActive( true ),
m_bScripting( false ),
m_bModifyCollision( false ),
m_bSingleFrame( false ),
m_bDestroy( false ),
m_nFrameRateModifier( 0 ),
m_nFrameSkipCount( 0 ),
m_nFrameWidth( 0 ),
m_nFrameHeight( 0 ),
m_nFramesAcross( 1 ),
m_nFrameOffset_x( 0 ),
m_nFrameOffset_y( 0 ),
m_nWidthScaling( 0 ),
m_nHeightScaling( 0 ),
m_nCurrentAnimation( 0 ),
m_nCurrentFrame( 0 ),
m_nCurrentScript( 0 ),
m_nCollisionTop( 0 ),
m_nCollisionBottom( 0 ),
m_nCollisionLeft( 0 ),
m_nCollisionRight( 0 )
{
	for(int i = 0; i < MAX_ANIM_PER; i++){
		m_nAnimations[i] = NULL;
	}
	for(int i = 0; i < MAX_SIZE; i++){
		m_chType[i] = NULL;
		m_chName[i] = NULL;
		m_chSpriteTextureName[i] = NULL;
	}
}

/*
 * Destructor
 */
CSprite::~CSprite(){
	if(m_pSpriteTexture != NULL)
		m_pSpriteTexture->Release();

	if(m_pD3DXSprite != NULL)
		m_pD3DXSprite->Release();
}

/*
 * resets all member vars to ther defaults
 */
void CSprite::zeroSpriteValues(){
    m_nWidth             = 0;
    m_nHeight            = 0;
    m_nID                = 0;
    m_nState             = 0;
    m_fPosition_x        = 0;
    m_fPosition_y        = 0;
    m_fVelocity_x        = 0;
    m_fVelocity_y        = 0;
    m_bVisible           = true;
    m_bCollide           = true;
    m_bAutoAnimate       = true;
    m_bActive            = true;
    m_bScripting         = false;
    m_bModifyCollision   = false;
    m_bSingleFrame       = false;
    m_bDestroy           = false;
    m_nFrameRateModifier = 0;
    m_nFrameSkipCount    = 0;
    m_nFrameWidth        = 0;
    m_nFrameHeight       = 0;
    m_nFramesAcross      = 1;
    m_nFrameOffset_x     = 0;
    m_nFrameOffset_y     = 0;
    m_nWidthScaling      = 0;
    m_nHeightScaling     = 0;
    m_nCurrentAnimation  = 0;
    m_nCurrentFrame      = 0;
    m_nCurrentScript     = 0;
    m_nCollisionTop      = 0;
    m_nCollisionBottom   = 0;
    m_nCollisionLeft     = 0;
    m_nCollisionRight    = 0;

    for( int i = 0; i < MAX_ANIM_PER; i++ )
        m_nAnimations[i] = NULL;

    for(int i = 0; i < MAX_SIZE; i++ )
    {
        m_chType[i]   = NULL;
        m_chName[i]   = NULL;
        m_chSpriteTextureName[i] = NULL;
    }
}

/*
 * releases all memory allocated for the sprite's anim arrays
 */
void CSprite::releaseMemory(){
	for(int i = 0; i < MAX_ANIM_PER; i++){
		//dealloc mem for each anim sequence
		if(m_nAnimations[i] != NULL){
			delete [] m_nAnimations[i];
			m_nAnimations[i] = NULL;
		}
	}
}

/*
 * creates an array of frame numbers for creation of animation effects
 */
void CSprite::loadAnimation(int nAnimNumber, int nStartFrame, int nEndFrame,
							AnimEndOption nOption, int nNextAnimation){
	// This function loads the frame numbers that make up an animation 
    // sequence into an array by calculating the frame number values 
    // that exist between the nStartFrame and nEndFrame values passed in. 
    // After it determines how big the array will need to be, it then 
    // creates the array  dynamically on the heap. The pointer to the new 
    // array is then stored in the Animations[] array where it can be 
    // accessed later by specifying the proper index value. The frame 
    // numbers are then pulled from the number range between nStartFrame 
    // and nEndFrame and loaded into the new array.
	
	bool bOverFlow = false;
	int nFrameNumber = 0;
	int nTotalFrames = 0;
	int i = 0;

	if(nAnimNumber >=0 &&
		nAnimNumber < MAX_ANIM_PER &&
		m_nAnimations[nAnimNumber] == NULL){
			if(nStartFrame < nEndFrame)
				nTotalFrames = (nEndFrame - nStartFrame);
			if(nStartFrame > nEndFrame)
				nTotalFrames = (nStartFrame - nEndFrame);
			//make room for the ctrl codes to be added later
			nTotalFrames += 3;

			m_nAnimations[nAnimNumber] = new int[nTotalFrames];
			m_nFrameCount[nAnimNumber] = nTotalFrames;

			nFrameNumber = nStartFrame;

			if(nAnimNumber >= 0 && nAnimNumber < MAX_ANIM_PER){
				while(nFrameNumber != (nEndFrame +1)){
					if(i <= (nTotalFrames - 1))
						m_nAnimations[nAnimNumber][i] = nFrameNumber;
					else
						bOverFlow = true;

					if(nStartFrame < nEndFrame)
						++nFrameNumber;
					else if(nStartFrame > nEndFrame)
						--nFrameNumber;

					++i;
				}

				//add control code stored in nOptions
					//this is so the sprite object will now how to reaches
					//the last frame in the animation sequence
				if(nOption == LOOP_ANIMATION)
					m_nAnimations[nAnimNumber][i] = LOOP_ANIMATION;

				if(nOption == MAINTAIN_LAST_FRAME)
					m_nAnimations[nAnimNumber][i] = MAINTAIN_LAST_FRAME;

				if(nOption == GOTO_NEXT_ANIMATION){
					m_nAnimations[nAnimNumber][i] = GOTO_NEXT_ANIMATION;
					m_nAnimations[nAnimNumber][i+1] = nNextAnimation;
				}

				if(nOption == GO_INACTIVE)
					m_nAnimations[nAnimNumber][i] = GO_INACTIVE;
			}
	}
}

/*
 * increments the cur anim to the next frame (allows for manual animation)
 */
void CSprite::incFrame(bool bUseModifier){
	DWORD dwNextNumber;
	int nTempHolder = 0;

	if(bUseModifier == false){
		nTempHolder = m_nFrameRateModifier;
		m_nFrameRateModifier = 0;
	}

	if(m_nFrameRateModifier > 0){
		//frame rate has been speed up->skip ahead # of frames given by nFrameRateModifier
		for(int i = 0; i < m_nFrameRateModifier; ++i){
			//check if cur frame # is ctrl code
			dwNextNumber = m_nAnimations[m_nCurrentAnimation][m_nCurrentFrame + 1];

			if(dwNextNumber == LOOP_ANIMATION)
				m_nCurrentFrame = -1;
			if(dwNextNumber == GOTO_NEXT_ANIMATION)
				return;
			if(dwNextNumber == MAINTAIN_LAST_FRAME)
				return;
			if(dwNextNumber == GO_INACTIVE)
				return;

			++m_nCurrentFrame;
		}
	}else if(m_nFrameRateModifier < 0){
		//frame rate has been slowed->keep skipping until move to next frame
		--m_nFrameSkipCount;

		if(m_nFrameRateModifier == m_nFrameSkipCount){
			//check if cur frame # is ctrl code
			dwNextNumber = m_nAnimations[m_nCurrentAnimation][m_nCurrentFrame + 1];

			if(dwNextNumber == LOOP_ANIMATION)
				m_nCurrentFrame = -1;
			if(dwNextNumber == GOTO_NEXT_ANIMATION)
				return;
			if(dwNextNumber == MAINTAIN_LAST_FRAME)
				return;
			if(dwNextNumber == GO_INACTIVE)
				return;

			++m_nCurrentFrame;
			m_nFrameSkipCount = 0;
		}
	}else if(m_nFrameRateModifier == 0){
		//check if cur frame # is ctrl code
		dwNextNumber = m_nAnimations[m_nCurrentAnimation][m_nCurrentFrame + 1];

		if(dwNextNumber == LOOP_ANIMATION)
			m_nCurrentFrame = -1;
		if(dwNextNumber == GOTO_NEXT_ANIMATION)
			return;
		if(dwNextNumber == MAINTAIN_LAST_FRAME)
			return;
		if(dwNextNumber == GO_INACTIVE)
			return;
		++m_nCurrentFrame;
	}

	if(bUseModifier == false)
		m_nFrameRateModifier = nTempHolder;
}

/*
 * decrements cur animation to frame before current frame num
 */
void CSprite::decFrame(bool bUseModifier){
	DWORD dwNextNumber;
	int nTempHolder = 0;

	if(bUseModifier == false){
		nTempHolder = m_nFrameRateModifier;
		m_nFrameRateModifier = 0;
	}

	if(m_nFrameRateModifier > 0){
		//frame rate increases->skip ahead num frames given
		for( int i = 0; i < m_nFrameRateModifier; ++i ){
            if( m_nCurrentFrame <= 0 ){
                for( int i = 0; i < m_nFrameCount[m_nCurrentAnimation]; i++ ){
                    dwNextNumber = m_nAnimations[m_nCurrentAnimation][i];

                    if( dwNextNumber == LOOP_ANIMATION )
                        m_nCurrentFrame = i - 1;

                    if( dwNextNumber == GOTO_NEXT_ANIMATION )
                        return;

                    if( dwNextNumber == MAINTAIN_LAST_FRAME )
                        return;

                    if( dwNextNumber == GO_INACTIVE )
                        return;
                }
            }else{
                --m_nCurrentFrame;
            }
        }
    }else if( m_nFrameRateModifier < 0 ){
        // The frame rate for animations has been slowed!
        // Keep skipping cycles until we can move on to
        // the next frame
        --m_nFrameSkipCount;

        if( m_nFrameRateModifier == m_nFrameSkipCount ){
            if( m_nCurrentFrame <= 0 ){
                for( int i = 0; i < m_nFrameCount[m_nCurrentAnimation]; i++ ){
                    dwNextNumber = m_nAnimations[m_nCurrentAnimation][i];

                    if( dwNextNumber == LOOP_ANIMATION )
                        m_nCurrentFrame = i - 1;

                    if( dwNextNumber == GOTO_NEXT_ANIMATION )
                        return;

                    if( dwNextNumber == MAINTAIN_LAST_FRAME )
                        return;

                    if( dwNextNumber == GO_INACTIVE )
                        return;
                }
            }else{
                --m_nCurrentFrame;
            }

            m_nFrameSkipCount = 0;
        }
    }else if( m_nFrameRateModifier == 0 ){
        if( m_nCurrentFrame <= 0 ){
            for( int i = 0; i < m_nFrameCount[m_nCurrentAnimation]; i++ ){
                dwNextNumber = m_nAnimations[m_nCurrentAnimation][i];

                if( dwNextNumber == LOOP_ANIMATION )
                    m_nCurrentFrame = i - 1;

                if( dwNextNumber == GOTO_NEXT_ANIMATION )
                    return;

                if( dwNextNumber == MAINTAIN_LAST_FRAME )
                    return;

                if( dwNextNumber == GO_INACTIVE )
                    return;
            }
        }else{
            --m_nCurrentFrame;
        }
    }

    if( bUseModifier == false )
        m_nFrameRateModifier = nTempHolder;
}

/*
 * Use sprite's properties to select bitmap, then copies onto give display
 */
HRESULT CSprite::drawSprite(LPDIRECT3DDEVICE9 pDevice){
	if(m_pD3DXSprite == NULL){
		D3DXIMAGE_INFO d3dxImageInfo;

		D3DXCreateTextureFromFileEx(pDevice,
									(LPCWSTR)m_chSpriteTextureName,
									m_nWidth,
									m_nHeight,
									1,
									0,
									D3DFMT_UNKNOWN,
									D3DPOOL_MANAGED,
									D3DX_DEFAULT,
									D3DX_DEFAULT,
									D3DCOLOR_COLORVALUE(0.0f, 0.0f, 0.0f, 1.0f),
									&d3dxImageInfo,
									NULL,
									&m_pSpriteTexture);

		D3DXCreateSprite( pDevice, &m_pD3DXSprite);
	}

	HRESULT hr = 0;

	if(m_bActive == true){
		RECT rcSource;
		DWORD dwFrameNumber;
		DWORD dwNextNumber;

		if(m_bSingleFrame == false){
			dwFrameNumber = m_nAnimations[m_nCurrentAnimation][m_nCurrentFrame];
		}else{
			dwFrameNumber = 0;
			m_nFramesAcross = 1;
		}

		//create RECT that represents section of bitmap where the next frame of animation will be copied from during call to Draw()
		rcSource.top = ((dwFrameNumber / m_nFramesAcross) * m_nFrameHeight);
		rcSource.left = ((dwFrameNumber % m_nFramesAcross) * m_nFrameWidth);
		rcSource.bottom = rcSource.top + m_nFrameHeight;
		rcSource.right = rcSource.left + m_nFrameWidth;

		//apply offset, if there is one
		if(m_nFrameOffset_x != 0 || m_nFrameOffset_y != 0){
			rcSource.top += m_nFrameOffset_y;
			rcSource.left += m_nFrameOffset_x;
			rcSource.bottom += m_nFrameOffset_y;
			rcSource.right += m_nFrameOffset_x;
		}

		D3DXVECTOR3 vCenter(0.0f, 0.0f, 0.0f);
		D3DXVECTOR3 vPosition(m_fPosition_x, m_fPosition_y, 0.0f);

		m_pD3DXSprite->Begin(D3DXSPRITE_ALPHABLEND);
		{
			m_pD3DXSprite->Draw(m_pSpriteTexture,
								&rcSource,
								&vCenter,
								&vPosition,
								D3DCOLOR_COLORVALUE(1.0f, 1.0f, 1.0f, 1.0f));
		}
		m_pD3DXSprite->End();

		if(m_bAutoAnimate == true && m_bSingleFrame == false){
			//check if next frame # is ctrl code
			dwNextNumber = m_nAnimations[m_nCurrentAnimation][m_nCurrentFrame+1];

			if(dwNextNumber == LOOP_ANIMATION)
				m_nCurrentFrame = -1;

			if(dwNextNumber == GOTO_NEXT_ANIMATION){
				m_nCurrentAnimation = m_nAnimations[m_nCurrentAnimation][m_nCurrentFrame+2];
				m_nCurrentFrame = -1;
			}
			if(dwNextNumber == GO_INACTIVE){
				m_bActive = false;
				m_nCurrentFrame = -1;
			}

			if(dwNextNumber == MAINTAIN_LAST_FRAME)
				return hr;

			if(m_nFrameRateModifier == 0){
				++m_nCurrentFrame;
			}else{
				if( m_nFrameRateModifier < 0 )
                {
                    // The frame rate for animations has been slowed!
                    // Keep skipping cycles until we can move on to
                    // the next frame
                    --m_nFrameSkipCount;

                    if( m_nFrameRateModifier == m_nFrameSkipCount )
                    {
                        ++m_nCurrentFrame;
                        m_nFrameSkipCount = 0;
                    }
                }
                else
                {
                    // The frame rate for animations has been speeded up!
                    // Skip ahead the number of frames given 
                    // by nFrameRateModifier
                    for( int i = 0; i < m_nFrameRateModifier; ++i )
                    {
                        incFrame(false);
                    }
                }
			}
		}
	}

	return hr;
	
}



Sprite.h
/***
 * Sprite class declaration for gathering
 *
 */

#include <d3d9.h>
#include <d3dx9.h>

#ifndef CSPRITE_H_INCLUDED

const int MAX_ANIM_PER = 5; //max number of animation states per sprite
const int MAX_SIZE = 25;

//declare the class
class CSprite{

public:
	enum AnimEndOption{
		LOOP_ANIMATION = 200,
		GOTO_NEXT_ANIMATION,
		MAINTAIN_LAST_FRAME,
		GO_INACTIVE,
		DESTROY_SPRITE
	};

	//func defitions
	CSprite();
	~CSprite();
	void zeroSpriteValues();
	void releaseMemory();
	void incFrame(bool bUseModifier = true);
	void decFrame(bool bUseModifier = true);
	void loadAnimation(int nAnimNumber, int nStartFrame, int nEndFrame,
						AnimEndOption nOption, int nNextAnimation = NULL);
	void loadAnimationString(int nAnimNumber, char* chString,
							AnimEndOption nOption, int nNextAnimation = NULL);
	HRESULT drawSprite(LPDIRECT3DDEVICE9 pDevice);

	//global vars
	LPDIRECT3DTEXTURE9 m_pSpriteTexture;
	LPD3DXSPRITE m_pD3DXSprite;
	int m_nWidth;
	int m_nHeight;
	int m_nID;
	int m_nState;
	char m_chType[MAX_SIZE];
	char m_chName[MAX_SIZE];
	char m_chSpriteTextureName[MAX_SIZE];
	float m_fPosition_x;
	float m_fPosition_y;
	float m_fVelocity_x;
	float m_fVelocity_y;
	bool m_bVisible;
	bool m_bCollide;
	bool m_bAutoAnimate;
	bool m_bActive;
	bool m_bScripting;
	bool m_bModifyCollision;
	bool m_bSingleFrame;
	bool m_bDestroy;
	int m_nFrameRateModifier;
	int m_nFrameWidth;
	int m_nFrameHeight;
	int m_nFramesAcross;
	int m_nFrameOffset_x;
	int m_nFrameOffset_y;
	int m_nWidthScaling;
	int m_nHeightScaling;
	int m_nCurrentAnimation;
	int m_nCurrentFrame;
	int m_nCurrentScript;
	int m_nCollisionTop;
	int m_nCollisionBottom;
	int m_nCollisionLeft;
	int m_nCollisionRight;

private:
	int *m_nAnimations[MAX_ANIM_PER];
	int m_nFrameCount[MAX_ANIM_PER];
	int m_nFrameSkipCount;
};

#define CSPRITE_H_INCLUDED
#endif /* CSPRITE_H_INCLUDED */



resource.h
//#define statements, used throughout Main.cpp
#define IDI_MAIN_ICON                   101
#define IDI_MAIN                        101
#define IDR_MENU                        102
#define IDR_MAIN_ACCEL                  103
#define IDB_DIRECTX                     107
#define IDM_ABOUT                       1000
#define IDM_EXIT                        1001
#define IDM_TOGGLEFULLSCREEN            1002


//constants
const int SCREEN_WIDTH    = 800;
const int SCREEN_HEIGHT   = 600;
const int SCREEN_BPP      = 16;

const int TOTAL_STARS     = 100;
const int TOTAL_PARTICLES = 250;
const int SHIP_SPEED      = 5;




Thanks in advance :D

Is This A Good Question/Topic? 0
  • +

Replies To: DirectX9, Sprite not displaying

#2 #define  Icon User is offline

  • Duke of Err
  • member icon

Reputation: 1432
  • View blog
  • Posts: 4,968
  • Joined: 19-February 09

Re: DirectX9, Sprite not displaying

Posted 14 February 2012 - 11:06 PM

You could try simplifying such as creating and drawing a sprite in the same scope. I'm not sure about loading from file in the drawsprite function, although you can check the return code for success or error.

Computer Games Programming
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1