2011-05-10 58 views
1

我在OpenGL的製作程序在曲線動畫固球動畫實心球
它會像
//顯示功能如何通過曲線

void display() 
{ 
    glClear(GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT); 
    glLoadIdentity(); 
    //set of condition 
    loop:j=1 to 5 
     loop:i=1 to 3 
      if(j==1) 
      { 
       animate(x,y,z) 
       glutSwapBuffers(); 
      } 
      elseif(j==5) 
      { 
       animate(x,y,z) 
       glutSwapBuffers(); 
      } 
      else //for all value j between 1 and 5 
      { 
       animate(x,y,z); 
       glutSwapBuffers(); 
      } 
} 

//animate function 
void animate(float x, float y, float z) 
{ 
    glLoadIdentity(); 
    glTranslatef(0,0,-20); 
    glPushMatrix(); 
    glTranslatef (x, y, z); 
    glutSolidSphere (0.3, 10, 10); 

    int i, j; 

    for(i = 0; i < 10000; i++) //for introducing delay 
     for(j = 0; j < 5000; j++); 


    glPopMatrix(); 
    glutSwapBuffers(); 
} 

問題:實球體在曲線上平移,但是對於其每個下一個位置,我不能移除其先前的位置...例如 如果球體從P1,P2,P3,P4,然後P5..after 來到位置P5它仍然可見在所有其他位置以前的位置(P1,P2,P3,P4) 但我希望它只在當前位置顯示球體,同時翻譯 我該如何做到這一點?

+1

使用睡眠(毫秒),而不是那些嵌套循環。它在windows.h頭文件中。 – atoMerz 2011-05-10 11:38:20

回答

6

您不清除幀緩衝區,這意味着您要在前一幀的頂部繪製每個幀。嘗試使用你想要的顏色glClearColor(0.0f, 0.0f, 0.0f, 1.0f);

+0

您是否願意告訴我在上面的代碼中,我應該使用這一行 – Tarun 2011-05-10 11:38:48

+0

謝謝您的回答對我有用 – Tarun 2011-05-10 11:47:19

+0

@fluty:不幸的是,它不能解決您的真正問題。到目前爲止,您並沒有以有用的方式實現OpenGL動畫。看到我的答案。 – datenwolf 2011-05-10 11:59:08

5

OpenGL不是場景圖。它所做的就是着色像素。在你將一些幾何圖形發送給OpenGL並處理之後,它就消失了,所有剩下的東西都留在了幀緩衝區中。請注意,頂點緩衝區對象的內容本身不是幾何圖形。只有繪圖調用(glDrawElements,glDrawArrays)將頂點緩衝區中的值轉換爲幾何。

此外,您的程序不遵循典型的動畫循環。你現在做的方式不允許用戶交互,或者在動畫過程中進行任何其他類型的事件處理。你應該改變你的代碼如下:

static timeval delta_T = {0., 0.}; 

struct AnimationState { 
    // ... 
    float sphere_position[3]; 
}; 

AnimationState animation; 

void display() 
{ 

    // Start time, frame rendering begins: 
    timeval time_begin_frame; 
    gettimeofday(&time_begin_frame, 0); 

    animate(delta_T.tv_sec + delta_T.tv_usec * 1.e6); 

    glClear(GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT); 

    glMatrixMode(GL_PROJECTION); 
    glLoadIdentity(); 
    set_projection(); 

    glMatrixMode(GL_MODELVIEW); 
    glLoadIdentity(); 
    apply_camera_transform(); 

    draw_sphere(animation.sphere_position[0], 
       animation.sphere_position[1], 
       animation.sphere_position[2]) 

    glutSwapBuffers(); 

    // frame render end time 
    timeval time_end_frame; 
    gettimeofday(&time_end_frame, 0); 
    timersub(&time_end_frame, &time_begin_frame, &delta_time); 

} 

void draw_sphere(float x, float y, float z) 
{ 

    glMatrixMode(GL_MODELVIEW); 
    glPushMatrix(); 
    glTranslatef (x, y, z); 
    glutSolidSphere (0.3, 10, 10); 

    glPopMatrix(); 

} 

void animate(float dT) 
{ 
    // advance animation by timestep dT 
} 

void idle() 
{ 
    glutPostRedisplay(); 
} 

編輯全部工作的代碼示例

/* sinsphere.c */ 
#include <GL/glut.h> 

#include <stdlib.h> 

#include <sys/time.h> 
#include <math.h> 

#define M_PI 3.1415926535897932384626433832795029L 
#define M_PI_2 1.5707963267948966192313216916397514L 

# define timersub(a, b, result)            \ 
    do {                  \ 
    (result)->tv_sec = (a)->tv_sec - (b)->tv_sec;        \ 
    (result)->tv_usec = (a)->tv_usec - (b)->tv_usec;       \ 
    if ((result)->tv_usec < 0) {            \ 
     --(result)->tv_sec;              \ 
     (result)->tv_usec += 1000000;           \ 
    }                   \ 
    } while (0) 

void idle(void); 
void animate(float dT); 
void display(void); 
void init_sphere(unsigned int rings, unsigned int sectors); 
void draw_sphere(void); 

int main(int argc, char *argv[]) 
{  
    glutInit(&argc, argv); 
    glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE); 
    glutCreateWindow("SinSphere"); 
    glutIdleFunc(idle); 
    glutDisplayFunc(display); 

    init_sphere(10, 30); 

    glutMainLoop(); 

    return 0; 
} 

struct AnimationState 
{ 
    float time; 
     float sphere_speed; 
    float sphere_path_radius; 
    float sphere_path_bobbing; 
    float sphere_position[3]; 
}; 

static struct AnimationState animation = { 
    0., 
    0.1, 3., 1., 
    {1., 0., 0.} 
}; 

void animate(float dT) 
{ 
    animation.time += dT; 

    animation.sphere_position[0] = animation.sphere_path_radius * cos(2*M_PI * animation.time * animation.sphere_speed); 
    animation.sphere_position[1] = animation.sphere_path_bobbing * sin(2*M_PI * animation.time * 5 * animation.sphere_speed); 
    animation.sphere_position[2] = animation.sphere_path_radius * sin(2*M_PI * animation.time * animation.sphere_speed); 
} 

GLfloat *sphere_vertices_normals; 
unsigned int sphere_quads = 0; 
GLushort *sphere_indices; 

void init_sphere(unsigned int rings, unsigned int sectors) 
{ 
    float const R = 1./(float)(rings-1); 
    float const S = 1./(float)(sectors-1); 
    int r, s; 

    sphere_vertices_normals = malloc(sizeof(GLfloat)*3 * rings*sectors); 

    GLfloat *v = sphere_vertices_normals; 
    for(r = 0; r < rings; r++) for(s = 0; s < sectors; s++) { 
     float const y = sin(-M_PI_2 + M_PI * r * R); 

     float const x = cos(2*M_PI * s * S) * sin(M_PI * r * R); 

     float const z = sin(2*M_PI * s * S) * sin(M_PI * r * R); 

     v[0] = x; 
     v[1] = y; 
     v[2] = z; 

     v+=3; 
    } 

    sphere_indices = malloc(sizeof(GLushort) * rings * sectors * 4); 
    GLushort *i = sphere_indices; 
    for(r = 0; r < rings; r++) for(s = 0; s < sectors; s++) { 
     *i++ = r * sectors + s; 
     *i++ = r * sectors + (s+1); 
     *i++ = (r+1) * sectors + (s+1); 
     *i++ = (r+1) * sectors + s; 
     sphere_quads++; 
    } 
} 

void draw_sphere() 
{ 
    glTranslatef(animation.sphere_position[0], animation.sphere_position[1], animation.sphere_position[2]); 

    glEnableClientState(GL_VERTEX_ARRAY); 
    glEnableClientState(GL_NORMAL_ARRAY); 

    glVertexPointer(3, GL_FLOAT, 0, sphere_vertices_normals); 
    glNormalPointer(GL_FLOAT, 0, sphere_vertices_normals); 
    glDrawElements(GL_QUADS, sphere_quads*4, GL_UNSIGNED_SHORT, sphere_indices); 
} 

void idle() 
{ 
    glutPostRedisplay(); 
} 

static GLfloat const light_pos[4] = {-1., 1., 1., 0.}; 
static GLfloat const light_color[4] = {1., 1., 1., 1.}; 

void display() 
{ 
    static struct timeval delta_T = {0., 0.}; 
    struct timeval time_frame_begin, time_frame_end; 

    int win_width, win_height; 
    float win_aspect; 

    gettimeofday(&time_frame_begin, 0); 

    animate(delta_T.tv_sec + delta_T.tv_usec * 1.e-6); 

    win_width = glutGet(GLUT_WINDOW_WIDTH); 
    win_height = glutGet(GLUT_WINDOW_HEIGHT); 
    win_aspect = (float)win_width/(float)win_height; 

    glViewport(0, 0, win_width, win_height); 
    glClearColor(0.6, 0.6, 1.0, 1.0); 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

    glMatrixMode(GL_PROJECTION); 
    glLoadIdentity(); 
    glFrustum(-win_aspect, win_aspect, -1., 1., 1., 10.); 

    glMatrixMode(GL_MODELVIEW); 
    glLoadIdentity(); 
    glTranslatef(0,0,-5.5); 

    glLightfv(GL_LIGHT0, GL_POSITION, light_pos); 
    glLightfv(GL_LIGHT0, GL_DIFFUSE, light_color); 

    glPushMatrix(); 

    glEnable(GL_DEPTH_TEST); 

    glEnable(GL_LIGHTING); 
    glEnable(GL_LIGHT0); 
    draw_sphere(); 

    glPopMatrix(); 

    glutSwapBuffers(); 

    gettimeofday(&time_frame_end, 0); 
    timersub(&time_frame_end, &time_frame_begin, &delta_T); 

} 
+0

datenwolf請你給我提供一個工作實例....或者我可以從那裏獲得soure code.of任何這樣的例子的鏈接,這樣我就可以通過試驗使我自己更加熟悉這個概念 – Tarun 2011-05-10 12:33:09

+0

@ fluty:這裏你去:http://homepages.physik.uni-muenchen.de/~Wolfgang.Draxinger/stuff/sinsphere.c – datenwolf 2011-05-10 14:36:34