2

如何在openGL中制作一步一步的显示动画?

我正在做一个 reprap 打印机项目来读取 GCode 文件并将其解释为图形。现在我很难一步一步地绘制整个对象的动画。我需要画很多短线来组成一个完整的对象。例如:

|-----|
|     |
|     |
|-----|

正方形由许多短线组成,每条线由如下代码生成:

glPushMatrix();
.....
for(int i=0; i< instruction[i].size(),i++)
{  ....
   glBegin(GL_LINES);
     glVertex3f(oldx, oldy, oldz);
     glVertex3f(x, y, z);
   glEnd();
}
glPopMatrix();

现在我想制作一个步进动画来展示这个正方形是如何制作的。每次绘制新线时我都尝试刷新屏幕,但它不起作用,整个正方形立即出现。有人知道怎么做吗?

4

3 回答 3

0

如果您只希望线条一个接一个地出现,并且您不必对效率或良好的编程风格挑剔,请尝试以下操作:

(在你的绘图程序中)

if (timer > 100) {

//draw the next line

timer = 0;

}

else

timer++;

//draw all the other lines (you have to remember wich one already appeared)

//for example using a boolean array "lineDrawn[10]"

计时器是一个整数,它告诉您绘制场景的频率。如果你把它变大,当你运行你的程序时,屏幕上的东西会变得更慢。

当然,这仅在您有绘图例程时才有效。如果没有,我强烈建议使用一个。

->到处都有很多教程,例如

http://nehe.gamedev.net/tutorial/creating_an_opengl_window_%28win32%29/13001/

祝你好运!

PS:我认为你做了几乎相同的事情,但没有计时器。这就是为什么所有东西都画得如此之快,以至于你认为它同时出现。

于 2012-10-22T08:32:59.287 回答
0

您应该在每次绘制调用后调用 SwapBuffer 方法。确保你没有搞砸矩阵堆栈,你可能需要一些东西来“暂停”渲染,比如断点。

于 2012-10-21T21:23:06.953 回答
0

典型的 OpenGL 实现会将大量调用排队,以将它们批处理成活动突发,以最佳利用可用的通信带宽和 GPU 时间资源。

您要做的基本上与双缓冲渲染相反,即在每个绘图步骤立即可见的地方进行渲染。一种方法是渲染到单个缓冲窗口并glFinish()在每一步之后调用。主要缺点:它可能无法在使用合成窗口管理器等的现代系统上运行良好。

我推荐的另一种方法是使用单独的缓冲区进行增量绘图,并不断刷新主帧缓冲区。关键主题是Frame Buffer ObjectRender To Texture

首先,您创建一个 FBO(大量教程以及 StackOverflow 上的答案)。FBO 基本上是一种抽象,您可以将目标缓冲区(如纹理或渲染缓冲区)连接到它,并且可以将其绑定为绘图调用的目的地。

那么如何解决你的问题呢?首先,您不应该通过延迟绘图循环来制作动画。这有几个原因,但主要问题是,您因此失去了程序的交互性。相反,您在动画中的哪一步维护一个(全局)计数器。让我们称之为step

int step = 0;

然后在您的绘图功能中,您必须分阶段:1)纹理更新 2)屏幕刷新

第一阶段包括将帧缓冲区对象绑定为渲染目标。为此,目标纹理必须是未绑定的

glBindTexture(GL_TEXTURE_2D, 0);
glBindFramebuffer(GL_FRAMEBUFFER, animFBO);
glViewport(0, 0, fbo.width, fbo.height);
set_animFBO_projection();

现在的诀窍是,您只清除一次 animFBO,即在创建之后,然后再也不清除。现在您根据动画步骤绘制线条

draw_lines_for_step(step);

并增加计步器(可以作为复合语句执行此操作,但这更明确)

step++;

更新动画 FBO 后,是时候更新屏幕了。首先解绑animFBO

glBindFramebuffer(GL_FRAMEBUFFER, 0);

我们现在在主要的屏幕帧缓冲区上

glViewport(0, 0, window.width, window.height);
set_window_projection(); //most likely a glMatrixMode(GL_PROJECTION); glOrtho(0, 1, 0, 1, -1, 1);

现在绑定 FBO 附加纹理并将其绘制到一个完整的视口四边形

glBindTexture(GL_TEXTURE_2D, animFBOTexture);
draw_full_viewport_textured_quad();

最后做缓冲区交换以显示动画步骤迭代

SwapBuffers();
于 2012-10-21T23:00:58.717 回答