Как анимировать сплошную сферу над кривой

#c #opengl #3d

#c #opengl #3D

Вопрос:

я создаю программу на 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();  
}  
  

Проблема: сплошная сфера перемещается по кривой, но для каждого следующего
position я не могу удалить ее предыдущую позицию…например
если сфера переходит из последовательности позиций, такой как P1, P2, P3, P4, А ЗАТЕМ P5 .. после
переход к позиции P5 по-прежнему виден во всех предыдущих позициях (P1, P2, P3, P4)
но я хочу, чтобы при переводе сфера отображалась только в текущем положении
Как я могу это сделать?

Комментарии:

1. используйте Sleep (миллисекунды) вместо этих вложенных циклов. Это в заголовочном файле windows.h.

Ответ №1:

Вы не очищаете буфер кадров, что означает, что вы рисуете каждый кадр поверх предыдущего кадра. Попробуйте использовать glClearColor(0.0f, 0.0f, 0.0f, 1.0f ); с желаемым цветом.

Комментарии:

1. не могли бы вы, пожалуйста, сказать мне, где в приведенном выше коде я должен использовать эту строку

2. @fluty: К сожалению, это не решает вашу реальную проблему. Пока вы не реализуете анимацию OpenGL полезным способом. Смотрите мой ответ.

Ответ №2:

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(amp;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(amp;time_end_frame, 0);
    timersub(amp;time_end_frame, amp;time_begin_frame, amp;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(amp;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(amp;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(amp;time_frame_end, 0);
    timersub(amp;time_frame_end, amp;time_frame_begin, amp;delta_T);

}
  

Комментарии:

1. datenwolf не могли бы вы, пожалуйста, предоставить мне рабочий пример …. или ссылку, по которой я могу получить исходный код. любого подобного примера, чтобы я мог лучше ознакомиться с этой концепцией, поэкспериментировав с ней

2. @fluty: Вот, пожалуйста: домашние страницы. physik.uni-muenchen.de/~Wolfgang. Draxinger /stuff / …