[英]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行的另一个缓冲区中,依此类推,这样您就会闪烁。
如果希望图形“扩展”每一帧,则有几种选择:
GLUT_DOUBLE
标志替换为GLUT_SINGLE
并使用glFlush
而不是glutSwapBuffers
) 第三种选择对您来说似乎是最好的(也是最简单的)解决方案,但是从概念上讲,这是最糟糕的选择。 您应该重新考虑在OpenGL中实现动画的方式。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.