现在的位置: 首页 > 综合 > 正文

通俗的说OpenGL画图原理

2013年01月06日 ⁄ 综合 ⁄ 共 2403字 ⁄ 字号 评论关闭

通俗的说OpenGL画图原理

 

       首先我想我应该声明一下,一方面可以充一充文章字数,另一方面也免得贻笑大方。这不是一篇严谨的介绍OpenGL画图原理的文章,而是我根据自己不太长的学习过程,对OpenGL画图原理的个人总结。它用相当通俗的语言来解释OpenGL是怎么画图的,以及为什么需要使用OpenGL,而我本人也非常喜欢通俗易懂,知读者之所不懂的技术文章。通过我写的这篇文章,相信对于没有接触过OpenGL的哥们,能够对OpenGL有个大概的印象,仅希望别太深刻进而误人子弟。此外,文章不会出现任何OpenGLAPI函数,相信你们也不愿意看到那些东西。(哇,充了不少啊)

       我想,本质上,显示器只是将存放在显存中的一幅2D图像数据显示出来了,而这个2D图像数据可以是以RGBA的方式存放的。关键的地方来了,这个2D图像数据怎么获得呢?最简单的方式是直接写入,数据来源则是位图数据,这应该是2D画图的实现方式,例如JavaCanvas(事实上我不太肯定)。实际上,OpenGL也是允许直接绘制位图数据的,即在屏幕上绘制一张图片,这样速度很快,因为它不需要进行什么计算。显存中的这个2D图像数据还可以来至于OpenGL,或者说,OpenGL能够按照程序员指定的方式往这块显存中填充2D图像数据。注意这里所说的“程序员指定的方式”。事实上,程序员只能改变OpenGL绘制图像数据过程中的某些参数,而不能完全改变这个绘制过程,如果改变了,那它就不是OpenGL了,你应该重新给它起个名字,比如叫JlinYY什么的^_^

       先看下面一幅图像,如果我说它是从一个Windows窗口上截下来的,你能看出它是直接用2D的方式绘制的,还是用OpenGL的方式绘制的吗?哦,你们还

不知道OpenGL是怎么绘制的呢,自相矛盾了?呵呵,相信我,你们看不出来的。原因前面也提到了,那幅图像只是显示器针对显存中的一块2D图像数据的展示而已。既然没啥区别,用2D的方式画出来不就行了?干嘛那么麻烦又搞出个OpenGL呢?让我们假设上面那幅图像中的三角形是通过画线的方式分三次绘制出来的,我们知道,JavaCanvas是可以做得到的,同样的,OpenGL也做得到。实际上OpenGL可以根据三角形的那3个点,直接绘制出那个三角形。然而,仅仅凭借这点,并不能充分说明OpenGL的客观存在的必要性。让我们再看一幅图像:

跟之前那幅截图一样,这个我们也看不出它到底是用2D方式绘制的,还是用3D(或者说OpenGL)的方式绘制的。但是,很明显,如果我们也用JavaCanvas来绘制上面图像中的立方体,还得一条一条线的绘制,这也太麻烦了吧,且不说绘制代码本身麻烦,绘制的是不是个标准的立方体都是个问题——你怎么算出这个立方体在屏幕上各各点的位置呢?总不能凭感觉吧(我就是用Windows的画图工具凭感觉把上面那幅图片画出来的,因此不太自然)?这时候,OpenGL的作用慢慢体现了。OpenGL可以根据你 给出的3D世界中的立方体中的8个坐标点,绘制出非常逼真的立方体2D图像。事实上,OpenGL正是这样一种工具,根据程序员提供的3D世界中的坐标点(及其它跟该坐标点相关的数据,如颜色),用一套非常成熟的算法,来绘制一幅2D图像数据——哇,我觉得我说的太精辟了。注意这里我并没有考虑到图像中立方体的颜色,我们暂且不说这个吧,免得干扰了大家对OpenGL的理解。

       我考虑许久,我觉得我应该对OpenGL画图算法流程进行逆向讲解,即在形成上面所说的2D图像的前一步,OpenGL都在干什么。而不是从给出3D世界中的坐标点开始,依次讲解OpenGL是怎么对这个坐标点进行运算并得出最后的2D图像的。我想前面那种讲法会更能吸引住读这篇文章的“OpenGL菜鸟们”。

       那么前一步OpenGL在干什么呢?假设上面那幅图像中的立方体是个线框立方体,即那些面是没有颜色的,这样又会简单一点。这一步跟JavaCanvas类似,这时候OpenGL在画线并上色,即根据这一步的前一步得到的2D屏幕坐标点进行画线,也可以说这个过程是在进行直线的光栅化操作(Rasterization),光栅化这个术语会显得专业点,免得我这篇文章过于业余。我们知道,画线其实也有算法的,而常见的也就那么几种,如Bresenham 画线算法、中点画线算法等。你要问OpenGL用的是哪种画线算法?我会说其实我也不知道,呵呵,但我想逃不开这几种。画线算法,就是根据2D屏幕上的两个坐标点,算出屏幕中的哪些像素点是位于这2个坐标点所定义的直线上的。算出哪些像素应该画出来后,接着是上色了,或者叫做像素操作(Pixel Operation),针对每一个位于直线上的像素点,算出它的实际颜色,并写到显存中的2D图像缓冲区中。这个像素的上色操作其实也不是那么简单啊,是一个很值得研究的领域,在GPU编程中,我们称之为Pixel Shader或者叫Fragment Progamming。通过这个像素操作,我们可以做出各种3D游戏中的特效来。可惜这个细节上的东西我也不懂啊,没有仔细研究过,以后懂了再慢慢告诉大家更多相关的东西。像素操作完成之后,一条直线就画到缓冲区中了,然后就是显示啦,也就得到了那幅图像中的立方体了。

       上面有提到过,从上一步得到的2D屏幕的坐标点来进行画线并显示。那么这个上一步算出的2D屏幕的坐标点具体是如何得来呢?下回再说吧,太晚了,而且现在找个创新文档的题目不容易啊。本想写3D的一个阴影生成算法的,叫Shadow Mapping,突然发现功力不够,估计大伙也没多大兴趣,就作罢。兄弟们,这篇文章可是一个字一个字的敲出来的啊,没贴代码的哦,而且还讲得那么地俗了,多少给点辛苦分吧。­——第一次讨分,不知道效果如何……

抱歉!评论已关闭.