Direct3D应用中的2D应用_第1页
Direct3D应用中的2D应用_第2页
Direct3D应用中的2D应用_第3页
已阅读5页,还剩32页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、Direct3D应用中的2D应用2DApplication收藏(转载)2DApplication这一章将讨论IDirect3DDevices9接口怎样应用到简单的两维应用程序里去。然而,接下来讨论的方法和接口的方法不仅仅只应用在两维应用程序里面。开始我们将看看IDirect3DSurface9接口,它用于存放像素数据。我们将看看怎样创建surfaces,怎样填充数据,并且执行像素拷贝操作。接下来,我们讨论IDirect3DSwapChain9接口管理backbuffer集合。设备创建的时候都会携带一个默认的swapchain,但是也可以为window模式下多个视图创建新的swapchain。再

2、接下来,我们将讨论Presentation,Present也是IDirect3DDevice9提供的方法。即使Direct3D可以不使用GDI,但是他们也要处理发送到应用程序top-level窗口的消息。我们推荐使用Direct3D应用程序来处理窗口消息。DirectX并没有提供直接方法来将GDI和Direct3D结合起来。但是,通常是在内存DC和流水线产生的结果像素数据上执行GDI操作。最后,我们将讨论流水线的Videoscanout部分以及swapchain从backbuffer至1Jfrontback的过程。videoscanout电流读取数据,使用cursoroverlay,gamma

3、校正以及像素数据转化成monitor的模拟信号。PixelSurfacePixel面是像素数据的矩形集合。像素数据的内存layout是通过D3DFORMAT定义的。在设备上使用surface有几处地方:backbuffersurfaces,depth/stencilbuffersurfaces,纹理层surface,rendertargetsurface以及图片surface。Direct3D使用IDirect3DSurface9接口表示一个surface,CreateOffscreenPlainsurface方法可以创建一个图片surface,它能存在于scrath内存池,系统内存池和设备内

4、存池。CreateDepthStencilSurface和CreateRenderTarget分另U返回depth/stencil的surface和rendertarget的surface。一个plainsurface可能不是3D渲染的目标,但是你能在plainsurface和其他surface之间进行数据拷贝。HRESULTCreateOffscreenPlainSurface(UINTwidth,UINTheight,D3DFORMATformat,D3DPOOLpool,IDirect3DSurface9*result,HANDLE*unused);如果设备不支持被请求面的各式,Crea

