1.架构解析
如上图所示,OpenGL的渲染架构图主要分为两部分,客户端和服务端。
客户端: OpenGL对外暴露的API,可以使用C/C++来调用;
服务端: 指的是OpenGL的底层,其顶点着色器(Vertex Shader)和片元着色器(Fragment Shader)都可以自主编程。
在该架构中,客户端对于服务端只有三种通道: Attributes、Uniforms、Textture Data。
Attributes:翻译为'属性',且数据只能同向顶点着色器(Vertex Shader),然后间接传递到片元着色器。能传递的数据有:顶点坐标数据(x,y,z,w)、光照坐标、投影矩阵、模型矩阵、图片的纹理坐标(图片的映射坐标)等。
Uniforms:传递统一的批次,不需要更改的数据,能把数据传递到顶点着色器,也能传递到片元着色器。例如: 时间戳、变换矩阵、颜色值等。
Textture Data:纹理数据,虽然纹理数据能传递到顶点着色器,但是这样传递是没有意义的,因为顶点着色器只能处理顶点数据,无法处理纹理数据。
2.投影方式
2.1. 正投影-显示2D图形
其实我们在设置投影的时候,不是设置一个四边的坐标,而是设置一个“盒子”,在这个“盒子”里面来显示我们的数据,如果超过的这个“盒子”,那么我们设置的数据就看不见了。
可使用如下函数来设置可是区域的大小:
GLFumstum
2.2. 透视投影-显示3D图形(远小近大)
设置透视投影的时候其实就是设置一个平截体,这个平截体有一个角度,是观察这个物体的角度。
GLFrustum类通过setPerspective ⽅法为我们构建⼀个平截头体。
CLFrustum
参数:
fFov: 垂直⽅向上的视场⻆度 ,其角度越大平截体就越大
fAspect: 窗⼝的宽度与⾼度的纵横⽐
fNear: 近裁剪⾯距离
fFar: 远裁剪⾯距离
纵横⽐ = 宽(w)/⾼(h)
3.着色器
3.1.存储着色器
// GLShaderManager的初始化
3.2.单元着色器
shaderManager
参数1:存储着色器的种类-单元着色器
参数2:颜色
使用场景:绘制默认的OpenGL坐标系[-1, 1]下的图形,图形的所有片段都会以一种颜色填充。
3.3.平面着色器
使用最多的着色器
shaderManager
参数1: 存储着⾊器种类-平⾯着⾊器
参数2: 允许变化的4*4矩阵
参数3: 颜⾊
使⽤场景: 在绘制图形时, 可以应⽤变换(模型/投影变化)。
3.4.上⾊着⾊器
GLShaderManager
参数1: 存储着⾊器种类-上⾊着⾊器
参数2: 允许变化的4*4矩阵
使⽤场景: 在绘制图形时, 可以应⽤变换(模型/投影变化) 颜⾊将会平滑地插⼊到顶点之间。
3.5.默认光源着⾊器
GLShaderManager
参数1: 存储着⾊器种类-默认光源着⾊器
参数2: 模型4*4矩阵
参数3: 投影4*4矩阵
参数4: 颜⾊值
使⽤场景: 在绘制图形时, 可以应⽤变换(模型/投影变化) 这种着⾊器会使绘制的图形产⽣。
3.6.点光源着⾊器
GLShaderManager
参数1: 存储着⾊器种类-点光源着⾊器
参数2: 模型4*4矩阵
参数3: 投影4*4矩阵
参数4: 点光源的位置
参数5: 颜⾊值
使⽤场景: 在绘制图形时, 可以应⽤变换(模型/投影变化) 这种着⾊器会使绘制的图形产⽣,阴影和光照的效果.它与默认光源着⾊器⾮常类似,区别只是光源位置可能是特定的.。
3.7.纹理替换矩阵着⾊器
GLShaderManager
参数1: 存储着⾊器种类-纹理替换矩阵着⾊器
参数2: 模型4*4矩阵
参数3: 纹理单元
使⽤场景: 在绘制图形时, 可以应⽤变换(模型/投影变化)这种着⾊器通过给定的模,型视图投影矩阵.使⽤纹理单元来进⾏颜⾊填充.其中每个像素点的颜⾊是从纹理中获取。
3.8.纹理调整着⾊器
GLShaderManager
参数1: 存储着⾊器种类-纹理调整着⾊器
参数2: 模型4*4矩阵
参数3: 颜⾊值
参数4: 纹理单元
使⽤场景: 在绘制图形时, 可以应⽤变换(模型/投影变化)这种着⾊器通过给定的模型视图投影矩阵. 着⾊器将⼀个基本⾊乘以⼀个取⾃纹理单元nTextureUnit 的纹理.将颜⾊与纹理进⾏颜⾊混合后才填充到⽚段中。
3.9.纹理光源着⾊器
GLShaderManager
参数1: 存储着⾊器种类-纹理光源着⾊器
参数2: 模型4*4矩阵
参数3: 投影4*4矩阵
参数4: 点光源位置
参数5: 颜⾊值(⼏何图形的基本⾊)
参数6: 纹理单元
使⽤场景: 在绘制图形时, 可以应⽤变换(模型/投影变化)这种着⾊器通过给定的模型视图投影矩阵. 着⾊器将⼀个纹理通过漫反射照明计算进⾏调整(相乘)。
4.基本图元连接⽅式
GL_LINES: 每⼀对顶点定义⼀个线段。
GL_LINE_STRIP:⼀个从第⼀个顶点依次经过每⼀个后续顶点⽽绘制的线条。
GL_LINE_LOOP:和GL_LINE_STRIP相同,但是最后⼀个顶点和第⼀个顶点连接起来了。
GL_POINTS:每个顶点在屏幕上都是单独点。
GL_TRIANGLES:每3个顶点定义⼀个新的三⻆形。
GL_TRIANGLE_STRIP:共⽤⼀个条带(strip)上的顶点的⼀组三⻆形。
GL_TRIANGLE_FAN:以⼀个圆点为中⼼呈扇形排列,共⽤相邻顶点的⼀组三⻆形。
4.1.点和线的画法
//1.最简单也是最常⽤的 4.0f,表示点的⼤⼩
4.2.三角形的画法
4.2.1,正三角和逆三角
对于OpenGL光栅化最欢迎的是三⻆形。3个顶点就能构成⼀个三⻆形,三⻆形类型来⾃于顶点,并不是所有的三⻆形都是正三⻆形等。
在OpenGL中。顺时针叫逆三角,逆时针叫正三角。
修改顺时针和逆时针的函数
glFrontFace(GL_CW);
GL_CW: 告诉OpenGL 顺时针环绕的多边形为正⾯;
GL_CCW: 告诉OpenGL 逆时针环绕的多边形为正⾯;
4.2.2.三角形带
对于很多表⾯或者形状⽽⾔,我们会需要绘制⼏个相连的三⻆形,这时我们可以使⽤GL_TRIANGLE_STRIP 图元绘制⼀串相连三⻆形,从⽽节省⼤量的时间。
优点:
- ⽤前3个顶点指定第1个三⻆形之后,对于接下来的每⼀个三⻆形,只需要再指定1个顶点。需要绘制⼤量的三⻆形时,采⽤这种⽅法可以节省⼤量的程序代码和数据存储空间。
- 提供运算性能和节省带宽。更少的顶点意味着数据从内存传输到图形卡的速度更快,并且顶点着⾊器需要处理的次数也更少了。
4.2.3.三⻆形扇
对于很多表⾯或者形状⽽⾔,我们会需要绘制⼏个相连的三⻆形,这时我们可以使⽤GL_TRIANGLE_FAN 图元绘制⼀组围绕⼀个中⼼点相连的三⻆形。
4.2.3.使用批次类复制数据
GLBatch ,是在GLTools中包含的⼀个简单容器类.
void
参数1:图元
参数2:顶点数
参数3:⼀组或者2组纹理坐标(可选)
//复制顶点数据(⼀个由3分量x,y,z顶点组成的数组)
5.案例
画出点、线、线段、线环、⾦字塔、六边形、圆柱。用空格切换,且用上下左右键旋转。
1.实现SetupRC函数
// 此函数在呈现上下文中进行任何必要的初始化。.
2.实现DrawWireFramedBatch函数
void
3.实现RenderScene,显示场景
void
4.实现ChangeSize
// 窗口已更改大小,或刚刚创建。无论哪种情况,我们都需要
5.处理键位
//特殊键位处理(上、下、左、右移动)
6.在main函数里面注册
//注册回调函数(改变尺寸)
详情请见Demo3
GhostClock/OpenGLgithub.com