www.pudn.com > DirectX_demo.zip > DirectDraw.cpp


// ------------------------------------------------------------------------- 
// CDirectDraw Class 
// ------------------------------------------------------------------------- 
 
#define INITGUID 
 
#include "stdafx.h" 
#include "DirectDraw.h" 
 
static const CLSID IID_IDirectDraw2 = {0xB3A6F3E0,0x2B43,0x11CF, {0xA2,0xDE,0x00,0xAA,0x00,0xB9,0x33,0x56} }; 
 
// ------------------------------------------------------------------------- 
// CDirectDraw Constructor 
// ------------------------------------------------------------------------- 
 
CDirectDraw::CDirectDraw() 
{ 
	m_pDD	    = NULL; 
	m_pOSBInfo  = NULL; 
	m_pPrimary  = NULL; 
	m_pBuffer   = NULL; 
 
	m_bLocked   = FALSE; 
} 
 
// ------------------------------------------------------------------------- 
// CDirectDraw Destructor 
// ------------------------------------------------------------------------- 
 
CDirectDraw::~CDirectDraw() 
{ 
	if (m_pOSBInfo){ 
		delete m_pOSBInfo; 
		m_pOSBInfo = NULL; 
	} 
	if (m_pPrimary){ 
		m_pPrimary->Release(); 
		m_pPrimary = NULL; 
	} 
	if (m_pDD){ 
		m_pDD->RestoreDisplayMode(); 
		m_pDD->Release(); 
		m_pDD = NULL; 
	} 
} 
 
// ------------------------------------------------------------------------- 
// CDirectDraw Clear Back Buffer 
// ------------------------------------------------------------------------- 
 
void CDirectDraw::Clear(int nColor) 
{ 
	Lock(); 
 
	BYTE* pAddress = (BYTE*) m_pOSBInfo->lpSurface; 
	DWORD dwBuffer = m_pOSBInfo->lPitch*m_pOSBInfo->dwHeight; 
	memset(pAddress,nColor,dwBuffer); 
 
	Unlock(); 
} 
 
// ------------------------------------------------------------------------- 
// CDirectDraw Create 
// ------------------------------------------------------------------------- 
 
BOOL CDirectDraw::Create(CWnd* pWnd,int nXRes,int nYRes,int nBPP) 
{ 
	LPDIRECTDRAW m_pDDInterface; 
 
	// Create Direct Draw Original Interface 
	if (FAILED(DirectDrawCreate(NULL,&m_pDDInterface,NULL))) 
		return Error("Failure Creating DirectDraw Object"); 
	 
	// Get Latest Direct Draw Interface 
	if (FAILED(m_pDDInterface->QueryInterface(IID_IDirectDraw2, (LPVOID*)&m_pDD))) 
		return Error("Failure Obtaining Latest DirectDraw Interface"); 
 
	// Delete Original Direct Draw Object 
	m_pDDInterface->Release(); 
	m_pDDInterface=NULL; 
 
	// Set Co-Operation Levels 
	if (FAILED(m_pDD->SetCooperativeLevel(pWnd->GetSafeHwnd(),DDSCL_ALLOWMODEX|DDSCL_FULLSCREEN|DDSCL_EXCLUSIVE|DDSCL_ALLOWREBOOT))) 
		return Error("Failure Setting Co-operation Level"); 
 
	// Set Video Mode 
	if (FAILED(m_pDD->SetDisplayMode(nXRes,nYRes,nBPP,0,0))) 
		return Error("Failure Setting Video Mode"); 
 
	// Create Primary Surface Structure 
	DDSURFACEDESC ddInfo; 
	ddInfo.dwSize = sizeof(DDSURFACEDESC); 
	ddInfo.dwFlags = DDSD_CAPS|DDSD_BACKBUFFERCOUNT; 
	ddInfo.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE|DDSCAPS_FLIP|DDSCAPS_COMPLEX; 
	ddInfo.dwBackBufferCount = 1; 
 
	// Create Primary Surface 
	if (FAILED(m_pDD->CreateSurface(&ddInfo,&m_pPrimary,NULL))) 
		return Error("Failure Creating Main Primary Surface"); 
 
	// Create Back Buffer Structure 
	DDSCAPS ddCaps; 
	ddCaps.dwCaps = DDSCAPS_BACKBUFFER; 
 
	// Create BackBuffer Surface 
	if (FAILED(m_pPrimary->GetAttachedSurface(&ddCaps,&m_pBuffer))) 
		return Error("Failure Creating Back Buffer"); 
 
	// Get Surface Information 
	m_pOSBInfo = new DDSURFACEDESC; 
	memset(m_pOSBInfo,0,sizeof(DDSURFACEDESC)); 
	Clear(0); 
 
	return TRUE; 
} 
 
