游戏开发基础:游戏开发基础(4)



第 4章 diectxdarw基础篇
节 DirectDraw介绍

Grubers个观点是DirectDraw“只是个bltting发动机”这是相当准确但却太简化了更准确地讲DirectDraw是个可以提供软件Software仿真测试独立于硬件设备bltting发动机DirectDraw主要用途是尽可能快、尽可能可靠并且尽可能连续地将图形考贝到视频显示设备上
   另外个定义DirectDraw方式是把它作为个视频存储器管理器同常规存储器管理器DirectDraw发放存储器信息包跟踪每个信息包状态信息包可以随意地创建、复制、修改或破坏同时这些操作细节被员隐含起来这样讲是过于简单了此外DirectDraw是能够使用系统RAM和视频RAM存储器管理器也经常被设计成和主要目标样强健而不只是追求性能对于DirectDraw性能只是设计目标的
从技术角度讲DirectDraw是随同设备驱动器集合便携式APIDirectDraw设计成完全避开传统意义上Windows图形机构(GDI或称图形设备接口)GDI由于性能低而名声不好所以DirectDraw设备独立性在提供最佳性能方面是至关重要

第 2节 DirectDraw基本概念
1. 显示模式
显示模式是由允许将要显示图形输出显示硬件支持可视配置最常用显示模式属性是分辨率Windows使用显示模式默认值是640×480分辨率这意味着水平方向有640个像素垂直方向有480个像素其他些常见显示模式分辨率有800×6001024×768些显示卡支持Mode X显示模式个典型Mode X显示模式分辨率为320×200
   显示模式也随像素深度变化而变化像素深度决定着每个像素所容纳多少区别因而也就可以显示多少种颜色例如对于8位像素深度显示模式每个像素能够再现256种颜色像素深度为16位显示模式支持65536种颜色(即2n次方)典型像素深度为8、16、24和32位
   显示模式由安装在机器中显示设备或视频卡支持显示设备有自己RAM从计算机RAM中分离出来我们把位于显示设备中存储器称为显示RAM而把常规存储器称为系统RAM
支持个给定显示模式RAM容量取决于显示模式分辨率和像素深度例如640×480×8(640×480像素深度为8位)显示模式需要307200字节1024×768×16显示模式需要1572864字节支持显示模式存储器必须是显示RAM个给定显示设备所支持显示模式因此也被可以利用显示RAM容量所限制例如1024×768×16显示模式需要兆字节以上内存所以就不能被只有兆字节RAM显示设备所支持
DirectDraw个主要特征是显示模式切换这允许个DirectDraw应用检测和激活所安装显示设备所支持任何显示模式我们将在第4章中讨论显示模式切换细节
2. 硬件加速
DirectDraw具有最优性能最重要原因是它尽可能地使用硬件加速来进行设计硬件加速发生在当显示设备能够用建立在显示设备的中处理功能执行操作时硬件加速具有两个优点首先当硬件加速出现时候硬件按指定要求设计成支持图形操作这提供了执行给定任务最快思路方法:其次硬件加速使得计算主处理器从执行操作中解放出来这使得主处理器可以执行其他任务
3. 表面
表面是存储器个矩形部分DirectDraw术语通常包括图像数据该存储器通常用来表示个存在于显示RAM或系统RAM中表面驻留在显示RAM中表面享有超高性能绝大多数显示硬件不能对系统RAM直接存取
表面分为向大类最简单类型是脱离屏幕表面脱离屏幕表面可以驻留在显示RAM中或系统RAM中但却不能被显示这类表面般用于存储子画面和背景
方面个主表面是可在屏幕上看到视频RAM部分部分所有DirectDraw(可以提供视频输出)都拥有主表面主表面必须驻留在显示RAM中
主表面通常很复杂或是可翻转可翻转表面允许页面翻转这是项整个表面内容可以通过个硬件操作而瞬时可见技术页面翻转用于许多基于DirectDraw或其他图形应用它可以产生相当平滑、不闪烁动画个可翻转主表面实际上是两个表面个可见个不可见不可见表面称为后备缓冲区当发生页面翻转时以前是后备缓冲区表面就成为可见而以前可见表面则成为后备缓冲区
   离屏表面和主表面都有两类:调色板和无调色板在DirectDraw中只有8位表面是调色板表面调色板表面并不包含色彩数据但是却引入个色彩表该表称为调色板像素深度为16、24或32位表面是无调色板表面无调色板表面存储实际色彩值而不引入调色板
在无调色板表面中个像素都存储色彩数据所以知道表面像素格式是很重要像素格式描述了存储于像素中红色、绿色和蓝色(RGB)元件方式像素格式随像素深度、显示模式和硬件设计区别而区别在第5章中可以了解所有像素格式
4. Bltting
Bltting是用于复制图形语言典型blt操作是将离屏表面内容拷贝到个后备缓冲区中当Bltting通过硬件完成时候执行速度相当快如果无法得到硬件加速DirectDraw将使用个软件Software操作来仿真blt这种仿真操作虽然也能够完成任务但却比硬件慢得多.般只有驻留在显示RAM中表面能够通过使用显示硬件来完成blt
   blt操作个源表面和个目标表面源表面内容被拷贝到目标表面中源表面中内容在操作中不会改变只有目标表面受blt影响blt操作也并不需要使用全部源表面或目标表面源表面中任何矩形区域可以被放置于目标表面中任何位置
不规则形状表面bltting(例如典型子画面)是以透明方式完成透明性是通过指定表面中某个不被blt操作拷贝像素而获得像素值通过使用色彩键码给以标志
色彩键码可以附加到源表面或目标表面上源色彩键码是很普遍源色彩键码允许透明性源表面中像素值并未被考贝至于目标色彩只有目标表面中通过色彩所指定像素值能够被源表面内容所覆盖
DirectDraw也支持些特定操作包括拉伸、压缩、镜像映射以及混合等这些功能实现往往取决于显示硬件DirectDraw能够仿真其中某些操作但是跟性能相比价格往往是昂贵
DirectDraw也有不能仿真功能(例如目标色彩键码)使用这些功能是冒险除非该功能为所安装显示硬件支持否则使用该功能操作将失败这给DirectDraw开发者带来两种基本选择:要么放弃使用这些功能:要么往应用中增加定制软件Software
5. 调色板
   使用8位显示模式应用需要提供调色板调色板就是任何时候都可以使用色彩表如果8位显示模式不需要调色板应用将被迫使用256种颜色固定设置调色板允许用户定义将要使用256种颜色的
   当你使用调色板显示模式时必须保证在应用图像也使用同调色板如果没有做到这所显示些或全部图像中将出现颜色调色板也会带来麻烦尤其是用个调色板来显示大量图像时候调色板也有些优势正如前面提到调色板允许在个有限色彩场合使用最多色彩调色板也允许调色板动画
   调色板动画是动画通过改变调色板项目而不是改变像素值来执行技术这就使得个屏幕上很多像素可以瞬时改变颜色对于些有限应用诸如分配、重复动画调色板动画很有用处
6. 剪裁
理想状态下个blt操作就是整个表面被blt成为另个表面通常源表面被blt成为目标表面或者目标表面被另个表面或窗口遮蔽像这样情况就需要进行剪裁剪裁只允许部分或个表面部分被blt
在编写窗口DirectDraw应用时经常用到剪裁这些应用必须遵守Windows桌面规则我们将在本章后面讨论窗口应用
DirectDraw提供全矩形剪裁支持也有这种情况就是付费提供定制剪裁例程我们将在第3章中研究定制剪裁解决方案
7. 其他表面
离屏表面和主表面(具有任选后备缓冲区)是绝大多数DirectDraw应用主干然而些其他表面就有区别包括重叠表面、alpha通道表面、Z-缓冲区以及3D设备表面等
重叠表面是硬件单色画面因而也就在仅在支持重叠显示硬件上获得和软件Software单色画面区别它可以被移动而不需要背景图像被恢复
alpha通道表面用来执行alpha调配Alpha调配是透明高级形式允许表面以透明度或半透明方式来拷贝alpha通道表面可用来控制每像素透明度设置alpha通道表面深度有1、2、4、8位1位深度alpha通道表面仅支持两种透明设置不透明(非透明)或不可见(全透明)方面8位alpha通道表面允许256种区别透明度设置Alpha调配是不被DirectDraw仿真功能个例子为了使用alpha调配因而就需要有支持它显示硬件或建立在应用的中定制调配方案
Z-缓冲区和3D设备表面用于3D应用这些类型表面已被特别地加入到DirectDraw的中以支持Direct3DZ-缓冲区用于景象绘制时期以跟踪景象中离浏览者最近对象从而该对象可以在其他对象前面出现3D设备表面可以用来作为Direct3D绘制目标表面本书并不包括Z-缓冲区或3D设备



第 3节 元件对象模型(COM)
1.MicrosoftCOM规格
DirectDraw根据MicrosoftCOM(Component Object Model)规格得以实现COM设计成用来提供完全便携、安全、可升级软件Software结构COM是个大项目但是它并不是本软件Software讨论对象我们讨论COM只是为了方便使用DirectDraw进行编程
COM使用个面向对象模型这要比像C等语言所用模型更严格例如COM对象经常通过成员进行存取而且并不具备公共数据成员COM对继承性支持和C相比也是有限
2. 对象和接口比较
COM在对象和接口的间具有很大区别COM对象提供实际而COM接口则提供存取思路方法COM对象不能被直接存取相反所有存取者通过接口来完成这条规则是如此强有力得到遵守以致于我们不能给任何COM对象以名称我们只能给用来存取对象接口名称我们无法存取COM对象所以这里绝大多数时候是根据接口来讲
个COM对象能够支持多个接口这听起来像个特例但是它经常出现根据COM规格个COM接口旦定义的后就不能再被改变或增加这样做是为保证旧个COM对象升级时候不会被停止使用这个接口始终存在个新、替换接口在提供存取对象时候才被提供
3. IUnknown接口
所有COM接口都是从IUnknown接口中衍生出来“I”标志经常用于命名COM接口(它代表Interface即界面)DirectDraw接口总以“I”开头但是在文献中经常看不到这个标志以后提到接口时也将省略“I”标志
   IUnknown接口将提供3个成员所有COM接口因而继承这些:
