科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道基础软件基于Visual Basic 6.0的DirectDraw编程

基于Visual Basic 6.0的DirectDraw编程

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

随这计算机技术、多媒体技术的飞速发展,图形图像已经广泛应用到现实生活中的各个领域

作者:刘 涛 来源:yesky 2007年10月15日

关键字:

  • 评论
  • 分享微博
  • 分享邮件
三、DirectDraw编程

  正如上节介绍的那样,DirectDraw提供了与硬件无关性的同时允许直接操作显存,它是一个与Windows 图形系统接口(GDI)相兼容的直接操作显示设备的软件接口,是DirectX技术中进行图像处理的基础,是DirectX中的关于视频输入输出的基本部分,只要使用的硬件支持DirectDraw,开发人员就可以使用DirectDraw可以方便地编制出高效的视频处理、图像处理的程序来。

  DirectDraw类包含DirectDraw7、DirectDrawClipper 、DirectDrawEnumModes、 DirectDrawPalette、DirectDrawSurface7等对象。其中,DirectDraw7对象是DirectX7中的DirectDraw对象,你需要首先建立一个DirectX7对象,然后使用该对象的DirectDrawCreate方法来建立DirectDraw7对象。

  DirectDraw7的GetDisplayModesEnum方法可以建立一个DirectDrawEnumModes对象,通过它可以获得当前系统支持的显示模式;DirectDraw7的CreatePalette方法可以建立一个DirectDrawPalette对象,DirectDrawPalette对象是DirectDraw下的绘图调色板对象,它很类似于Windows下的调色板。

  利用DirectDraw7的CreateClipper方法可以建立一个DirectDraw7下的DirectDrawClipper对象,DirectDrawClipper对象的作用是建立一个屏幕的剪裁区域,这样DirectDraw就知道绘图时那些部分是可见的而那些部分应该被剪裁掉。

  DirectDrawSurface7是DirectDraw下的最重要的对象,这个对象描述了一块线型的显存区域,我们所进行的所有图形、文本操作都是在这个对象上进行的,你可以通过DirectDrawSurface7对象直接操作这片区域。

  通过DirectDraw7的CreateSurface方法,可以建立一个单一绘图表面、复合绘图表面或者三维绘图表面对象。而利用DirectDraw7的CreateSurfaceFromFile方法、CreateSurfaceFromResource方法可以分别根据位图文件和位图资源建立一个包含图像数据的 DirectDrawSurface7对象。

  仅仅知道如何创建DirectDraw编程需要使用到的一些对象是远远不够的,还需要使用灵活的使用这些对象提供的方法,下面按照DirectDraw处理图像的步骤来说明这些方法的使用。

  1、建立协作层

  当建立了一个DirectDraw对象之后,首先要设定DirectDraw的协作层。实现的方法是调用DirectDraw对象的SetCooperativeLevel函数。该函数的定义是:

SetCooperativeLevel( hdl As Long, flags As CONST_DDSCLFLAGS)

  其中参数hdl指定程序的窗口句柄,参数flag决定程序运行的方式,它的值可以使用Or组合起来。具体值的含义如下:DDSCL_FULLSCREEN表示使用全屏幕(必须和DDSCL_EXCLUSIVE一起用)、DDSCL_ALLOWMODEX使用Modex模式、DDSCL_EXCLUSIVE 使用独占模式、DSCL_NORMAL 使用Windows的窗口、DDSCL_NOWINDOWCHANGES 禁止改变窗体大小。例如函数调用SetCooperativeLevel Me.hWnd, DDSCL_NORMAL将使程序运行于普通的协作层既窗口模式之下,在这种协作层你无法改变主表面调色板或进行页交换。而函数调用SetCooperativeLevel MainForm.hWnd, DDSCL_EXCLUSIVE Or _DDSCL_FULLSCREEN将使程序运行于全屏幕模式之下。在全屏幕协作模式之下你可以完全使用硬件的一切,你可以设置自己的调色板,改变显示分辨率及进行页交换。

  2、设置显示模式

  设置系统的显示模式是使用DirectDraw的SetDispalyMode函数实现的,函数的定义如下:

SetDisplayMode( w As Long, h As Long, bpp As Long, ref As Long, mode As CONST_DDSDMFLAGS)

  其中参数w、h分别指定屏幕的宽度和高度,bpp指定屏幕显示的颜色位数,参数ref指定屏幕的刷新频率,设置为0使用显示驱动的缺省刷新频率,mode指定附加的参数。为了保证程序的健壮性,需要获得系统支持的显示模式,此时可以使用DirectDraw对象的GetDisplayModesEnum函数来遍历所有支持的显示模式,然后根据返回的结果进行设置。

  3、建立DirectDrawSurface表面对象显示图像

  DirectDrawSurface对象是DirectDraw用来进行图像显示和绘制的对象,开发人员不仅可以在DirectDrawSurface上贴位图、绘制图形,还可以直接操作DirectDrawSurface对象来处理显存或内存里的图像数据。一般来说它分成以下几种类型:primarysruf surface(主表面), 屏幕上可以看到的显示记忆体,图像画在上面就能显示在屏幕上;backsurf surface (后备表面),这是一个能跟primarysruf surface作快速切换的表面;offscreen surface (离屏表面),这是一个屏幕上看不见的Surface,主要用来存放图像数据。

  利用DirectDraw对象的CreateSurface方法可以建立一个DirectDrawSurface7对象,设置DDSURFACEDESC2结构对象的不同标志可以实现不同的表面对象。为了改善图像显示效果,在DirectDraw编程时,一般设立一个主表面、后备表面和若干个离屏表面,主表面就是用户看到的显示图像的表面,也就是当前显示的表面,后备表面是主表面的附带缓冲表面,用来存储、处理即将显示的图像,离屏表面用来装载最初的图像数据,可以利用DirectDraw对象的CreateSurfaceFromFile函数或者CreateSurfaceFromResource函数建立一个DirectDrawSurface7对象,同时将图象文件或者资源文件中的图像装入建立的 DirectDrawSurface中,该函数调用成功后返回一个DirectDrawSurface对象。

  处理后使用Blt函数将数据拷贝到后备表面,此时DirectDraw使用filp方法交换主表面和后备表面,后备表面变为主表面显示图像,先前的主表面变为后备表面,这样作既提高的图像数据的处理速度,又有效的避免图像闪烁,笔者认为这是DirectDraw编程中最重要的思想。

  上面给出了DirectDraw的主要编程步骤,为了使读者更清楚的了解一些编程细节,下面给出了一个具体的实现代码,该程序在Windows98、Visual Basic 6.0编译环境下编译通过,运行正常,它实现了全屏幕显示一个图像,同时在图像的左上方叠加了一行文字说明。读者可以在此基础上实现动画效果,比如让说明文字在背景图像上动态显示等。

//////////////////////////////////////
Option Explicitf '声名全局变量;
Dim dx As New DirectX7 'DirectX对象;
Dim dd As DirectDraw7 'DirectDraw对象;
Dim picturesurf As DirectDrawSurface7 '离屏表面对象;
Dim primarysruf As DirectDrawSurface7 '主表面对象;
Dim backsurf As DirectDrawSurface7 '后备表面对象;
Dim ddsd1 As DDSURFACEDESC2 'DDSURFACEDSC2对象;
Dim ddsd2 As DDSURFACEDESC2
Dim ddsd3 As DDSURFACEDESC2
Dim brunning As Boolean
Dim binit As Boolean
/////////////////////////////////////////////
Private Sub Form_Load()
 On Local Error GoTo errOut
 Set dd = dx.DirectDrawCreate("") '生成DirectDraw对象;
 Me.Show
 '设置协作模式
 Call dd.SetCooperativeLevel(Me.hWnd, DDSCL_FULLSCREEN Or DDSCL_ALLOWMODEX Or DDSCL_EXCLUSIVE)
 '设置"1024*768*24"的显示模式
 dd.SetDisplayMode 1024, 768, 24, 0, DDSDM_DEFAULT
 '设置主绘图平面的属性
 ddsd1.lFlags = DDSD_CAPS Or DDSD_BACKSURFCOUNT
 ddsd1.ddsCaps.lCaps = DDSCAPS_PRIMARYSRUFSURFACE Or DDSCAPS_FLIP Or DDSCAPS_COMPLEX
 ddsd1.lBacksurfCount = 1
 '创建主表面和后备表面;
 Set primarysruf = dd.CreateSurface(ddsd1)
 Dim caps As DDSURFACEDESC2
 '设置缓冲绘图平面的属性
 caps.lCaps = DDSCAPS_BACKSURF
 Set backsurf = primarysruf.GetAttachedSurface(caps)
 backsurf.GetSurfaceDesc ddsd3 '获取后备表面的尺寸;
 backsurf.SetForeColor vbBlue '设置后备表面中的字体颜色为蓝色;
 backsurf.SetFontTransparency True '设置后备表面的字体为透明效果;
 Set picturesurf = Nothing
 ddsd2.lFlags = DDSD_CAPS Or DDSD_HEIGHT Or DDSD_WIDTH
 ddsd2.ddsCaps.lCaps = DDSCAPS_OFFSCREENPLAIN
 ddsd2.lWidth = ddsd3.lWidth
 ddsd2.lHeight = ddsd3.lHeight
 Set picturesurf = dd.CreateSurfaceFromFile("c:\Waterskier.bmp", ddsd2)
 '离屏表面以全屏幕的尺寸来装载图像;
 binit = True
 brunning = True
 Do While brunning
  blt
  DoEvents
 Loop
