为什么GlutPostRedisplay和sleep函数在这段代码中不起作用?

我试图在这个项目中实现usb和cpu之间的数据传输。 数据传输显示为从计算机的一个组件移动到另一个组件的小矩形。

在下面的代码中,GlutPostRedisplay不起作用。

另外,有人可以告诉我使用的sleep()是否正确,因为显示中调用的函数不能同步工作。 从不执行casing()。 在fisrtscreen()之后,它直接跳转到opened()并且operation()不起作用。

这段代码的错误是什么?

void operate() { URLTEXTX = 200; URLTEXTY = 950; displayString(READUSB,1); //southbrigde to northbrigde bottom(488.0,425.0,380.0); back(488.0,188.0,380.0); top(188.0,380.0,550.0); //northbridge to cpu front(230.0,350.0,595.0); top(345.0,600.0,650.0); //read from usb back(700.0,625.0,465.0); bottom(625.0,460.0,385.0); back(620.0,525.0,390.0); sleep(1); URLTEXTX = 200; URLTEXTY = 950; displayString(WRITEUSB,1); //cpu to northbridge bottom(350.0,650.0,595.0); back(350.0,230.0,600.0); //northbridge to southbridge bottom(188.0,550.0,380.0); front(188.0,488.0,380.0); top(483.0,380.0,425.0); //write to usb front(525.0,625.0,385.0); top(625.0,385.0,460.0); front(620.0,700.0,460.0); sleep(1); URLTEXTX = 200; URLTEXTY = 950; displayString(READDVD,1); //read from dvd back(600.0,560.0,810.0); bottom(570.0,810.0,600.0); back(560.0,525.0,610.0); //ram to northbridge back(450.0,230.0,580.0); //northbridge to cpu front(230.0,350.0,595.0); top(345.0,600.0,650.0); sleep(1); URLTEXTX = 200; URLTEXTY = 950; displayString(WRITEDVD,1); //cpu to northbridge bottom(350.0,650.0,595.0); back(350.0,230.0,600.0); //northbridge to ram front(230.0,450.0,580.0); //write to dvd front(525.0,570.0,600.0); top(570.0,600.0,800.0); front(560.0,600.0,800.0); sleep(1); URLTEXTX = 200; URLTEXTY = 950; displayString(READHD,1); //read from hard disc back(640.0,560.0,300.0); top(560.0,300.0,530.0); back(560.0,525.0,530.0); //ram to northbridge back(450.0,230.0,580.0); //northbridge to cpu front(230.0,350.0,595.0); top(345.0,600.0,650.0); sleep(1); URLTEXTX = 200; URLTEXTY = 950; displayString(WRITEHD,1); //cpu to northbridge bottom(350.0,650.0,595.0); back(350.0,230.0,600.0); //northbridge to ram front(230.0,450.0,580.0); //write to hard disc front(525.0,560.0,530.0); bottom(560.0,530.0,300.0); front(560.0,640.0,300.0); sleep(1); } void front(GLfloat x1,GLfloat x2,GLfloat y1)//to move in forward direction { GLfloat i; for(i=x1;i=x2;i--) { drawbit(i,i-5,y1,y1-5); glutPostRedisplay(); } } void top(GLfloat x1,GLfloat y1,GLfloat y2)//to move in upward direction { GLfloat i; for(i=y1;i=y2;i--) { drawbit(x1,x1-5,i,i-5); glutPostRedisplay(); } } void drawbit(GLfloat x1,GLfloat x2,GLfloat y1,GLfloat y2) { glBegin(GL_POLYGON); glColor3f(1.0,1.0,1.0); glVertex2f(x1,y1); glVertex2f(x2,y1); glVertex2f(x2,y2); glVertex2f(x1,y2); glEnd(); glFlush(); } void display() { glClear(GL_COLOR_BUFFER_BIT); firstscreen(); //introduction to the project sleep(3); glClear(GL_COLOR_BUFFER_BIT); casing(); //cpu case sleep(2); glClear(GL_COLOR_BUFFER_BIT); opened(); //when cpu case is opened shows internal components sleep(1); operate(); //data transfer between various components } 

问题类似于: 在OpenGL中连续暂停

glutPostRedisplay只是在glut中设置一个标志,在下一个循环中调用你的显示回调。 它实际上并没有绘制任何东西。

我怀疑你所追求的function是glutSwapBuffers 。 如果没有双缓冲,几何体将直接绘制到屏幕上(尽管GPU的“绘制”命令是缓冲的,您需要glFlush )。 这通常会导致闪烁,因为您会看到后来被更近的几何体覆盖的事物(因为深度缓冲区)。 双缓冲通过渲染到屏幕外缓冲区然后一次显示结果来解决这个问题。 确保GLUT_DOUBLE传递给glutInit以便你有一个后台缓冲区。

当您正在sleep() ,您的应用程序将无法捕获和处理事件。 让我们说你要关闭窗口。 在睡眠恢复之前,整个事情都会没有反应。 睡眠仍然很重要,因此您不会占用CPU。 我将这些概念分开。

  1. 使用idlefunction循环/轮询,直到延迟时间结束。 然后调用glutPostRedisplay 。 如果你是双缓冲,添加glutSwapBuffersdisplay
  2. 写一个调用睡眠的帧速率限制器 ,这样就不会占用周期。

设置延迟后绘制不同内容的一种简单方法是编写一个小型状态机…

 int state = STATE_INIT; float timer = 0.0f; void idle() { //insert framerate limiter here //calculate time since last frame, perhaps using glutGet(GLUT_ELAPSED_TIME) float deltaTime = ... timer -= deltaTime; if (timer < 0.0f) { switch (state) { case STATE_INIT: state = STATE_DRAW_FIRST_THING; timer = 123.0f; ... } glutPostRedisplay(); } } void display() { ... if (state == STATE_DRAW_FIRST_THING) { ... } ... glutSwapBuffers(); } 

随着你的应用程序变得更大,我怀疑这将是可维护的,你会想要更强大的东西,但在此之前这是一个良好的开端。

只需更改void (*currentView)(void); idle回调函数会在display保存一些硬编码。 您可能想要创建面向对象的状态机 。 除了布尔状态,您可能希望查看动画和关键帧插值。 而不是硬编码所有东西,在文件中存储几何,关键帧和状态序列是分离代码和数据的好方法。 如果您使用库,XML非常适合使用它。