posts - 2, comments - 1, trackbacks - 0, articles - 4
  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

高级DirectDraw和位图图形(2)

Posted on 2008-05-26 18:06 cacar 阅读(508) 评论(0)  编辑 收藏 引用 所属分类: DirectX

一、关于Blt
    直接通过主表面指针调用,指明源区域,源表面,目标区域,目标表面,Blt就可以。源表面和目标表面可以是同一个,不过不经常这样做。而且如果目标区域超出了目标表面的矩形范围,则会出现问题,因此必须裁剪。

二、关于Clipper
    要设置DirectDraw裁剪,需要如下步骤
    (1)创建裁剪器对象;
    (2)创建裁剪序列(就是一个结构体保存的一系列RECT);
    (3)用IDIRECTDRAWCLIPPER::SetClipList()将裁剪器序列发送给裁剪器;
    (4)用IDIRECTDRAWSURFACE7::SetClipper()将裁剪器同窗口或表面相关联。
    封装该过程如下:
LPDIRECTDRAWCLIPPER 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(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_Clipper

    上述过程可以如此调用
RECT rect_list[3= {{},{},{}};
// 调用
LPDIRECTDRAWCLIPPER lpddclipper = DDraw_Attach_Clipper(lpddsback,3,rect_list);


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理