●AddRef
●Release
●QueryInterface
AddRef和Release成员为称为生命期封装(letime encapsulation)COM功能提供支持生命期封装是个将每个对象根据它自己结构放置协议
生命期封装通过引用值来实现个对象拥有个可以跟踪对象指针数或者引用内部值当对象创建的后该值为1如果附加接口或接口指针被创建则该值递增和此类似如果接口指针被破坏则该值递减当它引用数到0时候该对象自行破坏
AddRef用来使对象内部引用值递增绝大部分时间里通过DirectDraw API被用户例如当你使用DirectDrawaw API创建个新接口时创建就自动AddRef
Release用来给对象内部引用值递减用户应该在接口指针将要超出范围时或者要通过使用接口指针来结束时使用这个AddRef和Release都返回个值表示对象新引用值
QueryInterface允许COM对象就它们是否支持特定接口进行查询例如升级COM对象提供附加接口而非现有接口修改版QueryInterface可以用来确定旧接口以决定新接口是否被支持如果被查询对象不支持有问题接口则更替接口指针就返回
4. GUID
为了查询个对象是否支持使用QueryInterface指定接口就有秘要识别有问题接口这通过接口GUID(Globally Unique IDentier)来实现个GUID是个128位也就是说对于所有意图和目是唯所有DirectDraw接口GUIDs都包含在DirectX头文件中
上述对于COM简单介绍就是为有效使用DirectDraw API所需要全部内容以后当我们再讨论DirectDraw API时你会发现这些内容是有联系

第 4节 DirectDraw接口
1.有关 DirectDraw API
衡量API个思路方法就是看它大小个庞大复杂API可能就是计划不周结果方面个庞大API有时就意味着每种情况都有可能出现个小API就是个新、缺乏功能软件Software包证据它也意味着个API只能做它所需要做而不能多做
DirectDraw API是比较小因此本章中所讨论不致于使本章看起来像本参考手册DirectDraw提供很少方便也很少有限制
DirectDraw由个COM对象构成每个对象可以通过个或多个接口存取这些接口包括:
●DirectDraw
●DirectDraw2
●DirectDrawSurface
●DirectDrawSurface2
●DirectDrawSurface3
●DirectDrawPalette
●DirectDrawClipper
我们将讨论每个接口并随后讨论它们成员但我们并不讨论每个细节我们并不是向您提供份参考手册相反我们将讨论每个是干什么为什么这样使用以及你有可能如何去使用它
当DirectX首次推出时候(早先它被称作Games SDK)DirectDraw核心性以DirectDraw接口表示当DirectX2推出时候DirectDraw也已经被升级了DirectDraw遵守COM规格而未被改变性可能通过DirectDraw2接口存取
特别要注意DirectDraw2接口是DirectDraw接口超级设置DirectDraw2接口可提供DirectDraw接口所有另外还增加了些新如果你正在使用DirectX或更高版高那么你可以随意选用DirectDraw接口或DirectDraw2接口但是由于DirectDraw2接口较DirectDraw接口功能更强所以没有必要使用DirectDraw接口同样Microsoft并不主张使用这些无组织、网络可变接口因此在本书以后中我们只使用DirectDraw2接口
DirectDraw和DirectDraw2接口提供成员如下(按字母顺序排列):
●Compact
●CreateClipper
●CreatePalette
●CreateSurface
●DuplicateSurface
●EnumDisplayModes
●EnumSurfaces
●FlipToGDISurface
●GetAvailableVidMem
●GetCaps
●GetDisplayMode
●GetFourCCCodes
●GetGDISurface
●GetMonitorFrequency
●GetScanline
●GetVerticalBlankStatus
●RestoreDisplayMode
●SetCooperativeLevel
●SetDisplayMode
●WaitForVerticalBlank
接下来我们讨论DirectDraw接口注意在本章以后内容中DirectDraw接口既表示DirectDraw接口也表示DirectDraw2接口只有在区分DirectDraw接口和DirectDraw2接口才加以区别
1. 接口创建
DirectDraw接口表示DirectDraw本身该接口在被用于创建其他DirectDraw接口例子时个主接口DirectDraw接口提供 3个这样接口例子创建:
●CreateClipper
●CreatePalette
●CreateSurface
CreateClipper用于创建DirectDrawClipper接口例子并非所有DirectDraw应用都用到剪裁器所以该并不是在所有中都出现我们将很快讨论DirectDrawClipper细节
CreatePalette用于创建DirectDrawPalette接口例子同DirectDrawClipper并非所有DirectDraw应用都用到调色板比如应用使用16位显示模式时就不用调色板但是当应用使用8位显示模式时就必须创建至少个DirectDrawPalette例子
CreateSurface用于创建DirectDrawSurface接口例子任何个DirectDraw应用都要用表面来生成图像数据因此经常要用到这
DirectDraw接口自己例子是由DirectDrawCreate创建DirectDrawCreate是DirectDraw中少有几个常规但并不是COM接口成员
2. GetCaps
DirectDraw接口允许准确确定软硬件都支持特征GetCaps可以对两个DDCAP结构例子进行个结构表明哪些特征由显示硬件直接支持个结构表明哪些特征由软件Software仿真支持最好是用GetCaps来决定你将用到特征是否被支持
提示:DirectX浏览器
DirectX SKD是和DXVIEW同时推出DXVIEW介绍说明了DirectX组件功能包括DirectDraw大多数系统中有两个DirectDraw项目:主显示驱动器和硬件仿真层项介绍说明了显示硬件功能第 2项介绍说明了在缺乏硬件支持情况下DirectDraw将要仿真些特征在具有两个以上DirectDraw支持显示卡计算机中DXVIEW会显示卡功能
3. SetCooperativeLevel
SetCooperativeLevel用于指定应用所要求对显示硬件控制程度比如个正常合作度意味着应用既改变不了当前显示模式也不能指定整个系统调色板内容个专有合作度允许显示模式切换并能完全控制调色板不管你决定使用哪种合作度都必须SetCooperativeLevel
4. 显示模式
DirectDraw接口提供4种显示模式操作它们是:
●EnumDisplayModes
●GetDisplayMode
●RestoreDisplayMode
●SetDisplayMode
EnumDisplayModes可用于查询DirectDraw使用何种显示模式通过设置EnumDisplayModes默认值可以得到所有显示模式而且可以通过显示模式描述消除那些不感兴趣模式进行显示模式切换过程中最好使用EnumDisplayModes现在市场上有各种各样显示设备每种显示设备都有自己特征和局限除了默认640×480×8窗口显示模式最好不要依靠任何给定显示模式支持
   GetDisplayMode可以检索到有关当前显示模式信息并在DDSURFACEDESC结构例子中显示当前显示模式宽度、高度、像素深度以及像素格式等信息还有别途径可以检索到同样信息(比如检索主表面描述)因此该并不出现在所有
   SetDisplayMode用于激活所支持显示模式SetDisplayModeDirectDraw2版本还允许设定显示模式刷新率而DirectDraw接口版本SetDisplayMode只能进行显示模式宽度、高度和像素深度设置任何个要进行显示模式切换都要用到SetDisplayMode
RestoreDisplayMode用于存储SetDisplayMode的前显示模式SetDisplayMode和RestoreDisplayMode都要求优先使用SetCooperativeLevel得到专有合作存取
5. 表面支持
除了CreateSurface的外DirectDraw接口还提供了以下向个表面相关:
●DuplicateSurface
●EnumSurfaces
●FlipToGDISurface
●GetGDISurface
●GetAvailableVidMem
●Compact
DuplicateSurface用于考贝当前表面只复制表面接口不复制内存被复制表面和源表面共享内存因此改变内存内容就同时改变了两个表面图像
EnumSurfaces可用于迭代所有满足指定标准表面如果没有指定标准那么所有当前表面都被枚举
FlipToGDISurface作用是在终止页面翻转应用前确保主表面得以正确存储取消页面翻转时有两个表面交替显示这就是说在终止应用的前有可能没有保存最初可见表面这种情况下Windows通过绘制个不可见表面来恢复利用FlipToGDISurface就可以轻而易举地避免发生这种情况
GetGDISurface可以向只被GDI认可表面返回个提针GDI表面是Windows用于输出表面在进行屏幕捕捉时这个非常有用DirectDraw可以捕捉到Windows桌面部分
GetAvailableVidMem用于检索正在使用中视频存储器(显示RAM)数量由DirectDraw2接口提供而不是由DirectDraw接口提供用于确定应用利用显示RAM可创建表面数量
Compact不是通过DirectX5实现但它可以为视频存储器提供碎片整理窍门技巧在基于显示RAM表面被不断创建或受到破坏时候可以释放大量内存
6. 监视器刷新
DirectDraw接口提供了4种适于计算机显示设备或监视器但这些不适于显示卡它们是:
●GetMonitorFrequency
●GetScanLine
●GetVerticalBlankStatus
●WaitForVerticalBlank
这些尤其和监视器刷新机制紧密机连这在确保生成动画时尽可能不产生闪烁和图像撕裂现象时是至关重要但必须注意并非所有显示卡/监视器组合都支持这些
GetMonitorFrequency用于检索监视器当前刷新率刷新率通常用赫兹表示缩写为Hz例如60Hz刷新率表示屏幕每秒更新60次
GetScanLine用于向监视器返回当前正在被刷新扫描行(水平像素行)不是所有显示设备/监视器组合都支持该如果这功能得不到支持将返回DDERR-UNSUPPORTED
对于高性能图形应用来说通常要求利用垂直刷新同步地更新屏幕尤其是当显示器刚完成屏幕刷新时最好能够更新主表面否则屏幕部分显示新图像数据而另部分仍显示旧图像数据这种现象就是所谓图像撕裂DirectDraw默认利用垂直刷新同步更新屏幕如果不是这样还可以利用GetVerticalBlankStatus和WaitForVerticalBlank实现同步刷新
7. GetFourCCCodes
DirectDraw接口提供最后是GetFourCCCodes用于返回显示卡所支持FourCC代码FourCC代码用于描述非RGB或YUV表面我们不在此讨论YOV表面它们已超出本书范围
第 5节 DirectDrawSurface接口
同DirectDraw接口DirectDrawSurface接口也遵守COM规格.最初表面支持是由DirectDrawSurface接口提供DirectX2介绍了DirectDrawSurface2接口DirectX5介绍了DirectDrawSurface3接口
尽管本软件Software中讨论是DirectDraw2接口而不是DirectDraw接口但我们仍忠于最初DirectDrawSurface接口DirectDrawSurface2和DirectDrawSurface3接口新增并不十分重要在以后内容里我们将用DirectDrawSurface接口表示这3种接口除非特别注明
DirectDrawSurface是最大DirectDraw接口它允许表面内容拷贝、清除以及被直接存取DirectDrawSurawSurface接口总共提供36个成员按字母顺序排列如下:
●AddAttachedSurface
●AddOverlayDirtyRect
●Blt
●BltBatch
●BltFast
●DeleteAttachedSurface
●EnumAttachedSurfaces
●EnumOverlayZOrders
●Flip
●GetAttachedSurface
●GetBltstatus
●GetCaps
●GetClipper
●GetColorKey
●GetDC
●GetDDInterface
●GetFlipStatus
●GetOverlayPosition
●GetPalette
●GetPixelFormat
●GetSurfaceDesc
●IsLost
●Lock
●PageLock
●PageUnlock
●ReleaseDC
●Restore
●SetClipper
●SetColorKey
●SetOverlayPosition
●SetPalette
●SetSurfaceDesc
●Unlock
●UpdateOverlay
●UpdateOverlayDisplay
●UpdateOverlayZOrder
1. 表面描述
我们首先讨论个可用于检索表面自身信息它们是:
●GetCaps
●GetPixelFormat
●GetSurfaceDesc
●SetSurfaceDesc
同DirectDraw接口提供GetCapsDirectDrawSurface接口提供GetCaps用于输出表征哪些特征可被表面支持数据该信息包括:表面是主表面还是离屏表面;表面使用存储器定位于显示RAM还是系统RAM
GetPixelFormat在用于高彩和真彩表面时是非常重要这是由于像素格式因显示卡区别而区别返回表征码这些表征码表明每种颜色部件是如何存储
GetSurfaceDesc返回个表面描述该信息包括表面宽度、高度和深度表面像素格式(同样被GetPixelFormat检索)也包含在其中
SetSurfaceDesc(对于DirectX5)来讲是新增只由DirectDrawSurface3接口提供)允许设定某些表面属性可用于指定表面使用内存点在设计定制表面存储器管理器策略时非常有用
2 表面Blt
DirectDrawSurface接口提供3个支持blt操作:
●Blt
●BltBatch
●BltFast
Blt个主要Blt能够进行常规blting(无特殊影响简单表面到表面blt)同时支持延伸、旋转、镜像和颜色填充操作当用于同剪裁器关联表面时Blt可进行剪裁blt操作
BltBatch不是在DirectX3下实现(你可以但什么也不会发生)执行BltBatch如果可能它可同时进行多blt操作
BltFast是Blt优化版本BltFast效率提高了但性能却下降了BltFast不能进行些特殊blt操作而Blt可以而且BltFast不能用于剪裁但是BltFast支持源和目标色彩键码blt操作在遵循定制剪裁例程情况下BltFast可进行DirectDraw能够提供最快捷、灵活blt操作在下章中我们将执行个定制剪裁例程
以上3个blt均将源表面和目标表面作为变量其他数据例如blt在目标表面上理想定位是通过指定理想blt操作确切属性来提供旦可能这3个将进行硬件加速blt
3. Flip
Flip用于页面翻转操作Flip可隐藏屏幕上先前可见表面并使个后备缓冲区显现只有被明确地创建为翻转表面表面才响应该
必须牢记真正翻转操作不可能总是成功页面翻转要求有足够显示RAM容纳两整屏有效数据如果满足不了这要求系统RAM中将创建个后备缓冲区这时Flip进行是blt操作而不是页面翻转基于系统RAM后备缓冲区中内容被拷贝到主表面上这样会严重影响性能但是在真正页面翻转中如果没有足够显示RAM又不退出也只能如此了如果你应用要求最佳性能就得设法避免激活不能进行真正页面翻转显示模式
4. 表面状态
下面讨论两个能检索有关操作和翻转操作信息它们是:
●GetBltStatus
●GetFlipStatus
GetBltStatus用于确定当前是否进行blt操作点很重要正被blt表面不能进行其他操作表明给定表面是否正是个进行blt操作源表面或目标表面
同样地GetBltStatus表明是否正在进行翻转操作即使DirectDraw通过blt操作仿真页面翻转而不GetBltStatus也必须用于由Flip监视器页面翻转
5. 色彩键码
DirectDrawSurface接口提供了以下两个来设置和检查表面色彩键码或色彩键码范围它们是:
●GetColorKey
●SetColoKey
默认状态下表面没有色彩键码个色彩键码只对应种颜色但某些硬件支持色彩键码范围色彩键码和色彩键码范围是DDCOLORKEY结构定义GetColorKey和SetColoKey都将该结构指针作为变量在要求表面部分透明时或需要进行目标色彩键码操作时可以使用这两个
6. Lock和Unlock
DirectDraw个主要特点就是能够提供对图像数据直接存取直接存取可以提供最佳性能和更好灵活性没有中间API影响运行速度并且开发人员呆任意使用图像数据对表面存储器中间存取通过以下出众个实现:
●Unlock
●Lock
Lock向组成表面存储器返回个指针不管表面存储器位于显示RAM还是系统RAM存储器般按线性风格排列以便能简单地进行图像 数据存取Unolock在完成表面存储器存取的后指定给DirectDraw
对图像数据直接存取必须付出代价为了支持这种存取方式DirectDraw在表面锁定时候必须关闭基本Windows机构在Windows95状态下如果忘记解锁表面必定会损坏机器
因此表面锁定时间应尽量缩短测试前应仔细检查Lock和Unlock的间无法用传统调试进行调试
锁定表面不能被blt和翻转因此试图保持表面处于锁定状态没有任何有益的处而且旦表面解锁由Lock检索指针就失效了
表面锁定后不能再次被锁定在表面锁定时也就无法Lock
7. GetDCReleaseDC
对表面直接存取占用很大内存有时候把表面作为个常规Windows设备会更好在此DirectDrawSurface接口提供以下两个:
●GetDC
●ReleaseDC
GetDC提供了个DC(设备环境)可以用常规Win32写到表面上例如DC可以用Win32TextOut在表面上绘制文本用完DC后必须马上ReleaseDC
同Lock和Unlock使用完GetDC后必须马上ReleaseDC这是GetDC内部Lock而ReleaseDC内部Unlock
8. PageLock和PageUnlock
接下来我们讨论另外两个和Lock和Unlock看上去非常相像:
●PageLock
●PageUnlock
尽管这两个看上去很像Lock和Unlock但它们却有完全区别作用PageLock和PageUnlock用于控制Windows对基于系统RAM表面处理方式这两个由DirectDrawSurface2接口提供而不是由DirectDrawSurface接口提供
当Windows认为当前正在运行其他应用或进程更适于使用内存时Windows会向硬盘释放部分内存这种缓冲对于整个系统内存都起作用因此驻留在系统内存中DirectDraw表面有可能被存到硬盘上如果要用到这样表面Windows需要花费时间从硬盘上读取表面数据
PageLock提示Windows哪些给定表面不应该释放到硬盘上这样在使用表面时就不用耗费时间进行硬盘存取了相反地PageUnlock用于告知Windows哪些表面内存可被释放
过程PageLock会减少缓冲内存总量从而导致Windows速度大大降低至于这种情况何时发生取决于页面锁定系统内存量及机器提供系统内存量
PageLock和PageUnlock主要是由DirectDraw提供而非DirectDraw应用举个例子来说DirectDraw自动使用PageLock以确保运行blt操作时基于系统RAM表面不被释放到硬盘
PageLock可以被同个表面多次DirectDraw用参考计数法记录PageLock次数因此多次PageUnlock就必须避免多次PageLock
PageLock和PageUnlock对于驻留在显示RAM中表面不起作用
9. IsLostRestore
现在讨论两个和使用驻留在显示RAM中表面有关:
●IsLost
●Restore
让我们来看看下面这种情况应用正在运行时尽量把表面分配到显示RAM中剩下创建到系统RAM中应用在运行段时间的后用户执行或切换到另个应用该应用是任意可以是个常规Windows如Windows开发或记事本它也可以是另外DirectDraw应用也试图将尽可能多地分配显示RAM如果DirectDraw不接受显示RAM那么新应用就很可能根本运行不了相反情况就意味着应用不允许分配到任何显示RAM中
因此DirectDraw可以随意将任何个或者所有基于显示RAM表面从非激活应用中移走这种情况就是所谓表面丢失从技术上讲仍具有表面但它们不再同任何内存相关要使用丢失表面会导致DDERR-SURFACELOSTIsLost可用于确定个表面是否丢失了内存
表面内存丢失后可通过Restore恢复但只能在应用被重新激活的后才可恢复这会导致应用无法将处于最小化状态所有表面复原
Restore可恢复附属于表面内存但并不恢复内存内容表面被复原后应用就可以恢复表面内容了
注意这种使用方法不适合利用系统RAM创建表面如果需要用到基于系统RAM表面所占内存那么Windows会立即将这些表面释放到硬盘上Windows自动地处理存储和恢复包括恢复表面内容
10. GetDDInterface
GetDDInterface可检索用于创建给定表面DirectDraw接口指针由于中大多数情况下只有个DirectDraw接口例子所以GetDDInterface并不常用但是个应用中有可能使用多个DirectDraw接口在这种情况下GetDDInterface会起到重要作用
11. 表面连接
DirectDrawSurface接口提供以下4个用来维持表面间连接:
●AddAttachedSurface
●DeleteAttachedSurface
●EnumAttachedSurfaces
●GetAttachedSurface
DirectDraw支持大量用于表面间连接情况最常见情况就是页面翻转进行页面翻转时两个或两个以上表面连接成环状每次Flip都会使连成环状表面中个表面显现
表面连接用于创建、检查或消除表面间连接但这些并非必不可少DirectDraw往往是自动创建连接表面比如当创建个主翻转表面时可以指定用于连接表面后备缓冲区数量DirectDraw就会创建这些表面并将它们连接起来
12. 重叠
DirectDrawSurface接口用于支持重叠如下:
●AddOverlayDirtyRect
●EnumOverlayZOrders
●GetOverlayPosition
●SetOverlayPosition
●UpdateOverlay
●UpdateOverlayDisplay
●UpdateOverlayZOrder
GetOverlayPosition和SetOverlayPosition用于控制重叠位置UpdateOverlay用于更新大量重叠设置包括重叠是否可见以及重叠是以色彩键码还是用alpha混合到背景表面上
UpdateOverlayDisplay用于更新显示设置用于更新整个重叠显示或者只更新由AddOverlayDirtyRect指定矩形重叠部分EnumOverlayZOrders可根据重叠Z值(Z值控制哪个重叠位于最上面)重复重叠重叠可按从前到后或从后到前顺序枚举
13. 剪裁器
DirectDraw支持剪裁是将DirectDrawClipper接口(该接口我们尚未讨论)个例子连接到表面旦连接完毕剪裁器对象就会有规律地blt到表面剪裁器/表面连接由以下两个DirectDrawSurface控制:
●GetClipper
●SetClipper
SetClipper用来将剪裁器对象连接到表面GetClipper用于向前个连接剪裁器对象返回个指针SetClipper还可用于解除表面同剪裁器连接具体做法是通过指定NULL来替代DirctDrawClipper接口指针
14 调色板
像剪裁器调色板也可连接到表面DirctDrawSurface接口为此提供以下两个:
●GetPalette
●SetPalette
SetPalette用来将DirctDrawPalette接口(该接口我们接下来就要讨论)个例子连接到表面GetPalette用于检索前个连接调色板指针
调色板可被连接到任何表面但只有连接到主表面时调色板才起作用当和主表面连接时调色板决定显示硬件调色板设置
第 6节 DirectDrawPlette接口
DirctDraw提供DirctDrawPalette接口用于调色板显示模式和表面尽管Windows支持几种低于8位像素深度显示模式但DirctDraw所支持调色板显示模式是8位模式
DirctDrawPalette接口例子由DirctDraw CreatePalette创建CreatePalette用大量标志来定义调色板属性
DirctDrawPalette接口只提供以下3个:
●GetCaps
●GetEntries
●SetEntries
GetCaps用于检索有关调色板信息包括调色板项目数量调色板是否支持同步垂直刷新以及在8位调色板状态下是否所有256个调色板项目都能被设定
SetEntries允许在中设置调色板色彩值该数据从文件中读取而这些项目在运行过程中可被计算和设定GetEntries用于检索先前设定调色板项目
DirctDrawPalette接口例子可利用DirctDrawSurface SetPalette连接到表面将区别调色板连接到主表面或利用SetEntries改变调色板项目都可激活调色板



