📄 direct_draw_impl.h
字号:
#ifndef _DIRECT_DRAW_H
#error You must include "direct_draw.h" before use this file!
#else
#ifndef _DIRECT_DRAW_IMPL_H
#define _DIRECT_DRAW_IMPL_H
#pragma once
/*! Directdraw 功能封装
* \author nodman
* \date 2003-6-13
*/
//#include "stdafx.h"
//#include "direct_draw.h"
#pragma comment(lib,"dxguid.lib")
#pragma comment(lib,"ddraw.lib")
#define CHECK_HR if( FAILED(hr) ) return
#define BCHECK if( FAILED(hr) ) { destroy(); return false; } // BOOL CHECK
#ifdef _UNICODE
#undef TRACE
#define TRACE
#endif
//////////////////////////////////////////////////////////////////////////
/// !!! PUBLIC !!!
inline bool direct_draw::create(HWND owner, int width, int height,
DWORD fourcc, int bitcount)
{
HRESULT hr = 0;
rc.SetRect(0,0,0,0);
bc = bitcount;
o = owner;
w = width;
hi = height;
hr = DirectDrawCreate(NULL, &h, NULL); BCHECK;
hr = h->SetCooperativeLevel(owner, DDSCL_NORMAL); BCHECK;
if( !create_pm_surface() )
{
destroy();
return false;
}
if( !create_clipper(owner) )
{
destroy();
return false;
}
hr = pm->SetClipper(cl); BCHECK;
if( !create_bk_surface(width, height, fourcc, bitcount) )
{
destroy();
return false;
}
TRACE("direct_draw create succeeded\n");
return true;
}
//////////////////////////////////////////////////////////////////////////
/// !!! PRIVATE !!!
inline bool direct_draw::create_pm_surface()
{
HRESULT hr = 0;
ddsd dd;
dd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
hr = h->CreateSurface(&dd, &pm, NULL); BCHECK;
return true;
}
inline bool direct_draw::create_bk_surface(int width, int height,
DWORD fourcc, int bitcount)
{
HRESULT hr = 0;
ddsd dd;
dd.dwFlags |= DDSD_WIDTH | DDSD_HEIGHT;
dd.dwWidth = width;
dd.dwHeight = height;
dd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY;
// if not RGB, set fourcc option
if( fourcc != 0 )
{
dd.dwFlags |= DDSD_PIXELFORMAT;
dd.set_fourcc(fourcc, bitcount);
}
hr = h->CreateSurface(&dd, &bk, NULL); BCHECK;
return true;
}
inline bool direct_draw::create_clipper(HWND owner)
{
HRESULT hr = 0;
hr = h->CreateClipper(0, &cl, NULL); BCHECK;
hr = cl->SetHWnd(0, owner); BCHECK;
return true;
}
inline void direct_draw::store(void* buf)
{
int size = -1;
HRESULT hr = 0;
if(rc.Width() == 0)
{
TRACE("[direct_draw::draw()]: width=0\n");
return;
}
if( size == -1 )
size = width()*height()*bc/8;
ddsd dd;
hr = bk->Lock(NULL, &dd, DDLOCK_WAIT, NULL);
// TRACE("lock result: %08lx\n", hr);
if( hr == DDERR_SURFACELOST )
{
hr = pm->Restore();
hr = bk->Restore();
hr = bk->Lock(NULL, &dd, DDLOCK_WAIT, NULL);
}
CHECK_HR;
byte* p0 = (byte*)buf;
byte* p1 = (byte* )dd.lpSurface;
DWORD line_px = width()*bc/8;
if( dd.lPitch == (LONG)line_px )
memcpy(p1, p0, size);
else
{
//TRACE("direct_draw_impl.h warning: Pitch size does not match width\n");
for( int i=0; i<height(); i++ )
{
memcpy( p1, p0, line_px );
p0 += line_px;
p1 += dd.lPitch;
}
}
hr = bk->Unlock(NULL); CHECK_HR;
}
inline void direct_draw::blt()
{
HRESULT hr = 0;
//hr = bk->Blt(CRect(10,10, 30, 20), bk, CRect(0,0,w,hi), DDBLT_WAIT, NULL);
hr = pm->Blt(&rc, bk, CRect(0,0,w,hi), DDBLT_WAIT, NULL);
// hr = pm->Blt(CRect(100,100, 250, 200), bk, CRect(0,0,w,hi), DDBLT_WAIT, NULL);
// TRACE("rc left:%d\n", rc.left);
}
// safe blt
inline void direct_draw::draw(void* buf /*=NULL*/, DWORD size/*=-1*/)
{
store(buf);
blt();
}
inline byte* direct_draw::lock()
{
ddsd dd;
dd.dwFlags = 0;
HRESULT hr = 0;
hr = bk->Lock(NULL, &dd, DDLOCK_WAIT, NULL);
return (byte*)dd.lpSurface;
}
inline void direct_draw::unlock()
{
bk->Unlock(NULL);
}
inline void direct_draw::update_bound()
{
if( IsWindow(o) )
{
CWnd* p = CWnd::FromHandle(o);
p->GetWindowRect(&rc);
// p->ClientToScreen(&rc);
}
else
TRACE("o is not a window\n");
}
#undef CHECK_HR
#undef BCHECK
#ifdef _UNICODE
#undef TRACE
#define TRACE ::AfxTrace
#endif // _UNICODE
#endif // _DIRECT_DRAW_IMPL_H
#endif // _DIRECT_DRAW_H
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -