使用 glfw 动画对象

Posted

技术标签:

【中文标题】使用 glfw 动画对象【英文标题】:animating object with glfw 【发布时间】:2015-03-23 13:24:58 【问题描述】:

我正在尝试在窗口上设置一个圆的动画,该圆的默认坐标为 -1.0

GLint modelLoc = glGetUniformLocation(program, "model");
GLfloat timer = glfwGetTime();
timer /= 10;

glm::mat4 model;
glm::vec3 position = circle.get_position();
GLfloat angle = glm::radians(circle.get_angle());

position.x += timer*cos(angle);
position.y += timer*sin(angle);   

model = glm::translate(model, position);
glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));
glDrawArrays(GL_LINE_LOOP, 0, NUM_CIRCLE_VERTICES);

现在对象从其初始位置动画到屏幕外。我希望它在到达边缘时出现在窗口的另一侧(即将x变成-x)。我在想正弦函数在这里会很有用,但我不太确定如何实现它。

【问题讨论】:

【参考方案1】:

比使用 trig 简单得多:

if(position.x < -1)
    position.x+=2;
if(position.y < -1)
    position.y+=2;
if(position.x > 1)
    position.x-=2;
if(position.y > 1)
    position.y-=2;

【讨论】:

这不起作用。假设原始位置是 x = 0.0。随着定时器在正方向增加。一旦 x == 1.0,那么 x 将变为 -1.0。但是计时器正在增加,所以下一次迭代 x = 1.1(假设)然后 x 将是 -1.1,依此类推。 如果 x 为 1.1 那么它将变为 -0.9 此解决方案不提供圆的运动连续性。圆心刚过界,对面就会出现圆。你能做的就是复制你的圈子。使用棘轮怪的解决方案,当中心越界时,让一个圆圈继续移动,让另一个圆圈从对面出现。【参考方案2】:

为了得到更流畅的动画,一定不能使用timer的绝对值,而是上一个值与当前值的差值,称为delta。

因此,我建议您更改代码以完成此操作:

static GLfloast last = 0;
GLfloat delta;
GLfloat timer = glfwGetTime();
delta = timer - last;
last = timer;

...
position.x += delta*cos(angle);
position.y += delta*sin(angle);   

// using ratchet freak's solution
if(position.x < -1)
    position.x+=2;
if(position.y < -1)
    position.y+=2;
if(position.x > 1)
    position.x-=2;
if(position.y > 1)
    position.y-=2;

【讨论】:

以上是关于使用 glfw 动画对象的主要内容,如果未能解决你的问题,请参考以下文章

✠OpenGL-2-图像管线

在 Pyqt 窗口中使用 glfw 窗口

多个对象无法渲染?

增量时间无法与 GLFW 正常工作

在 GLFW 窗口中启用多重采样不会提高抗锯齿的质量

OpenGL代码适用于GLFW,但不适用于Qt OpenGL