用于仿真器的 VB6 垂直同步

发布于 2024-07-26 22:24:48 字数 126 浏览 6 评论 0 原文

这可能是一个间接的问题:

我正在用 VB6 编写一个模拟器(我很傻)。 为了在模拟器本身中平滑地刷新窗口,我想获取显示器的垂直同步。 我可以使用任何 Windows API 调用吗? 或者这是一个不可能的要求?

This is maybe an oblique question:

I'm writing an emulator in VB6 (silly me). For smooth window refreshing in the emulator itself, I would like to grab the vertical sync of the monitor. Are there any Windows API calls I can use? Or is this an impossible request?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

原谅我要高飞 2024-08-02 22:24:49

我相信,最好使用 DirectX API WaitForVerticalBlank 来实现这一点,它是 DirectDraw v7 及以上版本的一部分。 比在 RasterStatus 中查找要简单得多。

This is best achieved using the DirectX API WaitForVerticalBlank, part of DirectDraw from v7 onward, I believe. Much simpler than rooting around in RasterStatus.

归属感 2024-08-02 22:24:49

WPF 工具在 XP 上起作用,但只能工作引入开放GL,但这可能不受所有人支持视频卡。

唯一有效的解决方案是使用 Direct3D,但您不必将其用于渲染。 只需利用其功能即可。 看起来 IDirect3DDevice9::GetRasterStatus() 是只是事情。 您的第一顺序解决方案可以轮询该问题,直到报告 InVBlank TRUE。 然后,您可以执行二阶解决方案,通过一帧进行轮询以确定垂直同步速率和相对时间。 然后使用计时器来保持同步。 也许每半帧醒来一次,并验证在脱离垂直同步时是否命中相同的扫描线。 这样您就可以调整时间以保持同步。

我有自己的宠物模拟器,可以使用此功能。 如果我编写解决方案,我将在此处发布更多详细信息。

There are WPF facilities which function on XP but only work properly on Vista. You can bring in open GL but that may not be supported by all video cards.

The only effective solution is to use Direct3D, but you don't have to use it for your rendering. Just piggyback its capabilities. Looks like IDirect3DDevice9::GetRasterStatus() is just the thing. Your first order solution can poll that until it reports InVBlank TRUE. Then you can do a second order solution where you poll it through one frame to determine vsync rate and relative timing. Then use a timer to keep in sync. Perhaps waking up every half frame and verify that you're hitting about the same scan line when out of vsync. That way you can adjust the timing to keep in sync.

I've got my own pet emulator that could use this functionality. If I code up a solution I'll post more details here.

紙鸢 2024-08-02 22:24:49

您要求“显示器的垂直同步”。 垂直同步是一种显卡设置,可将帧渲染速率锁定到显示器刷新率。 据 NVida 称,“这通过消除 3D 图像中的水平撕裂效应来提高图像质量。” 您想知道垂直同步是打开还是关闭,或者您正在寻找显示器的刷新率吗? 我不知道如何做前者,但你可以这样得到后者:

Private Const CCHDEVICENAME = 32
Private Const CCHFORMNAME = 32

Private Type DEVMODE
    dmDeviceName As String * CCHDEVICENAME
    dmSpecVersion As Integer
    dmDriverVersion As Integer
    dmSize As Integer
    dmDriverExtra As Integer
    dmFields As Long
    dmOrientation As Integer
    dmPaperSize As Integer
    dmPaperLength As Integer
    dmPaperWidth As Integer
    dmScale As Integer
    dmCopies As Integer
    dmDefaultSource As Integer
    dmPrintQuality As Integer
    dmColor As Integer
    dmDuplex As Integer
    dmYResolution As Integer
    dmTTOption As Integer
    dmCollate As Integer
    dmFormName As String * CCHFORMNAME
    dmUnusedPadding As Integer
    dmBitsPerPel As Long
    dmPelsWidth As Long
    dmPelsHeight As Long
    dmDisplayFlags As Long
    dmDisplayFrequency As Long
End Type

Private Declare Function EnumDisplaySettings Lib "user32.dll" Alias _
    "EnumDisplaySettingsA" (ByVal lpszDeviceName As String, _
    ByVal iModeNum As Long, ByRef lpDevMode As DEVMODE) As Long

Private Function GetRefreshRate() As Long

    Dim dm As DEVMODE

    dm.dmSize = Len(dm)
    EnumDisplaySettings vbNullString, ENUM_CURRENT_SETTINGS, dm

    GetRefreshRate = dm.dmDisplayFrequency

End Function

You are asking for the "vertical sync of the monitor". Vertical sync is a graphics card setting that locks the frame rendering rate to the monitor refresh rate. According to NVida, "This improves image quality by eliminating horizontal tearing effects in the 3D image." Do you want to know whether vertical sync is on or off or were you looking for the refresh rate of the monitor? I don't know how to do the former, but you can get the latter this way:

Private Const CCHDEVICENAME = 32
Private Const CCHFORMNAME = 32

Private Type DEVMODE
    dmDeviceName As String * CCHDEVICENAME
    dmSpecVersion As Integer
    dmDriverVersion As Integer
    dmSize As Integer
    dmDriverExtra As Integer
    dmFields As Long
    dmOrientation As Integer
    dmPaperSize As Integer
    dmPaperLength As Integer
    dmPaperWidth As Integer
    dmScale As Integer
    dmCopies As Integer
    dmDefaultSource As Integer
    dmPrintQuality As Integer
    dmColor As Integer
    dmDuplex As Integer
    dmYResolution As Integer
    dmTTOption As Integer
    dmCollate As Integer
    dmFormName As String * CCHFORMNAME
    dmUnusedPadding As Integer
    dmBitsPerPel As Long
    dmPelsWidth As Long
    dmPelsHeight As Long
    dmDisplayFlags As Long
    dmDisplayFrequency As Long
End Type

Private Declare Function EnumDisplaySettings Lib "user32.dll" Alias _
    "EnumDisplaySettingsA" (ByVal lpszDeviceName As String, _
    ByVal iModeNum As Long, ByRef lpDevMode As DEVMODE) As Long

Private Function GetRefreshRate() As Long

    Dim dm As DEVMODE

    dm.dmSize = Len(dm)
    EnumDisplaySettings vbNullString, ENUM_CURRENT_SETTINGS, dm

    GetRefreshRate = dm.dmDisplayFrequency

End Function
流云如水 2024-08-02 22:24:49

如果您确实想在 VB6 中执行此操作,则必须考虑 DirectX。 这里是如何在 Vb6 中执行 DirectX 的良好起点。 星球源代码CDVG 还有一些教程。

If you really want to do this in VB6, you are going to have to look at DirectX. Here is a good starting ground for how to do DirectX in Vb6. Planet Source Code and CDVG have some more tutorials.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文