OpenGL笔记之绘制几何图元(geometric primitives)

本文是学习OpenGL过程中的一篇笔记。在学习过程中,主要参照了大名鼎鼎的
  • 《OpenGL Programming Guide》(中文名《OpenGL编程指南》,有些人还称之为OpenGL红宝书)
  • 《OpenGL SuperBible》(中文名《OpenGL超级宝典》,有些人还称之为OpenGL蓝宝书)

另外还有

  • 《3D Computer Graphics: A Mathematical Introduction with OpenGL》
  • 《Advanced Graphics Programming Using OpenGL Morgan Kaufmann Series in Computer Graphics and Geometric Modeling 》

等书籍。

 

一、OpenGL的一些基本概念

1、建模(Modeling):生成模型的过程。

2、模型(model):需要在图形系统上显示物体的数学描述。它需要精确地描述物体的几何外观(点、线、三角形、多边形等)和特征(点的大小、线的宽度和点画模式、边界边标志、着色模型、表面法线、光源位置、材料属性、颜色、纹理坐标、雾坐标等)。

3、渲染(Rendering):根据模型生成在图形系统上显示的图像的像素的过程。

4、着色(Shading):通过对模型顶点的颜色插值化生成模型颜色的过程。通过着色,可以掩盖模型多边形的菱角特征,使模型更加真实化。效果请参见下图:

5、图元(primitives):一维或二维实体(点、线、多边形)。这些实体用来在3D空间中创建3D实体。

The geometrical forms of these objects are each represented by a set of vertices and a particular type of graphics primitive that indicates how the vertices are connected to produce a shape.

6、缓冲区(buffer):图形系统中用来显示或者创建图像的内存区,其存储了图像像素的相关信息。

7、位平面(bitplane):为每个像素存储一位信息的缓冲区。颜色缓冲区(Color buffers)、深度缓冲区(Depth buffer)、模板缓冲区(Stencil buffer)和累积缓冲区(Accumulation buffer)都是由不同数量的位平面构成。

8、帧缓冲区(frame buffer):颜色缓冲区(Color buffers)+  深度缓冲区(Depth buffer)+  模板缓冲区(Stencil buffer)+ 累积缓冲区(Accumulation buffer)

9、颜色缓冲区(Color buffers):又叫图形缓冲区(Image buffers)。图形系统中用来显示或者创建图像的内存区,其存储了图像像素的相关信息。

  • 当开启双缓冲模式时,正在显示的缓冲区叫前缓冲区(front buffer),正在创建图形的缓冲区叫后缓冲区(back buffer)。通常,OpenGL并不直接在屏幕上描画图元,而是在缓冲区中描画。当图元绘制完成后,通过调用glutSwapBuffers或者glDrawBuffer来把缓冲区的内容刷新到屏幕上。为了避免撕裂现象,缓冲区切换需要和屏幕刷新率同步(The buffer swap is often synchronized with the refresh frequency of the display to avoid an artifact known as  tearing. Tearing occurs when a buffer swap is performed during the display refresh interval, causing the upper and lower parts of a viewport to show data from different image buffers. );
  • 当开启单缓冲模式时,图元绘制完成后,需要调用glFlush或者glFinish来把缓冲区的内容刷新到屏幕上。

 10、深度缓冲区(Depth buffer):又叫z-buffer。深度缓冲是在三维图形中处理图像深度坐标的过程,这个过程通常在硬件中完成,它也可以在软件中完成,它是可见性问题的一个解决方法。可见性问题是确定渲染场景中哪部分可见、哪部分不可见的问题。当三维图形卡渲染物体的时候,每一个所生成的像素的深度(即 z 坐标)就保存在一个缓冲区中。这个缓冲区叫作 z 缓冲区或者深度缓冲区,这个缓冲区通常组织成一个保存每个屏幕像素深度的 x-y 二维数组。如果场景中的另外一个物体也在同一个像素生成渲染结果,那么图形处理卡就会比较二者的深度,并且保留距离观察者较近的物体。然后这个所保留的物体点深度保存到深度缓冲区中。最后,图形卡就可以根据深度缓冲区正确地生成通常的深度感知效果:较近的物体遮挡较远的物体。这个过程叫作隐藏表面剔除(hidden surface elimination)。使用深度缓冲区,一旦像素的深度已经确定,那么就可以对这个像素进行裁剪,这样如果该像素不可见的话就可以完全跳过照明与纹理处理的过程,并且需要消耗许多时间的像素浓淡工具通常也会跳过对于裁剪掉的像素的处理。这样隐藏表面剔除就成为了在填充速度、光照、纹理或者像素浓淡处理是主要瓶颈的场合的一种很好的优化工具。
        在场景开始的时候,必须将深度缓冲区初始化为一个特定的值,通常初始化为 1.0,这是因为 1.0 是深度范围 0 到 1 的上限,它意味着在整个视体(viewing frustum)之内没有任何物体。当一个像素第二次被绘制时,例如当一个物体在另一个物体之后被绘制,深度缓冲要么保留前面的深度值,要么使用第二个像素的深度值替换当前深度值。那个深度保留哪个深度抛弃取决于你选择的深度函数。例如,如果当前深度函数是CompareFunction.LessEqual时,只有小于等于当前深度值的值才会被保留,而大于当前深度值的值会被抛弃。这叫做深度测试,每次绘制像素时都会进行深度测试。当对一个像素进行深度测试时,它的颜色会被写入渲染目标,而深度被写入深度缓冲。

二、几何图元的一些备注

1、点:概括的说,图形系统中的点是由一个正方形构成,这个正方形由一个或多个像素组成。在电视或CRT中,每个像素由3个独立的点构成,每个点都有自己的颜色和亮度。当点比较小而且人离点比较远时,人眼不能识别出组成像素的3个点,在视网膜里最终会形成一个有颜色的像素。像素的构成请参见下图:

2、多边形属性

隐藏表面删除(Hidden Surface Removal):如果绘制的物体有多个,其中一个物体位于其他物体之前或者要绘制一个3D实体,此时如果想让位于前面的物体挡住后面的物体或者显示3D实体的前表面挡住后表面,就要开启隐藏表面删除功能。隐藏表米删除功能是通过启动OpenGL深度测试的特性来实现的。相关命令为:

  • glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
  • glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  • glEnable(GL_DEPTH_TEST);

具体实例可以参见《OpenGL SuperBible》第三章的triangle实例。

 

环绕(Winding):OpenGL会判断多边形表面是面向还是背离观察者,换句话说,OpenGL可以给多边形指定前面(front face)和后面(back face)。默认情况下,逆时针顺序的顶点数组形成的面被认为是多边形的前面。我们可以通过glFrontFace来修改OpenGL的默认值。

 

剔除面(Cull Face):剔除用来消除已经知道不会显示的几何图形。绘制3D实体例如圆锥体时,通常我们只需要看见外表面而不能看见内表面,此时如果还向图形系统发送描画内表面的命令就是一种对资源的浪费,此时我们就可以开启剔除功能来减少描画,提高性能。

可以通过glCullFace来选择剔除面;启动剔除功能需要调用glEnable(CL_CULL_FACE);

具体实例可以参见《OpenGL SuperBible》第三章的triangle实例。

 

 法线向量(Normal Vector):是一条垂直于某个表面的方向向量。法线向量定义了物体相对于光源的方向,OpenGL使用它确定物体各个顶点接受光照的情况。根据光的反射定律,如果知道光的入射方向和照射点处的法线就可以知道光的反射方向。因此,对于某个特定物体,在指定观察点、光源位置和特征、物体顶点法线向量的情况下,就可得出光线的反射方向,进而计算出物体顶点处的光照效果。考虑到曲线和曲面,OpenGL中只能给顶点分配发线向量。OpenGL命令glNormal3*()。法线向量的方向和物体的环绕方向符合右手法则。

 

你可能感兴趣的:(OpenGL)