0


I'm working on OpenGL project and I'm using VS15 C++.
My code:

timeBeginPeriod(1);

//start timer to measure the gap 
GetSystemTime(&timeMiddle);             
timeMiddleLong = (timeMiddle.wMinute * 60 * 1000) +                                        
       (timeMiddle.wSecond * 1000) + timeMiddle.wMilliseconds;
myfile << "middle time = " << timeMiddleLong << endl;


glClearColor(1.0f, 0, 0, 1.0f);//red screen

//update screen
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
SwapBuffers(hdc);
glfwPollEvents();

Sleep(1); //sleep for ~2ms

glClearColor(0, 0, 0, 0);//invisiable screen

//update screen
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
SwapBuffers(hdc);
glfwPollEvents();

//stop timer and print to file the result
GetSystemTime(&timeEnd);
timeEndLong = (timeEnd.wMinute * 60 * 1000) + (timeEnd.wSecond * 1000) + 
            timeEnd.wMilliseconds;
myfile << "gap = " << timeEndLong - timeMiddleLong << endl;

ReleaseDC(hWnd, hdc);

What I want ?
To switch between a red screen and invisible screen as fast as possible.
What I know ?
My monitor is 60Hz with respond time of ~7ms which means that if the monitor refreshes exactly when the red screen is up it will stay there for 13ms.
What I get ?
By filming the screen I noticed that the red screen stay for ~32ms which is too long for me.
In addition, the gaps show values of ~2ms in most time and in some times 5-9ms

How do I show the red screen for the shortest time? and how long it will be?

genpfault
  • 51,148
  • 11
  • 85
  • 139
Hido
  • 49
  • 13
  • 2
    sleep is unreliable under windows, it will sleep for up to the next schedule, which is usually about 20ms. Did you get the same problem removing the sleep line? – Adrian Maire Apr 24 '17 at 09:05
  • @Adrian Maire prior call to `timeBeginPeriod` should set timer resolution to 1 ms so `Sleep` should work fairly accurate. – user7860670 Apr 24 '17 at 09:06
  • @AdrianMaire I mentioned that the Sleep accurate. – Hido Apr 24 '17 at 09:08
  • @VTT: Correct, however, this is also unreliable: If the processor is busy, the processor do not reschedule, so the 1ms only works until the CPU is busy. After, back to 20ms. – Adrian Maire Apr 24 '17 at 09:09
  • @AdrianMaire yeah but according to my timers the Sleep works fine. – Hido Apr 24 '17 at 09:11
  • If this is supposed to work on Windows then you should've used [waitable swap chains provided by DXGI](https://learn.microsoft.com/en-us/windows/uwp/gaming/reduce-latency-with-dxgi-1-3-swap-chains) instead of legacy GDI / Opengl interop. – user7860670 Apr 24 '17 at 09:12
  • @VTT I need to do it in OpenGL, there is an option for it? – Hido Apr 24 '17 at 09:29

1 Answers1

5

Your approach won't work -- all the OpenGL functions, including the SwapBuffers, can be queued and executed on the GPU long after your code fragment had completed.

Instead, make sure that VSync is on (it is by default, usually), and execute all those commands without any sleeps in the middle:

glClearColor(1.0f, 0, 0, 1.0f);//red screen
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
SwapBuffers(hdc);
glClearColor(0, 0, 0, 0); //invisiable screen
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
SwapBuffers(hdc);

This will flash a red screen for exactly one frame (16.7ms for a 60Hz monitor).

Due to the asynchronous nature of OpenGL your time measurements aren't sensible either. You should use OpenGL Time Query Objects to measure the times on the GPU side.

Yakov Galka
  • 70,775
  • 16
  • 139
  • 220
  • The problem is that when I video recording my screen ( using my OnePlus 3T with "open camera" app while the frame rate set to 120 and then play it in slow motion of 1/8 ) I didn't see any red screen, but it should appears. How could I know that my monitor showed a red screen ? – Hido Apr 24 '17 at 15:13
  • Did your eyes see a red screen? If not then it means that your VSync is somewhere disabled in the driver settings -- look it up. – Yakov Galka Apr 24 '17 at 15:15
  • You can use `wglSwapIntervalEXT(1)` to force VSync through the code. – Yakov Galka Apr 24 '17 at 15:19
  • I don't want my eyes to see the red screen thought I want it to be there. In addition, something I still see the red screen, how can I avoid it? – Hido Apr 24 '17 at 15:28
  • @Peewe: that's impossible. You can't display an image on a screen for less than a duration of one frame (i.e. 16.7 ms), whereas human eyes can easily see one-frame flashes of a 60Hz monitor. – Yakov Galka Apr 24 '17 at 15:31
  • And if I'm using 75Hz monitor? – Hido Apr 24 '17 at 15:32
  • Even on a 1000Hz monitor you will see a flash. – Yakov Galka Apr 24 '17 at 15:32
  • 3
    @Peewe: 1) that's not true. 1/1000 sec is a typical duration of a camera flash, and people see it very well. many strobes go much less than that. 2) what matters is the total energy output of a flash, so a 1/1000 sec flash on a monitor will be 16 times dimmer than a 1/60 sec flash, but still very much perceivable. 3) you still didn't answer whether you seen the flash or not. 4) what is your *real* problem you want to solve? – Yakov Galka Apr 24 '17 at 15:40
  • 1) I don't think that you can see a flash of 0.001 sec it is so fast ... 2) what? 3) i didn't see but my camera didn't see it too so i think it never showed 4) I just wanna show a red screen with people notice .. – Hido Apr 24 '17 at 15:49
  • @Peewe: did you enable VSync? – Yakov Galka Apr 24 '17 at 15:51
  • the flash is way more than 16.63 ms and I trying to figure how to call to `wglSwapIntervalEXT(1)` , I just wanna say thank you I appreciate your help ! – Hido Apr 24 '17 at 15:52
  • Yep I enabled Vsync and still same result , I used that code : https://www.3dbuzz.com/forum/threads/188320-Enable-or-Disable-VSync-in-OpenGL – Hido Apr 24 '17 at 15:57
  • @Peewe: the problem must be elsewhere. Make sure that VSync is supported by your drivers etc... – Yakov Galka Apr 27 '17 at 08:45
  • 2
    @Peewe: Our eyes are not shuttered cameras but time integrating and derivating spatial resolving power meters. A very short, but intense flash will most certainly be registered. Just to give you an idea: I'm working in a lab that's also doing research on the functional processes in the retina. One of the groups is doing high speed functional imaging (several hundred frames per second) of processes in the retina in response to bright flashes of light that last only 1/1000000 (one millionth) of a second. And the test subject very clearly sees these flashes, as if they looked into a camera strobe – datenwolf Apr 27 '17 at 11:17
  • OK I checked that thing and you're right . But , it doesn't change the fact that the red screen for ~32ms ( 2 frames ) instead of ~16ms ( 1 frame ) , although I enabled Vsync and changed the code to just swap between the const buffers ( I don't change the buffers ). – Hido Apr 27 '17 at 11:33