2
\$\begingroup\$

I need to make a simple enough program in C#, but it seems to be impossible via usual WinForms means. I need to show something (a string of text, an image) on the screen for very small time interval. Since typical monitors are 60Hz, this interval would be 1 or 2 frames (16,6 or 33,3 ms). I tried doing this with usual WinForms, and it is not possible because, apparently, there is no way to know how many frames were output to the monitor since some point in time. I can only draw on the controls, and monitor output is totally independant.

So even if I run the timer, say, for 17 ms, between showing and hiding the image, it still sometimes manages not to draw a single frame of my image on the screen (even though theoretically it should, because 17ms > 16,6ms). Moreover, even 20ms seems to slow (even though i should be more than enough).

I did some game development as a hobby in the past (Delphi X, XNA) and I know that you usually draw the whole screen by yourself, each frame. Also, I know that there is an option called Vsync in most modern games, that allows you to synchronize your framerate to your monitor's frame rate.

So, is it possible? I mean, to actually know how many frames were sent to the monitor with w/e I want to show?

EDIT:

After doing some study, I guess there really is no way to check when monitor is updated. All you can do is use vsync - and all that does it just pauses your double-buffer-flipping until right after monitor refresh. Which would achieve what I want... if only it would be possible to guarantee that it will actually work! Turns out, it works only if it was not disabled previously in one of the million ways to disable it (like, in the driver, in the driver-bundled software, and wherever else).

I guess there is no way from your software to check if vsync is disabled in the driver either... Or is there? I guess only outputting several frames and checking timestamps between them - like, does outputting a blank screen and swapping buffers takes 16,(6)ms or 0,1 ms.

Anyways, I think I'll be using C# SDL and try to somehow do it via setting double buffering and swap control... If someone has useful information to add though, please do!

\$\endgroup\$
3
  • \$\begingroup\$ I edited your post to remove the side question, it was a "which tech to use" question, which are off topic here. See the help center for more info about those. \$\endgroup\$
    – House
    Commented Nov 11, 2013 at 14:25
  • \$\begingroup\$ How long do you have to make that sleep in your WinForms code for the image to show up reliably? \$\endgroup\$
    – Adam
    Commented Nov 11, 2013 at 23:25
  • \$\begingroup\$ Well, if I do it for ~30ms, I haven't yet encountered a single event of text/image not showing, but first, this isn't reliable - I mean, I'd have to test for like 1 000 000 times to be absolutely sure, and second, this means that sometimes it shows for 1 frame, sometimes for 2 frames - I need it to show consistently for same period of time. \$\endgroup\$
    – Istrebitel
    Commented Nov 12, 2013 at 7:25

1 Answer 1

1
\$\begingroup\$

VSync is generally not possible to control precisely on a PC without writing driver level code. Most graphics drivers even have an option to disable it completely. However there is an OpenGL API for controlling it on Windows (which doesn't override driver settings).

Also note that not everybody's monitor is 60Hz. There's some 120Hz ones available for example so you'll need to do some high precision timing to get it right (on Windows that generally means using either timeBeginPeriod(1) or QueryPerformanceCounter()).

\$\endgroup\$
2
  • \$\begingroup\$ It's not about exactly X frames, but moreso about exactly X ms, and this X must be small enough (25ms or less) so 1 frame of 60Hz monitor (or 2 frames of 120Hz monitor) is the target. Problem is getting exactly 1 frame - on WinForms I keep getting zero (even with 20ms timer on a 60Hz monitor) \$\endgroup\$
    – Istrebitel
    Commented Nov 11, 2013 at 13:17
  • \$\begingroup\$ I edited the OP and have edited your answer to match the updated question. \$\endgroup\$
    – House
    Commented Nov 11, 2013 at 14:26

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .