前言
最近才发现,自己写的glsl和教程的glsl版本对不上,一直以为是xcode不允许使用太高版本,只能使用OpenGL 2.0的版本,却不知使用glfw可以使用到最新的OpenGL版本。?发现了解OpenGL 版本的迭代对于理解OpenGL是有帮助的。
OpenGL
2.0
从OpenGL 2.0开始,OpenGL 发生了重大的改变,其中最大的改变莫过于有了自己的着色语言,版本为1.00,毕竟之前使用的是固定管线,这也导致两个实现方式并存的局面。(注意从这个版本开始也不再限制纹理大小必须是2的幂次数)
3.0
在这个版本又进行了大改,弃用了之前版本的很多东西,增加了很多新东西。
从OpenGL 3开始,编程模式被分为3种:
- 兼容模式:传统模式。
- 核心模式:完全新的纯可编程流水线模式,但是兼容废弃特性。(API不再兼容旧的)
- 核心向前兼容模式:完全不兼容废弃特性,其它和核心模式相同。
3.2
这个版本,最大的变化就是支持了几何着色器,存在于顶点着色器和像素着色器之间,它的输入为:点、线和三角形,其输出点为点、线带和三角形带,虽然从根本上来说都是顶点的处理,但是进入顶点着色器的是一次一个的顶点,而进入几何着色器的是一次一批的顶点。
3.3
这个版本就是现在教程里面使用的(好吧,我使用的版本差这么多),这个版本的shader model 4.0的OpenGL的最终版本,这个版本不再需要查询输入变量(attribute)的location的方式,可以使用layout去指定位置,还有片元着色器中的内建变量也弃用了,取而代之的是自定义的out变量。
4.0
这个版本增加细分曲面着色器,还有使用最新的Shader Language 4.00的subroutine提供了在运行时刻不需要切换着色器或者是重新编译或者使用if判断选择不同功能的方法,降低了切换着色器程序所带来的巨大开销(切换着色器的CPU循环消耗真的非常的惊人)。
其中,细分曲面着色器同样在顶点着色器之后执行,但是细分曲面着色器和几何着色器谁先谁后呢?我在维基百科上找到了这个图。
4.3
这个版本则是增加了可以用于并行计算的computer shader,避免在CPU中进行大量复杂的计算,可以减轻CPU的负担;同时在uniform也可以使用layout进行指定了。
比较
在网上找了相关的OpenGL和glsl的版本比较
OpenGL Version | GLSL Version |
---|---|
2.0 | 110 |
2.1 | 120 |
3.0 | 130 |
3.1 | 140 |
3.2 | 150 |
3.3 | 330 |
4.0 | 400 |
4.1 | 410 |
4.2 | 420 |
4.3 | 430 |
嗯,以后看shader就可以知道项目使用的版本了?。
举个例子:
version 110
Vertex shader:
uniform mat4 projTrans; attribute vec2 Position; attribute vec2 TexCoord; varying vec2 vTexCoord; void main() { vTexCoord = TexCoord; gl_Position = u_projView * vec4(Position, 0.0, 1.0); }
Fragment shader:
uniform sampler2D tex0; varying vec2 vTexCoord; void main() { vec4 color = texture2D(tex0, vTexCoord); gl_FragColor = color; }
Version 330
Vertex shader:
#version 330 uniform mat4 projTrans; layout(location = 0) in vec2 Position; layout(location = 1) in vec2 TexCoord; out vec2 vTexCoord; void main() { vTexCoord = TexCoord; gl_Position = u_projView * vec4(Position, 0, 1); }
Fragment shader:
#version 330 uniform sampler2D tex0; in vec2 vTexCoord; //use your own output instead of gl_FragColor out vec4 fragColor; void main() { //'texture' instead of 'texture2D' fragColor = texture(tex0, vTexCoord); }
我们可以发现,attribute和varying已经不再使用了。取而代之的是in/out了(好吧,之前做的总结没用了,哈哈??)。
使用
我们知道mac osx是默认支持OpenGL 的,大家可以到官网上去查看自己的电脑支持的版本,我看了一下,最近的电脑都普遍已经支持到了4.1以上。
如果不想使用max os那套obj-c,可以使用别的库,比如glfw。
使用glfw
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
这样就可以是使用到最新的GL版本了。