简体   繁体   中英

How to swap buffer as fast as possible


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?

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM