DirectX 视频闪烁

标签 directx doublebuffered direct3d

好吧,所以我写了一个自定义的VMR9 Allocator/Presenter,它看起来工作得很好。但是,当我尝试将视频帧从分配器/演示器表面复制到我的应用程序表面时,视频似乎闪烁。音频播放很好,所以我相当确定这不是机器陷入困境或其他任何问题。这是我的渲染循环中的代码。

g_pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(255, 0, 0, 0), 1.0f, 0);

// render the scene
if (SUCCEEDED(g_pd3dDevice->BeginScene()))
{
//g_pd3dDevice->SetRenderTarget(0, g_pd3dSurface);

g_pd3dDevice->StretchRect(vmr9_ap->renderSurface, src, g_pd3dSurface, dest, D3DTEXF_NONE);

    // end the scene
    g_pd3dDevice->EndScene();
}

但是,如果我将其更改为此(注释掉清除缓冲区)

// g_pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(255, 0, 0, 0), 1.0f, 0);

// render the scene
if (SUCCEEDED(g_pd3dDevice->BeginScene()))
{
//g_pd3dDevice->SetRenderTarget(0, g_pd3dSurface);

g_pd3dDevice->StretchRect(vmr9_ap->renderSurface, src, g_pd3dSurface, dest, D3DTEXF_NONE);

    // end the scene
    g_pd3dDevice->EndScene();
}

这种闪烁消失了。我担心这在某种程度上是一种不好的形式/黑客行为,并且可能会导致比它解决的问题更多的问题。有人有这方面的经验吗?有更好的解决办法吗?

谢谢!

最佳答案

如果您打算每帧重新绘制整个视口(viewport),则没有理由进行清除,而且它实际上可以带来很多性能提升,所以就去做吧!至于你的闪烁,那可能是不同的。您正在使用 WM_PAINT 消息进行绘图吗?如果是这样,您可能还想拦截 WM_ERASEBKGND 消息,并在收到它时简单地返回 1。这可以防止 Windows 尝试删除背景,并帮助我消除了过去的一些闪烁。

仅供引用:在《毁灭战士》或《雷神之锤》中,noclip 是否曾经作弊过,当你走到墙外时,一切都开始留下“痕迹”?这是因为他们没有清除后台缓冲区,因为在正常情况下,整个场景每次都会重新绘制。我说如果它对 id 来说足够好,那么对我来说就足够了! :)

编辑:哦,还有更多事情!我不确定是否需要,但我总是在调用 BeginScene() 之后进行清除。也可能导致你的闪烁。

关于DirectX 视频闪烁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1450291/

相关文章:

java - 窗口大小调整后调整组件大小

c++ - HLSL 在代码中获取线程组数和线程数

windows - DIDEVICEINSTANCE guidInstance 和 guidProduct 在同一设备上发生变化

java - 使用 JWindow 进行双缓冲

javascript - 如何提高我的 Canvas 动画速度?

directx - D3D9 中的抗锯齿/多重采样

multithreading - OpenGL PBO映射缓冲区: multi-threaded unpack slow, memcpy fast

c++ - Visual Studio Express 2010 C++ 反汇编调试

direct3d - DirectX 架构资源

xna - 使用 VS2012 Shader Designer 创建 XNA 着色器