OpenGl glutIdleFunc动画

时间:2018-10-06 17:36:27

标签: c++ opengl graphics

我的问题

我仍在学习opengl,并且正在从事类似于鸡肉入侵者的游戏。我要做的是要有一个与鸡侵略者相似的背景,并带有一些恒星和星系。我使用添加了纹理的屏幕大小使用了四边形。到目前为止,一切都很好,但我现在正尝试向下转换此星系背景,以使太空飞船和小鸡看起来好像它们正在太空中前进。我的想法是使用glutIdleFunc()函数,并且在每次迭代时,我应该先休眠30毫秒,然后更新星系背景,以便每行像素向下移动1行,最后一行复制到第一行。问题是这种方法在大约15秒钟内可以正常工作,然后程序完全停止,并且计算机挂起并冻结,直到需要重新启动PC为止。我认为每次调用glutIdleFunc()时,我的方法都需要大量操作。我搜索了网上遇到类似情况的人,但没有找到类似的帖子。

代码:

主要功能

int main(int argc, char** argr) {
   glutInit(&argc, argr);

   glutInitWindowSize(SCREEN_WIDTH, SCREEN_WIDTH);

   // background is a global variable that contains the bitmap array
   int err = load_image("Art/background.bmp", &background);
   if(err)
   {
       fprintf(stderr, "%d\n", err);
       exit(1); 
   }

   glutCreateWindow("OpenGL - 2D Template");
   glutDisplayFunc(Display);
   glutMotionFunc(mo);
   glutMouseFunc(mou);

   glutIdleFunc(Animate);
   glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
   glClearColor(1.0f, 1.0f, 1.0f, 0.0f);
   gluOrtho2D(0.0, 1000, 0.0, 600);

   glutMainLoop();
}

动画

void Animate(void)
{
    msleep(300);
    translate_image(&background, 30);
    glutPostRedisplay();
}
void translate_image(image_t* img, const int c)
{
    uint32_t copy[img->height][img->width];
    for(int i = 0; i < img->height; i++)
    {
        for(int j = 0; j < img->width; j++)
        {
            copy[i][j] = img->data[i * img->width + j];
        }
    }

    for(int i = 0; i < img->height; i++)
    {
        for(int j = 0; j < img->width; j++)
        {
            int index = (i + c) % img->height;
            img->data[index * img->width + j] = copy[i][j];
        }
    }
}

显示功能

void Display() {
    glClear(GL_COLOR_BUFFER_BIT);
    glEnable(GL_TEXTURE_2D);
    texture = glInitTexture(background);
    drawImage(texture, 0.0f, 0.0f, background.width, background.height);
    glDisable(GL_TEXTURE_2D);

    drawSpaceShip();


    glFlush();


}

主要问题

是否有一种更有效的方式来完成我每次尝试冻结计算机时都执行的相同操作?

1 个答案:

答案 0 :(得分:1)

您不必复制图片内容。只需为纹理坐标设置动画即可,您可以使用该纹理坐标将图片映射到四边形。

还必须 glutInitDisplayMode之前致电glutCreateWindow才能生效。另外,您不希望使用单个缓冲的帧缓冲,而希望使用双缓冲的GLUT_DOUBLE而不是GLUT_SINGLE,而是调用glutSwapBuffers而不是glFinish

相关问题