2012-09-20 17 views
1

我目前正在研究在3D空間中繪製洛倫茲吸引子的圖形,並試圖在屏幕上爲其繪製動畫圖形。我在我的顯示函數中寫了下面的while循環,認爲它會按我期望的那樣工作。OpenGL - 顯示循環迭代的每個點

int i; 
    float x = 0, y = 1, z = 0; 
    glBegin(GL_LINE_STRIP); 

    while (i < initialIterations) { 
     glColor3f(0,1,0); 
     // compute a new point using the strange attractor equations 
     float dx = sigma*(y-x); 
     float dy = x*(r-z) - y; 
     float dz = x*y - b*z; 

     // save the new point 
     x = x + dx*dt; 
     y = y + dy*dt; 
     z = z + dz*dt;   

     glVertex3f(x/50,y/50,z/50); 
     i++; 
    } 

    glEnd(); 

但是它只是描繪整個吸引子並且不顯示每個迭代。

+0

什麼是internalIterations?你在哪裏設置它? – Tim

+0

initialiterations只是一個50000的集合 – Sean

回答

4

如果您的上下文是雙緩衝,那麼將無法看到此動畫,因爲它會將所有內容都畫到屏幕外,然後在調用swapbuffers後將圖片翻轉到屏幕。

如果你想要解決這個問題,而不是繪製整個吸引子,建立一個循環計數器,使得在第0幀,你只繪製點0,在第1幀繪製點0到1,在第2幀繪製分0〜2等

如果你的背景是單緩衝,你可以看到它作爲動畫繪製,雖然它很可能如此之快,你就永遠無法看到它的動畫。它可能在大約一毫秒內完成繪製該循環。如果您希望動畫對人眼可見,則需要在每個循環之間進行某種等待或睡眠。

+0

您可以通過使用glDrawBuffer(GL_FRONT)將其選爲渲染操作目標來繪製到前端緩衝區; – datenwolf

1

給這一個鏡頭:

#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; 
} 

它使用glutTimerFunc()捅顯示功能每隔16毫秒左右,此時它繪製未來兩個洛倫茲頂點。