如何通过使用 sleep() 或其他方式使您的代码执行缓慢?
How to make your code execute slowly by using sleep() or something else?
我试图让一些形状每 0.5 秒旋转一次,同时一直显示它,但使用循环时,它只显示最终结果。如何让它不断显示变化的图像?
这是我的资料:
for (float i = 190.0; i <= 200; i+= 2.0){
viewMatrix = glm::lookAt(
glm::vec3(i, 70.0f, 200.0f), // eye position
glm::vec3(0), // look at position
glm::vec3(0.0f, 1.0f, 0.0f)); // up vect0r
std::this_thread::sleep_for(std::chrono::milliseconds(500));//problem here
glutPostRedisplay();
}
我不是 OpenGL 程序员,但我猜
glutPostRedisplay();
之后
std::this_thread::sleep_for(std::chrono::milliseconds(500));
可能是问题的根源,根据我使用 ncurses 和 window 刷新的经验。
此外,我一直使用 nanosleep 来延迟
#include <time.h>
int msleep(unsigned long milisec)
{
struct timespec req={0};
time_t sec=(int)(milisec/1000);
milisec=milisec-(sec*1000);
req.tv_sec=sec;
req.tv_nsec=milisec*1000000L;
while(nanosleep(&req,&req)==-1)
continue;
return 1;
}
按照你说的去做(不以你的例子为基础)我会写这样的东西:
int main(){
init();
using Clock = std::chrono::high_resolution_clock;
using std::chrono::duration_cast;
using std::chrono::milliseconds;
auto start = Clock::now();
while(1){
auto now = Clock::now();
if(duration_cast<milliseconds>(now - start).count() >= 500){
// do animation
start = now;
}
swap_buffers();
}
finish();
}
没有使用睡眠,只是一个繁忙的循环。
此外,使用 float
作为 for
循环计数器通常是不受欢迎的。并且有充分的理由。
您已经得到了 3 个答案。他们每个人都完全错过了实际问题(我对每个答案都添加了相同的评论):
您遇到的问题是“glutPostRedisplay”没有主动显示任何内容。它所做的只是设置一些标志,在事件循环的下一次迭代中,显示函数调用被调用。 IE。像这样:
bool do_display = false;
void glutPostRedisplay()
{
do_display = true;
}
void glutMainLoop()
{
while(running) {
...
if( do_display ) call_display_callback();
do_display = false;
...
}
}
设置那个 do_display
标志,当然不会在循环中做任何事情,除了 reduantly 设置它。
您要做的是将 idle
函数本身视为循环体并在其中递增循环变量。即
float i = 190.0;
void anim_idle()
{
if( i >= 200 ) { glutIdleFunc(NULL); }
viewMatrix = glm::lookAt(
glm::vec3(i, 70.0f, 200.0f), // eye position
glm::vec3(0), // look at position
glm::vec3(0.0f, 1.0f, 0.0f)); // up vect0r
glutPostRedisplay();
i += 0.02;
}
另外你不应该在那里睡觉,这样程序才能保持互动。而是测量迭代之间的时间并根据传递的时间间隔调整增量。
我试图让一些形状每 0.5 秒旋转一次,同时一直显示它,但使用循环时,它只显示最终结果。如何让它不断显示变化的图像?
这是我的资料:
for (float i = 190.0; i <= 200; i+= 2.0){
viewMatrix = glm::lookAt(
glm::vec3(i, 70.0f, 200.0f), // eye position
glm::vec3(0), // look at position
glm::vec3(0.0f, 1.0f, 0.0f)); // up vect0r
std::this_thread::sleep_for(std::chrono::milliseconds(500));//problem here
glutPostRedisplay();
}
我不是 OpenGL 程序员,但我猜
glutPostRedisplay();
之后
std::this_thread::sleep_for(std::chrono::milliseconds(500));
可能是问题的根源,根据我使用 ncurses 和 window 刷新的经验。
此外,我一直使用 nanosleep 来延迟
#include <time.h>
int msleep(unsigned long milisec)
{
struct timespec req={0};
time_t sec=(int)(milisec/1000);
milisec=milisec-(sec*1000);
req.tv_sec=sec;
req.tv_nsec=milisec*1000000L;
while(nanosleep(&req,&req)==-1)
continue;
return 1;
}
按照你说的去做(不以你的例子为基础)我会写这样的东西:
int main(){
init();
using Clock = std::chrono::high_resolution_clock;
using std::chrono::duration_cast;
using std::chrono::milliseconds;
auto start = Clock::now();
while(1){
auto now = Clock::now();
if(duration_cast<milliseconds>(now - start).count() >= 500){
// do animation
start = now;
}
swap_buffers();
}
finish();
}
没有使用睡眠,只是一个繁忙的循环。
此外,使用 float
作为 for
循环计数器通常是不受欢迎的。并且有充分的理由。
您已经得到了 3 个答案。他们每个人都完全错过了实际问题(我对每个答案都添加了相同的评论):
您遇到的问题是“glutPostRedisplay”没有主动显示任何内容。它所做的只是设置一些标志,在事件循环的下一次迭代中,显示函数调用被调用。 IE。像这样:
bool do_display = false;
void glutPostRedisplay()
{
do_display = true;
}
void glutMainLoop()
{
while(running) {
...
if( do_display ) call_display_callback();
do_display = false;
...
}
}
设置那个 do_display
标志,当然不会在循环中做任何事情,除了 reduantly 设置它。
您要做的是将 idle
函数本身视为循环体并在其中递增循环变量。即
float i = 190.0;
void anim_idle()
{
if( i >= 200 ) { glutIdleFunc(NULL); }
viewMatrix = glm::lookAt(
glm::vec3(i, 70.0f, 200.0f), // eye position
glm::vec3(0), // look at position
glm::vec3(0.0f, 1.0f, 0.0f)); // up vect0r
glutPostRedisplay();
i += 0.02;
}
另外你不应该在那里睡觉,这样程序才能保持互动。而是测量迭代之间的时间并根据传递的时间间隔调整增量。