我在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的位置序列开始.在到达P5位置后,它仍然可以看到所有其他位置(P1,P2,P3,P4),但我希望它只在当前位置显示球体,而翻译我该怎么做?
您没有清除帧缓冲区,这意味着您正在前一帧的顶部绘制每个帧.尝试使用glClearColor(0.0f, 0.0f, 0.0f, 1.0f );
您想要的颜色.
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#include #include #include #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); }