OpenGL和GLSL版本更迭

前言

最近才发现,自己写的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版本了。

posted @ 2017-02-20 02:37  banananana  阅读(4384)  评论(0编辑  收藏