关键词不能为空

当前您在: 主页 > 英语 >

12.屏蔽缓冲区

作者:高考题库网
来源:https://www.bjmy2z.cn/gaokao
2021-03-01 02:09
tags:

-

2021年3月1日发(作者:anxi)


12.


屏蔽缓冲区



屏蔽是一项我们尚未讨论过的高阶绘制功能,这是一项在发展商业应用程序时很有用的技


术。如果想让您的


3D


程序与众不同,最好能结合屏蔽以及前面 学到的贴图技术。本章会详


述如何运用屏蔽,并且展示能用它产生的不同类型效果。



市面上很多


3D


游戏和模拟都用电影级的特效添加戏剧性的冲击。您可以用屏蔽缓冲区来建


立像合成、印 花(


decal


)、溶入、淡出淡入(


fade


)、边框、剪影(


silhouette


)、刷抹



swipe


)以 及阴影等效果。屏蔽缓冲区能决定会绘制影像中的哪些像素。屏蔽缓冲区能让


您针对各像 素开启或关闭对绘制目的绘图页来达成这些功能。这表示您的软件可以「遮住」


部份的影 像让它不要显示。



当屏蔽功能启动时,


Microsoft Direct3D< /p>


会对要写入绘制目的绘图页的每个像素进行屏蔽测


试。屏蔽测试会 用一个屏蔽参考值、一个屏蔽板(


stencil mask


) 、一个比较函式、以及一


个取自屏蔽缓冲区的像素值(对应于目的绘图页中的现行像素) 。下面是这个测试中所作的


步骤:



1.



屏蔽板对屏蔽参考值作位


AND


运算。



2.



屏蔽板针对现行像素的屏蔽缓 冲区值作位


AND


运算。



3.



比较函式比较步骤

< p>
1


和步骤


2


的结果。



控制比较函式、屏蔽板、屏蔽参考值、以及屏蔽测试通过或失败时 的动作,就可以控制屏蔽


缓冲区的运作。当测试成功时,现行像素会被写入目标。预设比 较动作(


D3DCMPFUNC


列举类型所定义的


D3DCMP_ALWAYS


)不会管屏蔽缓冲区的内容而直接写入像素。您 可


以设定


D3DRENDERSTATE_STENCILFU NC


绘制状态并转入任一个


D3DCMPFUNC


成员


值来改用任何所要的函式。



建立一个屏蔽缓冲区





在建立屏蔽缓冲区之前必须决定目标系统所支持的屏蔽功能。 方法是呼叫


IDirect3DDevice7::GetCaps

方法。


dwStencilCaps


旗标表示装置所支持的 屏蔽缓冲区运


算。回报的旗标对全部三种屏蔽缓冲区运算都有效:


D3DRENDERSTATE_STENCILFAIL



D3DRENDERSTATE_STENCILPASS


以及


D3DRENDERSTATE_STENCILZFAIL



Direct3D


定义了下列的


dwStencilCaps< /p>


旗标:



?



D3DSTENCILCAPS_DECR


表示有支持


D3DSTENCILOP_DECR


运算





?



D3DSTENCILCAPS_DECRSAT


表示有支持


D3DSTENCILOP_DECRSAT


运算





?



D3DSTENCILCAPS_INCR


表示有支持


D3DSTENCILOP_INCR


运算





?



D3DSTENCILCAPS_INCRSAT


表示有支持


D3DSTENCILOP_INCRSAT


运算





?



D3DSTENCILCAPS_INVERT


表示有支持


D3DSTENCILOP_INVERT


运算





?



D3DSTENCILCAPS_KEEP


表示有支持


D3D STENCILOP_KEEP


运算





?



D3DSTENCILCAPS_REPLACE


表示有支持


D3DSTENCILOP_REPLACE


运算





?



D3DSTENCILCAPS_ZERO


表示有支持


D3DSTENCILOP_ZERO


运算




< /p>


Direct3D


会用深度缓冲区数据来纪录屏蔽缓冲区信息。要 找出目标系统的硬件支持哪些深


度缓冲区及屏蔽缓冲区格式,可以呼叫

< br>IDirect3D7::EnumZBufferFormats


方法,宣告如


下:



HRESULT IDirect3D7::EnumZBufferFormats (





);


参数



riidDevice



lpEnumCallback



LpContext



说明



指向一个代表所要列举深度缓冲 区格式的全域唯一辨别码(


GUID


)的参照

< br>


指向


D3DenumPixelFormatsCal lback


函式的地址,


Direct3D

< br>会对每个支持的深


度缓冲区格式呼叫这个函式。



由应用程序所定义并传入回传函式的数据



REFCLSID riidDevice,


LPD3DENUMPIXELFORMATSCALLBACK lpEnumCallback,


LPVOID lpContext


如果这个方法成功就会传回


D3D_OK


。如果失败 就会传回以下四个值之一:



?



DDERR_INVALIDOBJECT




?



DDERR_INVALIDPARAMS




?



DDERR_NOZBUFFERHW




?



DDERR_OUTOFMEMORY




下列程序会找出系统提供哪些屏蔽缓冲区以及支持哪些运算, 然后建立一个屏蔽缓冲区。您


可以看到,这段程序代码注明屏蔽缓冲区支持是否大于


1


位。如果只支持


1


位屏蔽缓冲


区,某些屏蔽技术就得用不同的方法处理。



HRESULT CMyD3DApplication::CreateStencilBuffer()


{








{




}


else


{


//


最好使用上下限为


0/max



sat


运算,不过如果屏蔽位足够的话可

以用其它运算。




g_StencIncOp=(dwStencilCaps &D3DSTENCILCAPS_INCRSAT)?





}



m_ pddsRenderTarget->DeleteAttachedSurface(0,NULL); < /p>


//


由绘制目标取得


z

< br>缓冲区大小。



//


建立


z


缓冲区的绘图页描述。



DDSURFACEDESC2 ddsd;


D3DUtil_InitSurfaceDesc(ddsd);




D3DSTENCILOP_INCRSAT:D3DSTENCILOP_INCR;


D3DSTENCILOP_DECRSAT:D3DSTENCILOP_DECR;


g_StencDecOp=(dwStencilCaps &D3DSTENCILCAPS_DECRSAT)?


//


必须用


1


位屏蔽缓冲区。



g_bCanOnlyDoOneBitStencil=TRUE;


g_bCanOnlyDoOneBitStencil=FALSE;


DWORD dwStencilCaps =m_pDeviceInfo-


if((!(dwStencilCaps &D3DSTENCILCAPS_INCR)&&


!(dwStencilCaps &D3DSTENCILCAPS_INCRSAT))||


(!(dwStencilCaps &D3DSTENCILCAPS_DECR)&&


!(dwStencilCaps &D3DSTENCILCAPS_DECRSAT)))


>cilCaps;


m_pddsRenderTarget ->GetSurfaceDesc(&ddsd);


s =DDSD_WIDTH|DDSD_HEIGHT|DDSD_CAPS|


DDSD_PIXELFORMAT;


=DDSCAPS_ZBUFFER;


2 =0;


3 =0;


4 =0;


s =DDPF_ZBUFFER|DDPF_STENCILBUFFER;



if(m_pDeviceInfo->bHardware)



else




//


由格式列举动作取得适合的像素 格式。



m_pD3D->EnumZBufferForma ts((*m_pDeviceInfo->pDeviceGUID),



EnumZBufferFormatsCallback,


(VOID*)&xelFormat);



assert(cilBitDepth!=0);


g_bC anOnlyDoOneBitStencil=g_bCanOnlyDoOneBitStencil||



g_dwMaxStencilValue=(1<














//


建立并连接


z


缓冲区。



if(FAILED(m_pDD->Create Surface(&ddsd,&m_pddsDepthBuffer,


NULL)))


return E_FAIL;


if( FAILED(m_pddsRenderTarget->AddAttachedSurface(


return E_FAIL;







SetMenuStates();


//

在窗口大小改变的时候保持


g_bUseOneBitStencil


为被设定。



if(!g_bUseOneBitStencil)



g_bUseOneBitStencil=g_bCanOnlyDoOneBitSte ncil;





((1<










|=DDSCAPS_SYSTEMMEMORY;








|=DDSCAPS_VIDEOMEMORY;














构。




}



//


必须呼叫


SetRenderTarget()


来重建新连接


z


缓冲区所用的内部结


return m_pd3dDevice->S etRenderTarget(m_pddsRenderTarget,0L);


//------------------------------------------------ ----------------


---


//


名称:


EnumZBufferFormatsCallback


//


说明:回报合法


z


缓冲区像素格式的列举函式



//------------- -------------------------------------------------- -


---


static


HRESULT WINAPI EnumZBufferFormatsCallback(DDPIXELFORMAT*pddpf,


VOID*pddpfDesired)


{













}


if(NULL==pddpf||NULL==pddpfDesired)


return D3DENUMRET_CANCEL;


//


如果目前的像素格式符合需要


(DDPF_ZBUFFER


,可能也有



//DDPF_STENCI LBUFFER)


,复制格式并返回。这个函式并不挑剔,



//


它会接受第一个传回的合法格式。



if(pddpf->dwFlags ==((DDPIXELFORMAT*)pddpfDesired)->dwFlags)


{




}


return D3DENUMRET_OK;


memcpy (pddpfDesired,pddpf,sizeof(DDPIXELFORMAT));


return D3DENUMRET_CANCEL;








清除屏蔽缓冲区





您可以用


IDirect3DDevice7


接口的


Clear


方法同时清除绘制目标的色彩缓冲区、深度缓冲


区以及屏蔽缓冲区。下面 是


IDirect3DDevice7::Clear


方法的宣 告:



HRESULT IDirect3DDevice7::Clear(




DWORD dwCount,


LPD3DRECT lpRects,





);


DWORD dwFlags,


D3DVALUE dvZ,


DWORD dwStencil


参数



说明



dwCount



< br>lpRects


中的矩形数量。



一个


D3DRECT


结构的数组,数组中定义了要清除的矩形 区域。您可以把矩形设成


lpRects


绘制目标绘图页的大小来清除整个绘图页。这些矩形都是用对应于绘制目标绘图


页上 图点的画面坐标。坐标值会受检视



埠矩形的边界限制。



指示要清除哪个 绘图页的旗标。这个参数可以是下列旗标的组合,



不过至少要有


一个旗标:



D3DCLEAR_TARGET


把绘制目标绘图页清成< /p>


dwColor


参数中的颜色。



D3DCLEAR_STENCIL


把屏蔽缓冲区清成


dwStencil


参数中的值。



D3DCLEAR_ZBUFFER


把深度缓冲区清成


dvZ


参数的值。



dwColor



用来清除绘制目标绘 图页的


32



RGBA


色彩值。



dvZ



由这个方法存到深度缓冲区的新


z


值。参数值由


0.0



1.0



0.0


表示离观察者最近


的距离。


1.0


表示最远的距离。


< p>
储存在各个屏蔽缓冲区内容的整数值。这个参数的范围为


0



2



n

次方


-1


,其中


n


是屏蔽缓冲区的位深度。



dwFlags



dwStencil



IDirect 3DDevice7::Clear


方法还是能接受以前的


D3 DCLEAR_TARGET


旗标,意思是用


dwColor< /p>


参数提供的


RGBA


色彩清除绘制目标。 这个方法也还能接受


D3DCLEAR_ZBUFFER


旗标, 意思是把深度缓冲区清除成在


dvZ


(其中

0.0


表示最近的距


离而


1.0< /p>


表示最远的距离)所设定的深度。


DirectX 6

< p>
引入了


D3DCLEAR_STENCIL


旗标,


作用是用


dwStencil


参数所指 定的值重设屏蔽位。这个值的范围是


0



2



n


次方


-1


,其中


n


是屏蔽缓冲区的位深度。



设定屏蔽状态





您用


ID irect3DDevice7::SetRenderState


方法来控制屏蔽缓冲 区的各种设定。下面是与屏蔽


相关的


D3DRENDERSTA TETYPE


列举类型成员:



typedef enum _D3DRENDERSTATETYPE{



















.


.


.











D3DRENDERSTATE_STENCILREF


D3DRENDERSTATE_STENCILMASK




=57,//


屏蔽测试的参考值



=58,//


屏蔽测试所用的屏


=59,/ /


屏蔽缓冲区写入的


.


.


.



D3DRENDERSTATE_STENCILFAIL


D3DRENDERSTATE_STENCILPASS


D3DRENDERSTATE_STENCILFUNC





=53,//


屏蔽运算



=54,//


屏蔽运算



=55,//


屏蔽运算



=56,//


屏蔽比较函式



D3DRENDERSTATE_STENCILZFAIL












D3DRENDERSTATE_STENCILENABLE



=52,//


启动或关闭屏蔽





mask




D3DRENDERSTATE_STENCILWRITEMASK


屏蔽


mask





} D3DRENDERSTATETYPE;


下面是与屏蔽相关的绘制状态定义:



?



D3DRENDERSTATE_STENCILENABLE


用这个成员来启动或关 闭屏蔽。要启动屏


蔽时把这个成员设成


TRUE


,要关闭时则设成


FALSE


。默认值为


FALSE






?



D3DRENDERSTATE_STENCILFAIL


用这个成员来指定当屏蔽测 试失败时所做的屏


蔽测试。屏蔽运算可以是


D3DSTENCI LOP


列举类型的任一个成员。默认值是


D3DSTENCIL OP_KEEP






?



D3DRENDERSTATE_STENCILZFAIL


用这个成员来指定当屏蔽 测试通过而深度测


试(


z


测试)失败时 所作的屏蔽运算。这个运算可以是


D3DSTENCILOP


列 举类型


的任一个成员。默认值为


D3DSTENCILOP_K EEP






?



D3DRENDERSTATE_STENCILPASS


用这个成员来指定当屏蔽测 试和深度测试(


z


测试)都通过时所作的屏蔽运算。这个运算可 以是


D3DSTENCILOP


列举类型的任

< br>一个成员。默认值为


D3DSTENCILOP_KEEP






?



D3DRENDERSTATE_STENCILFUNC


用这个成员来指定屏蔽测试 所用的比较函


式。这个比较函式可以是


D3DCMPFUNC< /p>


列举类型的任一个成员。默认值是


D3DCMP_ALWAYS< /p>


。这个函式会把参考值和屏蔽板所设的屏蔽缓冲区值相比较。


(< /p>


D3DRENDERSTATE_STENCILMASK


绘制状 态会设成屏蔽板)如果比较结果为


真,屏蔽测试就通过。





?



D3DRENDERSTATE_STENCILREF


用 这个成员来指定屏蔽测试所用的整数参考


值。默认值为


0






?



D3DRENDERSTATE_STENCILMASK


用这个成员来指定套用在参 考值及各个屏蔽


缓冲区内容以决定屏蔽测试重要位的屏蔽值。预设屏蔽板为



FFFFFFFF






?



D3DRENDERSTATE_STENCILWRITEMASK


用这个成员来指定作用在写入屏蔽缓


冲区值的屏蔽值。默认值为



FFFFFFFF






D3DSTENCILOP


列举类型叙述


D3DRENDERSTATE_STENCILFAI L



D3DRENDERSTATE_STENCILZFAI L


以及


D3DRENDERSTATE_STENCILPAS S


绘制状


态所用的屏蔽运算。下面是


D 3DSTENCILOP


的定义:



typedef enum _D3DSTENCILOP {











D3DSTENCILOP_KEEP


D3DSTENCILOP_ZERO






=3,


=4,


=5,


=6,




=7,


=8,


=1,


=2,


D3DSTENCILOP_REPLACE



D3DSTENCILOP_INCRSAT



D3DSTENCILOP_DECRSAT



D3DSTENCILOP_INVERT



D3DSTENCILOP_INCR


D3DSTENCILOP_DECR




D3DSTENCILOP_FORCE_DWORD


=0x7fffffff


}D3DSTENCILOP;


这些成员的目的如下:



?



D3DSTENCILOP_KEEP


表示您不想更新屏蔽缓冲区中的数据。这是预设的运算。




-


-


-


-


-


-


-


-



本文更新与2021-03-01 02:09,由作者提供,不代表本网站立场,转载请注明出处:https://www.bjmy2z.cn/gaokao/685175.html

12.屏蔽缓冲区的相关文章

  • 爱心与尊严的高中作文题库

    1.关于爱心和尊严的作文八百字 我们不必怀疑富翁的捐助,毕竟普施爱心,善莫大焉,它是一 种美;我们也不必指责苛求受捐者的冷漠的拒绝,因为人总是有尊 严的,这也是一种美。

    小学作文
  • 爱心与尊严高中作文题库

    1.关于爱心和尊严的作文八百字 我们不必怀疑富翁的捐助,毕竟普施爱心,善莫大焉,它是一 种美;我们也不必指责苛求受捐者的冷漠的拒绝,因为人总是有尊 严的,这也是一种美。

    小学作文
  • 爱心与尊重的作文题库

    1.作文关爱与尊重议论文 如果说没有爱就没有教育的话,那么离开了尊重同样也谈不上教育。 因为每一位孩子都渴望得到他人的尊重,尤其是教师的尊重。可是在现实生活中,不时会有

    小学作文
  • 爱心责任100字作文题库

    1.有关爱心,坚持,责任的作文题库各三个 一则150字左右 (要事例) “胜不骄,败不馁”这句话我常听外婆说起。 这句名言的意思是说胜利了抄不骄傲,失败了不气馁。我真正体会到它

    小学作文
  • 爱心责任心的作文题库

    1.有关爱心,坚持,责任的作文题库各三个 一则150字左右 (要事例) “胜不骄,败不馁”这句话我常听外婆说起。 这句名言的意思是说胜利了抄不骄傲,失败了不气馁。我真正体会到它

    小学作文
  • 爱心责任作文题库

    1.有关爱心,坚持,责任的作文题库各三个 一则150字左右 (要事例) “胜不骄,败不馁”这句话我常听外婆说起。 这句名言的意思是说胜利了抄不骄傲,失败了不气馁。我真正体会到它

    小学作文