繁体   English   中英

我在使用双缓冲吗?

[英]Am I using double buffering?

我正在构建一个 Windows MFC 应用程序。 在一些物体高速碰撞的动画中,我的物理引擎表现得无法预测。 我相信这与我以某种方式掉帧有关。 有人告诉我我没有使用双缓冲。 我以为我是,但我对此还是很陌生。 这是我在 OnPaint 中绘制到屏幕的方式:

#include "pch.h"
#include "framework.h"
#include "ChildView.h"
#include "DoubleBufferDC.h"

void CChildView::OnPaint()
{
    CPaintDC paintDC(this);     // device context for painting
    CDoubleBufferDC dc(&paintDC); // device context for painting
    Graphics graphics(dc.m_hDC);    // Create GDI+ graphics context
    mGame.OnDraw(&graphics);

    if (mFirstDraw)
    {
        mFirstDraw = false;
        SetTimer(1, FrameDuration, nullptr);

        /*
         * Initialize the elapsed time system
         */
        LARGE_INTEGER time, freq;
        QueryPerformanceCounter(&time);
        QueryPerformanceFrequency(&freq);

        mLastTime = time.QuadPart;
        mTimeFreq = double(freq.QuadPart);
    }

    /*
     * Compute the elapsed time since the last draw
     */
    LARGE_INTEGER time;
    QueryPerformanceCounter(&time);
    long long diff = time.QuadPart - mLastTime;
    double elapsed = double(diff) / mTimeFreq;
    mLastTime = time.QuadPart;

    mGame.Update(elapsed);
}

void CChildView::OnTimer(UINT_PTR nIDEvent)
{
    // TODO: Add your message handler code here and/or call default
    RedrawWindow(NULL, NULL, RDW_UPDATENOW);
    Invalidate();
    CWnd::OnTimer(nIDEvent);
}

当我从 CDoubleBufferDC object 创建图形 object 时,这不是在创建后台缓冲区吗? 然后我将此图形 object 传递给绘制它的 OnDraw。 如果它正在创建一个后台缓冲区,我对创建前台缓冲区的位置以及在屏幕上绘制它的时间感到困惑。

以下是我目前对我认为这是如何工作的想法:

  1. CPaintDC object是前台缓冲区
  2. CDoubleBufferDC object 是后台缓冲区
  3. 图形 object 是从 CDoubleBufferDC object 创建的,我在上面绘制了游戏的当前 state

如果是这种情况,前台缓冲区何时会被后台创建的新缓冲区替换? 有人可以帮助我理解,如果我还没有使用双缓冲吗?

要回答您的实际问题,可能发生的情况是您的 CDoubleBufferDC() class 有一个换出 DC 的析构函数 - 这是一个常见的习语(“现代”MFC 版本中的 IIRC CMemDC 也这样做)。 所以是的,我认为你在这里使用双缓冲,即使是不小心。 简单的游戏你可以用GDI(+)画图,如果这整个事情是一个学习练习,这种方式比使用DirectX更容易理解。

但是,您确实需要将碰撞检测与绘图例程分离,这样任何丢失的帧都不会打乱您的时间(也就是说,如果您的事情太复杂以至于需要那么多时间 - 在这种情况下,您可能不应该使用 GDI...)。 换句话说,如果您的碰撞检测假设每个 OnDraw() 调用在不到 1/framerate 秒内完成,但这并不总是发生,那么您有时会遇到问题。 网上有很多关于如何构建游戏循环的文章; 我没有足够的信息将您链接到特定的。 此外,要在 2020 年找到使用您正在使用的技术的技术并不容易……但我确实认为使用简单的 OnPaint()/GDI 非常适合学习,因为它会隐藏很多复杂性您需要更现代的方法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM