openGL 学习日志003
书接上文,需要复制一组货或者两组的纹理坐标
void GLBatch::Beigin(GLenum primitive,GLuint nVerts,GLuint NtextrueUits = 0);
然后,至少要复制一个由3 分量(x,y,z) 顶点组成的数组
void GLBatch::CopyVertesData3f(GLFloat *vVerts);
还可以选择复制表面法线,颜色,纹理 和坐标
void GLBatch :: CopyuNormalDataf(GLFloat *vVerts);
void GLBatch :: GopyColorData4f:(GLFloat *vColors);
void GLBatch :: CopyTextCoorData2f(GLFloat *vTExtcoords,GLuint uiTexturelayer);
完成上述工作,需要结束。 结束函数为
void GLbatch : End (void);
实际上,可以在任何我们想要的时候进行复制,只要不改变类的大小即可,而一旦调用end 函数,就不能在增加新的属性了。
不希望出现的几何图形。
在默认的情况下。我们所渲染的点,线 或者三角形都会在屏幕丧进行光删化,并且会按照图元批次时制定的顺序进行排列,在某些情况下会产生问题,如果我们绘制一个由很多三角形组成的实体的对象,那么第一个绘制的三角形可能会被后面绘制的三角形覆盖,例如,假设我们绘制一个由很多三角形组成的花托(一种形状像面包圈的物体),其中一些三角形在花托的背面,而另一些花托在三角形的正面,我们看不到背面,对于这个问题的解决办法时,对这些三角形进行排序,这种方式称之为 油画法
这种方式在计算机图形处理是非常低效的,主要由两个原因。其中一个原因是
- 我们必须对任何发生集合图形重叠的地方的每个像素进行两次操作,而在存储其中进行写操作会使速度变慢
- 对独立的三角形进行排序的内存开销会变高。
正面剔除 和 背面剔除
对正面和背面的三角形进行区分的原因之一就是为了剔除,背面剔除能够极大的提高性能,这种方式非常高效,在渲染的图元装配阶段就整体抛弃了一些三角形,并且没有执行任何不恰当的光删化操作,一般表面剔除按如下方式进行开启
开启
glEnable (GL_CULL_FACE);
关闭
glDisable(GL_CULL_FACE);
指明剔除的是正面 还是背面 这个是由两个函数控制的 glCullFace 控制的
void glCullFace(GLenum model);
model 参数的可用值为 :GL_FRONT , GL_BACK 或者 GL_FRONT_AND_BACK
要消除不透明物体的内部几何图形需要2行代码
glCullFace(GL_BACK); //配置
glEnable(GL_CULL_FACE); //开启
深度测试
深度测试是另一种高效消除隐藏表面的技术,他的概念很简单,在绘制一个像素时,将一个值(称为z)分配给他,这个值表示它到观察者的距离,然后,当另一个像素需要在屏幕上同样的位置进行绘制的时候,新的像素 z. 将与存储的像素 z. 进行比较,如果像素 z 比较大,那么它离观察者的距离就比较近,这样原来的像素就在上面,所以原来的像素就会被新的像素覆盖,如果新像素的 z 值更低,那么它就必须位于原来像素的后面,不能遮住原来的像素,在内部,这个任务是通过深度缓冲区来实现的,它存储了屏幕上每个像素的深度值。(多数情况下会采用深度测试)
启用深度测试
glEnable(GL_DEPATH_TEST);
启用深度测试之前,必须要申请一个深度缓冲区,否则上述代码将被忽略。下列代码为申请缓冲区
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
深度测试将消除那些应该被已存在像素覆盖的像素,可节省储存器的带宽。
多边模式
多变形(含三角形)不一定是实心的,在默认情况下,多边形是作为实心图形绘制的,但我们可以通过将多变形制定为显示轮廓或只有点(只显示顶点)来改变这种行为。函数 glpolygonMode
允许将多变形渲染成实体,轮廓或只有点,此外,我们可以在多变形的两面都应用这个渲染模式,也可以只在正面或背面应用。
void glpolygonMode (GLenum face,GLenum model);
第一个参数为 : GL_FRONT , GL_BACK 或者 GL_FRONT_AND_BACK
第二个参数为 :GL_FILL,GL_LINE,GL_POINT;
顺便提一句 GL_FILL
是默认值。
原来的效果
通过glPolygonMode 可实现 一个物体的 正面 或者背面为 线框模式。结合使用
glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
添加上述代码可实现下图这种效果
glPolygonMode(GL_FRONT_AND_BACK,GL_POINT);
如果切换成GL_POINT 可实现以下这种效果
多边形偏移。
我硬是没看懂书上说的是什么,这里找到了一篇文章讲的比较清楚
剪裁
另一种是一种提高性能的刷新方法,只刷新屏幕上变化的部分,我们可能还需要将OpenGL 渲染限制在窗口中一个较小的矩形区域中,OpenGL 允许我们在将要进行渲染的窗口制定一个剪裁框,在默认情况下,剪裁框与窗口大小相同,并且不会进行剪裁测试,几乎处处都要用到GlEnable函数开启剪裁测试。
开启剪裁测试
GLEnable(GL_SCISSOR_TEST);
相应的,我们也可以关闭剪裁测试
GLDisable(GL_SCISSOR_TEST);
指定剪裁窗口大小和位置的函数为
void glScissor(GLint x,GLint y,GLSizei width,GLSizei height);
其中 x.和 y. 参数指定了剪裁框的左下角。 宽度和高度是剪裁的响应尺寸,以左下角为原点,在三维坐标系里。
混合
通常情况下OpenGL 渲染时,会把颜色值放在颜色缓冲区中,我们还知道,每个片段的深度值也是放在深度缓冲区中的,当深度测试被(关闭)的时候,新的颜色值简单地覆盖颜色缓冲区中已经存在的其他值,当深度测试被打开(启用)的时候,新的颜色片段只有当它比原来的值更接近临近的剪裁平面时才会替换原来的颜色片段,在通常情况下,任何个绘制操作不是被完全丢弃,就是完全覆盖原来的颜色值,这取决于深度测试的结果,如果打开了Oepngl 的混合功能,那么下层的颜色就不会被清除。
打开混合
glEnable(GL_BLEND);
关闭混合
GLDisable(GL_BLEND);
组合颜色
目标色
:已经存储在颜色缓冲区的颜色叫做目标色:颜色 包含 (R。G。B A);
源颜色
:作为当前渲染命令的结果进入颜色缓冲区的颜色值。
注意 :目标色 可能或者不可能与 源颜色进行交互。
当混合功能被启用时,源颜色 和 目标色的组合方式是由混合方程式控制的,混合方程式如下
Cf = (Cs *S) + (CD *D);
Cf :最终计算色
Cs:源颜色
Cd:目标色
S 和 D 分别是源颜色 和 目标色 混合因子。
以下函数可 设置混合 因子
glBlendFunc(GLEnum S,GLenum D);
抗锯齿
混合功能另一个用途就是抗锯齿,在绝大多数情况下,一个独立渲染片段会映射到计算机屏幕上的一个像素。……………………
1开启抗锯齿
glEnable(GL_BLEND);
2设置混合函数
glBendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
在启用混合功能并选择正确的混合函数以及混合方程式之后,我们可以选择调用glEnable 函数对点,直线 和 多边形 进行抗锯齿处理
如下:
glEnable(GL_POINT_SMOOTH); //点
glEnable(GL_LINE_SMOOTH); //线
glEnable(GL_POLYGON_SMOOTH); //多边形
多重采样
设置 GL_POLYGON_SMOOTH 的时候,对整个场景进行抗锯齿处理并没有想象的那么方便,因为抗锯齿处理是基于混合操作的,这就需要从千岛后对所有的图元进行排序,这个是非常麻烦的。
为此OpenGL 新增了一个特性,称为多重采样。
为了进行多重采样,首先必须获得一个支持多重采样帧缓冲区的渲染环境,这在不同的平台可能各不相同,但是GLUT 提供了一个 位段(GLUT_MULTISAMPLE)允许请求这种缓冲区。
可调用下面的函数。
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH | GLUT_MULTISAMPLE);
打开多重采样
glEnable(GL_MULLTISAMPLE);
关闭多重采样
glDisable(GL_MULLTISAMPLE);