【问题标题】:time delay inside recursive function in openglopengl中递归函数内的时间延迟
【发布时间】:2015-12-03 04:55:34
【问题描述】:

我的问题是我的功能完成的太快了,以至于我在屏幕上看不到进度,这是我的显示功能:

 void showMaze(const Maze::Maze &m){

 glPushMatrix();
 glTranslatef(-1,1, 0);

 for(int i=0;i<m.num_Y;i++) 
   {
 for(int j=0;j<m.num_X;j++)  
     {

char c = m.maze[i][j]; 

if(c=='1'){   glColor3f(255,255,0);
            glRectf(0.05, -0.05, -0.05,0.05);
        }
if(c=='0'){   glColor3f(20,60,60);
            glRectf(0.05, -0.05, -0.05,0.05);
        } 
 glTranslatef(0.1,0, 0);
  }
     glTranslatef(-(m.num_X*0.1),-0.1, 0);
  }
  glPopMatrix();
  } 

递归函数:

    bool findPath(Maze* M, char m){  

    showMaze(*M);
    glutPostRedisplay();

        if(M->isFinish())   
            return true;

        if (m!='s' && M->north()){
            update(M, 'n');
            if(isNew(M) && findPath(M, 'n') && M->isFinish()){  
                return true;
            }
            else{       
                M->south();
            }
        }
        // ..... 
            else{
            return false;
        }
    }
  void render()
 {
 glClear( GL_COLOR_BUFFER_BIT );
      findPath(N,'z');
 glutSwapBuffers();
 }

主要:

   glutDisplayFunc( render );

所以我的问题是,每当调用 findpath 时,我如何等待几秒钟(以便我可以看到进度),我尝试过 glutimeelapsed、sleep、gettickcount,但没有一个能正确完成工作。

编辑1: 当我在调用 showMaze() 后立即放置类似 sleep() 的内容时,几秒钟内什么都没有显示,然后显示最终屏幕,我不是 c++ 专家,但我想应该先执行 showMaze(),然后是 sleep( ) 函数,还是 c++ 等待执行整个函数以显示结果? 编辑2: 我找到了解决这个问题的方法,每当 X 和 Y 发生变化时,我就将它们从迷宫中取出,并将它们存储在两个向量中,在我的绘图函数中,我首先显示空迷宫,然后慢慢添加变化的 X 和 Y。

【问题讨论】:

  • 既然你用的是glut,有没有考虑用glutTimerFunc()
  • 我想过,但由于它是一个递归函数,一旦它被调用,它就会卡在递归循环中,直到函数的最终结果
  • 创建一个具有独立线程的类。在这个类中,创建draw()。主要是在render() 内调用object.draw()。不要用一些循环打扰MainLoop()。这将冻结您的屏幕。您可以从主函数中的任何位置触发findPath
  • 对于一个简单的问题,它很难改变整个结构,我也很关心定时回调,但如果我找不到解决方案,多线程是我会做的

标签: c++ opengl freeglut


【解决方案1】:

除非您通过交换缓冲区显示您正在渲染的内容,否则屏幕上不会显示任何内容(除非您正在渲染到前端缓冲区,但那是不确定的)。因此,您可以在递归函数中间睡多久,但在退出该调用堆栈之前,您将看不到任何东西。到那时,你已经画完了所有东西。

因此,当您希望某些内容可见时,您需要在递归调用堆栈中使用glutSwapBuffers,而不是仅仅睡觉。

但是,这是一个坏主意。 render 调用不应该做诸如睡眠之类的事情。系统需要您的 render 来实际渲染,因为屏幕可能需要更新,原因有多种(另一个窗口显示更多窗口等)。你不应该让你的 render 循环像这样挂起。

相反,您应该做的是每次渲染循环执行一个段,依靠glutPostRedisplay 确保循环不断被调用。并且您应该将动画基于循环执行之间的时间增量,或者您应该使用睡眠计时器来确保循环之间始终至少经过 X 时间。

因此,您需要将递归调用展开为迭代过程。

或者,如果您可以访问 Boost.Context 或 Boost.Coroutine,您可以使用它来处理事情。这样,您可以保留递归结构。当你渲染了你想要显示的所有东西后,你只需将你的协程挂回给render,后者将交换缓冲区并返回。

【讨论】:

  • 正如你所说,弄乱渲染是一个坏主意,所以我将递归函数与渲染分离,通过将函数结果按顺序放在一个向量中,我可以根据需要显示我的结果跨度>
猜你喜欢
  • 2012-04-27
  • 1970-01-01
  • 2015-09-19
  • 2013-01-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多