public void MainLoop() { var context = new System.Windows.Forms.ApplicationContext(this); context.MainForm.Visible = true; var openAdapter = new D3DKMT_OPENADAPTERFROMHDC(); var waitForVblankEvent = new D3DKMT_WAITFORVERTICALBLANKEVENT(); openAdapter.hDc = CreateDC(Screen.PrimaryScreen.DeviceName, null, null, IntPtr.Zero); bool useD3DKMT = false; double targetTime = 1.0 / 60; if (D3DKMTOpenAdapterFromHdc(ref openAdapter) == 0) { useD3DKMT = true; waitForVblankEvent.hAdapter = openAdapter.hAdapter; waitForVblankEvent.hDevice = 0; waitForVblankEvent.VidPnSourceId = openAdapter.VidPnSourceId; } else { var mode = new DEVMODE(); if (EnumDisplaySettings(null, ENUM_CURRENT_SETTINGS, ref mode) && mode.dmBitsPerPel > 0) { targetTime = 1.0 / mode.dmDisplayFrequency; } } while (!IsDisposed) { var msg = new MSG(); while (PeekMessage(ref msg, IntPtr.Zero, 0, 0, 0x0001 /*PM_REMOVE*/)) { TranslateMessage(ref msg); DispatchMessage(ref msg); } if (useD3DKMT) { D3DKMTWaitForVerticalBlankEvent(ref waitForVblankEvent); if (!_control.OnRender()) { return; } } else { var startTime = Clock.GetSeconds(); if (!_control.OnRender()) { return; } var renderTime = Clock.GetSeconds() - startTime; var msTimeout = (int)((targetTime - renderTime) * 1000.0 + 0.5); if (msTimeout > 0) { Thread.Sleep(msTimeout); } } } }
public static extern uint D3DKMTOpenAdapterFromHdc(ref D3DKMT_OPENADAPTERFROMHDC pData);