使用硬件blitter来移动位图和填充像素

通常,当你想绘制位图或者对视频表面进行填充时,你只能手工一个像素一个像素地进行。

例如:

UCHAR *video_buffer; ///points  to VRAM  or  offscreen  surface(离屏表面)

 

UCHAR *bitmap[8*8] ;holds our  bitmap  in  row  major  form

///curde(粗)  bitmap copy

///outer  loop  is  for  each  row

for (int index_y = 0; index_y < 8; index_y++)

{

       ///inner loop is  for  each  row

         for(int index_x = 0; index_x < 8;index_x++)

               {

                              video_buffer[x + index_x + (y + index_y)*640] = bitmap[index_x + index_y*8];

               }end for index_x

}///end for index_y

 

上面操作的问题:1、出奇的慢;   2、没有考虑到透明度的存在,也就是说如果你在位图中有个被黑色围绕的物体,黑色将一并被拷贝

优化(考虑了透明度------用色彩0):

void    Blit8*8(int x, int y,UCHAR *video_buffer , UCHAR  *bitmap)

{

video _buffer = video_buffer + (x + y*640)

video_buffer += (x + (y << 9) + (y << 7));

UCHAR  pixxel ; ///used to read/write  pixels

for (int index_y = 0; index_y < 8; index_y++)

{

       ///inner loop is  for  each  row

         for(int index_x = 0; index_x < 8;index_x++)

               {

                          if(pixel = bitmap[index_x])

                                 video_buffer[index_x ] = pixel;

               }end for index_x

bitmap += 8;

video_buffer += 640;

}///end for index_y

}

但是这个函数还有有太多的限制,不够好!!!!

 

利用硬件blitter:

内存填充意味着用某些值填充VRAM中的一块区域。大致过程是:先锁定表面,然后利用memset()或memcpy()操作和填充表面内存。

但是这个方法有一些问题:首先,既然采用主cpu进行内存填充,所以主总线是传输的一部分。其次,组成表面的VRAM不一定完全是线性的,这时,你将不得一线一线

的填充或者移动。

但是,利用硬件Blitter,你将可以立即直接填充或者移动大块VRAM和DirectDraw表面。

DirectDraw有两个用于显存块移动的函数Blt()和BltFast()。

 

为什么有两个不同的blitter函数?原因是Blt()功能全但较复杂,BltFast较简单但具有较少的参数。另外,Blt使用DirectDraw裁剪器,而BltFast没有。

Blt和BltFast都是从目标表面的接口上调用。

 


int Game_Main(void *parms = NULL, int num_parms = 0)
{
// this is the main loop of the game, do all your processing
// here

DDBLTFX ddbltfx; // the blitter fx structure
RECT dest_rect;  // used to hold the destination RECT

// make sure this isn't executed again
if (window_closed)
   return(0);

// for now test if user is hitting ESC and send WM_CLOSE
if (KEYDOWN(VK_ESCAPE))
   {
   PostMessage(main_window_handle,WM_CLOSE,0,0);
   window_closed = 1;
   } // end if

// first initialize the DDBLTFX structure
DDRAW_INIT_STRUCT(ddbltfx);

// now set the color word info to the color we desire
// in this case, we are assuming an 8-bit mode, hence,
// well use a color index from 0-255, but if this was a
// 16/24/32 bit example then we would fill the WORD with
// the RGB encoding for the pixel - remember!
ddbltfx.dwFillColor = _RGB16BIT565(rand()%256, rand()%256, rand()%256);

// get a random rectangle
int x1 = rand()%SCREEN_WIDTH;
int y1 = rand()%SCREEN_HEIGHT;
int x2 = rand()%SCREEN_WIDTH;
int y2 = rand()%SCREEN_HEIGHT;

// now set up the RECT structure to fill the region from
// (x1,y1) to (x2,y2) on the destination surface
dest_rect.left   = x1;
dest_rect.top    = y1;
dest_rect.right  = x2;
dest_rect.bottom = y2;

// make the blitter call  ///使用硬件Blitter
if (FAILED(lpddsprimary->Blt(&dest_rect, // pointer to dest RECT
                             NULL, // pointer to source surface
                             NULL, // pointer to source RECT
                             DDBLT_COLORFILL | DDBLT_WAIT,
                             // do a color fill and wait if you have to
                             &ddbltfx))) // pointer to DDBLTFX holding info
   return(0);

// return success or failure or your own return code here
return(1);

} // end Game_Main

 

具体详细操作见P259.

 

 

                                                                             从一个表面向另一个表面复制位图,见下节...........

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值