GLSL语法跟C语言非常相似:
    
    1.数据类型:
    
    GLSL包含下面几种简单的数据类型
    
    float
    
    bool :false or ture
    
    int
    
    向量:
    
    vec {2,3,4} 长度为2, 3, 4的float向量
    
    bvec {2,3,4} 长度为2, 3, 4的bool向量
    
    ivec {2,3,4} 长度为2, 3, 4的int向量
    
    矩阵:
    
    mat2 2*2的浮点矩阵
    
    mat3 3*3的浮点矩阵
    
    mat4 4*4的浮点矩阵
    
    以上三种矩阵可以简写为mat2 mat3 mat4
    
    矩阵的行和列并没有规定相等,因为可以使用mat2*3 mat 4*2等方法来声明行数和列数
    
    一种特殊的数据类型:取样器–用于纹理采样
    
    sampler1D 访问一个一维纹理
    
    sampler2D 访问一个二维纹理
    
    sampler3D 访问一个三维纹理
    
    samplerCube 访问一个立方体纹理
    
    sampler1DShadow 访问一个带对比的一维深度纹理
    
    sampler2DShadow 访问一个带对比的二维深度纹理
   
    GLSL提供了类似C语言的用户定义结构:
    
    struct dirlight{
    
    vec3 direction;
    
    vec3 color;
    
    };
   
    变量限定符:
    
    限定符赋给变量特殊的含义:
    
    const– 用于声明非可写的编译时常量变量
    
    
     attribute
    
    – 用于经常更改的信息,
    
     只可以在顶点着色器中使用
    
    
    
     uniform
    
    – 用于不经常更改的信息,用于顶点着色器和片元着色器
    
    
     varying
    
    – 用于从顶点着色器传递到片元着色器的插值信息,
    
     顶点和片元两者声明必须一致
    
   
    控制流:
    
    GLSL的控制流 与C++非常类似,可以使用for while以及do-while实现循环,也可以使用if和if-else进行选择,不过if语句中的变量声明,只是在最近的硬件中才提供
   
    函数:
    
    GLSL也提供了一些特殊的实现:
    
    continue
    
    break
    
    discard –只可用于片元着色器,当控制流遇到这个关键字时,正在处理的片元就会被标记为将要丢弃
    
    函数
    
    main() 可以返回除了数组外的任何类型
    
    对于函数的参数 可以使用下面几种限定符
    
    in – 复制进函数但不在返回时复制,在函数内部仍然是可写的
    
    out–只在返回时复制,是可读的
    
    inout 复制进函数并在返回时复制
    
    如果没有指定限定符,默认情况下为in
    
    函数可以通过参数类型重载,但是不能仅仅通过返回类型重载,同样,因为不会执行参数类型自动提升,所以调用函数时参数类型必须完全匹配
    
    函数不能被递归调用
   
    GLSL Vertex shader内置的输入变量,注意这些变量都是不可更改的
    
    attribute vec4 gl_Color; 顶点数据字段的Diffuse颜色
    
    attribute vec4 gl_SecondaryColor; 顶点数据字段的Specular颜色
    
    attribute vec4 gl_Normal; 顶点法线
    
    attribute vec4 gl_Vertex; 顶点位置
    
    attribute vec4 gl_MultiTexCoord0; 8组贴图坐标
    
    attribute vec4 gl_MultiTexCoord1;
    
    attribute vec4 gl_MultiTexCoord2;
    
    attribute vec4 gl_MultiTexCoord3;
    
    attribute vec4 gl_MultiTexCoord4;
    
    attribute vec4 gl_MultiTexCoord5;
    
    attribute vec4 gl_MultiTexCoord6;
    
    attribute vec4 gl_MultiTexCoord7;
    
    attribute vec4 gl_MultiTexCoord0;
    
    attribute vec4 gl_FogCoord; 使用雾效果的参考数值
    
    在编写shader时,可以把这些输入数据所代表的功能重新定义,名称只是用来让传入数据时有个规则可循而已,C++调用glVertexPointer所指到的vetex buffer数据,在GLSL中可以通过gl_Vertex变量来获得。
   
    
     Vertex Shader的输出数据时使用的内置变量:
    
    
    vec4 gl_posotion; 用来设置顶点转换到屏幕坐标的位置,Vertex Shader一定要去更新这个数值
    
    float gl_pointSize; 是启动PointSprite功能时,用来设置矩形大小的数值
    
    vec4 gl_ClipVertex; 如果启用了Clip Plane功能,gl_ClipVertex可以放入用来与Clip Plane平面做测试用的位置
   
    下面的输出数据在Vertex Shader中用来输出数据,在Fragment Sahder也可以使用这些变量,但是是用来读取数据:
    
    araying Vec4 gl_FrontColor; 对正面做不同的光照计算 ,这两组颜色分主要颜色和次要颜色 代表的是固管的Diffuse值
    
    varying vec4 gl_BackColor; 背面
    
    varying vec4 gl_FrontSecondDaryColor; 固管的Specular值
    
    varying vec4 gl_BackSecondaryColor;
    
    varying vec4 gl_TexCoord[gl_MaxTextureCoords]; glTextCoord[0]是指第0个贴图坐标
    
    varying vec4 gl_FogFragCoord;
    
    Fragment Sahder除了可以从上面几个所列出的变量获得内插结果外,还可以从另外两个内置变量得到一些无法从Vertex Shader获得的数值
    
    vec4 gl_FragCoord; gl_FragCoorg.xy代表像素在Framebuffer画面的位置,gl_FragCoord.z代表这个店在做Z Buffer测试时所用的Z值
    
    bool gl_FrontFacing; 可用来查询目前正在画的像素是来自三角形的正面还是来自他的背面
   
    
     Fragment Shader的内置输出变量:
    
    
    vec4 gl_FragColor; 代表画面所要填入的颜色
    
    vec4 gl_FragData[gl_MaxDrawBuffers]; 用来填入画面的颜色,用在启用多个FrameBuffer时,调用gl_FragData填入画面颜色
    
    vec4 gl_FrData填入画面颜色
    
    vec4 gl_FragDepth; 用来指定Z Buffer测试时所使用的Z值,这样就可以不通过顶点内插得到的Z值
   
 
