如何在曲线上为实心球体设置动画
How to animate a solid sphere over a curve
我正在用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 <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);
}
相关文章:
- 为不同配置设置MSVC_RUNTIME_LIBRARY的正确方法是什么
- 在C++/Linux中设置单调时钟的一些技巧
- 如何在选项卡视图Qt中设置一个新项目,并保存以前的项目
- 嵌套在类中时无法设置成员数据
- 需要帮助设置在C++中使用的Potrace
- 如何在自删除后将对象设置为nullptr
- 将指针设置为"nullptr"并不能防止双重删除?
- 如何在Ubuntu中使用cmake设置qt4
- ld:bind_at_load和-bitcode_bundle(Xcode设置ENABLE_bitcode=YES)不能
- 如何在boost beast http请求中设置http头
- 如何解决gcc编译器优化导致的centos双编译器设置中的分段错误
- 如何将这个C++哈希表转换为动态扩展和收缩,而不是使用硬设置的最大值
- 为什么文件名被设置为一个点,而不是在读取矢量中的文件名时
- 如何在24位SDL_Surface上设置像素的颜色
- std::设置自定义比较器
- 如何设置一个范围来提取我想要获得的信息
- 如何在C/C++中用FD_set Unix设置套接字文件描述符
- 通过选项卡的文本设置QTabWidget顺序
- 将特征矩阵的向量设置为0
- 如何在曲线上为实心球体设置动画