Jump to content

  • Log In with Google      Sign In   
  • Create Account


my program runs super slow( rendering)


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
6 replies to this topic

#1 thestien   Members   -  Reputation: 102

Like
0Likes
Like

Posted 15 March 2012 - 05:29 PM

Hi Guys,

Sorry for the title i couldnt think of any thing to explain it better than that Posted Image

i am working through a book called " the Zen of direct3d game programming" which i have recently brought but i havent got the CD. i have got to a chapter on layers i have copied the code and as far as i can see it is the same as the books.

the structure of the code is very bad and as i dont have the CD i cant compare it to see if i have done it wrong. I have worked through many bugs but now i have a working demo of layers but it runs very very slowly.

i just wondered if anyone could spot any obvious problems or point me in the right direction.

again the code is quite long and not very well structured so i do appologise for that.
Main
#define WIN32_LEAN_AND_MEAN

#include <Windows.h>
#include <stdlib.h>
#include "Engine.h"
#include <MMSystem.h>


int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR pstCmdLine, int iCmdShow)
{
	wc.cbSize = sizeof( WNDCLASSEX);
	wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
	wc.cbClsExtra = 0;
	wc.cbWndExtra = 0;
	wc.lpfnWndProc = WndProc;
	wc.hInstance = hInstance;
	wc.hbrBackground = (HBRUSH)GetStockObject( BLACK_BRUSH);
	wc.hIcon = LoadIcon( NULL, IDI_APPLICATION);
	wc.hIconSm = LoadIcon( NULL, IDI_APPLICATION);
	wc.hCursor = LoadCursor( NULL, IDC_ARROW);
	wc.lpszMenuName = NULL;
	wc.lpszClassName = strAppName;

	RegisterClassEx( &wc);

	hWnd = CreateWindowEx( NULL, strAppName, strAppName, WS_OVERLAPPED | WS_CAPTION |
		WS_SYSMENU, CW_USEDEFAULT, CW_USEDEFAULT, 640, 480, NULL, NULL, hInstance, NULL);

	g_hWndMain = hWnd;
	ShowWindow( hWnd, iCmdShow);
	UpdateWindow( hWnd);
	if(FAILED(GameInit()))
	{
			SetError( "init failed");
			GameShutdown();
			return E_FAIL;
	}

	while( TRUE)
	{
		if(PeekMessage( &msg,NULL, 0, 0, PM_REMOVE))
		{
			if(msg.message == WM_QUIT)
				break;
			TranslateMessage( &msg);
			DispatchMessage( &msg);
		}
		else
		{
			GameLoop();
		}
	}

	GameShutdown();

	return msg.wParam;
}

			 	


Engine.h
#include <Windows.h>
#include <d3d9.h>
#include <d3dx9.h>
#include <D3D9Types.h>

#pragma once
#define RENDER_GDI 2
#define RENDER_D3D 1
#define RENDER_BOTH 0

class CLayer
{
public:
	CLayer();
	~CLayer();

public:

	void SetColorKey( D3DCOLOR ColorKey);
	D3DCOLOR GetColorKey(){ return m_ColorKey;}
	void SetVelocity(int vx, int vy){ m_VelocityX = vx; m_VelocityY = vy;}
	void GetVelocity( int* pvx, int* pvy){ *pvx = m_VelocityX; *pvy = m_VelocityY;}
	void SetPosition( int x, int y){ m_x = x; m_y = y;}
	void GetPosition( int* px, int* py){*px = m_x; *py =m_y;}
	void Update();
	HRESULT Initialize( char* strPathName, BOOL vTransparent);
	HRESULT Render( LPDIRECT3DSURFACE9 pTargetSurface);
	void Shutdown();

protected:
	LPDIRECT3DSURFACE9 m_pLayerSurface;
	BOOL m_bTransparent;
	D3DCOLOR m_ColorKey;
	int m_x, m_y;
	int m_VelocityX;
	int m_VelocityY;
	int m_SurfaceWidth;
	int m_SurfaceHeight;
	enum MOVEMENT{ NONE, HORIZONTAL, VERTICAL, BOTH} m_MoveDirection;
};

class CSprite
{
public:
	CSprite();
	~CSprite();

protected:
	LPDIRECT3DSURFACE9 m_pSpriteSurface;
	LPDIRECT3DSURFACE9 m_pActiveSurface;
	BOOL m_bInitialized;
	D3DCOLOR m_ColorKey;
	int m_x, m_y;
	int m_VelocityX;
	int m_VelocityY;
	CSprite* m_pNext;

public:
	HRESULT Initialize( char* strPathName, int SpriteWidth, int SpriteHeight, int NumSprites);
	HRESULT Initialize( LPDIRECT3DSURFACE9 pSourceSurface, int SpriteWidth,
		int SpriteHeight, int NumSprites);
	void Shutdown();
	HRESULT SelectActiveSprite( int SpriteNum);
	HRESULT Render( LPDIRECT3DSURFACE9 pDestSurface);
	void SetColorKey( D3DCOLOR ColorKey);
	D3DCOLOR GetColorKey() { return m_ColorKey;}
	void SetPosition( int x, int y){ m_x = x; m_y = y;}
	void GetPosition( int* px, int* py){ *px = m_x; *py = m_y;}
	void GetBounds( RECT* pRect);
	BOOL CheckForCollisionWith( CSprite * pOtherSprite);
	void SetVelocity( int vx, int vy)
	{
		m_VelocityX;
		m_VelocityY;
	}
	void GetVelocity( int* pvx, int*pvy)
	{
		*pvx = m_VelocityX;
		*pvy = m_VelocityY;
	}
	void SetNext( CSprite* pNext){ m_pNext = pNext;}
	CSprite* GetNext(){ return m_pNext;}
	void Update();

public:
	int m_SurfaceWidth;
	int m_SurfaceHeight;
	int m_SpriteWidth;
	int m_SpriteHeight;
	int m_NumSprites;
	BOOL m_bTransparent;
	int m_State;


};

CSprite g_RingSprite;
CLayer g_Layer;
int g_AlphabetWidth =0;
int g_AlphabetHeight =0;
int g_AlphabetLetterWidth =0;
int g_AlphabetLetterHeight =0;
int g_AlphabetLettersPerRow =0;
INT64 g_FrameRate;
INT64 g_FrameCount;
HWND hWnd ;
MSG msg;
WNDCLASSEX wc;
static char strAppName[] = "Zong!! - the game of the great ones";
HDC g_phGDIBitmapDC;
HDC g_hDC = NULL;
HWND g_hWndMain ;
LPDIRECT3D9 g_pD3D = 0;
LPDIRECT3DDEVICE9 g_pDevice = 0;
int g_DeviceHeight;
int g_DeviceWidth;
D3DPRESENT_PARAMETERS g_SavedPresParams;
int g_RenderMode =0;
LPDIRECT3DSURFACE9 g_pBackSurface =0;
LPDIRECT3DSURFACE9 g_pD3DBitmapSurf =0;
HBITMAP g_hGDIBitmap =0;
HDC g_hGDIBitmapDC =0;
INT64 g_Frequency =0;
BOOL g_bAlphabetLoaded = FALSE;
LPDIRECT3DSURFACE9 g_pAlphabetSurface =0;




void PrintFrameRate( int x, int y, BOOL bTransparent, D3DCOLOR ColorKey, DWORD* pDestData, int DestPitch);
void PrintChar( int x, int y, char Character, BOOL bTransparent, D3DCOLOR ColorKey,
	DWORD* pDestData, int DestPitch);
void PrintString( int x, int y, char* String, BOOL bTransparent, D3DCOLOR ColorKey,
	DWORD* pDestData, int DestPitch);
HRESULT UnloadAlphabet();
HRESULT LoadAlphabet( char* strPathName, int LetterWidth, int LetterHeight);
void FrameCount();
float GetNumTicksPerMs();
void Pause( int Milliseconds);
HRESULT InitTiming();
HRESULT CopySurfaceToSurface( RECT* pSourceRect, LPDIRECT3DSURFACE9 pSourceSurf, POINT* pDestPoint,
	LPDIRECT3DSURFACE9 pDestSurf, BOOL bTransparent, D3DCOLOR ColorKey);
HRESULT RestoreGraphics();
HRESULT ValidateDevice();
int GameInit();
int GameLoop();
int GameShutdown();
long CALLBACK WndProc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam);
void SetError( char* string);
int InitDirect3DDevice( HWND hWndTarget, int Width, int Height, BOOL bWindowed,
							D3DFORMAT FullScreenFormat, LPDIRECT3D9 pD3D,
							LPDIRECT3DDEVICE9* ppDevice);
int Render();
HRESULT CopyDCToSurface( LPDIRECT3DSURFACE9 pDestSurf, POINT* pDestPoint,
	HDC hDCSource, HBITMAP hDibSection, RECT* pSrcRect, COLORREF ColorKey);

void DeleteD3DCompatibleDC( HDC hDC, HBITMAP hDibSection);
HDC CreateCompatibleDC( int Width, int Height, HBITMAP* phDibSection);
	
////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT ValidateDevice()
{
	HRESULT r =0;
	r = g_pDevice->TestCooperativeLevel();
	if( FAILED( r))
	{
		if( r == D3DERR_DEVICELOST)
			return E_FAIL;
		if( r == D3DERR_DEVICENOTRESET)
		{
			g_pBackSurface->Release();
			r = g_pDevice->Reset( &g_SavedPresParams);
			if( FAILED( r))
			{
				SetError( "Could not reset device");
				PostQuitMessage( E_FAIL);
				return E_FAIL;
			}

			r = g_pDevice->GetBackBuffer( 0, 0, D3DBACKBUFFER_TYPE_MONO, &g_pBackSurface);
			if( FAILED( r))
			{
				SetError( "Unable to reaquire the back buffer");
				PostQuitMessage( 0);
				return E_FAIL;
			}

			g_pDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 0.0f, 0);
			RestoreGraphics();
		}
	}
	return S_OK;
}
HRESULT RestoreGraphics()
{
	return S_OK;
}



void SetError( char* string)
{
	OutputDebugString(string);
	OutputDebugString("\n");
}

HRESULT CopyDCToSurface( LPDIRECT3DSURFACE9 pDestSurf, POINT* pDestPoint,
	HDC hDCSource, HBITMAP hDibSection, RECT* pSrcRect, COLORREF ColorKey)
{
	HRESULT r;
	RECT SourceRect;
	POINT DestPoint;
	DIBSECTION DibSection;
	D3DLOCKED_RECT LockedRect;
	GetObject( hDibSection, sizeof( DIBSECTION), &DibSection);
	int SrcTotalWidth = DibSection.dsBm.bmWidth;
	int SrcTotalHeight = DibSection.dsBm.bmHeight;

	if(!pSrcRect)
		SetRect( &SourceRect, 0, 0, SrcTotalWidth, SrcTotalHeight);

	else
		SourceRect = *(pSrcRect);

	if( !pDestPoint)
		DestPoint.x = DestPoint.y = 0;
	else
		DestPoint = *(pDestPoint);

	if( !pDestSurf)
		return E_FAIL;
	if( !hDCSource)
		return E_FAIL;

	r = pDestSurf->LockRect(&LockedRect, 0, 0);

	if( FAILED( r))
	{
		SetError( "unable to lock the surface for GDI transfer");
		return E_FAIL;
	}

	DWORD* pSrcData = (DWORD*)(DibSection.dsBm.bmBits);
	DWORD* pDestData = (DWORD*)(LockedRect.pBits);
	int Pitch32 = LockedRect.Pitch / 4;

	int SrcHeight = SourceRect.bottom - SourceRect.top;
	int SrcWidth = SourceRect.right - SourceRect.left;
	DWORD SrcOffset = SourceRect.top * SrcTotalWidth + SourceRect.left;
	DWORD DestOffset = DestPoint.y * Pitch32 + DestPoint.x;

	if( ColorKey == -1)
	{
		for( int y =0; y < SrcHeight; y++)
		{
			memcpy( (void*)&(pDestData[ DestOffset]),(void*)&(pSrcData[SrcOffset]), SrcWidth*4);
			DestOffset += Pitch32;
			SrcOffset +=SrcTotalWidth;
		}
	}
	else
	{
		for( int y =0; y< SrcHeight; y++)
		{
			for( int x =0; x< SrcWidth; x++)
			{

				if( pSrcData[ SrcOffset] != ColorKey)
					pDestData[DestOffset] = pSrcData[ SrcOffset];
				SrcOffset++;
				DestOffset++;
			}
		}
	}

	pDestSurf->UnlockRect();

	return S_OK;
}