第 7节 DirectDrawClipper接口
DirctDrawClipper接口支持剪裁将剪裁器对象连接到表面并在blt操作中将其当作目标表面就可以进行剪裁
directDrawClipper例子由DirectDraw CreateClipper创建DirectDrawClipper接口支持以下5个:
●SetHWnd
●GetHWnd
●IsClipListChanged
●SetClipList
●GetClipList
剪裁器对象般用于出现在窗口中DirctDraw应用必需剪裁要求剪裁器必须确保在blt操作过程中考虑到桌面上其他窗口比如当应用全部或部分被另个窗口遮蔽剪裁就必须确保被遮蔽窗口不被DirctDraw应用破坏
桌面剪裁由SetWnd完成SetHWnd将剪裁器对象连接到个窗口句柄这样就化了Windows和剪裁器对象的间通讯当桌面上任何个窗口发生变化时剪裁器对象就会得到通知并作出反应GetHWnd用于决定剪裁器同哪个窗口句柄连接IsClipListChanged用于决定内部剪裁清单是否因桌面改变而被更新
SetClipList和GetClipList为DirectDrawClipper接口提供便利定制使用SetClipList用于定义些矩形区域这些矩形区域用来定义blt操作合法区域GetClipList用于检索剪裁器内部剪裁数据
旦被连接到表面BltBltBatch以及UpdateOverlay所进行blt操作将根据DirctDrawCliper接口中包含数据被自动地剪裁注意Blt Fast在此被忽略BltFast不支持剪裁

