游戏开发论坛

 找回密码
 立即注册
搜索
查看: 2329|回复: 5

用VB.net写了个Sprite类

[复制链接]

13

主题

594

帖子

595

积分

高级会员

Rank: 4

积分
595
发表于 2006-3-20 23:07:00 | 显示全部楼层 |阅读模式
和DX里的Sprite类差不多,用法也相近,功能比较简单,只写了这么多
只对连续绘制相同的图象做了优化


Imports Microsoft.DirectX
Imports Microsoft.DirectX.Direct3D
Imports System.Drawing

Public Class SESprite
    Implements System.IDisposable
    Private mVB As VertexBuffer '顶点缓冲
    Private mIB As IndexBuffer '索引缓冲
    Private mDevice As Device '设备
    Private mDrawDesc() As DrawDesc '绘制描述
    Private mDrawCount As Integer '绘制数量
    Private mDrawBufferMax As Integer = 10000 '绘制缓冲数量

    Public Sub Draw(ByVal srcTex As Texture, ByVal srcSize As Vector2, ByVal Center As Vector2, ByVal Position As Vector2, ByVal Color As Integer)
        Dim Desc As DrawDesc = AddDesc()
        Desc.Tex = srcTex
        Desc.X = -Center.X
        Desc.Y = -Center.Y
        Desc.Width = srcSize.X
        Desc.Height = srcSize.Y
        Desc.M11 = 1
        Desc.M22 = 1
        Desc.M41 = Position.X
        Desc.M42 = Position.Y
        Desc.Color = Color
        Desc.u1 = 0
        Desc.v1 = 0
        Desc.u2 = 1
        Desc.v2 = 1
    End Sub
    Public Sub Draw(ByVal srcTex As Texture, ByVal srcSize As Vector2, ByVal Center As Vector2, ByVal Position As Vector2, ByVal Scal As Vector2, ByVal Angle As Single, ByVal Color As Integer)
        Dim Desc As DrawDesc = AddDesc()
        Desc.Tex = srcTex
        Desc.X = -Center.X
        Desc.Y = -Center.Y
        Desc.Width = srcSize.X
        Desc.Height = srcSize.Y
        Dim tCosV As Single = CSng(Math.Cos(Angle))
        Dim tSinV As Single = CSng(Math.Sin(Angle))
        Desc.M11 = tCosV * Scal.X
        Desc.M21 = -tSinV * Scal.X
        Desc.M12 = tSinV * Scal.Y
        Desc.M22 = tCosV * Scal.Y
        Desc.M41 = Position.X
        Desc.M42 = Position.Y
        Desc.Color = Color
        Desc.u1 = 0
        Desc.v1 = 0
        Desc.u2 = 1
        Desc.v2 = 1
    End Sub

    Private Function AddDesc() As DrawDesc '添加绘制描述
        If mDrawCount >= mDrawBufferMax Then '绘制数量超过缓冲上限,立即绘制
            [End]()
            mDrawCount = 0
        End If
        If mDrawDesc(mDrawCount) Is Nothing Then
            AddDesc = New DrawDesc
            mDrawDesc(mDrawCount) = AddDesc
        Else
            AddDesc = mDrawDesc(mDrawCount)
        End If
        mDrawCount += 1
    End Function

    Public Sub [End]() '绘制
        If mDrawCount <= 0 Then Exit Sub
        mVB = New VertexBuffer(GetType(VTranColorTex), mDrawCount * 4, mDevice, Usage.None, VTranColorTex.Format, Pool.Managed)
        mIB = New IndexBuffer(GetType(Short), mDrawCount * 6, mDevice, Usage.None, Pool.Managed)

        Dim VBData As VTranColorTex()
        VBData = CType(mVB.Lock(0, LockFlags.None), VTranColorTex())
        Dim IBData As RectTriangleIndex()
        IBData = CType(mIB.Lock(0, GetType(RectTriangleIndex), LockFlags.None, mDrawCount), RectTriangleIndex())

        Dim i As Integer
        Dim tV As Integer
        For i = 0 To mDrawCount - 1
            tV = i * 4
            VSet.Vset(mDrawDesc(i), VBData(tV), VBData(tV + 1), VBData(tV + 2), VBData(tV + 3))
            IBData(i).SetData(tV)
        Next

        mVB.Unlock()
        mIB.Unlock()

        mDevice.SetStreamSource(0, mVB, 0)
        mDevice.VertexFormat = VTranColorTex.Format
        mDevice.Indices = mIB
        DrawPrimitives()

        mDrawCount = 0
        mVB.Dispose()
        mIB.Dispose()
    End Sub

    Private Sub DrawPrimitives()
        '绘制,对相同的连续的单位做优化
        Dim i As Integer
        Dim tTex As Texture
        Dim Start As Integer
        tTex = mDrawDesc(0).Tex
        For i = 1 To mDrawCount - 1
            If tTex Is mDrawDesc(i).Tex Then

            Else
                mDevice.SetTexture(0, tTex)
                mDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, Start * 4, (i - Start) * 4, Start * 6, (i - Start) * 2)
                tTex = mDrawDesc(i).Tex
                Start = i
            End If
        Next
        i = i - Start
        mDevice.SetTexture(0, tTex)
        mDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, Start * 4, i * 4, Start * 6, i * 2)
    End Sub

    Public Sub New(ByVal Device As Device)
        mDevice = Device
        ReDim mDrawDesc(mDrawBufferMax)
    End Sub

    Public Sub Dispose() Implements System.IDisposable.Dispose
        If Not (mVB Is Nothing) Then
            mVB.Dispose()
            mIB.Dispose()
        End If
        GC.SuppressFinalize(Me)
    End Sub

    Protected Overrides Sub Finalize()
        Dispose()
        MyBase.Finalize()
    End Sub

    Private Class DrawDesc
        Public Tex As Texture
        Public X, Y As Single
        Public Width, Height As Single
        Public M11, M12 As Single
        Public M21, M22 As Single
        Public M41, M42 As Single
        Public Color As Integer
        Public u1, v1, u2, v2 As Single
    End Class

    Private Class VSet
        Public Shared Sub Vset(ByVal Desc As DrawDesc, ByRef V1 As VTranColorTex, ByRef V2 As VTranColorTex, ByRef V3 As VTranColorTex, ByRef V4 As VTranColorTex)
            Dim tX, tY As Single
            Dim M11, M12 As Single
            Dim M21, M22 As Single
            Dim M41, M42 As Single
            M11 = Desc.M11
            M12 = Desc.M12
            M21 = Desc.M21
            M22 = Desc.M22
            M41 = Desc.M41
            M42 = Desc.M42

            tX = Desc.X
            tY = Desc.Y
            V1.X = tX * M11 + tY * M21 + M41
            V1.Y = tX * M12 + tY * M22 + M42
            'V1.Z = 0
            'V1.Rhw = 1
            V1.Color = Desc.Color
            V1.Tu = Desc.u1
            V1.Tv = Desc.v1

            tX = Desc.X + Desc.Width
            tY = Desc.Y
            V2.X = tX * M11 + tY * M21 + M41
            V2.Y = tX * M12 + tY * M22 + M42
            'V2.Z = 0
            'V2.Rhw = 1
            V2.Color = Desc.Color
            V2.Tu = Desc.u2
            V2.Tv = Desc.v1

            tX = Desc.X
            tY = Desc.Y + Desc.Height
            V3.X = tX * M11 + tY * M21 + M41
            V3.Y = tX * M12 + tY * M22 + M42
            'V3.Z = 0
            'V3.Rhw = 1
            V3.Color = Desc.Color
            V3.Tu = Desc.u1
            V3.Tv = Desc.v2

            tX = Desc.X + Desc.Width
            tY = Desc.Y + Desc.Height
            V4.X = tX * M11 + tY * M21 + M41
            V4.Y = tX * M12 + tY * M22 + M42
            'V4.Z = 0
            'V4.Rhw = 1
            V4.Color = Desc.Color
            V4.Tu = Desc.u2
            V4.Tv = Desc.v2
        End Sub
    End Class

    Public Structure SEMatrix '简化的2D矩阵
        Public M11, M12 As Single
        Public M21, M22 As Single
        Public M41, M42 As Single
        Public Function Modulate(ByVal inM As SEMatrix) As SEMatrix
            Dim newMatrix As SEMatrix
            newMatrix.M11 = M11 * inM.M11 + M12 * inM.M21
            newMatrix.M12 = M11 * inM.M12 + M12 * inM.M22

            newMatrix.M21 = M21 * inM.M11 + M22 * inM.M21
            newMatrix.M22 = M21 * inM.M12 + M22 * inM.M22

            newMatrix.M41 = M41 * inM.M11 + M42 * inM.M21 + inM.M41
            newMatrix.M42 = M41 * inM.M12 + M42 * inM.M22 + inM.M42
            Return newMatrix
        End Function
        Public Sub ModulateV(ByRef X As Single, ByRef Y As Single)
            Dim tX, tY As Single
            tX = X : tY = Y
            X = tX * M11 + tY * M21 + M41
            Y = tX * M12 + tY * M22 + M42
        End Sub
    End Structure

    Public Structure RectTriangleIndex '6个顶点索引
        Public AA, AB, AC As Short
        Public BA, BB, BC As Short
        Public Sub SetData(ByVal Data As Integer)
            AA = CShort(Data)
            AB = CShort(Data + 1)
            AC = CShort(Data + 2)
            BA = CShort(Data + 2)
            BB = CShort(Data + 1)
            BC = CShort(Data + 3)
        End Sub
    End Structure

    Public Structure VTranColorTex '顶点格式
        Public X As Single
        Public Y As Single
        Public Z As Single
        Public Rhw As Single
        Public Color As Integer
        Public Tu As Single
        Public Tv As Single
        Public Const Format As VertexFormats = VertexFormats.Diffuse Or VertexFormats.Transformed Or VertexFormats.Texture1
    End Structure
End Class

20

主题

451

帖子

470

积分

中级会员

Rank: 3Rank: 3

积分
470
发表于 2006-3-21 01:47:00 | 显示全部楼层

Re:用VB.net写了个Sprite类

何谓优化连画相同的图片?

13

主题

594

帖子

595

积分

高级会员

Rank: 4

积分
595
 楼主| 发表于 2006-3-21 02:37:00 | 显示全部楼层

Re:用VB.net写了个Sprite类

就是在一次DP/DIP命令中尽可能的画更多的东西

2D里面图片单位太多,而相对的每个单位又很简单(两个三角形而已),一次DP/DIP只画一个单位的话就太亏了……

20

主题

451

帖子

470

积分

中级会员

Rank: 3Rank: 3

积分
470
发表于 2006-3-21 02:49:00 | 显示全部楼层

Re:用VB.net写了个Sprite类

这样的,不过个人觉得没什么必要,用d3d来渲染2d对象效率应该够用了~

13

主题

594

帖子

595

积分

高级会员

Rank: 4

积分
595
 楼主| 发表于 2006-3-21 17:46:00 | 显示全部楼层

Re:用VB.net写了个Sprite类

只是渲染的话当然够了,但是过多的DP/DIP却是把时间浪费在非渲染上了,假如游戏中出现了3000-5000个以上的单位的话,就会发现优化与不优化完全是两个数量级的

13

主题

594

帖子

595

积分

高级会员

Rank: 4

积分
595
 楼主| 发表于 2006-3-21 18:53:00 | 显示全部楼层

Re: Re: Re:用VB.net写了个Sprite类

惩伐者: Re: Re:用VB.net写了个Sprite类



3000-5000个以上的单位有这个可能吗?
举个游戏例子吧!


假如游戏中出现了3000-5000个以上的单位的话

请注意第一个词:“假如”

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2026-1-23 23:53

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表