ImageVerifierCode 换一换
格式:DOCX , 页数:16 ,大小:24.64KB ,
资源ID:6867948      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/6867948.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(Direct3D应用中的2D应用.docx)为本站会员(b****5)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

Direct3D应用中的2D应用.docx

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

2、w模式下多个视图创建新的swap chain。 再接下来,我们将讨论Presentation,Present 也是IDirect3DDevice9提供的方法。 即使Direct3D可以不使用GDI,但是他们也要处理发送到应用程序top-level窗口的消息。我们推荐使用Direct3D应用程序来处理窗口消息。DirectX 并没有提供直接方法来将GDI和Direct3D结合起来。但是,通常是在内存DC和流水线产生的结果像素数据上执行GDI操作。 最后,我们将讨论流水线的Video scan out部分以及swap chain从back buffer到front back 的过程。video s

3、can out 电流读取数据,使用cursor overlay,gamma校正以及像素数据转化成monitor的模拟信号。Pixel Surface Pixel 面是像素数据的矩形集合。像素数据的内存layout是通过D3DFORMAT定义的。在设备上使用surface有几处地方:back buffer surfaces, depth/stencil buffer surfaces,纹理层surface,render target surface 以及图片surface。Direct3D 使用IDirect3DSurface9接口表示一个surface,CreateOffscreenPlain

4、surface方法可以创建一个图片surface,它能存在于scrath内存池,系统内存池和设备内存池。CreateDepthStencilSurface和CreateRenderTarget分别返回depth/stencil的surface和rendertarget的surface。一个plain surface可能不是3D 渲染的目标,但是你能在plain surface和其他surface之间进行数据拷贝。 HRESULT CreateOffscreenPlainSurface(UINT width, UINT height, D3DFORMAT format, D3DPOOL pool

5、, IDirect3DSurface9 * result, HANDLE * unused);如果设备不支持被请求面的各式,CreateOffscreenPlainSurface将会失败,或者是系统内存里面没有足够的存储空间。使用CheckDeviceFormat可以用来预先检查设备是否支持某种格式的surface。interface IDirect3DSurface9 : IDirect3DResource9HRESULT GetContainer(REFIID container_iid, void * value);HRESULT GetDC(HDC *value);HRESULT Ge

6、tDesc(D3DSURFACE_DESC * value);HRESULT LockRect(D3DLOCKED_RECT *data, const RECT * locked_region,DWORD flags);HRESULT Release(HDC context);HRESULT UnlockRect(); 对于CreateOffscreenPlainSurface创建的surface,当container_iid是IID_Direct3DDevice9时,GetContainer将返回成功。GetDESC将返回D3DSURFACE_DESC结构体里面的像素数据的描述信息。type

7、def struct _D3DSURFACE_DESCD3DFORMAT Format;D3DRESOURCETYPE Type;DWORD Usage;D3DPOOL Pool;D3DMULTISAMPLE_TYPE MultiSampleType;/与render target surface一起使用的multisamplingDWORD MultiSampleQuality;UINT Width;UINT Height; D3DSURFACE_DESC;Accessing Surface Pixel Data 为了获取surface的像素数据,我们需要使用LockRect和UnlockR

8、ect方法。当lockRect方法的locked_region不为NULL的时候,就只lock住了surface的某个局部。参数flags告诉Direct3D一旦surface被锁住,数据将怎么办。Flags包括D3DLOCK_DISCARD, D3DLOCK_DONOTWAIT, D3DLOCK_NO_DIRTY_UPDATE,D3DLOCK_NOSYSLOCK, D3DLOCK_READONLY。 D3DLOCK_DISCARD通知runtime整个locked区域将只被写入而不读取。使用discard flag, runtime不会提供一份surface数据的copy给应用程序读取。不使

