繁体   English   中英

具有Freeglut连续重新计算的图形闪烁的C ++ OpenGL

[英]C++ OpenGL with freeglut continuous recalculated graph flickering

我编写了以下代码来制作洛伦兹吸引子的动画:

#include <iostream>
#include <GL/freeglut.h>
double x = 1, y = 1, z = 1, a = 10, b = 28, c = 8/3, precision = 0.000001, lastx = x, lasty = y, lastz = z;
int counter = 0;
void draw() {
    glBegin(GL_LINES);
        glVertex2d(lastx, lasty);
        glVertex2d(x, y);
    glEnd();
    lastx = x;
    lasty = y;
    double dxdt = a*(y-x);
    double dydt = x*(b-z)-y;
    double dzdt = x*y-c*z;
    x += precision*dxdt;
    y += precision*dydt;
    z += precision*dzdt;
    counter++;
    if (counter == 40000)
    {
        glutSwapBuffers();
        counter = 0;
    }
    glutPostRedisplay();
}
void mykey(unsigned char mychar, int x, int y) {
    if (mychar == 27) {
        exit(0);
    }
}
int main(int argc, char **argv) {
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
    glutInitWindowSize(1000, 1000);
    glutCreateWindow("Lorenz Attractor");
    glutDisplayFunc(draw);
    glutKeyboardFunc(mykey);
    glClearColor(0, 0, 0, 1);
    glColor4d(0, 0, 1, 1);
    glViewport(0, 0, 1000, 1000);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluOrtho2D(-30, 30, -30, 30);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glEnable(GL_POINT_SMOOTH);
    glPointSize(1);
    glutFullScreen();
    glutMainLoop();
}

问题是,除了用2点缝合数千条线外,我不知道如何绘制连续图形。 一段时间后它开始闪烁,我认为这是原因。 有关如何解决的任何想法? 谢谢!

PS另外,如果您感觉比较慷慨,请给我一些关于如何实现缩放的提示,并在图形的移动端添加一个白点。 如果您发现任何可以改进的地方,请告诉我。 再次感谢!

编辑:

在glFlush()中使用单个缓冲区可解决此问题,只有在交换前有一种方法可以将前缓冲区复制回缓冲区时,双缓冲区才起作用。 如果有这种方法,请告诉我。

您正在使用一个双缓冲的opengl窗口。 如果要在这种情况下制作动画,则必须

  • 绘制要显示到后缓冲区的完整帧
  • 交换缓冲区以显示帧
  • 从开始画下一帧

这里的关键点是在SwapBuffers调用之后,后缓冲区的内容变为undefined 您的实现恰好在先前的某些帧缓冲区之间切换。 这意味着您要绘制40000行,交换缓冲区以便显示它们,然后将下一个40000行绘制到不包含前40000行的另一个缓冲区中,依此类推,这样您就会闪烁。

如果希望图形“扩展”每一帧,则有几种选择:

  1. 实际将行存储在某种数据结构中,然后每帧重绘整个图像
  2. 交换后将最后一帧的结果复制到新的后备缓冲区。 (一种更有效的方法是渲染到纹理)。
  3. 使用单个缓冲(将GLUT_DOUBLE标志替换为GLUT_SINGLE并使用glFlush而不是glutSwapBuffers

第三种选择对您来说似乎是最好的(也是最简单的)解决方案,但是从概念上讲,这是最糟糕的选择。 您应该重新考虑在OpenGL中实现动画的方式。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM