OpenGL超级宝典笔记一 - 基础渲染

1、渲染中的双缓冲:

使用但缓冲的时候,在渲染每一帧的绘图时,会对画板进行擦除然后在慢慢填充绘制,如果绘制时间过长的时候,就会出现闪烁的现象。为解决这个问题,所以引入双缓冲

双缓冲相当于,在显示的画板中重新创建另外一个画板,绘制的过程在另外的画板进行,绘制完成之后,将显示的画板的内容直接替换成另外一个画板的内容。这样呈现的过程中就不会出现闪烁的问题,即使是绘制的过程比较慢,最多就是出现顿的现象

在例子中渲染的RenderScene()函数中,每次渲染结束之后都会调用glutSwapBuffers()进行缓冲区的切换渲染

void RenderScene(){
	glClearColor(0.0f, 0.0f, 1.0f, 0.0f);
	glClear(GL_COLOR_BUFFER_BIT);

	glClearColor(1.0f,0.0f,0.0f,0.0f);
	glScissor(100,100,600,400);
	glEnable(GL_SCISSOR_TEST);
	glClear(GL_COLOR_BUFFER_BIT);

	glClearColor(0.0f,1.0f,0.0f,0.0f);
	glScissor(200,200,400,200);
	glClear(GL_COLOR_BUFFER_BIT);

	glDisable(GL_SCISSOR_TEST);

	glutSwapBuffers();
}

2、绘制过程:

图元最终的呈现其实是通过一个管线的过程,呈现一个图元,我们必定需要顶点数据,而且需要最终填充成像素的着色器。通过这两个着色器渲染成最终像素的过程就是图形的管线。

OpenGL2.0之后使用可编程的管线,也就是渲染图元的时候,我们是需要通过shader程序进行的,一般会分成两个过程,一个是顶点着色器的处理,一个是片段着色器的处理。

顶点着色器处理客户机输入的数据,应用变换,数学计算(光照,颜色,位移),逐顶点处理

片段着色器会输出我们最终在屏幕看到的像素颜色值,逐像素处理。

Shader的数据传递:顶点属性数据,uniform数据,纹理数据

顶点数据:顶点位置,顶点颜色值,纹理坐标,光照法线。这些数据一般都是传入顶点着色器进行处理的。

uniform数据:和属性数据不同的是,片段着色器中也可以有Uniform变量。Uniform变量在改变的时候是逐批次的不是逐顶点的。常用于设置变换矩阵

纹理数据:纹理数据提供给片段着色器进行采样,根据纹理坐标应用于图元的像素中

输出变量:可以将顶点着色器的值传递到片段着色器中

3、坐标系和投影

GLFrustum:使用该类作为投影矩阵的容器

正投影:通过调用GlFrustum::SetOrthographic(xMin,xMax,yMin,yMax,zMin,zMax)的函数来对最终绘制的图像进行投影。该投影一般用于2D绘图。

透视投影:通过调用GLFrustum::SetPerspective(fFov,fAspect,fNear,fFar)的函数来获取一个投影矩阵。

fFov:在垂直方向上的视觉角度

fAspect:窗口宽高的纵横比

fNear:近裁剪面的距离

fFar:远裁剪面的距离

4、一套现成封装好的Shader管理器

我们使用GLTools中的GLShaderManager进行进行渲染。自带了很多预定义的Shader。

在使用之前必须先 初始化:shaderManager.InitializeStockShaders()

顶点数据和Shader的绑定:有16种类型,编号为0-15.预定义类型一般为GLT_ATTRIBUTE_VERTEX...(GLT_ATTRIBUTE_XXX)

Uniform值的设置:GLShaderManager::UseStockShader(GLenum shader,....)

后面带的参数就是shader需要的uniform值

5、基于GLTools的图元绘制

使用GLTools中的GLBatch类可以进行图元的绘制,绘制前需要指定绘制的图元类型,顶点数和顶点数据

GLBatch::Begin(GLenum primitive,GLuint nVerts,GLuint nTextureUnits = 0)

可选的Private包括GL_POINTS,GL_LINES,GL_LINE_STRIP,GL_LINE_LOOP,GL_TRIANGLES,GL_TRIANGLE_STRIP,GL_TRIANGLE_FAN.

需要特别解释的是GL_LINE_STRIP和GL_LINE_LOOP,一个是线带,一个是线环,一个没有闭合一个有闭合

GL_TRIANGLE_STRIP和GL_TRIANGLE_FAN,一个是三角带,一个是三角扇,后者可以连成扇形甚至是圆形

通过CopyXXXData复制顶点各种属性数据之后,调用指定的着色器,调用Batch.Draw便可以绘制图元

6、背面剔除和深度缓冲

1、不开启背面剔除和深度测试的情况下,出现三角形重叠的时候,很难分出哪些三角形应该在前面哪些在后面,绘制顺序一团糟

2、一种优化的测试方法:先渲染远的三角形再渲染近的三角形。

缺点:需要对所有三角形进行排序,消耗大,而且重叠的像素需要进行两次写操作,在存储中进行写操作会是速度变慢

3、开启背面剔除:glEnable(GL_CULL_FACE)默认剔除背面,可以通过glCullFace(mode)来修改剔除正面还是背面。

优点:在渲染的图元装配阶段就抛弃一些三角形,提高性能

缺点:当发生自身重叠的情况,正常的渲染顺序还是会被打乱

注:当我们旋转的时候,原来的背面会变成正面,正面会变成正面,这应该是通过跟摄像机的法线判断来确定三角形的正反面的,也就是说不是一定顺时针环绕的背面永远看不到。(http://bbs.csdn.net/topics/380040702)

4、开启深度测试:glEnable(GL_DEPTH_TEST)开启深度测试,当然在开启之前,应该初始化一个深度缓冲区glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGBA|GLUT_DEPTH);

优点:深度测试将消除那些应该被以存在的像素覆盖的像素,解决背面剔除的问题

缺点:需要更多的内存开销

7、描边的效果:

开启深度测试之后,如果要描边或做贴花的效果,可能会出现Z轴冲突的现象,通过多边形偏移可以解决这个问题

glPolygonOffset(-1.0f,-1.0f)

glEnable(GL_POLYGON_OFFSET_LINE)

8、裁剪:确定最终渲染到窗口的视口大小

开启:glEnable(GL_SCISSOR_TEST)

设置:glScissor(x,y,width,height)

9、混合:Alpha显示以及抗齿锯支持的条件,只有开启混合才会有半透明和抗齿锯的效果

开启:glEnable(GL_BLEND)

常用的颜色混合:glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA):源颜色与自己身的alpha值相乘,加上目标颜色乘以1-源颜色的Alplha值。源颜色的Alpha值越高,添加的源颜色成分就越多,目标颜色保留的成分就越少

10、抗齿锯:

开启:glEnable(GL_BLEND)

glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA)  先开启颜色混合

glEnable(GL_POINT_SMOOTH)
点光滑

glEnable(GL_LINE_SMOOTH)
线光滑

glEnable(GL_POLYGON_SMOOTH)
多边形光滑,少用,一般使用多重采样替代

设置:glHint(GL_POINT_SMOOTH_HINT,GL_NICEST)
指定抗齿锯的算法

11、多重采样:需要多开启一个缓冲区,每次对像素更新的时候,都需要进行采样生成新的值

开启:glutInitDisplayMode(XXX|GLUT_MULTISAMPLE)

glEnable(GLUT_MULTISAMPLE)

设置:默认情况下使用片段的RGB值不包括A值

可以通过glSampleCoverage(value,invert)来修改

GL_SAMPLE_ALPHA_TO_COVERAGE - 使用Alpha值

..

时间: 2024-10-08 01:42:53

OpenGL超级宝典笔记一 - 基础渲染的相关文章

OpenGL超级宝典笔记二 - 基础变换

1.向量: 点乘:float m3dDotProduce3(u,v):返回两个单位向量的余弦值 叉乘:float m3dCrossProduct3(result,u,v):返回垂直于两个向量定义的平面的向量 2.矩阵: OpenGL使用的是列优先排序的矩阵 单位矩阵(对角线为1,其他为0):任何向量乘以一个单位矩阵都不会发生任何改变 3.变换:最终获得的变换矩阵会应用到每个顶点 视图矩阵x模型矩阵x投影矩阵->投影摄像机的位置变换,物体对象的位置变换,投影裁剪变换 若顶点向量为Vert,则变换公

OpenGL超级宝典笔记三 - 基础纹理1

纹理对象的使用:纹理图像数据的类型,图像数据的导入导出方式,纹理的使用过程:图像数据的加载,纹理参数的设置,纹理的绑定. 一.图像数据的分类:位图图像和像素图像 二.像素图像数据的包装: 在OpenGL中:使用4字节的行对齐方式,每一行补全到4的倍数,使用glPixelStorei(pname,param)可以改变或者恢复像素的存储方式 介绍常用的两组:内存<->缓冲区的压缩和解包 glPixcelStorei(GL_UNPACK_ALIGNMENT) ----图像数据从内存到缓冲区的解包设置

OpenGL超级宝典笔记五 - 基础Shader

1.基本着色器的架构 顶点着色器:接收客户端输入的Attribute属性数据,有些计算后自己用于顶点变换,有些传给片段着色器.除此之外,顶点着色器还接受uniform数据,一般是变换矩阵.最后输出顶点的位置变换值. 片段着色器:接收来自顶点着色器输出的纹理坐标和纹理等属性,另外也接收用于计算光照的光照颜色的uniform值,最后输出像素的颜色值. 2.Shader的变量和数据类型 数据类型:整数(有符号和无符号),浮点数和布尔值..没有指针和字符类型 复合数据类型:向量类型(vec3,ivec3

OpenGL超级宝典笔记四 - 基础纹理2

一.使用MipMap贴图(主要是应用在纹理缩小过滤中) 优点: 防止当纹理缩小太大的时候,出现闪烁的问题 提高性能,需要缩小的时候就不加载大内存的纹理 缺点: 需要额外的内存作为代价 组成:由一系列缩小的纹理图像组成,子层是父层的1/4 过滤类型:NEAREST快速,LINEAR效果好 GL_NEAREST_MINMAP_NEAREST选择最邻近Mip层并执行邻近过滤 GL_NEAREST_MINMAP_LINEAR选择最Mip层线性插补并执行邻近过滤 GL_LINEAR_MINMAP_NEAR

【转载】OpenGL超级宝典笔记——GLSL语言基础

变量 GLSL的变量命名方式与C语言类似.变量的名称可以使用字母,数字以及下划线,但变量名不能以数字开头,还有变量名不能以gl_作为前缀,这个是GLSL保留的前缀,用于GLSL的内部变量.当然还有一些GLSL保留的名称是不能够作为变量的名称的. 基本类型 除了布尔型,整型,浮点型基本类型外,GLSL还引入了一些在着色器中经常用到的类型作为基本类型.这些基本类型都可以作为结构体内部的类型.如下表: 类型 描述 void 跟C语言的void类似,表示空类型.作为函数的返回类型,表示这个函数不返回值.

OpenGL超级宝典笔记----渲染管线

在OpenGL中任何事物都在3D空间中,但是屏幕和窗口是一个2D像素阵列,所以OpenGL的大部分工作都是关于如何把3D坐标转变为适应你屏幕的2D像素.3D坐标转为2D坐标的处理过程是由OpenGL的图形渲染管线完成的.图像渲染管线可以被划分为两个主要部分:第一个部分把你的3D坐标转换为2D坐标,第二部分是把2D坐标转变为实际的有颜色的像素. 渲染管线接收一组3D坐标,然后把它们转变为你屏幕上的有色2D像素.渲染管线可以被划分为几个阶段,每个阶段需要把前一阶段的输出作为输入.所有这些阶段都是高度

OpenGL超级宝典笔记——深度纹理和阴影 【转】

目录[-] 光源视角 新型的纹理 深度纹理的大小 首先绘制阴影 然后是光照 投影阴影贴图 阴影比较 之前我们介绍过简单的把物体压平到投影平面来制造阴影.但这种阴影方式有其局限性(如投影平面须是平面).在OpenGL1.4引入了一种新的方法阴影贴图来产生阴影. 阴影贴图背后的原理是简单的.我们先把光源的位置当作照相机的位置,我们从这个位置观察物体,我们就知道哪些物体的表面是被照射到(被光源看到) 的,哪些是没有被照射到(被遮挡住)的(在某个方向上离光源最近的表面是被照射的,后面的表面则没有被照射到

OpenGL超级宝典笔记——遮挡查询 [转]

目录[-] 遮挡查询之前 包围体 遮挡查询 在一个场景中,如果有有些物体被其他物体遮住了不可见.那么我们就不需要绘制它.在复杂的场景中,这可以减少大量的顶点和像素的处理,大幅度的提高帧率.遮挡查询就是允许我们判断一组图形在进行了深度测试之后是否可见. 遮挡查询之前 为了显示遮挡查询对性能的提升,我们需要一个对照组(不使用遮挡查询来渲染场景). 首先我们先绘制“主遮挡物”.这个主遮挡物不需要太多的细节,一般是墙,天花板,地板之类的物体.在下面的例子中我们,使用6面墙来组成这个主遮挡物. void 

OpenGL超级宝典笔记——画三角形(转)

http://my.oschina.net/sweetdark/blog/161002 学习了画线的知识,我们可以使用GL_LINE_LOOP来画闭合的多边形.但是使用这种方式画出来的只有线框,多边形没有填充颜色.OpenGL支持绘制实心的多边形,并使用当前的颜色进行填充. 三角形 简单的三角形,需要指定三个顶点. 1: glBegin(GL_TRIANGLES); 2: glVertex2f(0.0f, 0.0f); // V0 3: glVertex2f(25.0f, 25.0f); //