9、用discard flag,runtime可能被迫停掉所有未决的操作,然后再返回一个surface数据的copy给应用程序。注意:这个flag不能使用在子区域。 D3DLOCK_DONOTWAIT 决定当lock的时候不会阻塞住runtime,等待未决的渲染操作完成。如果lock调用已经阻塞了,它将返回D3DERR_WASSTILLDRAWING。 Direct3D为每个可管理的surface(注意这里只能是managed surface)维护一个dirty 区域表,用来最小化unlock数据的拷贝量。如果已经是使用了D3D_NO_DIRTY_UPDATE,locked区域将不会影响dirty

10、 区域list。 使用D3DLOCK_READONLY,应用程序保证对锁定区域没有任何的写操作。 D3DLOCK_NOSYSLOCK只只能应用到video memory的surfaces。为了阻止video存储资源被锁时设备lost,Direct3D获取系统critical section来阻止设备丢失。它也能阻塞操作系统的其他部分执行,这样势必会影响系统的交互和反应灵敏度。 D3DLOCK_NOSYSLOCK 禁止获取系统的critical section。 LockRect 方法返回D3DLOCKED_RECT结构体,它定义了surface的像素数据。它保证了surface数据在sanli

11、ne上是连续的。 typedef struct _D3DLOCKED_RECT int pitch; /定义了相邻两个scanlines的距离。 void *pBits; /像素数据的指针。D3DLOCKED_RECT; 当遍历surface的每个像素时,pitch 和像素的大小是很重要的。像素数据的大小是跟D3DFORMAT有关。IDirect3DSurface9并没有提供方法用于从图片装载到surface,或者像素格式转换,D3DX却提供了很多这样的操作方法。Using GDI On a SurfaceGDI提供GetDC和ReleaseDC方法来操作与GDI兼容格式的surface。与G

12、DI兼容格式包括D3DFMT_R5G6B5,D3DFMT_X1R5G5B5,D3DFMT_R8G8B8和D3DFMT_X8R8G8B8。GDI device context可以使用GDI执行基于surface的渲染操作,然后立刻释放。一旦device context被创建,就会在Direct3D runtime里面建立一个lock。 这个lock保证runtime并不直接跟GDI rendering交互。因为这个lock的存在,应用程序应该尽可能快的释放GDI device context。而且, 只有device context释放以后,下面表里的方法才能调用。InterfaceMethod

13、IDirect3DCubeTexture9LockRectIDirect3DDevice9ColorFillPresentStretchRectUpdateSurfaceUpdateTextureIDirect3DSurface9LockRectIDirect3DSwapChain9PresentIDirect3DTexture9LockRect Swap Chain 每个设备都包含一组默认的swap chains。GetNumberOfSwapChains返回设备swap chains的数目。GetSwapChain方法返回默认swap chain集合里的swap chain的接口。 默认s

14、wap chain集合的属性定义在D3DPRESENT_PARAMETERS。Swap chain由1个,2个,3个back buffer surface 和一个front buffer surface。front buffer surface不能直接访问,但是它仍然参与到swap chain的presentation过程中。 当调用Present时back buffer surface显示在monitor。 exclusive 模式的设备使用它默认的back buffer。window模式的设备可以使用多个swap chain,每个都可以将渲染结果绘制它自己的窗口。exclusive模式的a

15、dapter group 设备也可以渲染到多个monitor。 CreateAdditionalSwapChain创建一个基于D3DPRESENT_PARAMETERS的swap chain,然后返回一个IDirect3DSwapChain9接口。注意一个Swap chain只能包含back buffer surface而不是depth/stencil surface。 HRESULT CreateAdditionalSwapChain(D3DPRESENT_PARAMETERS * params, IDirect3DSwapChain9 * result);interface IDirect

16、3DSwapChain9 : IUnknown HRESULT GetBackBuffer(UINT buffer, D3DBACKBUFFER_TYPE kind, IDirect3DSurface9 * value); HRESULT GetDevice(IDirect3DDevice9 * value); HRESULT GetDisplayMode(D3DDISPLAYMODE * value); HRESULT GetFrontBufferData(IDirect3DSurface9 * destination); HRESULT GetPresentParameters(D3DPR

17、ESENT_PARAMETERS * value); HRESULT GetRasterStatus(D3DRASTER_STATUS * value); HRESULT Present(CONST RECT * source, CONST RECT * destination, HWND override, CONST RGNDATA * dirty_region, DWORD flags); GetBackBuffer返回一个back buffer surface的接口指针。back buffer序号以0开始,present首先显示是back buffer 0里面的内容,然后再是back

18、buffer 1, 依此下去.。 D3DBACKBUFFER_TYPE定义了back buffer的类型。DirecX 9.0c 并不支持stereo 渲染,kind只能是D3DBACKBUFFERTYPE_MONO.typedef enum _D3DBACKBUFFER_TYPE D3DBACKBUFFER_TYPE_MONO = 0, D3DBACKBUFFER_TYPE_LEFT = 1, D3DBACKBUFFER_TYPE_RIGHT = 2D3DBACKBUFFER_TYPE; Present跟device的Present方法一样,都执行同样的功能。flag的值包括D3DPRESE

19、NT_DONOTWAIT和D3DPRESENT_LINEAR_CONTENT。D3DPRESENT_DONOTWAIT表示如果presentation引起应用程序阻塞,它将立刻返回D3DERR_WASSTILLDRAWING。 D3DPRESENT_LINEAR_CONTENT 告诉设备presentation时源区域像素应该从线性颜色空间转化到sRGB颜色空间。Presentation 当调用了Present后,back buffer的内容将会被复制到front buffer,video scan out 电流读取front buffer的像素把他们显示在monitor上。如果D3DCAPS

20、9:DevCaps的D3DDEVCAPS_CANRENDERAFTERFLIP被设置,present发生以后设备将继续queue渲染命令,也就是在设备与CPU之间有更多的并发,当前帧渲染的时候,下一帧已经queue。但是一个设备queue的帧数最多不能超过两帧。 #define D3DDEVCAPS_CANRENDERAFTERFLIP 0x000000800L HRESULT Present(const RECT * source_rect, const RECT* dest_rect,HWND override_window, const RGNDATA * dirty_region);

21、Present对Swap chain的行为使用D3DPRESENT_PARAMETERS的SwapEffect定义的。 typedef enum _D3DSWAPEFFECT D3DSWAPEFFECT_DISCARD = 1, D3DSWAPEFFECT_FLIP = 2, D3DSWAPEFFECT_COPY = 3 D3DSWAPEFFECT; 在window模式下面,所有的swap effec都是通过拷贝操作实现的。使用最近时间间隔创建的swap chain并不能让monitor的垂直扫描与拷贝操作同步。拷贝操作运行在在Video scan out过程中,这样导致了artifacts,

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

23、ent的Target。如果dest_window空而D3DPRESENT_PARAMETERS的hDeviceWindow不空,则hDeviceWindow就是present的Target。 如果两者都空,CreateDevice的focus_window参数将是present的target。source和dest只能应用到拷贝操作方式,Flip 和Discard这两个参数必须是空。空值表示整个source surface 和目的surface。dirty_region也只能使用在拷贝操作下。Lost Devices and Reset TestCooperativelevel检查设备的状态,

24、Reset重启设备。HRESULT Reset(D3DPRESENT_PARAMETERS * params);HRESULT TestCooperativeLevel();Video Scan out front buffer的内容来自于Present。GetDisplayMode返回了当前front buffer的显示模式。应用程序不能直接访问front buffer,但是可以通过GetFrontBufferData返回一份front buffer的拷贝。GetFrontBufferData的destination参数必须是一个存在的surface,它的维度等于adapter当前显示模式,

25、并且像素格式是D3DFMT_A8R8G8B8。在拷贝过程中数据将从adapter的显示模式格式转化成surface格式。 HRESULT GetDisplayMode(D3DDISPLAYMODE * value); HRESULT GetFrontBufferData(IDirect3DSurface* destination); 如果D3DCAPS:Caps的D3DCAPS_READ_SCANLINE位被设置,设备将它的video scan out scanline和垂直blank状态。 GetRasterStatus将使用D3DRASTER_STATUS结构体返回video scan o

26、ut 状态。scanline 成员指定了rater beam的当前位置,0是最顶端的scanline。如果是自下而上的垂直扫描,InVBlank成员将为TRUE。 HRESULT GetRasterStatus(D3DRASTER_STATUS * value); typedef struct _D3DRASTER_STATUS BOOLInVBlank; UINT Scanline; D3DRASTER_STATUS; Cursor 在exclusive模式下,Direct3D管理着cursor的显示。在video scan out的过程中硬件Cursor可能会取代cursor图像。如果硬件

27、cursor不可用,runtime会提供一个软件cursor对front buffer读,修改,写操作。在window模式下,应用程序可能会使用GDI cursor 或者Direct3D cursor。Direct3D cursor 能通过方法ShowCursor显示或者隐藏cursor。ShowCursor并不返回HRESULT,而是cursor的上一个隐藏状态。如果它是TRUE,cursor在调用ShowCursor之前是可见的。 BOOLShowCursor(BOOL Show); void SetCursorPosition(UINT x, UINT y, DWORD flags);

28、HRESULT SetCursorProperties(UINT hot_spot_x, UINT hot_spot_y, IDirect3DSurface9 * image); cursor的位置是通过SetCursorPosition设定的,flags参数 Gamma Ramp 在exclusive模式下,应用cursor以后, 在进行A/D转换之前将会对像素数据应用Gamma校正。在窗口模式下,应用程序也能使用GDI来做Gamma校正。如果D3DCAPS9:Caps的D3DCAPS2_FULLSCREENGAMMA设置,设备将会支持exclusive的Gamma Ramp。 GetGam

29、maRamp能读取Gamma Ramp的属性,它返回一个Gamma Ramp的结构体。void GetGammaRamp(D3DGAMMARAMP * value);void SetGammaRamp(DWORD Flags, const D3DGAMMARAMP * value);typedef struct _D3DGAMMARAMP WORD red256; WORD green256; WORD blue256; D3DGAMARAMP; Gamma ramp属性通过SetGammaRamp进行设置,并且它能够立刻产生反应。Flags参数表示设备是否使用ramp的calibration

30、,它包括D3DSGR_NO_CALIBRATION和D3DSGR_CALIBRATE。 如果D3DCAPS9:Caps2的D3DCAPS2_CANCALIBRATEGAMMA位设置,设备将能够给Gamma Ramp指定一个calibration。 下面例子显示了怎样计算ramp values。void compute_ramp(D3DGAMARAMP & ramp, float gamma) for (UINT i = 0;i< 256;i+) const WORD val = static_cast<int> (65535 * pow(i/255.f, 1.f/ga

31、mma); ramp.redi = val; ramp.greeni = val; ramp.bluei = val; 2D Pixel Copies 如果我们申请可锁住的back buffer,我们能锁住back buffer的矩形区域,然后使用软件直接对它读写操作。然而,back buffer surface是video memory的设备surface。通过CPU访问video memory将是一个昂贵的操作,我们应该避免。 但是存放系统内存池或者scratch内存池的图像surface能轻松的被CPU访问。 拷贝像素操作一般包括:设备内存到设备内存, 系统内存到设备内存,设备内存到系统

32、内存。StetchRect 能有效的进行设备内存之前的拷贝。UpdateSurface和UpdateTexture一般都是将数据从系统内存转移到设备内存里面。GetRenderTargetData用于从设备内存将像素数据转移到系统内存。 当你想要在设备资源直接拷贝数据时,你可以使用StretchRect。当你需要更新默认内存池的某个资源(如图像surface或者纹理资源),你可以使用UpdateSurface和updateTexture,不过managed池里的资源会自动更新,当它的系统内存的数据变化时,它会自动更新到设备内存里面去)。 Pixel Copies Within Device Memory StretchRect能够将一个矩形区域的像素从设备内存的一个surface转移到另一个上面去。这两个surface通常会是同样的D3DFORMAT。在拷贝过程中,St

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1