为什么GlutPostRedisplay和sleep函数在此代码中不起作用? [英] why is GlutPostRedisplay and sleep function is not working in this code?

查看:116
本文介绍了为什么GlutPostRedisplay和sleep函数在此代码中不起作用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

i have tried to implement the data transfer between usb and cpu in this project. The data transfer is being shown as a small rectangle moving from one component of the computer to another.

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

In the code below, the GlutPostRedisplay does not work.

此外,有人可以告诉我使用的sleep()是否正确,因为在display中调用的功能无法同步工作.永远不会执行套管().在fisrtscreen()之后,它会直接跳转到opened(),而operate()无法正常工作.

Also, can someone tell me if sleep() used is correct because the functions called in display do not work in sync. casing() is never executed. After fisrtscreen(), it directly jumps to opened() and operate() does not work.

此代码有什么错误?

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
}

推荐答案

问题类似于此: glutPostRedisplay只需在glut中设置一个标志,即可在下一个循环中调用您的显示回调.它实际上并没有画任何东西.

glutPostRedisplay simply sets a flag in glut to call your display callback on the next loop. It doesn't actually draw anything.

我怀疑您要使用的功能是glutSwapBuffers.如果没有双重缓冲,则将几何图形直接绘制到屏幕上(尽管您要glFlush缓冲了对GPU的绘制"命令).这通常会导致闪烁,因为您看到的东西后来被更近的几何形状覆盖(由于深度缓冲区).双重缓冲解决了此问题,方法是渲染到屏幕外的缓冲区,然后一次显示所有结果.确保将GLUT_DOUBLE传递给glutInit,以便有一个后备缓冲区.

The function I suspect you're after is glutSwapBuffers. Without double buffering, geometry is drawn directly to the screen (although "draw" commands to the GPU are buffered for which you'd want glFlush). This commonly causes flickering because you see things that later get covered by closer geometry (because of the depth buffer). Double buffering solves this by rendering to an off-screen buffer and then displaying the result all at once. Make sure GLUT_DOUBLE is passed to glutInit so that you have a back buffer.

在执行sleep()时,您的应用程序将无法捕获和处理事件.假设您要关闭窗口.直到睡眠返回,整个事物才会反应迟钝.睡眠仍然很重要,因此您不必占用CPU.我将这些概念分开.

While you're sleep()ing, your application won't be able to capture and process events. Lets say you want to close the window. Until sleep returns the whole thing will be unresponsive. A sleep can still be important so you don't hog your CPU. I'd separate these concepts.

  1. 具有idle功能的循环/轮询,直到您的延迟时间过去.然后调用glutPostRedisplay.如果要双重缓冲,请将glutSwapBuffers添加到display.
  2. 编写一个帧率限制器,该限制器会调用睡眠模式,这样您就不会浪费时间了.
  1. Loop/poll with an idle function until your delay time has elapsed. Then call glutPostRedisplay. Add glutSwapBuffers to display if you're double buffering.
  2. Write a framerate limiter that calls sleep so you don't hog cycles.

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

A simple method to draw different things after set delays is to write a small state machine...

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

随着您的应用程序变得更大,我怀疑这是否可以维护,并且您需要更强大的功能,但是在此之前,这是一个好的开始.

As your app becomes bigger this I doubt this will be maintainable and you'll want something more robust, but until then this is a good start.

只需更改idle中的void (*currentView)(void);回调函数,即可在display中节省一些硬编码.您可能要创建面向对象的状态机.除了布尔状态外,您可能还需要研究动画和关键帧插值.除了对所有内容进行硬编码之外,将几何图形,关键帧和状态序列存储在文件中是分离代码和数据的一种好方法.如果您使用库,那么XML可以很好地与之配合使用.

Simply changing a void (*currentView)(void); callback function in idle would save some hard coding in display. You might want to create an object orientated state machine. Beyond boolean states you might want to look into animation and keyframe interpolation. Rather than hard code everything, storing geometry, keyframes and state sequences in a file is a nice way to separate code and data. XML is very nice to work with for this provided you use a library.

这篇关于为什么GlutPostRedisplay和sleep函数在此代码中不起作用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