5、teOffscreenPlainSurface将会失败,或者是系统内存里面没有足够的存储空间。使用CheckDeviceFormat可以用来预先检查设备是否支持某种格式的surface。interfaceIDirect3DSurface9:IDirect3DResource9(HRESULTGetContainer(REFIIDcontainer_iid,void*value);HRESULTGetDC(HDC*value);HRESULTGetDesc(D3DSURFACE_DESC*value);HRESULTLockRect(D3DLOCKED_RECT*data,constRECT*l

6、ocked_region,DWORDflags);HRESULTRelease(HDCcontext);HRESULTUnlockRect();对于CreateOffscreenPlainSurface创建的surface,当container_iid是IID_Direct3DDevice9时,GetContainer将返回成功。GetDESC将返回D3DSURFACE_DESC结构体里面的像素数据的描述信息。typedefstruct_D3DSURFACE_DESC(D3DFORMATFormat;D3DRESOURCETYPEType;DWORDUsage;D3DPOOLPool;D3DM

7、ULTISAMPLE_TYPEMultiSampleType;/与rendertargetsurface一起使用的multisamplingDWORDMultiSampleQuality;UINTWidth;UINTHeight;D3DSURFACE_DESC;AccessingSurfacePixelData为了获取surface的像素数据,我们需要使用LockRect和UnlockRect方法。当lockRect方法的locked_region不为NULL的时候,就只lock住了surface的某个局部。参数flags告诉Direct3D一旦surface被锁住,数据将怎么办。Flags包

8、括D3DLOCK_DISCARD,D3DLOCK_DONOTWAIT,D3DLOCK_NO_DIRTY_UPDATE,D3DLOCK_NOSYSLOCK,D3DLOCK_READONLY。D3DLOCK_DISCARD通知runtime整个locked区域将只被写入而不读取。使用discardflag,runtime不会提供一份surface数据的copy给应用程序读取。不使用discardflag,runtime可能被迫停掉所有未决的操作,然后再返回一个surface数据的copy给应用程序。注意:这个flag不能使用在子区域。D3DLOCK_DONOTWAIT决定当lock的时候不会阻塞住

9、runtime,等待未决的渲染操作完成。如果lock调用已经阻塞了,它将返回D3DERR_WASSTILLDRAWING。Direct3D为每个可管理的surface(注意这里只能是managedsurface)维护一个dirty区域表,用来最小化unlock数据的拷贝虽。如果已经是使用了D3D_NO_DIRTY_UPDATE,locked区域"务不会影响dirty区域listo使用D3DLOCK_READONLY,应用程序保证对锁定区域没有任何的写操作。D3DLOCK_NOSYSLOCK只只能应用到videomemory的surfaces。为了阻止video存储资源被锁时设备los

10、t,Direct3D获取系统criticalsection来阻止设备丢失。它也能阻塞操作系统的其他部分执行,这样势必会影响系统的交互和反应灵敏度。D3DLOCK_NOSYSLOCK禁止获取系统的criticalsectionoLockRect方法返回D3DLOCKED_RECT结构体,它定义了surface的像素数据。它保证了surface数据在sanline上是连续的。typedefstruct_D3DLOCKED_RECTintpitch;定义了相邻两个scanlines的距离。void*pBits;/像素数据的指针。D3DLOCKED_RECT;当遍历surface的每个像素时,pitc

11、h和像素的大小是很重要的。像素数据的大小是跟D3DFORMAT有关。IDirect3DSurface9并没有提供方法用于从图片装载到surface,或者像素格式转换,D3DX却提供了很多这样的操作方法。UsingGDIOnaSurfaceGDI提供GetDC和ReleaseDC方法来操作与GDI兼容格式的surface。与GDI兼容格式包括D3DFMT_R5G6B5,D3DFMT_X1R5G5B5,D3DFMT_R8G8B8和D3DFMT_X8R8G8B8。GDIdevicecontext可以使用GDI执行基于surface的渲染操作,然后立刻释放。一旦devicecontext被创建,就会在

12、Direct3Druntime里面建立一个lock。这个lock保证runtime并不直接跟GDIrendering交互。因为这个lock的存在,应用程序应该尽可能快的释放GDIdevicecontext。而且,只有devicecontext释放以后,下面表里的方法才能调用。InterfaceMethodIDirect3DCubeTexture9LockRectIDirect3DDevice9ColorFillPresentStretchRectUpdateSurfaceUpdateTextureIDirect3DSurface9LockRectIDirect3DSwapChain9Prese

13、ntIDirect3DTexture9LockRectSwapChain每个设备都包含一组默认的swapchainsGetNumberOfSwapChains返回设备swapchains的数目。GetSwapChain方法返回默认swapchain集合里的swapchain的接口。默认swapchain集合的属性定义在D3DPRESENT_PARAMETERS。Swapchain由1个,2个,3个backbuffersurface和一个frontbuffersurface。frontbuffersurface不能直接访问,但是它仍然参与到swapchain的presentation过程中。当调

14、用Present时backbuffersurface显示在monitoroexclusive模式的设备使用它默认的backbufferowindow模式的设备可以使用多个swapchain,每个都可以将渲染结果绘制它自己的窗口。exclusive模式的adaptergroup设备也可以渲染到多个monitoroCreateAdditionalSwapChain创建一个基于D3DPRESENT_PARAMETERS的swapchain,然后返回一个IDirect3DSwapChain9接口。注意一个Swapchain只能包含backbuffersurface而不是depth/stencilsur

15、face。HRESULTCreateAdditionalSwapChain(D3DPRESENT_PARAMETERS*params,IDirect3DSwapChain9*result);interfaceIDirect3DSwapChain9:IUnknownHRESULTGetBackBuffer(UINTbuffer,D3DBACKBUFFER_TYPEkind,IDirect3DSurface9*value);HRESULTGetDevice(IDirect3DDevice9*value);HRESULTGetDisplayMode(D3DDISPLAYMODE*value);HRE

16、SULTGetFrontBufferData(IDirect3DSurface9*destination);HRESULTGetPresentParameters(D3DPRESENT_PARAMETERS*value);HRESULTGetRasterStatus(D3DRASTER_STATUS*value);HRESULTPresent(CONSTRECT*source,CONSTRECT*destination,HWNDoverride,CONSTRGNDATA*dirty_region,DWORDflags);GetBackBuffer返回一个backbuffersurface的接口

17、指针。backbuffer序号以0开始,present首先显示是backbuffer0里面的内容,然后再是backbuffer1,依此下去.。D3DBACKBUFFER_TYPE定义了backbuffer的类型。DirecX9.0c并不支持stereo渲染,kind只能是D3DBACKBUFFERTYPE_MONO.typedefenum_D3DBACKBUFFER_TYPED3DBACKBUFFER_TYPE_MONO=0,D3DBACKBUFFER_TYPE_LEFT=1,D3DBACKBUFFER_TYPE_RIGHT=2D3DBACKBUFFER_TYPE;Present跟device

18、的Present方法一样,都执行同样的功能。flag的值包括D3DPRESENT_DONOTWAIT和D3DPRESENT_LINEAR_CONTENT。D3DPRESENT_DONOTWAIT表示如果presentation引起应用程序阻塞,它将立刻返回D3DERR_WASSTILLDRAWING。D3DPRESENT_LINEAR_CONTENT告诉设备presentation时源区域像素应该从线性颜色空间转化到sRGB颜色空间。Presentation当调用了Present后,backbuffer的内容将会被复制到frontbuffer,videoscanout电流读取frontbuff

19、er的像素把他们显示在monitor上。如果D3DCAPS9:DevCaps的D3DDEVCAPS_CANRENDERAFTERFLIP被设置,present发生以后设备将继续queue渲染命令,也就是在设备与CPU之间有更多的并发,当前帧渲染的时候,下一帧已经queue。但是一个设备queue的帧数最多不能超过两帧。#defineD3DDEVCAPS_CANRENDERAFTERFLIP0X000000800LHRESULTPresent(constRECT*source_rect,constRECT*dest_rect,HWNDoverride_window,constRGNDATA*di

20、rty_region);Present对Swapchain的行为使用D3DPRESENT_PARAMETERS的SwapEffect定义的typedefenum_D3DSWAPEFFECT(D3DSWAPEFFECT_DISCARD=1,D3DSWAPEFFECT_FLIP=2,D3DSWAPEFFECT_COPY=3D3DSWAPEFFECT;在window模式下面,所有的swapeffec都是通过拷贝操作实现的。使用最近时间间隔创建的swapchain并不能让monitor的垂直扫描与拷贝操作同步。拷贝操作运行在在Videoscanout过程中,这样导致了artifacts,也称作图像te

21、aringo为了避免这种artifacts,我们需要同步videoscanout与拷贝操作,以便于当videobeam还停留在拷贝操作的目的地时,不能有拷贝操作发生。如果显卡并不支持videobeam位置信息,拷贝操作将会立刻发生。在exclusive模式下,presentation的频率是由D3DPRESENT_PARAMETERS的FullScreen_PresentationInterval指定的。默认的presentationinverval对应adapter视频模式的刷新率。如果dest_window不是空,dest_window客户端区域就是present的Target。如果des

22、t_window空而D3DPRESENT_PARAMETERS的hDeviceWindow不空,贝UhDeviceWindow就是present的Target。如果两者都空,CreateDevice的focus_window参数将是present的target。source和dest只能应用到拷贝操作方式,Flip和Discard这两个参数必须是空。空值表示整个sourcesurface和目的surfaceodirty_region也只能使用在拷贝操作下。LostDevicesandResetTestCooperativelevel检查设备的状态,Reset重启设备。HRESULTReset(

23、D3DPRESENT_PARAMETERS*params);HRESULTTestCooperativeLevel();VideoScanoutfrontbuffer的内容来自于Present。GetDisplayMode返回了当前frontbuffer的显示模式。应用程序不能直接访问frontbuffer,但是可以通过GetFrontBufferData返回一份frontbuffer的拷贝。GetFrontBufferData的destination参数必须是一个存在的surface,它的维度等于adapter当前显示模式,并且像素格式是D3DFMT_A8R8G8B8。在拷贝过程中数据将从a

24、dapter的显示模式格式转化成surface格式。HRESULTGetDisplayMode(D3DDISPLAYMODE*value);HRESULTGetFrontBufferData(IDirect3DSurface*destination);如果D3DCAPS:Caps的D3DCAPS_READ_SCANLINE位被设置,设备将它的videoscanoutscanline和垂直blank状态。GetRasterStatus将使用D3DRASTER_STATUS结构体返回videoscanout状态。scanline成员指定了raterbeam的当前位置,0是最顶端的scanline。

25、如果是自下而上的垂直扫描,InVBlank成员将为TRUE。HRESULTGetRasterStatus(D3DRASTER_STATUS*value);typedefstruct_D3DRASTER_STATUS(BOOLInVBlank;UINTScanline;D3DRASTER_STATUS;Cursor在exclusive模式下,Direct3D管理着cursor的显示。在videoscanout的过程中硕件Cursor可能会取代cursor图像。如果硕件cursor不可用,runtime会提供一个软件cursor对frontbuffer读,修改,写操作。在window模式下,应用程

26、序可能会使用GDIcursor或者Direct3DcursoroDirect3Dcursor能通过方法ShowCursor显示或者隐藏cursor。ShowCursor并不返回HRESULT,而是cursor的上一个隐藏状态。如果它是TRUE,cursor在调用ShowCursor之前是可见的。BOOLShowCursor(BOOLShow);voidSetCursorPosition(UINTx,UINTy,DWORDflags);HRESULTSetCursorProperties(UINThot_spot_x,UINThot_spot_y,IDirect3DSurface9*image)

27、;cursor的位置是通过SetCursorPosition设定的,flags参GammaRamp在exclusive模式下,应用cursor以后,在进行A/D转换之前将会对像素数据应用Gamma校正。在窗口模式下,应用程序也能使用GDI来做Gamma校正。如果D3DCAPS9:Caps的D3DCAPS2_FULLSCREENGAMMA设置,设备将会支持exclusive的GammaRamp。GetGammaRamp能读取GammaRamp的属性,它返回一个GammaRamp的结构体。voidGetGammaRamp(D3DGAMMARAMP*value);voidSetGammaRamp(D

28、WORDFlags,constD3DGAMMARAMP*value);typedefstruct_D3DGAMMARAMP(WORDred256;WORDgreen256;WORDblue256;D3DGAMARAMP;Gammaramp属性通过SetGammaRamp进行设置,并且它能够立刻产生反应。Flags参数表示设备是否使用ramp的calibration,它包括D3DSGR_NO_CALIBRATION和D3DSGR_CALIBRATE。如果D3DCAPS9:Caps2的D3DCAPS2_CANCALIBRATEGAMMA位设置,设备将能够给GammaRamp指定一个calibrat

29、ion。下面例子显示了怎样计算rampvalues。voidcompute_ramp(D3DGAMARAMP&ramp,floatgamma)for(UINTi=0;i<256;i+)constWORDval=static_cast<int>(65535*pow(i/255.f,1.f/gamma);ramp.redi=val;ramp.greeni=val;ramp.bluei=val;2DPixelCopies如果我们申请可锁住的backbuffer,我们能锁住backbuffer的矩形区域,然后使用软件直接对它读写操作。然而,ba

30、ckbuffersurface是videomemory的设备surface。通过CPU访问videomemory将是一个昂贵的操作,我们应该避免。但是存放系统内存池或者scratch内存池的图像surface能轻松的被CPU访问。拷贝像素操作一般包括:设备内存到设备内存,系统内存到设备内存,设备内存到系统内存。StetchRect能有效的进行设备内存之前的拷贝。UpdateSurface和UpdateTexture一般都是将数据从系统内存转移到设备内存里面。GetRenderTargetData用于从设备内存将像素数据转移到系统内存。当你想要在设备资源直接拷贝数据时,你可以使用StretchR

31、ect。当你需要更新默认内存池的某个资源(如图像surface或者纹理资源),你可以使用UpdateSurface和updateTexture,不过managed池里的资源会自动更新,当它的系统内存的数据变化时,它会自动更新到设备内存里面去)。PixelCopiesWithinDeviceMemoryStretchRect能够将一个矩形区域的像素从设备内存的一个surface转移到另一个上面去。这两个surface通常会是同样的D3DFORMAT。在拷贝过程中,StretchRect也能执行有限的几张颜色转换。HRESULTStretchRect(IDirect3DSurface9*sourc

32、e,constRECT*source_rect,IDirect3DSurface9*destination,constRECT*dest_rect,D3DTEXTUREFILTERTYPEfilter);当source_rect非空,整个source面将会拷贝到目的surfaceo当source_rect非空,它指向source面的一个子区域。dest_rect也是一样。当需要调整源像素区域大小来适应目的像素区域的时候,filter参数将指定调整的方式,它的值包括D3DTEXF_NONE,D3DTEXF_POINT,D3DTEXF_LINEAR。当缩小和放大源像素区域的时候,point和lin

33、ear的过滤将会支持。D3DCAPS9结构的StretchRectFilterCaps各个位标记描述了StretchRect的过滤支持情况#defineD3DPTFILTERRCAPS_MAGFLINEAR0X02000000L#defineD3DPTFILTERCAPS_MAGFPOINT0X01000000L#defineD3DPTFILTERCAPS_MINFLINEAR0X00000200L#defineD3DPTFILTERCAPS_MINFPOINT0X00000100L如果D3DCAPS9:DevCaps的D3DDEVCAPS_CANBLTSYSTONONLOCAL设置,Stre

34、tchRect能支持从系统内存到non-local视频存储(如AGP内存)转移数据。设备像素拷贝的格式转换StretchRect也能支持拷贝过程中的颜色转换操作。支持的转换可以是高性能的YUVsurface格式到高性能的RGBsurface格式。具体支持什么样的格式转换,你可以通过CheckDeviceFormatConversion方法来查看。HRESULTCheckDeviceFormatConversion(UINTadapter,D3DDEVTYPEdevice_kind,D3DFORMATsource_fmt,D3DFORMATtarget_fmt);source_fmt可能是FOU

35、RCC格式也可能是合理的backbuffer格式。Target格式将是下面中的一种:D3DFMT_A1R5G5B5,D3DFMT_A8R8G8B8,D3DFMT_A16B16G16R16,D3DFMT_X1R5G5B5,D3DFMT_A8R8G8B8,D3DFMT_A16B16G16R16,D3DFMT_R5G6B5,D3DFMT_X8B8G8R8,D3DFMT_A32B32G32R32F,D3DFMT_R8G8B8,D3DFMT_X8R8G8B8,D3DFMT_A2R10G10B10,D3DFMT_A2B10G10R10。设备像素拷贝限制:因为StretchRect直接工作在设备内存上,它将

36、面临很多限制。restrictions:1.source和destination不能是相同的surface。2.不能从rendertargetsurface至Voffscreensurfaceo3.不能基于压缩格式stretch。D3DDEVCAPS2_CAN_STRETCH_RECT_FROM_TEXTURES,如果source是纹理surfaceodepth/stencilrestrictions:1.不能是纹理,2.不能discardable;3.必须是整个surface拷贝;4.source和destination必须是同样的尺寸。不支持filtering。6.不能从一个场景里面被调用

37、。downsamplingmultisamplerendertarget:1.创建multisamplerendertarget;2.创建同样大小的non-multismapledrendertarget;3.从non-MSRT拷贝到MSRT。如下是source和destination的结合情况:DX8DrivernostretchingSourceDestinationTextureRTTextureOff-screenPlainTextureNONONONORTTextureNOYesYesNOYesYesNoOff-screenPlainYesYesYesYesDX8Drivernost

38、retchingTextureRTTextureRTOff-screenPlainTextureNoNoRTTextureNoNoNoNoRTYesNoOff-screenPlainNoYesYesNoDX9DrivernostretchingTextureRTTextureRTOff-screenPlainTextureNoYesYesRTTextureNoYesYesNoRTNoYesYesNoOff-screenPlainYesYesYesDX9DriverstretchingTextureRTTextureRTOff-screenPlainTextureNoYesYesNoRTText

39、ureYesNoRTNoYesYesNoOff-screenPlainNoYesCopiesFromSystemMemoryToDeviceMemory通常你lock一个surface,然后直接使用CPU为它填充数据。但是并且每个surface都是lockable。设备内存里面的surface通常是不经常lock的,因为lock住以后访问速度是非常慢的。所以我们通常的办法是先使用CPUupdate系统内存的surface,然后使用updateSurface或者UpdateTexture将他们传给设备内存。HRESULTUpdateSurface(IDirect3DSurface9*source

40、,constRECT*source_rect,IDirect3DSurface9*destination,CONSTPOINT*offset);offset参数指定了目的区域对应source区域左上角像素的位置偏移。如果source或者destination的surface用于multisampling或者depth/stencil,UpdateSurface也将失败。如下表是updateSurface的source和destinationa的结合情况。SourceDestinationTextureRTTextureRTOff-screenPlainTextureYESYESYESYESRTTextureNONONONoRTNONONOOff-screenPlainYesYesYesYesUpdateTexture与UpdateSurface相似,但是它对于整个纹理资源而不是单个surface。runtime将维护一个dirty区域。HRESULTUpdateTexture(IDirect3DBaseTexture9*source,IDirect3DBaseTexture9*destination);当UpdateTexture被调用,所有累计的dirty区域将会值为leve

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论