为啥 GlutPostRedisplay 和 sleep 功能在此代码中不起作用?

Posted

技术标签:

【中文标题】为啥 GlutPostRedisplay 和 sleep 功能在此代码中不起作用?【英文标题】:why is GlutPostRedisplay and sleep function is not working in this code?为什么 GlutPostRedisplay 和 sleep 功能在此代码中不起作用? 【发布时间】:2015-05-26 06:31:51 【问题描述】:

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

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

另外,有人可以告诉我使用的 sleep() 是否正确,因为 display 中调用的函数不能同步工作。 case() 永远不会执行。 fisrtscreen()后直接跳转opened(),operate()不起作用。

这段代码有什么错误??

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,x1+5,y1,y1-5);
        glutPostRedisplay();
    


void back(GLfloat x1,GLfloat x2,GLfloat y1)//to move in backward 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 bottom(GLfloat x1,GLfloat y1,GLfloat y2)//to move in downward 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

【问题讨论】:

【参考方案1】:

问题类似这样:Pausing in OpenGL successively

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

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

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

    使用idle 函数循环/轮询,直到您的延迟时间过去。然后拨打glutPostRedisplay。如果您使用双缓冲,请将 glutSwapBuffers 添加到 display。 写一个调用睡眠的framerate limiter,这样你就不会占用循环。

设置延迟后绘制不同事物的简单方法是编写一个小型状态机...

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();

随着您的应用变得越来越大,我怀疑这将是可维护的,并且您会想要更强大的东西,但在此之前这是一个好的开始。

只需更改idle 中的void (*currentView)(void); 回调函数即可节省display 中的一些硬编码。您可能想要创建一个面向对象的state machine。除了布尔状态,您可能还想研究动画和关键帧插值。将几何、关键帧和状态序列存储在一个文件中,而不是对所有内容进行硬编码,是一种分离代码和数据的好方法。如果您使用库,那么 XML 非常适合用于此。

【讨论】:

以上是关于为啥 GlutPostRedisplay 和 sleep 功能在此代码中不起作用?的主要内容,如果未能解决你的问题,请参考以下文章

如果 glutPostRedisplay() 被调用太快会发生啥?

GLUT Tutorials 19:glutPostRedisplay vs. Idle Func

为啥扁平列表中的空白项目

为啥 doctest 在 qpython3 中不起作用

为啥在 python 切片中允许非整数内置类型?

Sharepoint 2010 和 Silverlight Web 部件 SL 版本