簡體   English   中英

使用SlimDX進行雙緩沖

[英]Using double-buffering with SlimDX

我正在嘗試使用SlimDX來創建DirectX9應用程序。

如果我使用.PresentationInterval = PresentInterval.Default ,它會顯示〜我的顯示器的刷新率並且看起來很好。

如果我使用.PresentationInterval = PresentInterval.Immediate ,我得到~6,000 FPS但是存在嚴重的閃爍 - 可能是因為當立即呈現發生時設備正在被更新,因此它可能正確繪制也可能不正確。

有人可以告訴我如何使用后台緩沖區,以便在完成繪圖后立即不閃爍並交換緩沖區嗎?

顯然,我實際上並不想要6K FPS,但我確實希望控制幀速率上限,並且對緩沖有更好的理解。

設備初始化

PresentParameters = New PresentParameters()

With PresentParameters
    .BackBufferFormat = Format.X8R8G8B8
    .BackBufferCount = 2
    .Multisample = MultisampleType.None
    .SwapEffect = SwapEffect.Discard
    .EnableAutoDepthStencil = True
    .AutoDepthStencilFormat = Format.D24S8
    .PresentFlags = PresentFlags.DiscardDepthStencil
    .PresentationInterval = PresentInterval.Default '' or PresentInterval.Immediate
    Select Case Settings.Display.Mode
        Case WindowMode.FullScreen
            .BackBufferWidth = Settings.Display.Width
            .BackBufferHeight = Settings.Display.Height
            .Windowed = False
        Case WindowMode.Windowed Or WindowMode.WindowedNoBorder
            .BackBufferWidth = Settings.Display.Width
            .BackBufferHeight = Settings.Display.Height
            .Windowed = True
    End Select
    .DeviceWindowHandle = Handle
End With

Direct3D = New Direct3D()
Device = New Device(Direct3D,
                    Settings.Display.Adapter,
                    DeviceType.Hardware,
                    Handle,
                    CreateFlags.HardwareVertexProcessing,
                    PresentParameters)

最小渲染樣本......

Context9.Device.BeginScene()
Context9.Device.Clear(Direct3D9.ClearFlags.Target Or Direct3D9.ClearFlags.ZBuffer,
                Color.Black,
                1.0F,
                0)

Game.Render(Context9)

Using Sprite As New Sprite(Context9.Device)
    Sprite.Begin(SpriteFlags.AlphaBlend)
    Dim Mtx = Matrix.Translation(125, 200, 0)
    Dim Scaling = Matrix.Scaling(0.5, 0.5, 1)
    Matrix.Multiply(Mtx, Scaling, Mtx)
    Sprite.Transform = Mtx

    Dim Fade As Single = CSng(Math.Min(1, Math.Sin(FrameI / 30) * 0.5 + 0.5))
    Sprite.Draw(TestTex,
                Nothing,
                Nothing,
                Nothing,
                New Color4(Fade, Fade, Fade))


    Sprite.End()
End Using

Context9.Device.EndScene()

Context9.Device.Present()

窗口創建/主循環

Private Sub Run()
    Application.EnableVisualStyles()
    Application.SetCompatibleTextRenderingDefault(False)

    Window = New RenderForm("Test")

    InitializeDevice()

    ''Add lots of key handlers, etc here

    LoadResources()

    Clock.Start()
    MessagePump.Run(Window, AddressOf MessageLoop)
    Cleanup()

    Window.Dispose()
End Sub

Sub MessageLoop()
    Update()
    If Not IsResizing Then
        Render()
    End If
End Sub

(我省略了顯示FPS /其他位的代碼,因為它只是噪聲,但如果需要可以提供它)

我錯了,但我相信這與DirectX沒有關系。 您必須在窗口創建時啟用雙緩沖。

  • 如果您在使用System.Windows.Forms ,然后調用Control.SetStyle()所描述的在這里

     public void EnableDoubleBuffering() { // Set the value of the double-buffering style bits to true. this.SetStyle(ControlStyles.DoubleBuffer | ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint, true); this.UpdateStyles(); } 
  • 或者更好,只需使用SlimDX.Windows.RenderForm 它派生自Form ,默認啟用雙緩沖。

閃爍的另一個原因可能是錯誤的主循環結構。 您沒有向我們展示您的主循環以及如何調用渲染功能。 您可以在教程中找到典型的渲染循環。

希望能幫助到你!

DirectX總是使用雙緩沖,你不能解決這個問題(你可以去做tripple緩沖,但到目前為止我還沒有看到一個用例)。

發生的情況是,使用Default,后備緩沖區將被復制到監視器的兩個幀之間的屏幕上。 使用Immediate,直接發生這種情況。 這將總是閃爍一點,特別是如果新圖像與舊圖像非常不同,因為屏幕的上半部分將顯示一個圖像而下一個圖像將顯示底部。 對於大多數情況,渲染速度比監視器的刷新速率快。

所以....事實證明這是一個愚蠢的案例。

Dim Fade As Single = CSng(Math.Min(1, Math.Sin(FrameI / 30) * 0.5 + 0.5))

正如您將注意到的,衰落基於幀數而不是經過的時間。 所以當幀率上升時,褪色速度也會上升......

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM