Reputation: 113
I wrote this code to animate the Lorenz attractor:
#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();
}
The problem is, I have no idea how to draw a continuous graph other than stitching thousands of lines with 2 points. It starts to flicker after a while and I think this is the reason. Any ideas on how to fix? Thanks!
P.S. Also, if you're feeling extra generous, drop me some hints on how to implement zooming and a white dot at the moving end of the graph. If you see anything that could be improved, please let me know. Thanks again!
EDIT:
Using a single buffer with glFlush() fixed the problem, double buffers would only work if there was a way to copy front buffer to back to buffer before swapping. If there is such a way, let me know.
Upvotes: 0
Views: 382
Reputation: 45352
You are using a double-buffered opengl window. When you want to do animations in this case, you have to
The key point here is that after a SwapBuffers
call, the contents of the back buffer become undefined. Your implementation happens to switch between some previous framebuffers. This means that you draw 40000 lines, swap the buffers so that they are shown, draw the next 40000 lines to another buffer not containing the 40000 previous lines, and so on, so you get the flickering.
If you want your drawing to "extend" every frame, you have several options:
GLUT_DOUBLE
flag by GLUT_SINGLE
and use glFlush
instead of glutSwapBuffers
)The third option might seem like the best (and easiest) solution to you, but conceptually, it is the worst. You should rethink the way you implement animations in OpenGL.
Upvotes: 1