⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dx5.txt

📁 我下的时候觉得好编程类的
💻 TXT
📖 第 1 页 / 共 5 页
字号:
    像素格式指出了任何对表面内存中每个像素数据作出解释。DirectDraw使用DDPIXELFORMAT结构描述各种像素信息。
DDPIXELFORMAT结构的成员描述了像素格式的下述特性:
	.调色或非调色像素格式
	.如果是非调色格式,像素格式是RGB还是YUV格式
	.位深度
	.像素格式组成部分的位屏蔽
你可以调用IDirectDrawSurface3::GetPixelFormat方法来获取存在的表面的像素格式。
4.4、创建表面
    DirectDrawSurface对象表征了驻留在显示内存中的一个表面。如果显示内存用完了或者是显式地创建,该表面也可存在于系统内存中。
你可以使用IDirectDraw2::CreateSurface方法创建一个或多个表面。调用CreateSurface时,必须指定表面的大小、表面类型(是单一表面还
是复杂表面)、像素格式(如果表面不使用索引的调色板)。所有的这些特性都包含在DDSURFACEDESC结构中,在调用时需要将该结构的
地址传送过去。如果硬件不支持请求的特性或者此前已经将那些资源分配给了另一个DirectDrawSurface对象,调用就会失败。
    创建单一的表面或多表面只需要几行简单的代码。创建表面有四个主要的步骤。每一个步骤都需要比前一个步骤更多的准备工作,不过
并不太难,它们是:
	(1).	创建主表面
	(2).	创建一个屏外表面
	(3).	创建复杂表面和翻转链
	(4).	创建宽表面
    在缺省的情况下,DirectDraw在本地视频内存创建一个表面,如果足够的本地视频内存保存该表面,DirectDraw就尝试利用非本地视频
内存(仅在一些AGP设备系统中)。你可以在调用CreateSurface时对DDSCAPS结构赋以适当的标志来显式地指明在哪类内存中创建表面。
4.4.1、创建主表面
    主表面是当前在显示器上可见的并且由DDSCAPS_PRIMARYSURFACE标志指明的表面,每一个DirectDraw对象只能有一个主表面。
当你创建一个主表面时,其大小应该同当前的显示模式匹配。因此,在这种情况下你不需要指明表面的大小。事实上,如果你指明了表面的
大小,即使同当前的显示模式匹配,也会导致创建过程的失败。
    下面的例子显示了如何设置DDSURFACEDESC结构的相关成员来创建主表面:
DDSURFACEDESC ddsd; 
ddsd.dwSize = sizeof(ddsd); 
 		// Tell DirectDraw which members are valid. 
ddsd.dwFlags = DDSD_CAPS; 
    // Request a primary surface. 
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; 
 
4.4.2、创建屏外表面
    屏外表面通常用于位图的缓存,该位图将被位块传输到主表面或后台缓冲区中。你必须设定包含DDSC_WIDTH和DDSD_HEIGHT标
志并设定dwWidth和dwHeight成员 为适当的值来说明屏外表面的大小。另外,还必须在DDSCAPS结构中包含DDSCAPS_OFFSCREENPLAIN
标志。
    当没有足够的显示内存使用时,DirectDraw就使用系统内存来创建表面。你可以在DDSCAPS结构中的dwCaps成员包含
DDSCAPS_SYSTEMMEMORY或 DDSCAPS_VIDEOMEMORY标志来显式地指明是在显示内存还是在系统内存中创建表面。下面的例子显
示了创建一个屏外表面之前的准备工作:
DDSURFACEDESC ddsd; 
ddsd.dwSize = sizeof(ddsd); 
 	
// Tell DirectDraw which members are valid. 
ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH; 
 	
// Request a simple off-screen surface, sized 
// 100 by 100 pixels. 
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN; 
dwHeight = 100; 
dwWidth = 100; 
    在DirectX以前的版本中,屏外表面的最大宽度不能超过主表面的宽度。在DirectX 5中,你可以创建任意宽度的屏外表面,只要显示设
备指出就行。需要注意的是,当声明了屏外表面的宽度时,如果显示内存容不下请求的表面的宽度,该表面将换在系统内存中创建。如果显
式地声明使用视频内存,而视频内存又不够时,创建表面的工作就会失败。
4.4.3、创建复杂表面(Complex Surface)和翻转链(Flipping Chain)
    一个复杂表面就是用IDirectDraw2::CreateSurface方法创建的一组单一表面的组合。若在调用CreateSurface时设定了
DDSCAPS_COMPLEX标志,除了显式指定的表面外,DirectDraw还将隐式地创建一个或多个表面。你可以象管理单一表面一样管理复杂表
面。调用IDirectDraw::Release方法会释放所有的表面,调用IDirectDrawSurface3::Restore则会将这些表面恢复。
    最常用的复杂表面是翻转链。通常,一个翻转链由一个主表面和一个或多个后台缓冲区组成。DDSCAPS_FLIP标志说明了某一表面是
一翻转链一部分。用这种办法创建一个翻转链还需要包含DDSCAPS_COMPLEX标志。下面的例子创建一个主表面翻转链所需要的准备工作:
DDSURFACEDESC ddsd; 
ddsd.dwSize = sizeof(ddsd); 
 
// Tell DirectDraw which members are valid. 
ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT; 
 	
// Request a primary surface with a single 
// back buffer 
ddsd.ddsCaps.dwCaps = DDSCAPS_COMPLEX | DDSCAPS_FLIP | 
DDSCAPS_PRIMARYSURFACE; 
ddsd.dwBackBufferCount = 1;
    该例构建了一个双缓冲翻转环境。调用IDirectDrawSurface3::Flip方法将交换主表面和后台缓冲区的表面内存。如果DDSURFACEDESC
结构中的成员dwBackBufferCount取值为2,就会创建两个后台缓冲区,每次调用Flip就会循环地翻转表面,并提供三缓冲翻转环境。
4.4.4、创建宽表面(Wide Surface)
    DirectDraw允许创建比主表面宽的屏外表面,当然这需要显示硬件支持才行。要确定显示设备是否支持宽表面,需要调用
IDirectDraw2::GetCaps方法,查看第一个DDCAPS结构中的dwCaps2成员是否包含DDCAPS2_WIDESURFACES标志。如果该标志存在,
就表明可以在视频内存中创建比主表面还要宽的屏外表面。如果该标志不存在,在视频内存中创建宽表面将会失败,并返回一个
DDERR_INVALIDPARAMS错误。
系统内存表面、视频端口表面和执行缓冲区都支持宽表面。
4.4.5、翻转表面(Flipping Surface)
    DirectDraw中的任何表面都可以构建为一个翻转表面。一个翻转表面就是能够在前台缓冲区(front buffer)和后台缓冲区(back buffer)
之间互相交换的任意一块内存。通常,前台缓冲区就是主表面,但这并不是必需的。
当使用IDirectDrawSurface3::Flip方法执行表面翻转操作时指向主表面的表面内存的指针和后台缓冲区的表面内存的指针互换。因此,表面的
翻转是显示设备用于指向内存的指针的交换,而不是对表面内存的拷贝。唯一的例外是,当DirectDraw用软件仿真翻转时只是简单地拷贝表
面。如果一个后台缓冲区不能装入到显示内存中或硬件不支持DirectDraw时,DirectDraw就用软件仿真翻转操作。当一个翻转链包含了一个
主表面和多个后台缓冲区时,指针的转换就采用了循环的方式周而复始,如下图所示:
 
    DirectDraw对象的其它附加表面不是翻转链的一部分,不受Flip方法的影响。切记,DirectDraw翻转表面是通过交换DirectDrawSurface
对象表面内存的指针实现的,而不是交换这些对象。这就意味着,位块传输到后台缓冲区时,必须一直使用同一个DirectDrawSurface对象,
该缓冲区是你创建翻转链的后台缓冲区。而指向翻转操作一直是通过调用前台缓冲区的Flip方法完成的。
4.4.6、丢失表面(Losing Surface)
    当表征表面内存的DirectDrawSurface对象不必要释放时,同该表面关联的表面内存却被释放了。这就是失去了表面。当DirectDrawSurface
对象事情了它的表面内存时,许多方法就不执行其它的操作并返回DDERR_SURFACELOST。
因为改变了显示模式或另一个应用获得了对显示设备的独占访问而释放了当前分配的所有表面内存,表面就可能会丢失。
IDirectDrawSurface3::Restore方法重新创建这些丢失的表面并同DirectDrawSurface对象重新联结。恢复表面并不装入表面丢失之前存在的位
图。因此,如果丢失的表面,必须完全重新装入此前曾装入的图形。
4.4.7、释放表面(Releasing Surface)
    象所有的COM接口一样,不需要表面时,必须调用Release方法释放表面。每一个单独创建的表面都必须显式地释放。如果是一次调
用 IDirectDraw2::CreateSurface或IDirectDraw::CreateSurface方法显式地创建的多个表面(如翻转链等),你只需要释放前台缓冲区即可。在
这种情况下,指向后台缓冲区表面的任何指针都会显式地释放,并且不可再用。
4.4.8、更新表面特征(Updating Surface Characteristics)
    你可以使用IDirectDrawSurface3::SetSurfaceDesc方法来更新已有表面的特征。用该方法可以改变像素格式,也可以改变DirectDrawSurface
对象的表面内存在系统内存中的位置,该对象是应用程序显式地分配的。它允许一个表面直接使用先前分配的缓冲区中的数据而不需要拷贝,
这一新的表面内存由客户应用来分配,也由该客户应用来释放。
    调用 IDirectDrawSurface3::SetSurfaceDesc方法时,lpddsd参数必须是描述新的表面内存的结构DDSURFACEDESC的地址,也就是指向
该内存地址的指针。在DDSURFACEDESC结构中,可以只设定dwFlags成员来反映表面内存的位置、大小和像素格式。因此dwFlags只能
包含DDSD_WIDTH、DDSD_HEIGHT、DDSD_PITCH、DDSD_LPSURFACE和DDSD_PIXELFORMAT等标志的组合,用这些组合来设定
有效的结构成员。
    在设置结构的值前,必须分配内存来装入表面。分配的内存的大小非常重要 。你不仅需要分配足够的内存来容纳表面的宽和高,还需
要为表面间距(pitch)留下足够的内存空间,表面间距是一个QWORD(8个字节),间距是用高度而不是用像素度量的。
    设置结构中表面的值时,lpSurface成员是你分配的内存的指针, dwHeight和dwWidth成员以像素单位描述了表面的大小。如果指定了
表面的大小,也需要填充Ipitch成员来反映表面间距。ddpfPixelFormat成员描述了表面的像素格式。除了lpSurface成员外,若你不为这些成
员设定值,IDirectDrawSurface3::SetSurfaceDesc方法就从当前的表面中使用缺省的值。
在调用IDirectDrawSurface3::SetSurfaceDesc方法时需要注意一些问题。例如,lpSurface必须是系统内存的一个有效指针(该方法目前不支持
视频内存指针);dwWidth和dwHeight必须是非0的值;不能在主翻转链中重新分配主表面或其它任意表面。
    你可以为多个DirectDrawSurface对象分配同一内存,但必须注意当内存分配给任意表面对象后,就不能取消对该内存的分配。对
SetSurfaceDesc方法不正确的使用会导致不可预料的反应。因此,当不再需要表面内存时,你必须记住释放它。不过,在调用该方法时,DirectDraw
将释放创建表面时显式分配的表面内存。
4.4.9、直接访问帧缓冲区(Accessing the Frame-Buffer Directly)
    你可以使用IDirectDrawSurface3::Lock方法直接访问帧缓冲区或系统内存中的表面内存。当调用该方法时,lpDestRect参数是一个RECT
结构的指针。该结构描述了要直接访问的表面上的矩形。若想锁定整个表面,可将lpDestRect设为NULL。也可以指定一个只包含了表面的
一部分的RECT。如果没有两个矩形重叠,两个进程可以同时锁定一个表面中的多个矩形。
    Lock方法用需要适当地访问表面内存的所有信息填充DDSURFACEDESC结构。该结构包含了有关表面间距和像素格式的信息(在同主
表面的像素格式不同时)。在完成了对表面的访问后,调用IDirectDrawSurface3::Unlock方法对其进行解锁。
4.4.10、使用非本地视频内存表面(Using Non-local Video Memory Surfaces)
    DirectDraw支持高级图形端口AGP(Advanced Graphics Port)特性,能够在非本地视频内存中创建表面。在AGP系统中,如果本地视
频内存已用完或应用程序显式地要求使用非本地内存,DirectDraw将会使用非本地视频内存创建表面。
    目前,有两种AGP体系。一种是“执行模型”(Execute Model),一种是“DMA模型”(Direct Memory Access Model)。在执行模型中,
显示设备支持非本地视频内存和本地视频内存同样的特性。因此,当使用 IDirectDraw2::GetCaps方法获取硬件的性能时,同位块传输相关
的标志dwNLVBCaps、dwNLVBCaps2、dwNLVBCKeyCaps、dwNLVBFXCaps和dwNLVBRops将指明用于本地视频内存。在执行模式下,
如果本地视频内存被用完了,DirectDraw将自动使用非本地视频内存。
    在DMA模型中,对从非本地视频内存中位块传输的纹理贴图的支持是有限的。当显示设备使用了DMA模型时,欲获得硬件的性能,
dwCaps成员将被设为DDCAPS2_NONLOCALVIDMEMCAPS标志。同位块传输相关的标志包含在dwNLVBCaps、dwNLVBCaps2、
dwNLVBCKeyCaps、dwNLVBFXCaps和dwNLVBRops等成员中。除非显式地指明,D

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -