?? directdraw.cpp
字號:
// DirectDraw.cpp: implementation of the DirectDraw class.
//
//////////////////////////////////////////////////////////////////////
#include <string.h>
#include <stdio.h>
#include <assert.h>
#include <windowsx.h>
#include "DirectDraw.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
DirectDraw::DirectDraw()
{
m_lpDD=NULL;
m_lpDDSPrimary=NULL;
m_lpDDSBackbuffer=NULL;
memset(&m_ddsd,0,sizeof(DDSURFACEDESC));
m_ddsd.dwSize = sizeof (DDSURFACEDESC);
}
DirectDraw::~DirectDraw()
{
if (m_lpDD!=NULL)
{
if( m_lpDDSPrimary!=NULL)
{
m_lpDDSPrimary->Release();
m_lpDDSPrimary= NULL;
}
m_lpDD->Release();
m_lpDD=NULL;
}
}
bool DirectDraw::Create(HWND hWnd)
{
m_hWnd=hWnd;
if (DirectDrawCreate(NULL, &m_lpDD, NULL)!=DD_OK)
return false;
#ifdef _DEBUG
if (m_lpDD->SetCooperativeLevel(m_hWnd,DDSCL_NORMAL | DDSCL_NOWINDOWCHANGES) != DD_OK)
{
MessageBox(NULL,"協作層設置失敗!","協作層設置失敗!",MB_OK);
return false;
}
#else
if(m_lpDD->SetCooperativeLevel(m_hWnd,DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN)!=DD_OK)
{
MessageBox(NULL,"協作層設置失敗 !","協作層設置失敗 !",MB_OK);
return false;
}
if (m_lpDD->SetDisplayMode(DisplayMode_Width,DisplayMode_Height,DisplayMode_ColorDeep)!=DD_OK)
{
MessageBox(NULL,"顯示模式設置失敗!","顯示模式設置失敗!",MB_OK);
return false;
}
#endif
DDSURFACEDESC ddsd;
HRESULT ddrval;
// Create the primary surface with 1 back buffer
memset( &ddsd, 0, sizeof(ddsd) );
ddsd.dwSize = sizeof( ddsd );
#ifdef _DEBUG
ddsd.dwFlags = DDSD_CAPS ;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE ;
ddrval = m_lpDD->CreateSurface( &ddsd, &m_lpDDSPrimary, NULL );
if( ddrval != DD_OK ) return FALSE;
ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS;
ddsd.dwWidth = DisplayMode_Width;
ddsd.dwHeight = DisplayMode_Height;
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY; // 創建后緩沖
ddrval=m_lpDD->CreateSurface( &ddsd, &m_lpDDSBackbuffer, NULL );
#else
DDSCAPS ddscaps;
ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT ;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX;
ddsd.dwBackBufferCount = 1;
ddrval = m_lpDD->CreateSurface( &ddsd, &m_lpDDSPrimary, NULL );
if( ddrval != DD_OK ) return FALSE;
ddscaps.dwCaps = DDSCAPS_BACKBUFFER ;
ddrval = m_lpDDSPrimary->GetAttachedSurface(&ddscaps, &m_lpDDSBackbuffer);
#endif
if( ddrval != DD_OK )
{
MessageBox(NULL,"顯示表面初始化失敗 ! ","顯示表面初始化失敗 !",MB_OK);
return false;
}
#ifdef _DEBUG
LPDIRECTDRAWCLIPPER lpDDClipper;
if (m_lpDD->CreateClipper( 0, &lpDDClipper, NULL ) != DD_OK )
{
MessageBox(NULL,"Function: CreateClipper()...","剪裁器建立失敗 !",MB_OK);
return false;
}
if ( lpDDClipper->SetHWnd( 0, m_hWnd ) != DD_OK )
{
MessageBox(NULL,"Function: Clipper->SetHWnd()","剪裁器窗口句柄設置失敗 !",MB_OK);
return false;
}
if ( m_lpDDSPrimary->SetClipper( lpDDClipper ) != DD_OK )
{
MessageBox(NULL,"Function: SetClipper()...","剪裁器連接到主表面失敗 !",MB_OK);
return false;
}
lpDDClipper->Release();
#endif
DDPIXELFORMAT ddpf;
ddpf.dwSize=sizeof(DDPIXELFORMAT);
if (m_lpDDSPrimary->GetPixelFormat( &ddpf )!=DD_OK)
{
MessageBox(NULL,"Function: GetPixelFormat()...","失敗 !",MB_OK);
return false;
}
if (ddpf.dwGBitMask==0x3e0)
m_bColorMode=true; // 000001111100000 555
else
m_bColorMode=false; // 0000011111100000 565
return true;
}
bool DirectDraw::Lock(WORD * & lpBackbufferPtr, long & lPitch)
{
m_lpDDSBackbuffer->Lock(NULL, &m_ddsd, DDLOCK_WAIT, NULL);
//{
/// return false;
//}
//else
//{
lPitch = m_ddsd.lPitch >> 1;
lpBackbufferPtr=(WORD *)m_ddsd.lpSurface;
return true;
//}
}
bool DirectDraw::UnLock()
{
if (m_lpDDSBackbuffer->Unlock(&m_ddsd)!=DD_OK)
return false;
else
return true;
}
void DirectDraw::Dump(char *lpBuffer)
{
assert(lpBuffer);
static DWORD time=GetTickCount();
static int fps=0, frame=0, nt, ot=0;
if ((GetTickCount()-time)>10)
{
time=GetTickCount();
frame++;
nt=GetTickCount();
if (nt > ot+1000)
{
ot=nt;
fps=frame;
frame=0;
}
}
sprintf(lpBuffer,"幀數:%3.3d ",fps);
if (m_bColorMode) strcat(lpBuffer,"555顏色模式");
else strcat(lpBuffer,"565顏色模式");
}
void DirectDraw::Flip()
{
HRESULT hResult;
#ifdef _DEBUG
RECT src_rect, dst_rect;
POINT pt;
/*** src_rect is relative to offscreen buffer */
GetClientRect(m_hWnd,&src_rect);
//GetClientRect( AfxGetMainWnd()->m_hWnd, &src_rect );
/*** dst_rect is relative to screen space so needs translation */
pt.x = pt.y = 0;
ClientToScreen( m_hWnd, &pt );
dst_rect = src_rect;
dst_rect.left += pt.x;
dst_rect.right += pt.x;
dst_rect.top += pt.y;
dst_rect.bottom += pt.y;
/*** perform the blit from backbuffer to primary, using ** src_rect and dst_rect */
hResult=m_lpDDSPrimary->Blt(&dst_rect,m_lpDDSBackbuffer, &src_rect, DDBLT_WAIT,0);
if ( hResult!= DD_OK )
{
// something bad happened
}
#else
while( 1 )
{
hResult = m_lpDDSPrimary->Flip( NULL, DDFLIP_WAIT);
if( hResult== DD_OK )
{
break;
}
if( hResult== DDERR_SURFACELOST )
{
hResult= Restore();
if( hResult!= DD_OK )
{
break;
}
}
if( hResult!= DDERR_WASSTILLDRAWING )
{
break;
}
}
#endif
}
void DirectDraw::DebugInfo()
{
CleanDDSBackbuffer(RGB(0,0,0));
HDC dc;char * temp=new char[256];
m_lpDDSBackbuffer->GetDC(&dc);
Dump(temp);
TextOut(dc, 0, 0, temp, strlen(temp));
m_lpDDSBackbuffer->ReleaseDC(dc);
delete temp;
//鎖定表面測試
WORD *lpBackbuffer=NULL;
long lPitch;
if (Lock(lpBackbuffer,lPitch))
{
for(int i=0;i<100;i++)
*(lpBackbuffer+0+i*lPitch+i)=0x7fff;
UnLock();
}
//翻轉頁面
Flip();
}
void DirectDraw::CleanDDSBackbuffer(DWORD Color)
{
HRESULT hResult;
DDBLTFX ddfx;
ddfx.dwSize=sizeof(ddfx);
ddfx.dwFillColor=Color;
while(1)
{
hResult=m_lpDDSBackbuffer->Blt(NULL,NULL,NULL,DDBLT_COLORFILL,&ddfx);
if( hResult == DD_OK )
{
break;
}
if( hResult== DDERR_SURFACELOST )
{
hResult= Restore();
if( hResult!= DD_OK )
{
break;
}
}
if( hResult!= DDERR_WASSTILLDRAWING )
{
break;
}
}
}
bool DirectDraw::Restore()
{
if (m_lpDDSPrimary!=NULL) m_lpDDSPrimary->Restore();
return true;
}
bool DirectDraw::Capture(char *lpszFilename)
{
BITMAPFILEHEADER bmfh;
BITMAPINFOHEADER bmih;
FILE *fp=NULL;
bmfh.bfType=0x4d42;
bmfh.bfSize=0;
bmfh.bfReserved1=0;
bmfh.bfReserved2=0;
bmfh.bfOffBits=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);
bmih.biSize=sizeof(BITMAPINFOHEADER);
bmih.biWidth=DisplayMode_Width;
bmih.biHeight=DisplayMode_Height;
bmih.biPlanes=1;
bmih.biBitCount=24;
bmih.biCompression=BI_RGB;
bmih.biSizeImage=0;
bmih.biXPelsPerMeter=0;
bmih.biYPelsPerMeter=0;
bmih.biClrUsed=0;
bmih.biClrImportant=0;
if ((fp=fopen(lpszFilename,"wb"))==NULL) return FALSE;
fwrite(&bmfh,sizeof(bmfh),1,fp);
fwrite(&bmih,sizeof(bmih),1,fp);
//fseek(fp,bmfh.bfOffBits,SEEK_SET);
//conver every pixel form 256 to 15bit
HDC hDC;
m_lpDDSBackbuffer->GetDC(&hDC);
for (int j=bmih.biHeight-1;j>=0;j--)
for (int i=0;i<bmih.biWidth;i++)
{
COLORREF c=GetPixel(hDC,i,j);
BYTE r,g,b;
r=GetRValue(c);
g=GetGValue(c);
b=GetBValue(c);
fwrite(&b,1,1,fp);
fwrite(&g,1,1,fp);
fwrite(&r,1,1,fp);
}
m_lpDDSBackbuffer->ReleaseDC(hDC);
fclose(fp);
return TRUE;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -