如何在openGL中制作一步一步的显示动画?
Posted
技术标签:
【中文标题】如何在openGL中制作一步一步的显示动画?【英文标题】:How to make a step by step display animation in openGL? 【发布时间】:2012-10-21 21:13:59 【问题描述】:?
我正在做一个 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();
现在我想制作一个步进动画来展示这个正方形是如何制作的。每次绘制新线时我都尝试刷新屏幕,但它不起作用,整个正方形立即出现。有人知道怎么做吗?
【问题讨论】:
【参考方案1】:典型的 OpenGL 实现会将大量调用排队,以将它们批量处理成突发的活动,以充分利用可用的通信带宽和 GPU 时间资源。
您想要做的基本上与双缓冲渲染相反,即在每个绘图步骤立即可见的地方进行渲染。一种方法是渲染到单个缓冲窗口并在每一步之后调用glFinish()
。主要缺点:在使用合成窗口管理器等的现代系统上可能无法正常工作。
我推荐的另一种方法是使用单独的缓冲区进行增量绘制,并不断刷新主帧缓冲区。关键主题是Frame Buffer Object和Render To Texture。
首先,您创建一个 FBO(大量教程以及 *** 上的答案)。 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();
【讨论】:
【参考方案2】:您应该在每次绘制调用后调用 SwapBuffer 方法。 确保你没有搞砸矩阵堆栈,你可能需要一些东西来“暂停”渲染,比如断点。
【讨论】:
交换缓冲区调用很可能会破坏后台缓冲区的内容,因此无法继续绘制。 SwapBuffer 不起作用,不知道是坐标文件太大还是其他原因。程序一直处于运行状态,屏幕上什么也没有显示....但还是谢谢!【参考方案3】:如果您只想让线条一个接一个地出现,并且不必对效率或良好的编程风格挑剔,请尝试以下方法:
(在您的绘图程序中)
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:我认为您的做法几乎相同,但没有计时器。这就是为什么所有东西都画得如此之快,以至于你认为它同时出现。
【讨论】:
以上是关于如何在openGL中制作一步一步的显示动画?的主要内容,如果未能解决你的问题,请参考以下文章
我的OpenGL学习进阶之旅强烈推荐一款强大的 Android OpenGL ES 调试工具 GAPID并展示实战操作演练一步一步看如何使用GAPID调试工具