通过引入观察者,实现OpenGL中的背景移动

前一阵子学图形学课程,需要用OpenGL写一个小程序,弄完之后觉得很有意思,期间为了实现一个效果,想了点东西,与大家共享。

首先简单介绍一下背景:OpenGL是一个开源的图形学库,用它可以很方便的实现图形学的算法,有兴趣的可以搜一搜,网上大把大把的资料。OpenGL的工作方式很像流水线,分为好几个阶段,每一个阶段的任务就是对前一阶段的结果进行进一步的处理。其中一个阶段的名称叫做fragmentshader,本栗子主要就在这一阶段实现的。

作为一个课内实验,它的要求如下:给一张图片作为背景,最基本要求是做出水波的效果,在此基础上添加自己想的特效。水波是基本要求,使用离散格子玻尔兹曼方法就能够实现了。课程里给了详细的资料,以后有机会了可以写一篇介绍一下它。实现水波之后,我想控制背景图片运动,一开始不是很顺利,后来想办法用上了线性代数的一点内容才顺利实现了。

事情是这样的:OpenGL将最终的结果,也就是我们最后看见的结果保存在gl_FragColor数组中,而将输入的背景图片保存在Texture数组中,gl_FragColor和Texture大小相同。我们要做的其实就是将二维数组Texture中的内容映射到gl_FragColor中。刚开始的时候我对它的理解是只能按位置一一映射,也就是这样的:

通过引入观察者,实现OpenGL中的背景移动_第1张图片

使用这样的映射,背景图片只能显示在固定的位置。后来开了窍,想到这个模型中少了一样重要的东西:人眼。最终应还有一个gl_FragColor到人眼的投影,所以模型应该是这个样子的:

通过引入观察者,实现OpenGL中的背景移动_第2张图片

gl_FragColor到人眼的投影是固定的,无法改变,但Texture到gl_FragColor的投影却不仅仅只能按位置映射。我们可以gl_FragColor和人眼的位置固定,组成一个坐标系A,将Texture想象成一个另一个坐标系B。通过控制A相对于B运动,B保持不动,人眼就可以通过gl_FragColor这扇窗户“看到”Texture里面内容的运动。

通过引入观察者,实现OpenGL中的背景移动_第3张图片

下面是一个仅包含平移运动的例子。a本来位于Texture中比较偏右的位置,但将坐标系A右移之后,a在gl_FragColor中的对应的位置a’反而偏左了。对人眼而言,这就产生了a“左移”的效果。现在的问题是,知道坐标系A相对于B的位置以及a在Texture,也就是坐标系B中的位置,怎么计算a’在坐标系A中的位置?这个用线性代数中的坐标变换就可以算出来。

通过引入观察者,实现OpenGL中的背景移动_第4张图片

你可能感兴趣的:(通过引入观察者,实现OpenGL中的背景移动)