⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fgame.cpp

📁 DirectX 封装
💻 CPP
字号:
// fGame.cpp: implementation of the CfGame class.
//
//////////////////////////////////////////////////////////////////////

#include "fGame.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CfGame::CfGame()
{
	if(!InitDdraw())
	{
		MessageBox(NULL,"DirectDraw初始化失败!","错误",MB_OK);
		FreeDdraw();
		return;
	}
}

CfGame::~CfGame()
{
	FreeDdraw();
}

BOOL CfGame::InitDdraw()
{
	DDSURFACEDESC ddsd;
	HRESULT ddrval;
	if(DirectDrawCreate(NULL,&lpDD,NULL)!=DD_OK) 
		return FALSE;
	lpDD->SetCooperativeLevel(AppData.hMainWnd,DDSCL_NORMAL);
	//创建主表面
	ZeroMemory(&ddsd, sizeof(ddsd));
	ddsd.dwSize=sizeof(DDSURFACEDESC);
	ddsd.dwFlags=DDSD_CAPS;
	ddsd.ddsCaps.dwCaps=DDSCAPS_PRIMARYSURFACE;
	ddrval=lpDD->CreateSurface(&ddsd,&lpDDSPrimary,NULL);
	if(ddrval!=DD_OK)
		return FALSE;
	//创建缓冲页面
	ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
	ddsd.ddsCaps.dwCaps  = DDSCAPS_OFFSCREENPLAIN;
	ddsd.dwWidth = AppData.WndRect.right-AppData.WndRect.left;
	ddsd.dwHeight = AppData.WndRect.bottom-AppData.WndRect.top;
	lpDD->CreateSurface(&ddsd,&lpDDSBack,NULL); 
	//创建裁剪器
	lpDD->CreateClipper(0, &lpClipper, NULL);
	lpClipper->SetHWnd(0,AppData.hMainWnd);
	lpDDSPrimary->SetClipper(lpClipper);
	lpDDSBack->SetClipper(lpClipper);
	return TRUE;
}

void CfGame::FreeDdraw()
{
	if(this->lpDD!=NULL)
	{
		if(this->lpDDSPrimary!=NULL)
		{
			lpDDSPrimary->Release();
			lpDDSPrimary=NULL;
		}
		if(this->lpDDSBack!=NULL)
		{
			lpDDSBack->Release();
			lpDDSBack=NULL;
		}
		lpDD->Release();
		lpDD=NULL;
	}
}

void CfGame::Flip()
{
	RECT Window;
	POINT pt;
	GetClientRect(AppData.hMainWnd, &Window);
	pt.x=pt.y=0;
	ClientToScreen(AppData.hMainWnd, &pt);
	OffsetRect(&Window, pt.x, pt.y);
  
	HRESULT ddrval=lpDDSPrimary->Blt(&Window, lpDDSBack, NULL, DDBLT_WAIT, NULL);
	if(ddrval == DDERR_SURFACELOST) lpDDSPrimary->Restore();
}

BufferSurfaceAddress CfGame::BeginWriteBufferSurface()//得到缓冲表面的实际宽度,便于直接操纵表面
{
	DDSURFACEDESC       ddsd;
	HRESULT ddrval;
    //LPWORD              lpSurface;
    long                Pitch;
	BufferSurfaceAddress     BufferAddress;
    
    ddsd.dwSize = sizeof(ddsd);
    
    // 锁定Back Surface,DDraw中的Surface必须先锁定,然后才能访问
    while((ddrval=lpDDSBack->Lock(NULL, &ddsd, 0, NULL))==DDERR_WASSTILLDRAWING);
    if(ddrval == DD_OK)
	{
		BufferAddress.lpSurface = (LPWORD)ddsd.lpSurface;
        // 我们关心的Pitch,其值是字节(BYTE)数
        Pitch = ddsd.lPitch;
        Pitch >>= 1;        // 为了方便后面的计算,把它换算成字(WORD)数
		BufferAddress.Pitch=Pitch;	
	}
	//lpDDSBack->Unlock(NULL);
	return BufferAddress;
	// 作了以上处理以后,像素坐标到地址的换算公式为
    // (LPWORD)addr = BufferAddress.lpSurface + y*BufferAddress.Pitch + x;
}

void CfGame::EndWriteBufferSurface()
{
	lpDDSBack->Unlock(NULL);
}

int CfGame::TestFPS()
{
	static int newtime,oldtime=0;
	static int FlipCount=0;
	int Fps;
	newtime=GetTickCount();
	if(newtime>=oldtime+1000)
	{
		if(newtime==oldtime)
			return 0;
		Fps=FlipCount*1000/(newtime-oldtime);
		FlipCount=0;
		oldtime=newtime;
		return Fps;
	}
	FlipCount++;
	return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -