VB.NET实现DirectDraw9 (1) 托管的DDraw

原创 2005年02月26日 10:15:00

关键字: VB.NET DirectX DirectDraw 9                             作者:董含君
转载请注明来自: http://blog.csdn.net/a11s

================以下为废话(记日记是好习惯)===============
本来应该继续DirectSound 混音的,但是今天由于时间关系,完不成任务了.

发现国外的一个站点,里面的人比较牛X 直接自己用binaryreader读取wav

自愧不如啊~~~

================End 废话===============================

很多人都认为DirectDraw在DirectX7时代就终结了,到了VB.NET以及托管的DirectX

微软要继承旧的DirectDraw,又要托管.所以DDraw毕竟是有变化的.

现在拾起来.有点不适应.但是基本概念还是不会变化的.

国内高手对此不屑,而且还有人会了3D后敌视2D,我就不发表评论了,倒是让我有了填补国内空白的机会了

首先说大体过程.我的学习笔记比较基础,不是为了体现DDraw的性能,而是理清步骤(微软的例子就麻烦4了)

0 工程添加DirectDraw的引用,代码里面imports Microsoft.DirectX.DirectDraw

1 创建Device 设置合作级别 (只要是DirectX 都要这样)

2 创建描述 (为了创建Surface做准备,跟DirectSound创建Buffer的描述一个道理)

3 利用描述创建主缓冲以及二级缓冲(就是BackSurface)

4 为主缓冲指定一个Clipper

=============加载完成==================

绘制过程比较简单,你可以使用Timer设置时间间隔.但是一般人不会这么作,虽然实现过程简单.

为了体现平滑的动画,往往CPU能用就用,FPS越高越好(其实太高了也没用,但是当动画复杂的时候就有用了)

以下是参考大风给我的计时器.

        Dim tfp As Integer = 0                                      '''fps

        Dim mytime As Date = DateTime.Now                           '''临时用一下

        While (run = True)                                          '''如果游戏没有结束

            blt()                                                   '''主要绘制过程

            tfp += 1                                                '''fps++

            If tfp = 200 Then                                       '''200次的时候计算时间

                tfp = 0

                Dim ts As New TimeSpan

                ts = (DateTime.Now.Subtract(mytime))

                mytime = DateTime.Now

                If ts.TotalSeconds <> 0 Then

                    Dim qiqi As Double = 200 / (ts.TotalSeconds)

                    Me.Text = qiqi.ToString("##.##") + "F c"

                End If

 

            End If

 

            TT.Sleep(20)                                            '''硬性规定休息一下,当然可以去掉发挥MAX速度

        End While

需要知道,里面的变量都是临时定义的,如果你对速度很在意,这样做是不可取的,但是为了理解方便,所以才这么作,进行优化的时候就要拿出来了.

有了计数器,用它建立了游戏循环.循环自己管理主要的blt()过程,blt也很简单

    Sub blt()

 

        If PS Is Nothing Then Exit Sub

        Dim r1 As Rectangle

        Dim r2 As Rectangle

        r2.Height = desc2.Height

        r2.Width = desc2.Width

        r1.Height = P.Size.Height

        r1.X = 0

        r1.Y = 0

        r1.Width = P.Size.Width

        PS.Draw(r1, BS, r2, DrawFlags.Wait)

 

    End Sub

就是设置好矩形区域然后绘制,这里不再是DDraw7的RECT了,里面多少有些变化.

调用游戏循环很简单,直接main2就可以,但是不可取,这样做会让你的程序”卡死”,导致程序没有响应

需要新开一个线程处理这件事情

    Private Sub Label2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Label2.Click

        run = Not run

        If TT Is Nothing Then

            TT = New Threading.Thread(AddressOf main2)

            TT.Start()

        End If

    End Sub

ok,具体需要注意的就这么多,以下为全部源代码

======================================

Imports Microsoft.DirectX.DirectDraw

Imports Microsoft.DirectX

Imports System.Drawing

 

 

Public Class Form1

    Inherits System.Windows.Forms.Form

    Dim Dev As Device

    Dim PS As Surface

    Dim BS As Surface

    Dim desc As SurfaceDescription

    Dim desc2 As SurfaceDescription

    Dim Clip As Clipper

    Dim T As New Date

    Dim run As Boolean

    Dim TT As Threading.Thread

    Const fn = "d:/nerv.bmp"

 

#Region " Windows 窗体设计器生成的代码 "

 

    Public Sub New()

        MyBase.New()

 

        '该调用是 Windows 窗体设计器所必需的。

        InitializeComponent()

 

        '在 InitializeComponent() 调用之后添加任何初始化

 

    End Sub

 

    '窗体重写 dispose 以清理组件列表。

    Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)

        If disposing Then

            If Not (components Is Nothing) Then

                components.Dispose()

            End If

        End If

        MyBase.Dispose(disposing)

    End Sub

 

    'Windows 窗体设计器所必需的

    Private components As System.ComponentModel.IContainer

 

    '注意: 以下过程是 Windows 窗体设计器所必需的

    '可以使用 Windows 窗体设计器修改此过程。

    '不要使用代码编辑器修改它。

    Friend WithEvents P As System.Windows.Forms.PictureBox

    Friend WithEvents Label1 As System.Windows.Forms.Label

    Friend WithEvents Label2 As System.Windows.Forms.Label

    <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()

        Me.P = New System.Windows.Forms.PictureBox

        Me.Label1 = New System.Windows.Forms.Label

        Me.Label2 = New System.Windows.Forms.Label

        Me.SuspendLayout()

        '

        'P

        '

        Me.P.Location = New System.Drawing.Point(40, 48)

        Me.P.Name = "P"

        Me.P.Size = New System.Drawing.Size(640, 480)

        Me.P.TabIndex = 0

        Me.P.TabStop = False

        '

        'Label1

        '

        Me.Label1.Location = New System.Drawing.Point(16, 16)

        Me.Label1.Name = "Label1"

        Me.Label1.Size = New System.Drawing.Size(72, 24)

        Me.Label1.TabIndex = 1

        Me.Label1.Text = "init"

        '

        'Label2

        '

        Me.Label2.Location = New System.Drawing.Point(112, 16)

        Me.Label2.Name = "Label2"

        Me.Label2.Size = New System.Drawing.Size(80, 16)

        Me.Label2.TabIndex = 2

        Me.Label2.Text = "draw"

        '

        'Form1

        '

        Me.AutoScaleBaseSize = New System.Drawing.Size(6, 14)

        Me.ClientSize = New System.Drawing.Size(728, 541)

        Me.Controls.Add(Me.Label2)

        Me.Controls.Add(Me.Label1)

        Me.Controls.Add(Me.P)

        Me.Name = "Form1"

        Me.Text = "Form1"

        Me.ResumeLayout(False)

 

    End Sub

 

#End Region

 

    Private Sub Label1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Label1.Click

        initDD()

    End Sub

 

    Sub initDD()

        Dev = New Device(CreateFlags.Default)

        Dev.SetCooperativeLevel(Me, CooperativeLevelFlags.Normal)

 

        Dim caps As New SurfaceCaps

        Dim caps2 As New SurfaceCaps

        caps.PrimarySurface = True

        caps.VideoMemory = True

        caps2.OffScreenPlain = True

 

        desc = New SurfaceDescription(caps)

        desc2 = New SurfaceDescription(caps2)

        desc2.EmptyFaceColor = RGB(0, 0, 255)

 

        Clip = New Clipper(Dev)

        Clip.Window = P

        BS = New Surface(fn, desc2, Dev)

        PS = New Surface(desc, Dev)

        PS.Clipper = Clip

        Me.Text = "loaded"

 

    End Sub

 

    Private Sub Label2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Label2.Click

        run = Not run

        If TT Is Nothing Then

            TT = New Threading.Thread(AddressOf main2)

            TT.Start()

        End If

    End Sub

    Sub blt()

 

        If PS Is Nothing Then Exit Sub

        Dim r1 As Rectangle

        Dim r2 As Rectangle

        r2.Height = desc2.Height

        r2.Width = desc2.Width

        r1.Height = P.Size.Height

        r1.X = 0

        r1.Y = 0

        r1.Width = P.Size.Width

        PS.Draw(r1, BS, r2, DrawFlags.Wait)

 

    End Sub

 

    Sub main2()

        Dim tfp As Integer = 0                                      '''fps

        Dim mytime As Date = DateTime.Now                           '''临时用一下

        While (run = True)                                          '''如果游戏没有结束

            blt()                                                   '''主要绘制过程

            tfp += 1                                                '''fps++

            If tfp = 200 Then                                       '''200次的时候计算时间

                tfp = 0

                Dim ts As New TimeSpan

                ts = (DateTime.Now.Subtract(mytime))

                mytime = DateTime.Now

                If ts.TotalSeconds <> 0 Then

                    Dim qiqi As Double = 200 / (ts.TotalSeconds)

                    Me.Text = qiqi.ToString("##.##") + "F c"

                End If

 

            End If

 

            TT.Sleep(20)                                            '''硬性规定休息一下,当然可以去掉发挥MAX速度

        End While

    End Sub

 

    Private Sub Form1_Closing(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles MyBase.Closing

        End

    End Sub

End Class

 

====================================================

需要注意的是,这里进行绘制的时候,图片的位置是相对屏幕左上角的,只要你改变响应的rect就可

因为获得坐标牵扯到其他地方,不宜于降低本文难度,所以没加.

下一步的DirectDraw   全屏幕的动画 以及出现角色绘制

DirectSound混音好像很麻烦.....

VB.NET实现DirectDraw9 (2) 动画

关键字: VB.NET  DirectX DirectDraw 9                                    作者:董含君转载请注明来自 http://blog.csdn....
  • a11s
  • a11s
  • 2005年02月26日 18:25
  • 1553

vb.net托管线程池

托管线程池 发送反馈 ThreadPool 类为应用程序提供一个由系统管理的辅助线程池,从而使您可以集中精力于应用程序任务而不是线程管理。 如果您具有需...
  • wuhenzhangxing
  • wuhenzhangxing
  • 2015年01月13日 18:15
  • 2732

M8SDK教程-游戏开发心得(三):DDraw进阶教程-贴图,Alpha和Sprite动画,RPG游戏雏形

M8SDK教程-游戏开发心得(三):DDraw进阶教程-贴图,Alpha和Sprite动画,RPG游戏雏形引用:M8SDK教程-游戏开发心得(一): 游戏程序框架http://bbs.meizu.co...
  • ThinkingAboutLife
  • ThinkingAboutLife
  • 2010年01月22日 14:09
  • 1743

VB.net学习笔记(三)调试

1、下断点 就是在代码左侧处点一下鼠标,代码执行到此处,就会断下来 2、显示立即值 断后,鼠标指向变量时会显示值。 同时会有一个小窗体,可点图钉,让其固定显示 ...
  • dzweather
  • dzweather
  • 2013年07月20日 23:07
  • 3502

DDraw、D3D渲染效果的分析

DDraw Direct3D 离屏渲染 纹理渲染 文本叠加 灵活顶点格式
  • chen_0306
  • chen_0306
  • 2015年07月23日 00:13
  • 986

Ddraw--DirectDraw与GDI

DirectDraw与GDI区别如下: 1 DirectDraw是在GDI的基础上做的,是GDI的升级版。         GDI(Graphics Deveice Interface,图形设备接...
  • evsqiezi
  • evsqiezi
  • 2012年11月23日 17:06
  • 1375

用DirectDraw实现屏幕截图

  在DirectDraw的非独占模式中,主表面即为当前屏幕。你可以直接Lock住主表面,从而取得主表面图象数据。但如果你要对大量的数据进行直接的操作,最好还是先在系统内存中建一个和主表面一样大小的后...
  • Garfield
  • Garfield
  • 2005年02月12日 15:22
  • 5438

ddraw 显示YUV视频数据

#include "stdafx.h" #include "MyDDraw.h" CMyDDraw::CMyDDraw(void) {     m_hShowHwnd = NULL;  ...
  • goodadult2012
  • goodadult2012
  • 2014年10月30日 19:24
  • 1983

关于调用系统API 提示PInvoke 签名与非托管的目标签名不匹配问题的解决方案

关于C#调用系统API 提示PInvoke 签名与非托管的目标签名不匹配。请检查 PInvoke 签名的调用约定和参数与非托管的目标签名是否匹配。这类问题解决方案。 在网上搜了一些帖子看有说在DllI...
  • zhaoyun927
  • zhaoyun927
  • 2016年08月15日 14:09
  • 1692

DDraw的离屏blt

先说下操作吧:就是在两个离屏页面上相互blt,最后在一起blt到主页面上.(如离屏A,离屏B.要把离屏B的数据blt到A上,当然不是全部覆盖A了.全部覆盖A就没有意义了.就是覆盖A中的一小部分.最后统...
  • nogodoss
  • nogodoss
  • 2009年05月08日 17:43
  • 2050
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:VB.NET实现DirectDraw9 (1) 托管的DDraw
举报原因:
原因补充:

(最多只允许输入30个字)