本来打算晚上进行封装,不过由于上午进行HDR,只剩下RENDERBLOOM()了,有些疲倦,不妨先进行封装,闲话少说,现在是14:18,开始进行了。
这1节还是开头强调了硬件局限性,目前当然没有这个问题了,只考虑封装方法吧 。
大概浏览了一下这一节,主要说明了硬件blitter的优点,克服了以前的双缓冲的缺点
1, 速度加快,内存矩形填充代替逐行复制。
2, 透明色可以挑出,不复制。
从这里可以纠正上一节的错误,就是blt不只是窗口复制,也可以用于全屏。而双缓冲只能用于全屏
这部分主要讲了Blt()函数的使用,当然,也有个BltFast(),但是,我感觉意义不大。
BLT()函数的几个参数
Blt( 目标矩形,源表面,源矩形,标志,DDBLTFX参数);
具体使用方法
1, 将填充色彩或色彩索引放进DDBLTFX结构的dwFillColor字段
2, 将标志写为DDBLT_COLORFIL \ DDBLT_WAIT
在这个DEMO中,只是单纯BLT到目标表面,没有源表面,所以,其余可以写为NULL,
理论部分就这些,看看具体例子吧。
这个DEMO是16位,#define SCREEN_BPP 16 // bits per pixel
也不用锁定内存了,直接BLT,只需要设置颜色,目标矩形即可。也不用SLEEP()了。
初始化时,ddsd.dwFlags没有DDSD_BACKBUFFERCOUNT;了,当然也没有ddsd.dwBackBufferCount,
ddsd.ddsCaps.dwCaps也没有 DDSCAPS_COMPLEX | DDSCAPS_FLIP了。调色板可以不要了。
运行结果这样了,终于不全屏白点了。
现在考虑如何把这个弄到引擎过去,
HRESULT DDRAW_Interface::InitDDraw( HWND hWnd, DWORD width, DWORD height, DWORD bpp, bool windowed )
{
if( m_bWindowed == true )
{
m_dwCooprativeFlags = DDSCL_NORMAL;
m_lpdd->SetCooperativeLevel( m_hWnd, m_dwCooprativeFlags );
if ( m_dwBPP == 8)
{
for ( int index = 0; index < 10; index ++)
{
palette[index].peFlags = palette[index+246].peFlags = PC_EXPLICIT;
}
// create the palette object
if (FAILED( m_lpdd->CreatePalette(DDPCAPS_8BIT | DDPCAPS_INITIALIZE,
palette,&m_lpddpal, NULL)))
{
// error
return(0);
} // end if
}
DDSURFACEDESC2 ddsd;
// clear ddsd and set size
DDRAW_INIT_STRUCT( ddsd );
// enable valid fields
ddsd.dwFlags = DDSD_CAPS;
// request primary surface
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
// create the primary surface
if (FAILED( m_lpdd->CreateSurface(&ddsd, &m_lpddsprimary, NULL)))
{
// error
return(0);
} // end if
}
int Game_Main(void *parms = NULL, int num_parms = 0)
{
// for now test if user is hitting ESC and send WM_CLOSE
if (KEYDOWN(VK_ESCAPE))
{
exit( 0 );
//PostMessage(main_window_handle,WM_CLOSE,0,0);
} // end if
DDBLTFX ddbltfx;
RECT dest_rect;
DDRAW_INIT_STRUCT( ddbltfx );
ddbltfx.dwFillColor = _RGB16BIT565( rand() % 256, rand() % 256, rand() % 256 );
int x1 = rand() % SCREEN_WIDTH;
int y1 = rand() % SCREEN_HEIGHT;
int x2 = rand() % SCREEN_WIDTH;
int y2 = rand() % SCREEN_HEIGHT;
dest_rect.left = x1;
dest_rect.top = y1;
dest_rect.right = x2;
dest_rect.bottom = y2;
ddraw->getPrimarySurface()->Blt( & dest_rect, NULL, NULL, DDBLT_COLORFILL|DDBLT_WAIT, & ddbltfx );
// return success or failure or your own return code here
return(1);
} // end Game_Main
将位数改为16位,窗口,OK了
第三步,进行与T3DLIB结合。在T3DLIB,填充颜色的是
void DDRAW_Interface::DDraw_Fill_Surface(LPDIRECTDRAWSURFACE7 lpdds, USHORT color, RECT *client)
{
DDBLTFX ddbltfx;
DDRAW_INIT_STRUCT( ddbltfx );
ddbltfx.dwFillColor = color;
lpdds->Blt( client, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, & ddbltfx );
}
在调用时,
int Game_Main(void *parms = NULL, int num_parms = 0)
{
// for now test if user is hitting ESC and send WM_CLOSE
if (KEYDOWN(VK_ESCAPE))
{
exit( 0 );
//PostMessage(main_window_handle,WM_CLOSE,0,0);
} // end if
RECT dest_rect;
int x1 = rand() % SCREEN_WIDTH;
int y1 = rand() % SCREEN_HEIGHT;
int x2 = rand() % SCREEN_WIDTH;
int y2 = rand() % SCREEN_HEIGHT;
dest_rect.left = x1;
dest_rect.top = y1;
dest_rect.right = x2;
dest_rect.bottom = y2;
ddraw->DDraw_Fill_Surface( ddraw->getPrimarySurface(), _RGB16BIT565( rand() % 256, rand() % 256, rand() % 256 ), & dest_rect );
// return success or failure or your own return code here
return(1);
}
这个DEMO就结束了,相应的引擎也封装结束了。16:59,用时2小时41分钟,
小结:
这个DEMO主要就说了硬件BLT是多么的NB,原因是能够成块复制了,而不是逐行了