void DeleteD3DCompatibleDC( HDC hDC, HBITMAP hDibSection)
{
	DeleteObject( hDibSection);
	DeleteDC( hDC);
}

HDC CreateD3DCompatibleDC( int Width, int Height, HBITMAP* phDibSection)
{
	HDC hDC = CreateCompatibleDC(0);
	void* pDibSection = 0;

	BITMAPINFO bi;
	ZeroMemory( &bi, sizeof( BITMAPINFO));
	bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
	bi.bmiHeader.biWidth = Width;
	bi.bmiHeader.biHeight = Height;
	bi.bmiHeader.biPlanes = 1;
	bi.bmiHeader.biBitCount = 32;
	bi.bmiHeader.biCompression = BI_RGB;

	HBITMAP hDibSection = CreateDIBSection( hDC, &bi, DIB_RGB_COLORS, &pDibSection, NULL, NULL);

	SelectObject( hDC, hDibSection);
	*phDibSection = hDibSection;

	return hDC;
}

long CALLBACK WndProc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
{
	
	switch( uMessage)
	{
	case WM_CREATE:
		{
			
			return 0;
		}
	case WM_KEYDOWN:
		{
			switch( wParam)
			{
			case VK_SPACE:
				{
					g_RenderMode++;
					if( g_RenderMode > 2)
						g_RenderMode =0;
					break;
				}

			default:
				break;
			}
		}

	
	case WM_PAINT:
			{
				ValidateRect( hWnd, NULL);

				return 0;
			}

	case WM_DESTROY:
			{
				PostQuitMessage( 0);
				return 0;
			}

	default:
			{
				return DefWindowProc( hWnd, uMessage, wParam, lParam);
			}
	}
}

int InitDirect3DDevice( HWND hWndTarget, int Width, int Height, BOOL bWindowed,
							D3DFORMAT FullScreenFormat, LPDIRECT3D9 pD3D,
							LPDIRECT3DDEVICE9* ppDevice)
{
	D3DPRESENT_PARAMETERS d3dpp;
	D3DDISPLAYMODE d3ddm;
	HRESULT r = 0;
	if( *ppDevice)
		(*ppDevice)->Release();

	ZeroMemory( &d3dpp, sizeof( D3DPRESENT_PARAMETERS));
	r = pD3D->GetAdapterDisplayMode( D3DADAPTER_DEFAULT, &d3ddm);

	if(FAILED( r))
	{
		SetError( " Could not get display adapter information" );
		return E_FAIL;
	}

	d3dpp.BackBufferWidth = Width;
	d3dpp.BackBufferHeight = Height;
	d3dpp.BackBufferFormat = bWindowed ? d3ddm.Format : FullScreenFormat;
	d3dpp.BackBufferCount = 1;
	d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;
	d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
	d3dpp.hDeviceWindow = hWndTarget;
	d3dpp.Windowed = bWindowed;
	d3dpp.EnableAutoDepthStencil = TRUE;
	d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
	d3dpp.FullScreen_RefreshRateInHz = 0;
	d3dpp.PresentationInterval = bWindowed ? 0 : D3DPRESENT_INTERVAL_IMMEDIATE;
	d3dpp.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
	r = pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWndTarget,
		D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, ppDevice);

	if( FAILED( r))
	{
		SetError( " Could not create the render device");
		return E_FAIL;
	}
	g_DeviceHeight = Height;
	g_DeviceWidth = Width;
	g_SavedPresParams = d3dpp;
	return S_OK;
}

int Render()
{
	//Pause(1000);
	
	HRESULT r = 0;
	g_pDevice->Clear( 0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_ARGB( 0, 0, 0, 0),10.f, 0);

	if(!g_pDevice)
	{
		SetError( "cannot render because there is no device");
		return E_FAIL;
	}

	

	//r = ValidateDevice();
	//if( FAILED( r));
	//{
	//	return E_FAIL;
	//}

	
	D3DLOCKED_RECT Locked;
	g_pBackSurface->LockRect(&Locked, 0,0) ;
	//g_Layer.Render(g_pBackSurface);

	PrintFrameRate( 500, 400, TRUE, D3DCOLOR_ARGB( 0, 255, 0, 255), (DWORD*)Locked.pBits, Locked.Pitch);
	g_pBackSurface->UnlockRect();
	g_Layer.Render(g_pBackSurface);

	g_pDevice->Present( NULL, NULL, NULL, NULL);
	g_Layer.Update();
	
	
	return S_OK;

}

int GameInit()
{
	
	
	HRESULT r = 0;

	g_pD3D = Direct3DCreate9( D3D_SDK_VERSION);

	if( g_pD3D == NULL)
	{
		SetError( " Could not create IDIRECT3D9 object");
		return E_FAIL;
	}

	r = InitDirect3DDevice( g_hWndMain, 640, 480, FALSE, D3DFMT_A8R8G8B8, g_pD3D, &g_pDevice);

	if( FAILED( r))
	{
		SetError( "Init of the device failed");
		return E_FAIL;
	}
	
	g_pDevice->Clear( 0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_ARGB( 0, 0, 0, 0),10.f, 0);

	r = g_pDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &g_pBackSurface);

	if( FAILED( r))
	{
			SetError( "Couldnt get backbuffer");
			return E_FAIL;
	}

	LoadAlphabet( "alpha1632.bmp", 16, 32);
	g_Layer.Initialize( "layer.bmp", TRUE);
	g_Layer.SetVelocity(20,20);
	g_Layer.Update();
	srand( GetTickCount());
	InitTiming();
	return S_OK;
}


int GameLoop()
{
	
	FrameCount();
	Render();
	g_Layer.Update();
	if(GetAsyncKeyState(VK_ESCAPE))
	{
		PostQuitMessage(0);
		return S_OK;
	}
}
int GameShutdown()
	{
		UnloadAlphabet();
		
		if( g_pBackSurface)
			g_pBackSurface->Release();
		if( g_pD3DBitmapSurf)
			g_pD3DBitmapSurf->Release();
		if( g_pDevice)
			g_pDevice->Release();
		if( g_pD3D)
			g_pD3D->Release();
		return S_OK;
	}

HRESULT CopySurfaceToSurface( RECT* pSourceRect, LPDIRECT3DSURFACE9 pSourceSurf, POINT* pDestPoint,
	LPDIRECT3DSURFACE9 pDestSurf, BOOL bTransparent, D3DCOLOR ColorKey)
{
	HRESULT r =0;
	D3DLOCKED_RECT LockedSource;
	D3DLOCKED_RECT LockedDest;

	if( !pSourceSurf)
		return E_FAIL;

	if( !pDestSurf)
		return E_FAIL;
	RECT SourceRect;
	POINT DestPoint;

	D3DSURFACE_DESC d3dsdSource;
	pSourceSurf->GetDesc( &d3dsdSource);
	
	D3DSURFACE_DESC d3dsdDest;
	pDestSurf->GetDesc( &d3dsdDest);

	if( pSourceRect)
		SourceRect = *pSourceRect;

	else

		SetRect( &SourceRect, 0, 0, d3dsdSource.Width, d3dsdSource.Height);
	if( pDestPoint)
		DestPoint = *pDestPoint;

	else
	{
		DestPoint.x = DestPoint.y = 0;
	}

	r = pSourceSurf->LockRect( &LockedSource, 0, D3DLOCK_READONLY);
	if( FAILED( r))
		return E_FAIL;

	r = pDestSurf->LockRect( &LockedDest, 0, 0);
	if( FAILED( r))
	{
		pSourceSurf->UnlockRect();
		return E_FAIL;
	}

	LockedSource.Pitch /= 4;
	LockedDest.Pitch /= 4;

	DWORD* pSourceData = (DWORD*) LockedSource.pBits;
	DWORD* pDestData = (DWORD*) LockedDest.pBits;

	int SourceOffset = SourceRect.top * LockedSource.Pitch + SourceRect.left;
	int DestOffset = DestPoint.y * LockedDest.Pitch + DestPoint.x;

	for( int y = 0; y < SourceRect.bottom; y++)
	{
		for( int x = 0; x < SourceRect.right; x++)
		{
			if( bTransparent)
			{
				if( pSourceData[ SourceOffset] != ColorKey)
				{
					pDestData[DestOffset] = pSourceData[SourceOffset];
				}
			}
			else
			{
				pDestData[DestOffset] = pSourceData[SourceOffset];
			}

			DestOffset++;
			SourceOffset++;
		}
		SourceOffset += LockedSource.Pitch - SourceRect.right;
		DestOffset += LockedDest.Pitch - SourceRect.right;
	}
	pSourceSurf->UnlockRect();
	pDestSurf->UnlockRect();

	return S_OK;
}

HRESULT InitTiming()
{
	QueryPerformanceFrequency( (LARGE_INTEGER*)&g_Frequency);

	if( g_Frequency == 0)
	{
		SetError( "The system does not support high resolution timing");
		return E_FAIL;
	}
	return S_OK;
}

void Pause( int Milliseconds)
{
	INT64 SecondsDelay = (INT64)Milliseconds * 1000;

	INT64 StartTime;
	INT64 CurrentTime;

	QueryPerformanceCounter( (LARGE_INTEGER*)&StartTime);

	while( TRUE)
	{
		QueryPerformanceCounter( (LARGE_INTEGER*)&CurrentTime);
		
		if( (CurrentTime - StartTime) > (INT64)SecondsDelay)
			break;
	}
}

float GetNumTicksPerMs()
{
	return( (float)g_Frequency / 1000.0f);
}

void FrameCount()
{
	INT64 NewCount =0;
	static INT64 LastCount =0;
	INT64 Difference =0;

	QueryPerformanceCounter( (LARGE_INTEGER*)&NewCount);

	if( NewCount == 0)
	{
		SetError( " the system does not support high res timing");
	}

	g_FrameCount++;

	Difference = NewCount - LastCount;

	if( Difference >= g_Frequency)
	{
		g_FrameRate = g_FrameCount;
		g_FrameCount =0;
		LastCount = NewCount;
	}
}




CSprite::CSprite()
{
	m_SurfaceWidth = 0;
	m_SurfaceHeight = 0;
	m_SpriteWidth = 0;
	m_SpriteHeight = 0;
	m_NumSprites = 0;
	m_bTransparent = TRUE;
	m_State = 0;


	m_pSpriteSurface = 0;
	m_pActiveSurface = 0;
	m_bInitialized = FALSE;
	m_ColorKey = D3DCOLOR_ARGB( 0, 255, 0, 255);
	m_x = 0;
	m_y = 0;
	m_VelocityX = 0;
	m_VelocityY = 0;
	m_pNext = 0;
}

HRESULT CSprite::Initialize( char* strPathName, int SpriteWidth,
	int SpriteHeight, int NumSprites)
{
	if( m_pSpriteSurface)
	{
		m_pSpriteSurface->Release();
		m_pSpriteSurface = 0;
	}

	if( m_pActiveSurface)
	{
		m_pActiveSurface->Release();
		m_pActiveSurface = 0;
	}

	HRESULT r = 0;
	NumSprites--;


	D3DXIMAGE_INFO SrcInfo;
	D3DXGetImageInfoFromFile( strPathName, &SrcInfo);
	g_pDevice->CreateOffscreenPlainSurface( SrcInfo.Width, SrcInfo.Height, D3DFMT_A8R8G8B8,
		D3DPOOL_DEFAULT ,&m_pSpriteSurface, NULL);



	r = D3DXLoadSurfaceFromFile( m_pSpriteSurface, NULL, NULL, strPathName, NULL,
		D3DX_FILTER_NONE, 0, NULL);
	if(FAILED( r))
	{
		return E_FAIL;
	}
	m_SpriteWidth = SpriteWidth;
	m_SpriteHeight = SpriteHeight;
	m_NumSprites = NumSprites;

	D3DSURFACE_DESC d3dsd;
	m_pSpriteSurface->GetDesc( &d3dsd);
	m_SurfaceWidth = d3dsd.Width;
	m_SurfaceHeight = d3dsd.Height;

	r = g_pDevice->CreateOffscreenPlainSurface( m_SpriteWidth, m_SpriteHeight, D3DFMT_A8R8G8B8,
		D3DPOOL_DEFAULT, &m_pActiveSurface, 0);
	if( FAILED( r))
	{
		Shutdown();
		return E_FAIL;
	}
	RECT SpriteRect = { 0, 0, SpriteWidth, SpriteHeight};
	RECT SpritePoint = { 0, 0, SpriteWidth, SpriteHeight};
	g_pDevice->StretchRect( m_pSpriteSurface, &SpriteRect, m_pActiveSurface, &SpritePoint, D3DTEXF_NONE);
	m_bInitialized = TRUE;

	return S_OK;
}

HRESULT CSprite::Initialize( LPDIRECT3DSURFACE9 pSourceSurface, int SpriteWidth,
	int SpriteHeight, int NumSprites)
{
	if( m_pSpriteSurface)
	{
		m_pSpriteSurface->Release();
		m_pSpriteSurface = 0;
	}

	if( m_pActiveSurface)
	{
		m_pActiveSurface->Release();
		m_pActiveSurface = 0;
	}

	HRESULT r = 0;
	NumSprites--;

	if( !pSourceSurface)
	{
		SetError( " Invalid Source surface");
		return E_FAIL;
	}

	m_pSpriteSurface = pSourceSurface;
	pSourceSurface->AddRef();
	m_SpriteWidth = SpriteWidth;
	m_SpriteHeight = SpriteHeight;
	m_NumSprites = NumSprites;

	D3DSURFACE_DESC d3dsd;
	m_pSpriteSurface->GetDesc( &d3dsd);
	m_SurfaceWidth = d3dsd.Width;
	m_SurfaceHeight = d3dsd.Height;

	r = g_pDevice->CreateOffscreenPlainSurface( m_SpriteWidth, m_SpriteHeight, D3DFMT_A8R8G8B8,
		D3DPOOL_DEFAULT, &m_pSpriteSurface, 0);
	if( FAILED( r))
	{
		Shutdown();
		return E_FAIL;
	}
	RECT SpriteRect = { 0, 0, SpriteWidth, SpriteHeight};
	RECT SpritePoint = { 0, 0, 0, 0};
	g_pDevice->StretchRect( m_pSpriteSurface, &SpriteRect, m_pActiveSurface, &SpritePoint, D3DTEXF_NONE);
	m_bInitialized = TRUE;

	return S_OK;
}

void CSprite::Shutdown()
{
	if( m_pSpriteSurface)
	{
		m_pSpriteSurface->Release();
		m_pSpriteSurface = 0;
	}
	if( m_pActiveSurface)
	{
		m_pActiveSurface->Release();
		m_pActiveSurface = 0;
	}

	m_SpriteWidth = 0;
	m_SpriteHeight = 0;
	m_NumSprites = 0;
	m_pSpriteSurface = 0;
	m_SurfaceWidth = 0;
	m_SurfaceHeight = 0;
	m_bInitialized = FALSE;
}

HRESULT CSprite::Render( LPDIRECT3DSURFACE9 pDestSurface)
{
	if( !pDestSurface)
		return E_FAIL;

	HRESULT r = 0;

	RECT SourceRect = { 0, 0, m_SpriteWidth, m_SpriteHeight};
	RECT DestRect = { m_x, m_y, 0, 0};
	POINT DestPoint = { m_x, m_y};

	if( m_bTransparent)
		r = CopySurfaceToSurface( &SourceRect, m_pActiveSurface, &DestPoint,
		pDestSurface, TRUE, m_ColorKey);
	else
		r = g_pDevice->StretchRect( m_pSpriteSurface, &SourceRect, m_pActiveSurface,
		&DestRect, D3DTEXF_NONE);
	return r;
}

void CSprite::GetBounds( RECT* pRect)
{
	SetRect( pRect, m_x, m_y, m_SpriteWidth + m_x, m_SpriteHeight + m_y);
	return;
}


HRESULT CSprite::SelectActiveSprite( int SpriteNum)
{
	HRESULT r = 0;

	div_t Result;

	int OffsetX = 0;
	int OffsetY = 0;
	int SpritesPerRow = m_SurfaceWidth / m_SpriteWidth;
	if( SpriteNum > m_NumSprites)
		return E_FAIL;
	Result = div( SpriteNum, SpritesPerRow);
	OffsetX = Result.rem * m_SpriteWidth;
	OffsetY = Result.quot * m_SpriteHeight;

	if( OffsetX > m_SurfaceWidth)
		return E_FAIL;
	if( OffsetY > m_SurfaceHeight)
		return E_FAIL;
	RECT SpriteRect = { OffsetX, OffsetY, OffsetX + m_SpriteWidth, OffsetY + m_SpriteHeight};
	RECT DestPoint = { 0, 0, 128, 128};

	g_pDevice->StretchRect( m_pSpriteSurface, &SpriteRect, m_pActiveSurface, &DestPoint, D3DTEXF_NONE);

	return S_OK;
}
void CSprite::Update()
{
	m_x += m_VelocityX;
	m_y += m_VelocityY;
}

BOOL CSprite::CheckForCollisionWith( CSprite * pOtherSprite)
{
	if( !pOtherSprite)
		return 0;
	RECT ThisRect, OtherRect, TempRect;
	GetBounds( &ThisRect);
	pOtherSprite->GetBounds( &OtherRect);

	if( IntersectRect( &TempRect, &ThisRect, &OtherRect))
		return TRUE;
	else
		return FALSE;
}



HRESULT LoadAlphabet( char* strPathName, int LetterWidth, int LetterHeight)
{
	if( !strPathName)
		return E_FAIL;
	if( !LetterWidth || !LetterHeight)
		return E_FAIL;

	HRESULT r =0;
///////////////////////////////////////////////////////////////////////
	r = g_pDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &g_pBackSurface);

	if( FAILED( r))
	{
			SetError( "Couldnt get backbuffer");
			return E_FAIL;
	}

	r = g_pDevice->CreateOffscreenPlainSurface( 160, 320, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT ,&g_pAlphabetSurface, 0);
	if( FAILED( r))
	{
			SetError( "Couldnt get anything!!!AlphaBet");
			return E_FAIL;
	}
	
	r = D3DXLoadSurfaceFromFile( g_pAlphabetSurface, NULL, NULL, strPathName, NULL,
		D3DX_FILTER_NONE, 0, NULL);

	if( FAILED( r))
	{
			SetError( "Couldnt get anything!!!backbuffer");
			return E_FAIL;
	}

	//r = LoadBitmapToSurface( strPathName, &g_pAlphabetSurface, g_pDevice);
///////////////////////////////////////////////////////////////////////
	if( FAILED( r))
	{
		SetError( "unable to load alphabet bitmap");
		return E_FAIL;
	}

	D3DSURFACE_DESC d3dsd;
	g_pAlphabetSurface->GetDesc( &d3dsd);
	g_AlphabetWidth = d3dsd.Width;
	g_AlphabetHeight = d3dsd.Height;
	g_AlphabetLetterWidth = LetterWidth;
	g_AlphabetLetterHeight = LetterHeight;

	g_AlphabetLettersPerRow = g_AlphabetWidth / g_AlphabetLetterWidth;

	g_bAlphabetLoaded = TRUE;

	return S_OK;
}

HRESULT UnloadAlphabet()
{
	if( g_pAlphabetSurface->Release())
	{
		g_pAlphabetSurface =0;
		g_bAlphabetLoaded = FALSE;
	}
	return S_OK;
}

void PrintChar( int x, int y, char Character, BOOL bTransparent, D3DCOLOR ColorKey,
	DWORD* pDestData, int DestPitch)
{
	HRESULT r =0;
	div_t Result;
	int OffsetX = 0, OffsetY = 0;

	POINT LetterDestPoint = { 0, 0};
	RECT LetterRect = { 0, 0, 0, 0};

	if( !g_bAlphabetLoaded)
		return;
	Character -=32;
	Result = div( Character, g_AlphabetLettersPerRow);
	OffsetX = Result.rem * g_AlphabetLetterWidth;
	OffsetY = Result.quot * g_AlphabetLetterHeight;
	SetRect( &LetterRect, OffsetX, OffsetY, OffsetX + g_AlphabetLetterWidth,
		OffsetY + g_AlphabetLetterHeight);
	LetterDestPoint.x = x;
	LetterDestPoint.y = y;

	D3DLOCKED_RECT LockedAlphabet;

	r = g_pAlphabetSurface->LockRect( &LockedAlphabet, 0, D3DLOCK_READONLY);
	if( FAILED( r))
	{
		SetError( "couldnt lock alphabet surface for printchar()");
		return;
	}

	DWORD* pAlphaData = (DWORD*)LockedAlphabet.pBits;
	LockedAlphabet.Pitch /= 4;
	DestPitch /= 4;

	int AlphaOffset = OffsetY * LockedAlphabet.Pitch + OffsetX;
	int DestOffset = y * DestPitch +x;

	for( int cy = 0; cy < g_AlphabetLetterWidth; cy++)
	{
		for( int cx =0; cx < g_AlphabetLetterWidth; cx++)
		{		
			if( bTransparent)
			{
				if( pAlphaData[AlphaOffset] !=ColorKey)
				{
					pDestData[DestOffset] = pAlphaData[AlphaOffset];
				}
			}
			else
			{
				pDestData[DestOffset] = pAlphaData[AlphaOffset];
			}
			AlphaOffset++;
			DestOffset++;
		}

	DestOffset += DestPitch - g_AlphabetLetterWidth;
	AlphaOffset += LockedAlphabet.Pitch - g_AlphabetLetterWidth;
	}
		g_pAlphabetSurface->UnlockRect();	

}



void PrintString( int x, int y, char* String, BOOL bTransparent, D3DCOLOR ColorKey,
	DWORD* pDestData, int DestPitch)
{
	for( UINT i = 0; i < strlen( String); i++)
	{
		PrintChar( x + (g_AlphabetLetterWidth * i), y, String[i],
			bTransparent, ColorKey, pDestData, DestPitch);
	}
}

void PrintFrameRate( int x, int y, BOOL bTransparent, D3DCOLOR ColorKey, DWORD* pDestData, int DestPitch)
{
	char String[4];
	ZeroMemory( &String, sizeof( String));
	itoa( g_FrameRate, String, 10);
	PrintString( x, y, String, bTransparent, ColorKey, pDestData, DestPitch);
}
CSprite::~CSprite()
{
}
CLayer::CLayer()
{
	m_pLayerSurface = 0;
	m_bTransparent = TRUE;
	m_ColorKey = D3DCOLOR_ARGB( 0, 255, 0, 255);
	m_x = m_y = 0;
	m_VelocityX = 0;
	m_VelocityY = 0;
	m_SurfaceWidth = 0;
	m_SurfaceHeight = 0;
	m_MoveDirection = NONE;
}

CLayer::~CLayer()
{
	if( m_pLayerSurface)
	{
			m_pLayerSurface->Release();
			m_pLayerSurface = 0;
	}


}

HRESULT CLayer::Initialize( char* strPathName, BOOL bTransparent)
{
	if( m_pLayerSurface)
	{
		m_pLayerSurface->Release();
		m_pLayerSurface = 0;
	}

	HRESULT r = 0;

	r = g_pDevice->CreateOffscreenPlainSurface( 640, 480, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT ,&m_pLayerSurface, 0);
	if( FAILED( r))
	{
			SetError( "Couldnt get anything!!!Layer");
			return E_FAIL;
	}
	
	r = D3DXLoadSurfaceFromFile( m_pLayerSurface, NULL, NULL, strPathName, NULL,
		D3DX_FILTER_NONE, 0, NULL);

	if( FAILED( r))
	{
			SetError( "Couldnt get anything!!!LoadLayer");
			return E_FAIL;
	}

	m_bTransparent = bTransparent;
	D3DSURFACE_DESC d3dsd;
	m_pLayerSurface->GetDesc( &d3dsd);
	m_SurfaceWidth = d3dsd.Width;
	m_SurfaceHeight = d3dsd.Height;
	return S_OK;
}
HRESULT CLayer::Render( LPDIRECT3DSURFACE9 pTargetSurface)
{
	HRESULT r = 0;
	if( !pTargetSurface)
		return E_FAIL;
	D3DSURFACE_DESC d3dsd;
	pTargetSurface->GetDesc( &d3dsd);
	int OffsetX = m_x;
	int OffsetY = m_y;

	if( OffsetX < 0)
	{
		OffsetX = d3dsd.Width + m_x;
	}
	if( OffsetY < 0)
	{
		OffsetY = m_SurfaceHeight + OffsetY;
	}

	switch( m_MoveDirection)
	{
	case NONE:
		{
			r = CopySurfaceToSurface( 0, m_pLayerSurface, 0, pTargetSurface,
				m_bTransparent, m_ColorKey);
			if( FAILED( r))
			{
				SetError("stopppppp failing NOT MOVING");
			}
			return S_OK;
			
		}break;

	case HORIZONTAL:
		{
			RECT RectL, RectR;
			POINT DestPointR = { OffsetX, OffsetY};
			POINT DestPointL = { 0, OffsetY};
			SetRect( &RectR, 0, 0, m_SurfaceWidth - OffsetX, m_SurfaceHeight);
			SetRect( &RectL, m_SurfaceWidth - OffsetX, 0, OffsetX, m_SurfaceHeight);

			r = CopySurfaceToSurface( &RectR, m_pLayerSurface, &DestPointR, pTargetSurface,
				m_bTransparent, m_ColorKey);
			if( FAILED( r))
			{
				SetError("stopppppp failing rect L");
				return E_FAIL;
			}
			r = CopySurfaceToSurface( &RectL, m_pLayerSurface, &DestPointL, pTargetSurface,
				m_bTransparent, m_ColorKey);
			if( FAILED( r))
			{
				SetError("stopppppp failing rect R");
				return E_FAIL;
			}
			
			
		}break;

	case VERTICAL:
		{
			RECT RectT, RectB;
			POINT DestPointT = { OffsetX, 0};
			POINT DestPointB = { OffsetX, OffsetY};
			SetRect( &RectT, 0, m_SurfaceHeight - OffsetY, m_SurfaceWidth, OffsetY );
			SetRect( &RectB, 0, 0, m_SurfaceWidth, m_SurfaceHeight - OffsetY);

			r = CopySurfaceToSurface( &RectT, m_pLayerSurface, &DestPointT, pTargetSurface,
				m_bTransparent, m_ColorKey);
			if( FAILED( r))
			{
				SetError("stopppppp failing rect T");
				return E_FAIL;
			}
			r = CopySurfaceToSurface( &RectB, m_pLayerSurface, &DestPointB, pTargetSurface,
				m_bTransparent, m_ColorKey);
			if( FAILED( r))
			{
				SetError("stopppppp failing rect B");
				return E_FAIL;
			}
	
		}break;

	case BOTH:
		{
			RECT Rect0, Rect1, Rect2, Rect3;

			POINT DestPoint0 = {OffsetX, OffsetY},
				DestPoint1 = { OffsetX, 0},
				DestPoint2 = { 0, OffsetY},
				DestPoint3 = { 0, 0};
			SetRect( &Rect0, 0, 0, m_SurfaceWidth - OffsetX, m_SurfaceHeight - OffsetY);
			SetRect( &Rect1, 0, m_SurfaceHeight - OffsetY, m_SurfaceWidth - OffsetX, OffsetY);
			SetRect( &Rect2, m_SurfaceWidth - OffsetX, 0, OffsetX, m_SurfaceHeight - OffsetY);
			SetRect( &Rect3, m_SurfaceWidth - OffsetX, m_SurfaceHeight - OffsetY, OffsetX, OffsetY);

			r = CopySurfaceToSurface( &Rect0, m_pLayerSurface, &DestPoint0, pTargetSurface,
				m_bTransparent, m_ColorKey);
			if( FAILED( r))
			{
				SetError("stopppppp failing rect0");
				return E_FAIL;
			}
			r = CopySurfaceToSurface( &Rect1, m_pLayerSurface, &DestPoint1, pTargetSurface,
				m_bTransparent, m_ColorKey);
			if( FAILED( r))
			{
				SetError("stopppppp failing rect1");
				return E_FAIL;
			}
			r = CopySurfaceToSurface( &Rect2, m_pLayerSurface, &DestPoint2, pTargetSurface,
				m_bTransparent, m_ColorKey);
			if( FAILED( r))
			{
				SetError("stopppppp failing rect2");
				return E_FAIL;
			}
			r = CopySurfaceToSurface( &Rect3, m_pLayerSurface, &DestPoint3, pTargetSurface,
				m_bTransparent, m_ColorKey);
			if( FAILED( r))
			{
				SetError("stopppppp failing rect3");
				return E_FAIL;
			}
			
			
		}break;
	}
	return S_OK;
}

void CLayer::Update()
{
	if( m_VelocityX != 0 && m_VelocityY == 0)
		m_MoveDirection = HORIZONTAL;

	else if( m_VelocityY != 0 && m_VelocityX == 0)
		m_MoveDirection = VERTICAL;

	else if( m_VelocityX != 0 && m_VelocityY != 0)
		m_MoveDirection = BOTH;

	else if( m_VelocityX == 0 && m_VelocityY == 0)
		{
			m_MoveDirection = NONE;
			return;
	}

	m_x += m_VelocityX;
	m_y += m_VelocityY;

	if( m_x >= g_DeviceWidth)
		m_x = m_x - g_DeviceWidth;

	if( m_x <= -g_DeviceWidth)
		m_x = m_x + g_DeviceWidth;

	if( m_y >= g_DeviceHeight)
		m_y = m_y - g_DeviceHeight;

	if( m_y <= -g_DeviceHeight)
		m_y = m_y + g_DeviceHeight;
}



i have tried to figure this out and i think it may be because i have tried to change the code from dx8 to dx9 but i cant find the problem, any help is appreciate :) thanks in advance

Sponsor:

#2 thestien   Members   -  Reputation: 102

Like
0Likes
Like

Posted 16 March 2012 - 02:37 AM

Maybe i should explain the problem a little better.

I create a surface and load a bitmap onto it then i copy this to the backbuffer and render it to the screen. i am loading 1 640*480 bitmap so i cant see why it goes so slow well upto 4 parts of the same Bitmap at the most. i am getting about 4 frames a second in windowed or fullscreen. i had another example i made using most of the code but it used the CSprite stuff instead of the CLayer stuff and that ran at a decent sort of speed.

so if you can see any problems in the CLayer code please let me know :) thanks again

#3 Rld_   Members   -  Reputation: 1384

Like
0Likes
Like

Posted 16 March 2012 - 05:18 AM

I don't have a lot of knowledge about DirectX, but some common thing you can look into:

Make sure you are not calling methods in your render/update loop that only needs to be called once to work.

Sorry I can't be of more use, but it's a start :)

#4 NightCreature83   Crossbones+   -  Reputation: 2758

Like
0Likes
Like

Posted 16 March 2012 - 06:19 AM

Maybe i should explain the problem a little better.

I create a surface and load a bitmap onto it then i copy this to the backbuffer and render it to the screen. i am loading 1 640*480 bitmap so i cant see why it goes so slow well upto 4 parts of the same Bitmap at the most. i am getting about 4 frames a second in windowed or fullscreen. i had another example i made using most of the code but it used the CSprite stuff instead of the CLayer stuff and that ran at a decent sort of speed.

so if you can see any problems in the CLayer code please let me know Posted Image thanks again

It's not the loading of the bitmap that is slow it is the copy back from VRAm that is slow, the GPU has to flush it's command buffer before each copy can be done. Generally speaking you need to avoid copying texture from the GPU back to system Ram. CSprite is faster because at most it only does one copy each frame your layer is doing 2-4 copies, if you know you need to update two areas in the texture just lock the whole thing and then update both areas before unlocking the surface, this means only one copy. LockRect is the function that causes the copy from GPU to CPU memory btw.

If you can get away with rendering a quad with a texture to a render target it will be alot faster.If you can get away with rendering a quad with a texture to a render target it will be alot faster. Also split that header up into smaller files or post only the relevant pieces of code please.
Worked on titles: CMR:DiRT2, DiRT 3, DiRT: Showdown, GRID 2, Mad Max

#5 thestien   Members   -  Reputation: 102

Like
0Likes
Like

Posted 16 March 2012 - 08:25 AM

Thanks for the replies guys. first let me apologise for the code it is very nasty :( i will try to seperate the code better for the next time i run into trouble :)

you make perfect sense i didnt know that locking the surface is such a big overhead the code seems to be locking the surface many times per loop. wish i had the source code to this book so i could be sure that the book version runs just as slowly lol

im going to try and fix the CLayer stuff and ill let you know how i get on :)
if i lock a surface can i copy to it 4 times before i unlock it would that help speed it up when its moving in BOTH directions?

again many thanks for the help guys i appreciate it :)

PS if anyone has the source CD for this book please let me know :)

#6 NightCreature83   Crossbones+   -  Reputation: 2758

Like
0Likes
Like

Posted 16 March 2012 - 09:40 AM

I never checked what you where doing but usually locking is bad, once you have a resource on the GPU you want to keep it there. Yes you can, unless you are doing some rendering in between the backbuffer wont have changed between the locks, 2 locks cause 4 PCI-E resource travels once there and once back times two.

Is this code supposed to just move a few squares arround the screen, if so this is the completly wrong way to do this.
Worked on titles: CMR:DiRT2, DiRT 3, DiRT: Showdown, GRID 2, Mad Max

#7 thestien   Members   -  Reputation: 102

Like
0Likes
Like

Posted 16 March 2012 - 10:10 AM

basicly this is supposed to make a scrolling background but the fact im getting 3fps evan when the background isnt scrolling in fact i get 6fps when it is lol

this code is copied as best as i can from the book and the book is old so i dont know why it runs this slow i cant understand it at all i mean it dont have alot of stuff to process other than this simple copying does 6fps sound like the code is running as it was intended taking into account the way it is designed?

it goes

init everything
clear backbuffer
copy background to the screen ( this part has the most to do) it copys pixel by pixel upto 4 quadrants and each quadrant is lock back buffer copy all pixel if they are not pink unlock back buffer) so max of 4 times per frame.

lock backbuffer
print frame rate
unlock backbuffer
present

a few other things happen but nothing major does that sound like 3-6fps worth of work?

the problem i have is that all this 2d code needs to be in place before i can use the 3d examples in the later chapters and i dont want to build the 3d parts ontop of broken code.
is the performace hit only when locking the backbuffer? or any surface?


many thanks Posted Image

Edited by thestien, 16 March 2012 - 10:12 AM.





Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS