Give this a shot:
#include <GL/glut.h>
#include <vector>
struct Vertex
{
Vertex( float x, float y, float z ) : x(x), y(y), z(z) {}
float x;
float y;
float z;
};
std::vector< Vertex > verts;
void fillVerts()
{
// calculate vertices
// http://paulbourke.net/fractals/lorenz/
int N = 10000;
int i = 0;
double x0, y0, z0, x1, y1, z1;
double h = 0.01;
double a = 10.0;
double b = 28.0;
double c = 8.0 / 3.0;
x0 = 0.1;
y0 = 0;
z0 = 0;
for( i = 0; i < N; i++ )
{
x1 = x0 + h * a * (y0 - x0);
y1 = y0 + h * (x0 * (b - z0) - y0);
z1 = z0 + h * (x0 * y0 - c * z0);
x0 = x1;
y0 = y1;
z0 = z1;
if( i > 100 )
{
verts.push_back( Vertex( x0, y0, z0 ) );
}
}
}
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef( 0, 0, -10 );
// spin
static float angle = 0;
angle += 0.1;
glRotatef( angle, 1, 1, 1 );
// resize
float s = 1 / 10.0f;
glScalef(s,s,s);
// animate index
static size_t curIdx = 0;
curIdx += 2;
if( curIdx >= verts.size() )
curIdx = 0;
// draw curve
glEnableClientState( GL_VERTEX_ARRAY );
glVertexPointer( 3, GL_FLOAT, 0, &verts[0] );
glDrawArrays( GL_LINE_STRIP, 0, curIdx );
glDisableClientState( GL_VERTEX_ARRAY );
glutSwapBuffers();
}
void reshape(int w, int h)
{
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective( 60, (double)w / (double)h, 1.0, 10000.0 );
}
void timer(int extra)
{
glutPostRedisplay();
glutTimerFunc(16, timer, 0);
}
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE);
glutInitWindowSize(800,600);
glutCreateWindow("Attractor");
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutTimerFunc(0, timer, 0);
fillVerts();
glutMainLoop();
return 0;
}
It uses glutTimerFunc()
to poke the display function every 16 milliseconds or so, at which point it draws the next two Lorenz vertices.