2013年5月23日(7-9ddraw裁剪器)

 

进行裁剪步骤有4个

1,   创建ddraw裁减器对象

CreateClipper( 0, LPDIRECTDRAWCLIPPER * , NULL );

2,   创建裁剪队列(即RECT结构的矩形列表,blitter硬件只绘制裁剪区内的内容,其余的都剪掉)

裁剪队列需要填充RGBDATA()的数据结构

Typedef struct _RGNDATA

{

     RGNDATAHEADER               rdh; //头信息

     Char                        Buffer[1];         //分配大小

}

RGNDATAHEADER结构

Typedef struct _RGNDATAHEADER

{

     DWORD                       dwSize;  //sizeof( RGNDATAHEADER)

     DWORD                       iType;   //RDH_RECTANGLES

     DWORD                       nCount;//裁剪序列中的RECTS数目

     DWORD                       nRGNSize; //sizeof(RECT ) * nCount,以字节为大小的存储大小

     RECT                        rcBound; //包围所有RECTS的边界

}RGNDATAHEADER

 

3,   将裁剪队列发送给裁剪器

SetClipList( LPRGNDATA lpClipList, 0 );

4,   将裁剪器同窗口/表面相关联

Surface->SetClipper( & clipper );

 

原理就是这样,先看看例子。

 

 

OK,看看怎么封装,其实这个也简单,T3DLIB已经封装好了。

加上个裁剪器  LPDIRECTDRAWCLIPPER              m_lpddclipper;

m_lpddclipper                             = NULL;

DDraw_Attach_Clipper()函数,把整个步骤都封装好了。

LPDIRECTDRAWCLIPPER DDRAW_Interface::DDraw_Attach_Clipper(LPDIRECTDRAWSURFACE7 lpdds,

                                         int num_rects,

                                         LPRECT clip_list)

 

{

// this function creates a clipper from the sent clip list and attaches

// it to the sent surface

 

int index;                         // looping var

LPDIRECTDRAWCLIPPER lpddclipper;   // pointer to the newly created dd clipper

LPRGNDATA region_data;             // pointer to the region data that contains

                                   // the header and clip list

 

// first create the direct draw clipper

if (FAILED(m_lpdd->CreateClipper(0,&lpddclipper,NULL)))

   return(NULL);

 

// now create the clip list from the sent data

 

// first allocate memory for region data

region_data = (LPRGNDATA)malloc(sizeof(RGNDATAHEADER)+num_rects*sizeof(RECT));

 

// now copy the rects into region data

memcpy(region_data->Buffer, clip_list, sizeof(RECT)*num_rects);

 

// set up fields of header

region_data->rdh.dwSize          = sizeof(RGNDATAHEADER);

region_data->rdh.iType           = RDH_RECTANGLES;

region_data->rdh.nCount          = num_rects;

region_data->rdh.nRgnSize        = num_rects*sizeof(RECT);

 

region_data->rdh.rcBound.left    =  64000;

region_data->rdh.rcBound.top     =  64000;

region_data->rdh.rcBound.right   = -64000;

region_data->rdh.rcBound.bottom  = -64000;

 

// find bounds of all clipping regions

for (index=0; index<num_rects; index++)

    {

    // test if the next rectangle unioned with the current bound is larger

    if (clip_list[index].left < region_data->rdh.rcBound.left)

       region_data->rdh.rcBound.left = clip_list[index].left;

 

    if (clip_list[index].right > region_data->rdh.rcBound.right)

       region_data->rdh.rcBound.right = clip_list[index].right;

 

    if (clip_list[index].top < region_data->rdh.rcBound.top)

       region_data->rdh.rcBound.top = clip_list[index].top;

 

    if (clip_list[index].bottom > region_data->rdh.rcBound.bottom)

       region_data->rdh.rcBound.bottom = clip_list[index].bottom;

 

    } // end for index

 

// now we have computed the bounding rectangle region and set up the data

// now let's set the clipping list

 

if (FAILED(lpddclipper->SetClipList(region_data, 0)))

   {

   // release memory and return error

   free(region_data);

   return(NULL);

   } // end if

 

// now attach the clipper to the surface

if (FAILED(lpdds->SetClipper(lpddclipper)))

   {

   // release memory and return error

   free(region_data);

   return(NULL);

   } // end if

 

// all is well, so release memory and send back the pointer to the new clipper

free(region_data);

return(lpddclipper);

 

} // end DDraw_Attach_Cl

OK

下一步,看下根据T3DLIB,如何改进。关于clipper的,进行了下剪切后备缓冲。OK,由于还没有考虑窗口那边的,先只裁剪窗口的 。

 

         //一直裁剪后备缓冲

         RECT screen_rect            = { 0, 0, SCREEN_WIDTH,SCREEN_HEIGHT };

         m_lpddclipper               = DDraw_Attach_Clipper( m_lpddsback, 1, & screen_rect );

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值