OpenGL 编程指南 (3.1)

1、OpenGL使用的是RGB颜色空间,例如三个颜色分量各占8位,那么就说这个颜色值色深24,能够表示2^24中颜色。

2、多重采样是基于采样的抗锯齿技术,有OGAA(ordered grid anti-sliasing)、SGAA(sparse grid anti-aliasing)、MSAA(multi-sampling anti-aliasing)、CSAA(coverage sampling anti-aliasing)等众多实现方式。fragment shader中有gl_SamplePosition、gl_SampleID等内置变量与之相对应的相关信息,限定符sample修饰fragment shader的输入变量时,会在同一个像素上执行多次,每次输出不同的样本位置信息。sample shader 专门用于描述逐样本执行的shader。如下:

#version 330 core

sample in vec4 color;

out vec4 fragColor;

void main()

{

fragColor = color;

}

3、片元的测试与操作

1)剪切测试(scissor test)

是片元可见性判断的第一个附加测试。glEnable(GL_SCISSOR_TEST)启用该测试,void glScissor(GLint x, GLint y, GLsizei width, GLsizei height)将绘制区域限制在该函数参数所形成的矩形内。默认情况下,剪切矩形与窗口大小一致并且是关闭的。(与视窗的绘制限制不同,视窗的不会限制屏幕的清除操作)

2)多重采样操作

默认情况下多重采样计算片元覆盖率不会考虑alpha,开启一下功能则会将alpha纳入参考。

.GL_SAMPLE_ALPHA_TO_COVERAGE 使用片元的alpha来聚散最后采样覆盖率,并且这个过程与硬件实现无关。

.GL_SAMPLE_ALPHA_TO_ONE 将片元的alpha值设置为最大值,然后时候这个值进行覆盖率计算。

.GL_SAMPLE_COVERAGE 将使用glSampleCoverage设置的数值,与覆盖率计算结果进行 与 操作。

.GL_SAMPLE_MASK 使用glSampleMaski设置一个精确的位掩码来计算和表达覆盖率,与片元的采样覆盖值进行 与 操作。这个值也可以通过fragment shader 的 gl_SampleMask进行设置。

3)模板测试(stencil test)

使用模板测试需要在创建窗口时请求生成模板缓冲,使用glStencilFunc 与 glStencilOp 设置测试的mask与比较方法。

void glStencilFunc(Glenum func, GLint ref, GLuint mask)//func是比较方法的枚举,ref是参考值,mask是测试掩码

void glStencilSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)//允许我们为多边形的正面和背面分别设置模板参数

void glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)

void glStencilSeparateOp(GLenum fail, GLenum zfail, GLenum zpass)

4)深度测试(depth test)

使用深度测试需要在创建窗口时请求生成深度缓冲,启用GL_DEPTH_TEST。

void glDepthFunc(GLenum func)//可以选定比较深度的方法,GL_LESS等

比如需要给物体的边框加亮显示,那么可以正常的绘制一遍物体,然后使用glPolygonMode设置为点线模式绘制一遍物体,但是因为这两种绘制模式下的光栅化方法并非完全一致,所以可能造成深度冲突(斑驳,stitching),有一种通常的处理方法就是为它们加一个适当的偏移值,对应于glEnable的参数是GL_POLYGON_OFFSET_POINT、GL_POLYGON_OFFSET_LINE、GL_POLYGON_OFFSET_FILL中的一种,与下面这个函数配合确定偏移值。

void glPolygonOffset(GLfloat factors, GLfloat units)//offset = m*factor + r*units

m是多边形最大深度斜率(光栅化的时候得到),r是深度值最小可识别间隔。m的意义是在遍历多边形时,z相对于x或y坐标上的变化关系式

5)融合(blending)

一个片元通过了上面的所有测试,就可以与当前的颜色缓冲相对应的位置按照指定的方式进行内容的合并,这称之为融合。

void glBlendFunc(GLenum srcfactor, GLenum destfactor)//src是当前处理片元,dest是缓冲中已经存在的数据

void glBlendFunci(GLuint buffer, GLenum srcfactor, GLenum destfactor)//buffer是缓冲id,多缓冲绘制时候使用

void glBlendFuncSeparate(GLenum srcRGB, GLenum destRGB, GLenum srcAlpha, GLenum destAlpha)//功能与上面的相同,只是指定了src与dest的色值,设置的是所有可绘制的缓冲的混合参数

void glBlendFuncSeparatei(GLuint buffer, GLenum srcRGB, GLenum destRGB, GLenum srcAlpha, GLenum destAlpha)

上面的方法指定的都是混合是参与计算的数值比例等,下面的将是指定计算方法

void glBlendEquation(GLenum mode)

void glBlendEquationi(GLuint buffer, GLenum mode)

void glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)

void glBlendEquationSeparatei(GLuint buffer, GLenum modeRGB, GLenum modeAlpha)

计算方式有GL_FUNC_ADD(默认方式)、GL_FUNC_SUBTRACT、GL_REVERSE_SUBTRACT、GL_MIN、GL_MAX等

6)抖动(dithering)

对于颜色位面数目较小的系统,可以通过对图像中的颜色进行抖动来提升颜色的分辨率,代价是损失一定的空间分辨率(???)。抖动是与硬件相关的,OpenGL只提供了开启与关闭没有其它操作空,GL_DITHER。

7)逻辑操作

这是片元的最后一个逻辑操作,包括或(OR)、异或(XOR)、反转(INVERT),作用于src与dest。这种操作对于位块传输类型系统非常有用,因为它们的主要的图形操作就是讲某一处矩形数据拷贝到另外一处。逻辑操作是对输入数据与已有数据做一次逻辑操作来得到新的目标数据。可以通过传递GL_COLOR_LOGIC_OP参数开启它,默认状态值是GL_COPY。

void glLogicOp(Glenum opcode)//GL_AND、GL_OR、GL_NAND、GL_NOR......

但是对于浮点型缓冲或者是sRGB格式缓冲,逻辑操作将会被自动忽略。

4、渲染查询

为了尽可能的提高性能,尽可能的先判断几何物体的可见性再将它们的几何信息送入渲染管线,可以使用遮挡查询的方法判断几何物体的可见性,这一步在深度测试值后完成。算法的大致为先渲染一个精简版的几何物体测试可见性,而且这个渲染过程尽可能简单,只要不影响可见性的测试其它所有功能都可以关闭,通过后再渲染真实的几何物体。

(1)为查询生成ID,调用glBeginQuery(ID),开始查询

(2)渲染精简版的几何物体,调用glEndQuery(ID)完成查询

(3)获取深度测试通过的样本数目

void glGenQueries(GLsizei n, GLuint* ids)//生成n个查询id,存储到ids中

void glBeginQuery(GLenum target, GLuint queryid)//target是需要查询的信息GL_SAMPLES_PASSED等表示一类渲染结果的枚举

void glEndQuery(GLenum target)

void glGetQueryObjectiv(GLenum queryid, GLenum pname, GLint* params)//pname表示需要获取查询状态如GL_QUERY_RESULT,params用于存储获取的结果

void glGetQueryObjectuiv(GLenum queryid, GLenum pname, GLint* params)

void glDeletQueries(GLsizei n, GLuint* ids)

5、条件渲染

对于上面的渲染查询,OpenGL需要停止几何体与片元的处理来处理查询和将这些结果反馈给应用程序。目前,可用使用条件渲染来优化这一性能损失,根据查询结果确定接下来要做什么。

void glBeginConditionalRender(GLuint id, GLenum mode)//mode指定了如何使用查询结果GL_QUERY_WAIT、GL_QUERY_NO_WAIT、GL_QUERY_BY_REGION_WAIT、GL_QUERY_BY_REGION_NO_WAIT

void glEndConditionRender()

6、简单的反走样

OpenGL会通过像素块所覆盖的范围来就散每个片元的覆盖值,然后与Alpha相乘,接着就能进行混合的操作。可以使用glHint来控制图像的反走样,不过这个方法与硬件实现相关。

void glHint(GLenum target, GLenum hint)

1)线段反走样

首先需要开启融合状态。

glEnable(GL_BLEND);

glEnable(GL_LINE_SMOOTH);

glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

glHint(GL_LINE_SMOOTH_HINT, gl_DONT_CARE);

2)多边形反走样与线段反走样类似

原文地址:https://www.cnblogs.com/haihuahuang/p/12342741.html

时间: 2024-08-11 05:54:11

OpenGL 编程指南 (3.1)的相关文章

在Win7(64位)使用VS2015运行《OpenGL编程指南》第八版第一章程序的方法

前言:笔者第一次用vs2015来实现<OpenGL编程指南>第八版第一个程序时确实花费了不少时间,按照网上教程,尝试了各种方法,最终花费了两个上午加一个下午的时间, 成功运行了程序,花了这么多时间,确实让人懊恼,现在把运行程序的步骤记录下来,以便查阅. 1.第一步,下载oglpg-8th-edith. 如果去书本上的官网下载,下载的是第九版的,而不是第八版的源码. 去其他网站下载,下载的这个包里面没有第一章的源码,可以网上黏贴其他人的代码,建议下第八版源码,下载网址:链接:http://pan