第 8节 附加DirectDraw接口
DirctDraw还提供了另外个我们没有讨论接口它们是:
●DDVideoPortContainer
●DirectDrawColorControl
●DirectDrawVideoport
这些接口由DirectX5介绍它们提供低水平视频端口控制这些接口还向DirctDraw表面提供流活动视频思路方法尽管利用这些接口可以为DirctDraw应用增加视频支持但除非高水平视频APIs不能满足需要否则最好不用这思路方法

第 9节 DirectDraw结构
我们已讨论过DirctDraw接口及其成员接下来再看看DirctDraw定义结构DirctDraw总共定义了8全结构:
●DDBLTFX
●DDCAPS
●DDOVERLAYFX
●DDPIXELFORMAT
●DDSURFACEDESC
●DDSCAPS
●DDBLTBATCH
●DDCOLORKEY
我们已经见过其中些结构了比如在讨论DirctDrawSurface SetColorKey时我们就接触过DDCOLORKEY结构在此我们不详细讨论每个结构细节但必须指出DirctDraw quirk被忘记时会导致失败
以上所列结构中前5个有个称作dwSize字段该字段用于存储结构大小设定该字段工作由你来做另外该字段如果没有被正确设定那么任何个将这5个结构作为变量DirctDraw都会失效
以DDSURFACEDESC结构为例使用结构代码如下:
DDSURFACEDESC surfdesc;
surfdesc.dwSize=(surfdesc);
surf->GetSurfaceDesc(&surfdesc);
首先声明结构然后用关键字设定dwSize字段最后结构传递给DirctDrawSurface GetSurfaceDesc忘记设定dwSize字段将导致这段代码失效
到底为什么DirctDraw坚持要求给出它所定义结构大小?原因在于这5个包含dwSize字段结构将来有可能会改变DirctDraw会检查结构大小以便确定正在使用版本DirctDraw坚持要求给出个有效大小值是为了让开发者提供有效结构大小这样做是有好处DirctDraw新版本可以正确运用旧版本DirctDraw
在使用结构的前最好将结构化为零这样前面代码就变成:
DDSURFACEDESC surfdesc;
ZeroMemory (&surfdesc(surfdesc));
surfdesc.dwSize=(surfdesc);
surf->GetSurfaceDesc(&surfdesc);
ZeroMemory个Win32它将作为第个参数存储器设定为零.ZeroMemory第 2个参数表明有多少存储器应被做法好处是通过GetSurfaceDesc可以知道结构哪些字段被更新了如果没有对结构进行就有可能将结构字段中不可预测值当作DirectDraw设定值

第十节 窗口应用
DirctDraw应用主要有两种型式:窗口和全屏窗口DirctDraw应用看起来就像个常规Windows我们很快将讨论到全屏应用
窗口应用包括窗口边界、标题框以及菜单这些都是传统Windows应用中常见部分由于窗口应用同其他窗口起出现在桌面上因此它们被迫使用Windows当前所使用分辨率和比特深度
窗口个主表面但只在进行真实页面翻转时才显现而且主表面并不代表窗口客户区域(该区域在窗口边界内)主表面还代表整个桌面这就是说必须追踪窗口位置和大小以便在窗口内正确显示可见输出换言的利用窗口化应用中可以在整个桌面上进行绘图
如果不允许页面翻转那么图像就必须从离屏缓冲区blt到主表面上这就增加了图像撕裂可能性blt比页面翻转速度慢为了避免图像撕裂blt操作可以和监视刷新率保持同步
如果和窗口客户区域同样大小离屏缓冲区被创建到显示RAM中窗口应用就可以很好地运行这样窗口内容可利用离屏表面合成然后离屏表面可以通过硬件加速很快地到主表面上
由于显示存储器缺乏而不得不将离屏缓冲区创建到系统RAM中时会严重影响性能不幸这种情况常常发生尤其是在只有2MB显示卡时候这是人们总希望为自己Windows桌面设置高分辨显示模式例如采用1024×768×16显示模式主表面自己就要占用2MBRAM个2MB显示卡上几乎没有显示RAM留给离屏表面
窗口应用个问题是剪裁个性能良好应用必须有个连接到主表面剪裁对象这是有损性能原因在于为了检查剪裁器剪裁清单内容blt操作只能在个小矩形部分内进行而且不能使用优化BltFastBltting必须用较慢(而且更笨重)Blt
最后要讲窗口应用不允许全调色板控制由于Windows保留了20个调色板项所以在256种颜色只有236种颜色可被设定被Windows保留颜色只用系统调色板前10个项和后10个项因此在给图像上色时只能使用中间236个调色板项



第十节全屏应用
包含对显示设备进行专有存取DirctDraw应用就是全屏应用这种应用可以任意选取显示卡所支持显示模式并享有全调色板控制另外全屏应用还可进行页面翻转因此同窗口应用相比全屏应用速度更快灵活性更好
典型全屏应用首先检查所支持显示模式并激活其中然后创建具有个或更多后备缓冲区可翻转主表面剩下显示RAM用于创建离屏表面当显示RAM耗尽时就启用系统RAM屏幕被在后备缓冲区中合成个场景更新然后进行页面翻转即使主表面占用了所有可用显示RAM全屏应用还可输出执行其窗口化副本这是全屏应用可进行真实页面翻转
由于全屏应用定非得使用Windows当前显示模式所以显示RAM可用和否不存在多少问题如果只检测到2MB显示RAM就可使用低分辨率显示模式来保留内存如果检测到4MB显示RAM应用就可使用要求显示模式并仍有保持良好性能
全调色板控制也是个有利原因这样可以使用所有256个调色板项而无需根据Windows保留20中颜色重新分配位图

第十 2节混合应用
混合应用既可以在全屏方式下运行也可在窗口方式下运行混合应用内部非常复杂但却可以提供良好性能用户可在窗口方式下运行如果太慢则可切换到全屏方式下运行
编写混合应用最好思路方法是编写个定制库该库包括那些和应用使用全屏方式还是窗口方式无关

Tags:  网页游戏开发 网络游戏开发 游戏开发 游戏开发基础

延伸阅读

最新评论

发表评论