c++ - 当我单击窗口时 OpenGL 崩溃并且我的动画没有按预期工作

标签 c++ opengl visual-studio-2012

我目前正在使用 Visual Studio 2012,每当我运行我的代码以在 OpenGL 窗口中查看我的创建时,我无法单击它,甚至无法单击关闭窗口按钮而不会崩溃,我不得不强制关闭它.

当我不使用动画时不会发生这种情况(因此当我只使用键来控制移动时),并且当我的动画起作用时它们似乎只是随机起作用,而不是以所需的方式起作用。

在不更改任何代码的情况下,最后 3 次我运行了我的代码:第一次它成功地运行了所有 3 个动画阶段,但是当我重置它时卡在了第一个阶段。第二次卡在第一个动画上。第三次又卡在了第一阶段。

这是我的显示功能(包括我的 3 个动画功能):

// GLUT display callback function
void Display(void)
{
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
    glLoadIdentity(); // transformations are represented by matrices
    // for placing camera
    gluLookAt(0,1,50,0,0,0,0,1,0);
    // for mouse movement
    glTranslatef(g_fTransX,g_fTransY,g_fZoom);
    glRotatef   (g_fSpinX,1.0f,0.0f,0.0f);
    glRotatef   (g_fSpinY,0.0f,1.0f,0.0f);

    glLightfv(GL_LIGHT0,GL_POSITION,lpos);

    // xyz axes
    glDisable(GL_LIGHTING);
    glLineWidth(2.0);
    glBegin(GL_LINES);
        glColor3f(1.0, 0.0, 0.0);
        glVertex3f(0.0, 0.0, 0.0);
        glVertex3f(20.0, 0.0, 0.0);

        glColor3f(0.0, 1.0, 0.0);
        glVertex3f(0.0, 0.0, 0.0);
        glVertex3f(0.0, 20.0, 0.0);

        glColor3f(0.0, 0.0, 1.0);
        glVertex3f(0.0, 0.0, 0.0);
        glVertex3f(0.0, 0.0, 20.0);
    glEnd();
    glEnable(GL_LIGHTING);

    float Ambient_m[] = {0.0f,1.0f,0.0f,0.0f};
    glMaterialfv(GL_FRONT,GL_AMBIENT,Ambient_m);
    float Ambient_l[] = {0.2f,0.2f,0.2f,0.0f};
    glLightfv(GL_LIGHT0,GL_AMBIENT,Ambient_l);

    // implementing our custom cylinder function
    //draw_cylinder(g_translate_x, g_translate_y, g_dof3_angle);

    // our csg object with 4 DOF
    GLUquadricObj * qobj = gluNewQuadric();

    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
    //draw_lamp(g_dof3_angle);
    //glutSwapBuffers();

    /*animate(time_from, time_to, dof1_from, dof1_to,
    dof2_from, dof2_to, dof3_from, dof3_to,
    dof4_from, dof4_to, dof5_from, dof5_to,
    dof6_from, dof6_to, dof7_from, dof7_to)*/

    animate_lamp(0.0f, 5.0f, 0.0f, 0.0f,
        0.0f, 0.0f, 0.0f, 0.0f,
        0.0f, 45.0f, 0.0f, -45.0f,
        0.0f, 0.0f, 0.0f, 0.0f);

    animate_lamp(5.0f, 7.0f, 0.0f, 5.0f,
        0.0f, 5.0f, 0.0f, 0.0f,
        45.0f, -45.0f, -45.0f, 45.0f,
        0.0f, 0.0f, 0.0f, 0.0f);

    animate_lamp(7.0f, 10.0f, 5.0f, 10.0f,
        5.0f, 0.0f, 0.0f, 0.0f,
        45.0f, -45.0f, -45.0f, 45.0f,
        0.0f, 0.0f, 0.0f, 0.0f);



    //glutSwapBuffers(); // swap back buffer to front buffer (which is drawn on screen)

}

这是我的 animate_lamp() 函数:

void animate_lamp(float time_from, float time_to, float dof1_from, float dof1_to,
     float dof2_from, float dof2_to, float dof3_from, float dof3_to,
     float dof4_from, float dof4_to, float dof5_from, float dof5_to,
     float dof6_from, float dof6_to, float dof7_from, float dof7_to){



_ftime64_s( &timebuffer );
        timeline = _ctime64( & ( timebuffer.time ) );
        int time2 = convert_total_msec((int) timebuffer.millitm, timeline);
        float diff_time = (float) (time2 - g_time1) / 1000.0f;
        while ( (time_from <= diff_time) && (diff_time-time_to) ) {

            float dof1_trans = (diff_time-time_from)/(time_to-time_from) * (dof1_to-dof1_from) + dof1_from;
            float dof2_trans = (diff_time-time_from)/(time_to-time_from) * (dof2_to-dof2_from) + dof2_from;
            float dof3_angle = (diff_time-time_from)/(time_to-time_from) * (dof3_to-dof3_from) + dof3_from;
            float dof4_angle = (diff_time-time_from)/(time_to-time_from) * (dof4_to-dof4_from) + dof4_from;
            float dof5_angle = (diff_time-time_from)/(time_to-time_from) * (dof5_to-dof5_from) + dof5_from;
            float dof6_angle = (diff_time-time_from)/(time_to-time_from) * (dof6_to-dof6_from) + dof6_from;
            float dof7_angle = (diff_time-time_from)/(time_to-time_from) * (dof7_to-dof7_from) + dof7_from;

            glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
            draw_lamp(dof1_trans, dof2_trans, dof3_angle, dof4_angle, dof5_angle, dof6_angle, dof7_angle);
            glutSwapBuffers();
            //
            _ftime64_s( &timebuffer );
            timeline = _ctime64( & ( timebuffer.time ) );
            time2 = convert_total_msec((int) timebuffer.millitm, timeline);
            diff_time = (float) (time2 - g_time1) / 1000.0f;
            }
    }

最佳答案

您似乎误解了 GLUT 显示回调的用途。

它应该渲染单个帧,而不是整个动画。

如果您在 display() 中循环,您的程序将无法处理任何其他事件。单击窗口几秒钟后,Windows 会注意到您的程序“没有响应”并提出强制关闭它。

要让动画正常运行,首先要添加一个idle回调:

void idle()
{
    glutPostRedisplay();
}

// in main():
glutIdleFunc(&idle);

然后,让您的 Display 函数在每次调用时仅呈现“当前”帧。

另外,确保你没有泄露你的GLUquadricObj;每次调用 Display 时您都在创建一个新的,但您似乎没有释放它。随着时间的推移,这将填满您的内存。

关于c++ - 当我单击窗口时 OpenGL 崩溃并且我的动画没有按预期工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22520061/

相关文章:

c++ - 将字符串解析为整数数组

python - 在鼠标拖动 Pyglet 周围绘制一个矩形

c++ - 翻译过程中 MVP 行为异常

c++ - 使用 C 中系统调用的文件描述符

c++ - 计算 3D 平面的斜率

c++ - Freetype 字形在加载到 openGL 时换行

c# - Visual Studio 2012 Fakes 缺少必需的引用

c++ - 混合 VS2012 平台工具集

continuous-integration - VS2012发布配置文件-加密密码

c++ - 如何在 UML 类图中表示纯虚函数?