编译opengl编程指南第八版示例代码通过

最近在编译opengl编程指南第八版的示例代码,如下 1 #include <iostream> 2 #include "vgl.h" 3 #include "LoadShaders.h" 4 5 using namespace std; 6 7 8 enum VAO_IDs { Triangles, NumVAOs }; 9 enum Buffer_IDs { ArrayBuffer, NumBuffers }; 10 enum Attrib_IDs

VS15 openGL 编程指南 配置库 triangle例子

最近去图书馆借了一本书<OpenGL编程指南(原书第八版)>,今天倒腾了一天才把第一个例子运行出来. 所以,给大家分享一下,希望能快速解决配置问题. 一.下载需要的库文件 首先,我们需要去该书的网站中下载相关的配置文件,书中给的是"红宝书"的官方网址:http://www.opengl-redbook.com/ 但现在已经更新至第九版,里面的库不是很完整,不适宜用于此书示例. 所以我们要找一个第八版的资源:http://pan.baidu.com/s/1kVpv1MR 下载

Visual Studio 2017上配置OpenGL编程指南第8版开发环境

一直想学习一下OpenGL,买了红宝书第8版,却因为工作原因一直没有时间看,最近利用周末尝试了一下配置开发环境,遇到了一些坑点,现在记录下来备用. 第一步:打开Visual Studio 2017,建立一个空的C++工程 第二步:新建triangles.cpp文件,并写入书本例子中的代码 /////////////////////////////////////////////////////////////////////// // // triangles.cpp // //////////

《OpenGL编程指南第七版》学习——编译时提示“error C2381: “exit” : 重定义;__declspec(noreturn) 不同”错误的解决办法

解决办法一. #if defined(_WIN32) # ifndef GLUT_BUILDING_LIBextern _CRTIMP void __cdecl exit(int); 上面是glut.h中对exit的使用,意思是如果没有定义宏?GLUT_BUILDING_LIB,就使用它的exit,那我们就在项目的属性--预处理器 里定义这个宏,这样就不执行glut.h中的exit了,而只执行stdlib.h中的exit.这样也就不会冲突了.对了,还要在附加依赖项里手动加上?glut32.lib

OpenGL 编程指南 (3.2)

1.帧缓冲对象 帧缓冲对象对于离屏渲染.纹理贴图更新.缓存乒乓技术(buffer ping-pongqing,GPGPU的一种数据传输方式)的实现意义非凡,它减少了大量的数据拷贝工作. 建立帧缓冲需要负责建立帧缓冲使用的其它缓冲内容,也就是说,新建的帧缓冲只是一个空壳,具体的渲染缓冲对象被称之为帧缓冲附件.下面是一个简单的可用帧缓冲建立示例: 帧缓冲是比较消耗内存的,所以OpenGL提供了可以将帧缓冲一部分或者全部无效化从而立即释放内存的操作 void glInvalidFramebuffer(

OpenGL 编程指南 (8)

1.细分着色器(Tessellation shader)有两个阶段来生成几何图元的模型网格. 1)在顶点着色阶段,需要设置所有线段.三角形构成处理的网格,使用有序顶点列表生成新的目标图元,. 2)将新生成的图元顶点放置到指定的位置上后进入下一阶段. 2.tessellation shader 处理一种叫 面片(patch) 的新图元,它是一个保证了期望顺序的顶点列表.面片的的顶点数量需要自行设置,同一个绘制命令处理的面片大小是相同的. void glPathcParameteri(GLenum

如何将OpenGL编程指南中的带main的源码改写成可以在MFC单文档编程中可以运行的程序

paradise.ezla.com.tw/files/article/html/220/220964/6363794.htmlparadise.ezla.com.tw/files/article/html/220/220964/6363866.htmlparadise.ezla.com.tw/files/article/html/220/220964/6363918.htmlparadise.ezla.com.tw/files/article/html/220/220964/6363984.ht

opengl编程指南 第七版 源码有bug Page35 lines.c 红宝书

问题1:当我照着源码敲进去的时候发现,运行的结果不对.哪里不对?源码中没有glPushAttrib(GL_LINE_STIPPLE) glPopAttrib().所以会出现每次更新点画线时在下一次绘制时会以最后一次设置的信息重绘而覆盖掉之前已绘制好的点线.所以要进行状态压栈处理和谈栈处理,这样子在刷帧重绘才不会影响其他帧的绘制结果.(原因是什么目前我也不清楚,估计是状态机的管理问题.要了解内部的绘制机制才行.)但是每次手动添加压栈和弹栈太麻烦了,所以我处理C_style的宏定义形式去实现 问题2