// ------------------------------------------------------------------------- 
// CDirectDraw Lock 
// ------------------------------------------------------------------------- 
 
BOOL CDirectDraw::Lock() 
{ 
	memset(m_pOSBInfo,0,sizeof(DDSURFACEDESC)); 
	m_pOSBInfo->dwSize = sizeof(DDSURFACEDESC); 
 
	if (FAILED(m_pBuffer->Lock(NULL,m_pOSBInfo,DDLOCK_WAIT,NULL))) 
		return Error("Failure Locking Back Buffer"); 
 
	m_bLocked = TRUE; 
	return TRUE; 
} 
 
// ------------------------------------------------------------------------- 
// CDirectDraw Render 
// ------------------------------------------------------------------------- 
 
BOOL CDirectDraw::Render() 
{ 
	if (m_bLocked) 
		Unlock(); 
 
	if (m_pPrimary){ 
		while (m_pPrimary->Flip(NULL,DDFLIP_WAIT)!=DD_OK); 
			return TRUE; 
	} 
	return FALSE; 
} 
 
// ------------------------------------------------------------------------- 
// CDirectDraw Render Surface 
// ------------------------------------------------------------------------- 
 
BOOL CDirectDraw::RenderSurface(LPDIRECTDRAWSURFACE pSurface,int nXPos,int nYPos) 
{ 
	if (!pSurface || !m_pBuffer) 
		return Error("Cannot Render Surface If Surface/Back Buffer Is Invalid"); 
 
	// Get Surface Description 
	DDSURFACEDESC dsInfo; 
	memset(&dsInfo,0,sizeof(dsInfo)); 
	dsInfo.dwSize = sizeof(dsInfo); 
	pSurface->GetSurfaceDesc(&dsInfo); 
 
	// Calculate & Clip Rectangle 
	CRect rcSource (0,0,dsInfo.dwWidth,dsInfo.dwHeight); 
 
	// Clip Right Side 
	if (nXPos + dsInfo.dwWidth > m_pOSBInfo->dwWidth) 
		rcSource.right = m_pOSBInfo->dwWidth - nXPos; 
 
	// Clip Bottom 
	if (nYPos + dsInfo.dwHeight > m_pOSBInfo->dwHeight) 
		rcSource.bottom = m_pOSBInfo->dwHeight - nYPos; 
 
	// Clip Left Side 
	if (nXPos < 0){ 
		rcSource.left  = -nXPos; 
		rcSource.right = rcSource.left + rcSource.right + nXPos; 
		nXPos = 0; 
	} 
 
	// Clip Top 
	if (nYPos <0){ 
		rcSource.top	= -nYPos; 
		rcSource.bottom = rcSource.top + rcSource.bottom + nYPos; 
		nYPos = 0; 
	} 
 
	// Do Blit 
	if (FAILED(m_pBuffer->BltFast(nXPos,nYPos,pSurface,&rcSource,DDBLTFAST_WAIT))) 
		return FALSE; 
 
	return TRUE; 
} 
 
// ------------------------------------------------------------------------- 
// CDirectDraw Unlock 
// ------------------------------------------------------------------------- 
 
BOOL CDirectDraw::Unlock() 
{ 
	if (FAILED(m_pBuffer->Unlock(m_pOSBInfo->lpSurface))) 
		return Error("Failure Unlocking Back Buffer"); 
 
	m_bLocked = FALSE; 
	return TRUE; 
}