errOut:
 '显示出现错误的情况下恢复系统的正常显示模式;
 Call dd.RestoreDisplayMode
 Call dd.SetCooperativeLevel(Me.hWnd, DDSCL_NORMAL)
End
End Sub
//////////////////////////////////////////
Private Sub Form_Paint() '窗口重画函数;
 blt
End Sub
///////////////////////////////////////////////////////
Sub blt() '"画图"函数;
 On Local Error GoTo errOut
 If binit = False Then Exit Sub
 Dim rPicture As RECT, rback As RECT
 rPicture.Bottom = ddsd2.lHeight
 rPicture.Right = ddsd2.lWidth
 rback.Bottom = ddsd3.lHeight
 rback.Right = ddsd3.lWidth
 Call backsurf.BltFast(0, 0, picturesurf, rPicture, DDBLTFAST_WAIT)
 '在表面上书写文字;
 Call backsurf.DrawText(20, 20, "DirectDarw 编程示范", False)
 Call backsurf.DrawText(20, 40, "单击鼠标后退出!", False)
 primarysruf.Flip Nothing, DDFLIP_WAIT
errOut:
 Call dd.RestoreDisplayMode
 Call dd.SetCooperativeLevel(Me.hWnd, DDSCL_NORMAL)
End Sub
/////////////////////////////////////////////
Private Sub Form_Click() '单击鼠标后程序结束程序运行;
 Call dd.RestoreDisplayMode
 Call dd.SetCooperativeLevel(Me.hWnd, DDSCL_NORMAL)
 End
End Sub

  上面的程序虽然比较简单,但是它包含了DirectDraw的基本应用。首先通过DirectX7的DirectDrawCreate方法建立一个DirectDraw对象,然后通过调用DirectDraw对象的SetCooperativeLevel 方法将程序设置为独占、全屏的模式,SetDisplayMode方法设置系统的显示模式。

  接下来是设置绘图平面,DDSURFACEDESC2结构的dwFlags成员用来决定DDSURFACEDESC2结构中哪些成员将被填充有效的信息,例如程序中在创建主表面时,将DDSURFACEDESC2结构的lFlags设为想要用DDSCAPS结构(DDSD_CAPS)和想创建后备表面(back buffer)(DDSD_BACKBUFFERCOUNT),ddCaps成员在例子中标示一个将要在DDSCAPS结构中使用的标志位,程序中指定了一个主表面(DDSCAPS_PRIMARYSURFACE)、一个交换页(DDSCAPS_FLIP)、一个合成表面(DDSCAPS_COMPLEX);DDSURFACEDESC2结构中lBacksurfCount成员为"1"说明当前要在主表面下建立一个后备表面。

  创建主表面后,程序通过调用主表面的GetAttachedSurface方法获取了后备表面。获取了表面对象后,调用表面对象的SetForeColor、 DrawText等方法就可以在相应的表面上添加特定效果的文本了。至于程序中绘制图像我就不多解释了,读者可以仔细阅读上面的代码,其实说白了,DirectDraw显示图像时无非就是在不同表面之间Blt图像数据罢了。

查看本文来源

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章