?? draw.cpp
字號:
#include "draw.h"
#define SAFE_RELEASE(p) {if (p) {p->Release();p = NULL;}}
CDraw::CDraw()
{
m_pDD = NULL;
m_pddsFrontBuffer = NULL;
m_pddsBackBuffer = NULL;
m_hWnd = NULL;
}
CDraw::~CDraw()
{
SAFE_RELEASE(m_pddsBackBuffer);
SAFE_RELEASE(m_pddsFrontBuffer);
SAFE_RELEASE(m_pDD);
}
HRESULT CDraw::CreateFullScreenDisplay( HWND hWnd, DWORD dwWidth, DWORD dwHeight,DWORD dwBPP )
{
HRESULT hr;
// DDraw stuff begins here
if( FAILED( hr = DirectDrawCreateEx( NULL, (VOID**)&m_pDD,
IID_IDirectDraw7, NULL ) ) )
return E_FAIL;
// Set cooperative level
hr = m_pDD->SetCooperativeLevel( hWnd, DDSCL_EXCLUSIVE|DDSCL_FULLSCREEN );
if( FAILED(hr) )
return E_FAIL;
// Set the display mode
if( FAILED( m_pDD->SetDisplayMode( dwWidth, dwHeight, dwBPP, 0, 0 ) ) )
return E_FAIL;
// Create primary surface (with backbuffer attached)
DDSURFACEDESC2 ddsd;
ZeroMemory( &ddsd, sizeof( ddsd ) );
ddsd.dwSize = sizeof( ddsd );
ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
ddsd.ddsCaps.dwCaps = DDSCAPS_VIDEOMEMORY | DDSCAPS_COMPLEX | DDSCAPS_FLIP | DDSCAPS_PRIMARYSURFACE;
ddsd.dwBackBufferCount = 1;
if( FAILED( hr = m_pDD->CreateSurface( &ddsd, &m_pddsFrontBuffer,
NULL ) ) )
return E_FAIL;
// Get a pointer to the back buffer
DDSCAPS2 ddscaps;
ZeroMemory( &ddscaps, sizeof( ddscaps ) );
ddscaps.dwCaps = DDSCAPS_BACKBUFFER;
if( FAILED( hr = m_pddsFrontBuffer->GetAttachedSurface( &ddscaps,
&m_pddsBackBuffer ) ) )
return E_FAIL;
m_pddsBackBuffer->AddRef();
m_hWnd = hWnd;
m_bWindowed = FALSE;
UpdateBounds();
return S_OK;
}
HRESULT CDraw::CreateWindowedDisplay( HWND hWnd, DWORD dwWidth, DWORD dwHeight )
{
if( FAILED( DirectDrawCreateEx( NULL, (VOID**)&m_pDD, IID_IDirectDraw7, NULL ) ) )
return E_FAIL;
if( FAILED( m_pDD->SetCooperativeLevel( hWnd, DDSCL_NORMAL ) ) )
return E_FAIL;
LPDIRECTDRAWCLIPPER pcClipper;
// 創(chuàng)建主頁面
DDSURFACEDESC2 ddsd;
ZeroMemory( &ddsd, sizeof( ddsd ) );
ddsd.dwSize = sizeof( ddsd );
ddsd.dwFlags = DDSD_CAPS;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
if( FAILED( m_pDD->CreateSurface( &ddsd, &m_pddsFrontBuffer, NULL ) ) )
return E_FAIL;
// 創(chuàng)建后臺頁面
ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
ddsd.dwWidth = dwWidth;
ddsd.dwHeight = dwHeight;
if( FAILED( m_pDD->CreateSurface( &ddsd, &m_pddsBackBuffer, NULL ) ) )
return E_FAIL;
if( FAILED( m_pDD->CreateClipper( 0, &pcClipper, NULL ) ) )
return E_FAIL;
if( FAILED( pcClipper->SetHWnd( 0, hWnd ) ) )
{
pcClipper->Release();
return E_FAIL;
}
if( FAILED( m_pddsFrontBuffer->SetClipper( pcClipper ) ) )
{
pcClipper->Release();
return E_FAIL;
}
pcClipper->Release();
m_hWnd = hWnd;
m_bWindowed = TRUE;
UpdateBounds();
return S_OK;
}
HRESULT CDraw::CreateSurface( CSurface** ppSurface, DWORD dwWidth,DWORD dwHeight )
{
DDSURFACEDESC2 ddsd;
ZeroMemory( &ddsd, sizeof( ddsd ) );
ddsd.dwSize = sizeof( ddsd );
ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
ddsd.dwWidth = dwWidth;
ddsd.dwHeight = dwHeight;
(*ppSurface) = new CSurface();
if( FAILED( (*ppSurface)->Create( m_pDD, &ddsd ) ) )
{
delete (*ppSurface);
return E_FAIL;
}
return S_OK;
}
void CDraw::UpdateBounds()
{
GetClientRect( m_hWnd, &m_rcWindow );
ClientToScreen( m_hWnd, (POINT*)&m_rcWindow );
ClientToScreen( m_hWnd, (POINT*)&m_rcWindow+1 );
}
HRESULT CDraw::Clear( DWORD dwColor)
{
if( NULL == m_pddsBackBuffer )
return E_POINTER;
// 清除背景
DDBLTFX ddbltfx;
ZeroMemory( &ddbltfx, sizeof(ddbltfx) );
ddbltfx.dwSize = sizeof(ddbltfx);
ddbltfx.dwFillColor = dwColor;
return m_pddsBackBuffer->Blt( NULL, NULL, NULL, DDBLT_COLORFILL, &ddbltfx );
}
HRESULT CDraw::Blt( DWORD x, DWORD y, CSurface* pSurface, RECT* prc )
{
if( pSurface->IsColorKeyed() )
return m_pddsBackBuffer->BltFast( x, y, pSurface->GetDDrawSurface(), prc, DDBLTFAST_SRCCOLORKEY );
else
return m_pddsBackBuffer->BltFast( x, y, pSurface->GetDDrawSurface(), prc, 0 );
}
HRESULT CDraw::AlphaBlt( DWORD x, DWORD y, CSurface* pSurface, RECT* prc, float rate )
{
DDPIXELFORMAT DDPixelFormat;
ZeroMemory(&DDPixelFormat,sizeof(DDPixelFormat));
DDPixelFormat.dwSize=sizeof(DDPixelFormat);
m_pddsFrontBuffer->GetPixelFormat(&DDPixelFormat); //得到象素格式
DDSURFACEDESC2 ddsdDest,ddsdSour;
ZeroMemory(&ddsdDest,sizeof(ddsdDest));
ZeroMemory(&ddsdSour,sizeof(ddsdSour));
ddsdDest.dwSize=sizeof(ddsdDest);
ddsdSour.dwSize=sizeof(ddsdSour);
m_pddsBackBuffer->Lock(NULL,&ddsdDest,DDLOCK_WAIT,NULL);
pSurface->GetDDrawSurface()->Lock(NULL,&ddsdSour,DDLOCK_WAIT,NULL);
DWORD* BufDest=(DWORD*)ddsdDest.lpSurface;
DWORD* BufSour=(DWORD*)ddsdSour.lpSurface;
int width = prc->right - prc->left;
int height = prc->bottom - prc->top;
UINT avalue = (UINT)255*rate;
UINT Dest;
UINT Sour;
UINT R;
UINT G;
UINT B;
UINT A;
UINT R1;
UINT G1;
UINT B1;
UINT A1;
UINT R2;
UINT G2;
UINT B2;
UINT A2;
for(int i=0; i<height; i++)
{
for(int j=0; j<width; j++)
{
switch(DDPixelFormat.dwRGBBitCount)
{
case 32: // 此處將32位值分解成4個字節(jié)單獨處理,即OK.
{
Dest = BufSour[ddsdSour.lPitch*(i+prc->top)/4+prc->left+j];
Sour = BufDest[ddsdDest.lPitch*(i+y)/4+x+j];
R=Dest&0x00ff0000;
G=Dest&0x0000ff00;
B=Dest&0x000000ff;
A=Dest&0xff000000;
R1=Sour&0x00ff0000;
G1=Sour&0x0000ff00;
B1=Sour&0x000000ff;
A1=Sour&0xff000000;
R2=(((R1*(256-avalue))+(R*avalue)) >>8)&0x00ff0000;
G2=(((G1*(256-avalue))+(G*avalue)) >>8)&0x0000ff00;
B2=(((B1*(256-avalue))+(B*avalue)) >>8)&0x000000ff;
A2=(((A1*(256-avalue))+(A*avalue)) >>8)&0xff000000;
BufDest[ddsdDest.lPitch*(i+y)/4+x+j] = R2+B2+G2+A2;
}
break;
case 24:
break;
case 16:
break;
default:
break;
}
}
}
m_pddsBackBuffer->Unlock(NULL);
pSurface->GetDDrawSurface()->Unlock(NULL);
return S_OK;
}
HRESULT CDraw::DrawText( HFONT hFont, TCHAR* strText, DWORD dwX, DWORD dwY, COLORREF crBackground, COLORREF crForeground ,int bkmode)
{
HDC hDC = NULL;
HRESULT hr;
if( m_pddsBackBuffer == NULL || strText == NULL )
return E_INVALIDARG;
if( FAILED( hr = m_pddsBackBuffer->GetDC( &hDC ) ) )
return hr;
SetBkMode( hDC,bkmode );
// Set the background and foreground color
SetBkColor( hDC, crBackground );
SetTextColor( hDC, crForeground );
if( hFont )
SelectObject( hDC, hFont );
// Use GDI to draw the text on the surface
TextOut( hDC, dwX, dwY, strText, strlen(strText) );
if( FAILED( hr = m_pddsBackBuffer->ReleaseDC( hDC ) ) )
return hr;
return S_OK;
}
HRESULT CDraw::Present()
{
HRESULT hr;
if( NULL == m_pddsFrontBuffer && NULL == m_pddsBackBuffer )
return E_FAIL;
if( m_bWindowed )
hr = m_pddsFrontBuffer->Blt( &m_rcWindow, m_pddsBackBuffer,NULL, DDBLT_WAIT, NULL );
else
hr = m_pddsFrontBuffer->Flip( NULL, 0 );
return hr;
}
///////////////////////////////////////////////////////////
CSurface::CSurface()
{
m_bColorKeyed = FALSE;
}
CSurface::~CSurface()
{
SAFE_RELEASE( m_pdds );
}
HRESULT CSurface::DrawBitmap( TCHAR* strBMP, DWORD dwWidth, DWORD dwHeight )
{
HBITMAP hBitMap = (HBITMAP) LoadImage( NULL, strBMP, IMAGE_BITMAP,
dwWidth, dwHeight, LR_LOADFROMFILE | LR_CREATEDIBSECTION );
if ( hBitMap == NULL )
return E_FAIL;
HDC hdc = CreateCompatibleDC(NULL);
if(hdc == NULL)
{
return E_FAIL;
}
HBITMAP hOldBitMap = (HBITMAP)SelectObject(hdc,hBitMap);
if(hOldBitMap == NULL)
{
DeleteObject(hBitMap);
return E_FAIL;
}
HDC surfaceDC = NULL;
HRESULT ret = m_pdds->GetDC(&surfaceDC);
if(ret != DD_OK)
{
SelectObject(hdc,hOldBitMap);
DeleteObject(hBitMap);
return E_FAIL;
}
BitBlt(surfaceDC,0,0,dwWidth,dwHeight,hdc,0,0,SRCCOPY);
m_pdds->ReleaseDC(surfaceDC);
SelectObject(hdc,hOldBitMap);
DeleteDC( hdc );
DeleteObject(hBitMap);
return S_OK;
}
HRESULT CSurface::SetColorKey( COLORREF dwColorKeyLow, COLORREF dwColorKeyHig )
{
m_bColorKeyed = TRUE;
DDCOLORKEY ddck;
ddck.dwColorSpaceLowValue = dwColorKeyLow;
ddck.dwColorSpaceHighValue = dwColorKeyHig;
return m_pdds->SetColorKey( DDCKEY_SRCBLT, &ddck );
}
HRESULT CSurface::Create( LPDIRECTDRAW7 pDD, DDSURFACEDESC2* pddsd )
{
if( FAILED( pDD->CreateSurface( pddsd, &m_pdds, NULL ) ) )
return E_FAIL;
m_ddsd.dwSize = sizeof(m_ddsd);
m_pdds->GetSurfaceDesc( &m_ddsd );
return S_OK;
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -