欢迎来到天天文库
浏览记录
ID:25779837
大小:53.50 KB
页数:3页
时间:2018-11-22
《第四章全屏幕模式和深度缓冲.doc》由会员上传分享,免费在线阅读,更多相关内容在行业资料-天天文库。
第四章:全屏幕模式和深度缓冲Introduction(序)在此章中,我们把以往单个的文件(Main.cpp)转换成了两个类:CGame和CCuboid。CGame包含了主要的代码,例如游戏的初始化和循环、渲染工作都有它来完成。CCuboid用来创建立方体对象:你可以指定位置与尺寸。CCuboid也包含一个渲染函数,将会在CGame的渲染函数中被调用。其实程序并没有作什么太大的改动,你会发现它会像以往一样容易理解。我们改动了程序使它成为了全屏幕的模式,这在某方面这要比窗口式的强多了;我们还会接触一下深度缓冲。从现在起,程序代码不会像以往一样全部放在教程中了(因为很长,放进来也不容易看);取而代之,我会只放进来一些有意义的代码片断,其实这样也好。DepthBuffers(深度缓冲)嗯,深度缓冲,听起来挺神秘的,是吧?但我要告诉你,这又是一个简单的概念。深度缓冲(又称Z-buffer)的作用是确保多边形能够正确地显示在它们本来的深度(相对于摄像机)上。例如在你的场景中有两个矩形:一个是蓝色的而另一个是绿色的;蓝色的Z值为10,绿色的Z值为20(摄像机在原点);这就意味着蓝色的在绿色的前面(看下面的图示)。深度缓冲能确定哪个对象在另一个对象的前面,正确的将被渲染。DirectX会测试对象在屏幕上的像素点到摄像机的远近,并把得出的值保存在深度缓冲中;接着,DirectX会测试同一位置另一对象的像素点,并和刚才的像素进行比较:如果更近,就刷新刚才的纪录,否则就不理睬(有东西在它前面挡着它)。这会决定此位置像素点的颜色到底是蓝色的还是绿色的。下面是图示:Fig4.1要在程序中使用深度缓冲是很简单的事情,所有要做的只有:在初始化D3D的函数中选择正确的格式、激活深度缓冲和确保在渲染函数中清空深度缓冲。在此章的源代码中,CGame的InitialiseD3D模块里,我增加了一些选择深度缓冲格式的源代码。D3DPRESENT_PARAMETERS结构中,有两个参数要设置:d3dpp.AutoDepthStencilFormat=D3DFMT_D16;d3dpp.EnableAutoDepthStencil=TRUE;要激活深度缓冲,需要在你的InitialiseD3D模块中增加此行代码:m_pD3DDevice->SetRenderState(D3DRS_ZENABLE,D3DZB_TRUE);然后确保在CGame的Render模块中增加了D3DCLEAR_ZBUFFER标识使设备清除函数(Clear)能正确地清空深度缓冲:m_pD3DDevice->Clear(0,NULL,D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,D3DCOLOR_XRGB(0,0,0),1.0f,0); FullScreen(全屏幕)要使用全屏幕模式,我们需要调整一下InitialiseD3D模块:把D3DPRESENT_PARAMETERS结构的“Windowed”参数设置为FALSE,通知D3D我们要使用全屏幕模式;然后,我们还需要设置D3DPRESENT_PARAMETERS结构中的两个全屏幕参数:FullScreen_RefreshRateInHz用于设置屏幕刷新率,FullScreen_PresentationInterval用于设置页翻动的最大速度,我们选择了D3DPRESENT_INTERVAL_ONE标识来限定仅当屏幕刷新时完成页翻动。译者注:上面的后几句是按照原意翻译的,但我想这样可能不太好懂,我要在此大概地说明一下:当电子束从上至下完成了屏幕上的每一行水平回扫后,会被暂时关闭,回到屏幕的左上角;此过程所需的时间被称为垂直回扫周期或屏幕空白周期。有时,程序能完成的刷新速率(页翻动速度)可能要比屏幕刷新率还高,所以我们要使它在限定的垂直回扫周期内完成刷新工作,否则将产生“图像撕裂”。原文上述的设定为至少等待一个垂直回扫周期(一次的屏幕刷新完成后)来完成页翻动操作。d3dpp.Windowed=FALSE;d3dpp.FullScreen_RefreshRateInHz=D3DPRESENT_RATE_DEFAULT;d3dpp.FullScreen_PresentationInterval=D3DPRESENT_INTERVAL_ONE;嗯,我们还应该选择正确的后缓冲区格式。我写了一个模块CheckDisplayMode用来测试正确的格式,此模块会在InitialiseD3D模块中被调用。D3DFORMATCGame::CheckDisplayMode(UINTnWidth,UINTnHeight,UINTnDepth){UINTx;D3DDISPLAYMODEd3ddm;for(x=0;xGetAdapterModeCount(0);x++){m_pD3D->EnumAdapterModes(0,x,&d3ddm);if(d3ddm.Width==nWidth){if(d3ddm.Height==nHeight){if((d3ddm.Format==D3DFMT_R5G6B5)||(d3ddm.Format==D3DFMT_X1R5G5B5)||(d3ddm.Format==D3DFMT_X4R4G4B4)){if(nDepth==16){returnd3ddm.Format;}}elseif((d3ddm.Format==D3DFMT_R8G8B8)||(d3ddm.Format==D3DFMT_X8R8G8B8)){if(nDepth==32){returnd3ddm.Format;}}}}}returnD3DFMT_UNKNOWN;}还有一件要做的事就是我们修改了WinMain函数中的创建窗口部分,我们用了GetSystemMetrics函数得到了当前屏幕的宽与高,然后将我们的窗口设置成了与屏幕一样大。 Logging(实时记录)我们的程序还有了写纪录的功能,这在调试时是很有用的。我为CGame添加了EnableLogging和WriteToLog模块,而且在WinMain刚刚完成CGame的初始化时就调用了EnableLogging,它会清理当前的纪录然后激活纪录功能。一旦记录功能被激活了,WriteToLog就能单纯地向记录文件中写记录了。当程序关闭后,记录工作就会完成。你要记住:程序的显示速率不会高于屏幕刷新率,那是因为我们设置了FullScreen_PresentationInterval为D3DPRESENT_INTERVAL_ONE。程序运行后记录文件会存在于你的程序目录中,名为“Log.txt”。运行程序会得到下面的画面:六个不同大小和位置的立方体,怎么样?Summary(摘要)老外说:Wehaven'treallyaddedalotofcodeinthistutorial,butwehavere-organiseditintoclasses.Takesometimetofamiliariseyourselfwiththenewstructure,you'llseethatmostofthefunctionsareunchanged.Fullscreenrenderinganddepthbuffersareprettystraightforward;nowthatwe'vecreatedthemwedon'treallyneedtoworryaboutthemanyfurther.Inthenexttutorialwewilllookintomatrixtransformations.Wetouchedontheminthelasttutorial,butthistimewewillgoalittlefurtheranddemonstratethepowerofmatrixtransformations.俺说:此章中,我们学习了全屏幕模式与深度缓冲,这是令人兴奋的。其实慢慢学来,一切并非想象的那样难。你认为呢?好了,又翻译了一章,还真有点累,去歇一会儿了先…..啊,对了,下一章我们要学的是:神奇的-------------------矩阵变换。(读者:切~拉长音卖关子)
此文档下载收益归作者所有
举报原因
联系方式
详细说明
内容无法转码请点击此处