[Qt和GLSL的笔记4] GLSL基本语法和数据类型
来源:互联网 发布:c语言计算闰年switch 编辑:程序博客网 时间:2024/06/08 08:51
时间:2017年4月21日(大三下学期)
作者:RyuZhihao123 (Northwest A&F University,985/211)
Qt和GLSL开发4 - GLSL基本语法和数据类型
写在前面:
虽然说这一部分是GLSL中比较常见的内容。但是在下面的文章里,我有添加一些关于Qt中如何使用的方法和小例子,比如如何使用Qt设置uniform变量的值等等。在其他平台上使用过GLSL的可能会看起来比较简单,只需要关心在Qt中相应的使用方法就好。
这个是在下文中使用到的Qt代码的下载链接:
http://download.csdn.net/detail/mahabharata_/9822537
一、数据类型
1. GLSL的基本数据类型:
float、int、bool等等,和C语言类似。
2. GLSL的向量vec:
vec2、vec3、vec4: 长度为2,3,4的float向量。
bvec2、bvec3、bvec4:长度为2,3,4的bool向量。
ivec2、ivec3、ivec4:长度为2,3,4的int向量。
注:长度为4的vec4,可能有不同的含义。它可能表示坐标(x、y、z、w),也可以是颜色(r、g、b、a),还可以是纹理坐标(s、t、p、q)。这个时候,我们可以使用不同的成员来访问其值,也就是说我们允许下面的代码:
vec4 a = vec4(1,2,3,4);a.x = 2; a.y = 1; a.z = 2; a.w = 3; // 代表坐标a.r = 2; a.g = 1; a.b = 2; a.a = 3; // 代表颜色a.s = 3; a.t = 1; a.p = 2; a.q = 3; // 代表纹理
3. GLSL的矩阵mat:
mat2: 2x2的float矩阵
mat3:3x3的float矩阵
mat4:4x4的float矩阵
4. GLSL的纹理采样器sampler:
sampler1D - 一维纹理
sampler2D - 二维纹理
此外,还有sampler3D、samplerCube、sampler1DShadow、sampler2DShadow等。
5. GLSL允许声明、访问数组。但是不能边声明边初始化。
6. GLSL允许定义结构体:
struct point{ vec3 pos; vec3 dir;};
二、变量
1. 对于基本数据类型的变量,使用和C语言一样。
2. 对于向量和矩阵类型的赋值和初始化,也和C语言差不多。
3. [特殊] GLSL提供的使用的选择子(selector),可以简化我们的操作并让代码更简洁。例如:
vec4 a = vec4(1,2,3,4);vec2 av2 = a.xy; // 仅仅获取a的xy信息vec3 ac3 = a.rbb; // 仅仅获取a的rbb信息。
三、变量修饰符(所有变量均不可以跨shader访问)
总共四种:const、varying、uniform、attribute。
1. const:
声明一个常量。
2. varying:
用于从顶点shader向片段shader传递信息。在顶点着色器中声明并可写可读,在片段着色器中可读不可写(这个可以参考我前面给的例子~~)。
3. uniform:
用于从OpenGL主程序向shader传递信息。在两个shader中只读。
在Qt中:通过QGLShaderProgram::setUniformValue()函数指定。
Qt函数:QGLShaderProgram::setUniformValue(char* name, Type value);
第一个参数为一个字符串,其值为shader中的uniform变量的名字。表示是哪个uniform变量。
第二个参数为一个具体的值,含义是该uniform变量的值被设置为value。
[Uniform - 穿插的一个例子] 一个颜色不断变化的小球:
代码链接:http://download.csdn.net/detail/mahabharata_/9822537
其中,片段着色器代码为:
varying vec4 v_position;varying float v_cosin;uniform float time; // 从 OpenGL主程序获取的值。当前时间。void main(void){ // 预设的颜色(随时间变化) float r = 1.0*cos(time)*cos(time); float g = 1.0*sin(time); float b = 1.0*cos(time)*sin(time); // glFragColor表示该片段的最终颜色。 gl_FragColor = vec4(v_cosin * r, v_cosin * g, v_cosin * b, 1.0f);}相应的在opengl主程序的时间槽函数中不断修改(uniform)time的值:
void Widget::slot_time(){ program.setUniformValue("time",elapsed); // 修改(uniform float) time变量; elapsed+=0.03; updateGL();}
4. attribute:
用于从OpenGL主程序向shader传递信息。仅是只能在vertex shader中使用的可读不可写变量。(不能再fragment shader中声明attribute变量,也不能使用)
在Qt中,通过QGLShaderProgram::setAttributeValue()使用。用法和前面的uniform类似。
说明:uniform和attribute变量:
1. 其实两者除了attribute在片段着色器中不可用以外,本质上没有什么太大区别。
2. 但是习惯上,用attribute表示顶点的顶点坐标、纹理坐标、顶点颜色。其他信息如参数、材质、变换矩阵等等大多用unifrom表示。
例如:
uniform mat4 u_matViewProjection; // 矩阵uniform float time; // 参数attribute vec4 a_position; // 顶点坐标attribute vec2 a_texCoord0; // 纹理坐标varying vec2 v_texCoord; // 传递给片段着色器的纹理坐标void main(void){ gl_Position = u_matViewProjection * a_position; v_texCoord = a_texCoord0;}
四、內建变量和函数(build-in variables and functions)
1. 內建变量(需要从opengl主程序通过特定函数传入):
attribute vec4 gl_Vertex; // 由glVertex()指定的顶点坐标(未进行投影、模型视图变换)
attribute vec4 gl_Color; // 由glColor()指定的顶点颜色
attribute vec4 glSecondaryColor; // 顶点的辅助颜色
attribute vec3 gl_Normal; // 由glNormal()指定的顶点法向量
attribute vec4 gl_MultiTexCoord[0-N]; // 顶点纹理坐标(N = gl_MaxTextureCoords)
attribute float gl_FogCoord; // 顶点的雾坐标(深度)
注意,在Qt中,我们可以使用QGLShaderProgram::setAttributeValue()为自定义的attribute变量传值。
uniform mat4 gl_ModelViewMatrix; // 模型视图矩阵(model-view matrix)
--- 通过gluLookAt()及glTranslate()等模型视图矩阵变换的当前状态决定。
uniform mat4 gl_ProjectMatrix; // 投影矩阵(project matrix)
--- 通过gluPerspective()等函数决定
uniform mat4 gl_ModelViewProjectionMatrix; // 模型视图-投影矩阵
uniform mat3 gl_NormalMatrix; // 法向量变换到视空间的矩阵
uniform float gl_NormalScale; // 普通缩放因子
当然,在Qt中,我们也可以拥有QGLShaderProgram::setUniform()为自定义的uniform变量传值。
说明:
1. 这里仅仅列出了一部分GLSL的内置变量,其他内置变量可以再Google或者下面的博客中找到:
http://blog.csdn.net/dancing_night/article/details/50897510
2. 关于GLSL的內建函数,可以再下面的链接中获取到相关内容:
http://blog.csdn.net/hgl868/article/details/7876257
3. 如何在顶点着色器中获取经过变换后的顶点、法向量(常用写法):
varying vec4 v_normal; // 变换后的法向量varying vec4 v_position; // 变换后的坐标void main(void){ // 顶点着色器的唯一输出:gl_Position; gl_Position = gl_ProjectionMatrix*gl_ModelViewMatrix*gl_Vertex; v_position = gl_Position; v_normal = gl_NormalMatrix*gl_Normal; }
- [Qt和GLSL的笔记4] GLSL基本语法和数据类型
- [Qt和GLSL的笔记1] 程序的基本结构
- [Qt和GLSL的笔记3] GLSL基本知识和两个小例子
- [Qt和GLSL的笔记2] QGLShaderProgram类
- GLSL 数据类型和限定符
- 基于Qt和GLSL的着色器例子
- 关于GLSL中语法和调用规则
- OpenGL GLSL 语法和函数详解
- GLSL(4)关于layout和uniform使用的个人小结
- GLSL的多纹理输入和输出
- opengl GLSL基本语法 学习 随笔二
- GLSL 笔记
- GLSL Versions和GLSL ES Versions 的之间的关系和区别
- GLSL
- GLSL
- GLSL和深度测试解释
- GLSL基础概念和用法
- OpenGL基本笔记-GLSL语言基础
- Android Studio 将libs下的JAR打到总的Jar包下
- Android MVC框架模式和常见设计模式
- SVN更新项目A C D M G U R I的含义
- python 碎碎记
- bzoj 1029: [JSOI2007]建筑抢修 贪心+堆
- [Qt和GLSL的笔记4] GLSL基本语法和数据类型
- Oracle用户权限及权限设置
- ns-3 教程 —— 资源
- sizeof与内存对齐
- J
- 分组背包
- 整理 : 查看和修改 mysql库、表、字段编码
- 远程服务器发布web项目
- AngularJS学习:AngularJS的甜蜜点