A Simple OpenGL Shader Example II
A Simple OpenGL Shader Example II
Abstract. The OpenGL Shading Language syntax comes from the C family of programming languages. Tokes, identifiers, semicolons, nesting with curly braces, control-flow, and many key words look like C. GLSL provides three qualifiers which form the interfaces of the shaders to their outside world.
Key Words. OpenGL, GLSL, Qualifiers,
1. Introduction
GLSL的特性与C/C++非常类似,包括它的数据类型。GLSL有三种基本数据类型:float, int和bool,及由这些数据类型组成的数组和结构体。需要注意的是GLSL并不支持指针。
GLSL 中有4个限定符(Qualifier)可供使用,它们限定了被标记的变量不能被更改的“范围”。及通过这几个限定符可以与OpenGL的程序来通信,即为 OpenGL程序提供了一个将数据传递给Shader的界面(Interface to a Shader)。
OpenCASCADE中使用GLSL实现了Ray Tracing效果,刚开始使用第三方库OpenCL来使用GPU加速,最新版本统一使用GLSL。
Figure 1.1 OpenGL Training
在《OpenGL高级编程技术培训教材》中,GLSL也是一个重要内容。虽然当时听得云里雾里,还是要感谢公司提供这样的培训机会。
2.GLSL Data Types
GLSL内置了许多数据类型,使图形操作的表达式计算更方便。布尔类型、整型、矩阵、向量及结构、数组等都包括在内。
Scalars |
|
float |
Declares a single floating-point number. |
int |
Declares a single integer number. |
bool |
Declares a single Boolean number. |
这三种是GLSL的基本类型。
Vectors |
|
vec2 |
Vector of two floating-point numbers |
vec3 |
Vector of three floating-point numbers |
vec4 |
Vector of four floating-point numbers |
ivec2 |
Vector of two integers |
ivec3 |
Vector of three integers |
ivec4 |
Vector of four integers |
bvec2 |
Vector of two booleans |
bvc3 |
Vector of three booleans |
bvc4 |
Vector of four booleans |
向量非常有用,可以用来存储和操作颜色、位置、纹理坐标等等。GLSL内置的很多变量及函数中就大量使用了向量。
Matrices |
|
mat2 |
2x2 matrix of floating-point numbers |
mat3 |
3x3 matrix of floating-point numbers |
mat4 |
4x4 matrix of floating-point numbers |
矩阵主要用来实现线性变换。
Samplers |
|
sampler1D |
Accesses a one-dimensional texture |
sampler2D |
Accesses a two-dimensional texture |
sampler3D |
Accesses a three-dimensional texture |
samplerCube |
Accesses a cube-map texture |
sampler1DShadow |
Accesses a one-dimensional depth texture with comparison |
sampler2DShadow |
Accesses a two-dimensional depth texture with comparison |
3.Qualifiers
GLSL有4个限定符可供使用,它们限定了被标记的变量不能被更改的范围:
Qualifiers |
|
attribute |
For frequently changing information, from the application to a vertex shader |
uniform |
For infrequently changing information, from the application to either a vertex shader or a fragment shader |
varying |
For interpolated information passed from a vertex shader to a fragment shader |
const |
For declaring nonwritable, compile-time constant variables as in C |
const限定符和C/C++里的相同,表示限定的变量在编译时不可被修改,即它标记了一个常量。const限定符是4个限定符中被标记变量不可被更改的范围最大的。其余3个限定符是GLSL特有的,所以它们都用在着色器内部声明变量。
attribute限定符标记的是一种全局变量,该变量被用作从OpenGL应用程序向顶点着色器中传递参数,因此该限定符仅用于顶点着色器。
uniform限定符也标也一种全局变量,该变量对于一个图元来说是不可改变的。同attribute限定符一样,uniform可以从OpenGL应用程序中接收传递过来的数据。uniform限定符可以用于顶点着色器和像素着色器。
最后GLSL还提供了从顶点着色器向片段着色器传递数据的方法,即使用varying限定符。
4.Code Example
在《A Simple OpenGL Shader Example》
中已经成功实现了一个带Shader的OpenGL程序。事实上这是两个相对独立的Shader,它们只能使用OpenGL内置的变量从外部OpenGL
程序中获取一些数据。比如当前顶点坐标、当前像素颜色等。这些Shader还没有自定义的变量,以便从OpenGL程序中传递数据。通常程序的设计者需要
在OpenGL程序中更好地控制shader的行为,这就需要从OpenGL程序向shader传递数据。
如上述的4个限定符,可以用来声明变量帮助shader从外部获取数据。其中uniform变量可以用来从OpenGL程序中给vertex shader或fragment shader传递数据,最很常用的一个限定符变量。将《A Simple OpenGL Shader Example》中的程序稍做修改,使得片段shader可以收到一个来自OpenGL程序里面的数据。
实现的主要代码在这两个函数中:
void ShaderWidget::paintGL()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); mAngle += 0.1;
glRotatef(mAngle, 0.0, 1.0, 1.0); // update uniform variable value
mShaderProgram->setUniformValue(mTimeId, mAngle); glutSolidTeapot(1.0);
//glutWireTeapot(1.0);
}
void ShaderWidget::setShader()
{
if (!isValid())
{
return;
} const QGLContext* aGlContext = context(); mShaderProgram = new QGLShaderProgram(aGlContext); //mShaderProgram->addShaderFromSourceFile(QGLShader::Vertex, "vertex.vs");
mShaderProgram->addShaderFromSourceFile(QGLShader::Fragment, "uniform.fs"); mShaderProgram->link();
mShaderProgram->bind();
QString aLog = mShaderProgram->log(); // save the location of the uniform variable name within the shader program.
mTimeId = mShaderProgram->uniformLocation("v_time");
}
首 先通过QShaderProgram的函数uniformLocation()给GLSL中的变量用一个整数标记,对应在OpenGL中的函数是 GLint glGetUniformLocation(GLuint program, const char* name);再通过函数setUniformValue()来更新GLSL中变量的值,对应OpenGL中的函数为:glUniform{1234} (if,ui}。最后只用了一个片段着色器,代码如下所示:
// time(passed in from the application)
uniform float v_time; void main()
{
float fr = 0.9 * sin(0.0 + v_time*0.05) + 1.0;
float fg = 0.9 * cos(0.33 + v_time*0.05) + 1.0;
float fb = 0.9 * sin(0.67 + v_time*0.05) + 1.0; gl_FragColor = vec4(fr/2.0, fg/2.0, fb/2.0, 1.0);
}
运行程序,当程序视图重绘时就会改变茶壶的颜色,如下图所示:
Figure 4.1 Test uniform variable in GLSL
当将uniform.fs中的v_time改名后,就会发现视图一片漆黑,说明shader已经起作用了。
5.Conclusion
综上所述,GLSL中通过限定符Qualifiers来实现OpenGL程序与GLSL的数据传递。其中uniform变量可以用来从OpenGL程序向片段着色器和顶点传递数据,是很常用的一种方式。
本文在Qt中测试了uniform变量效果,可以发现Qt对OpenGL的面向对象封装还是很方便使用,也很容易找到与之对应的OpenGL函数。通过学习使用Qt中的OpenGL来方便学习理解OpenGL相关知识点。
6. References
1. san. Shader support in OCCT6.7.0. http://dev.opencascade.org/index.php?q=node/902
2. Qt Assistant.
PDF version and Source code: A Simple OpenGL Shader Example II
A Simple OpenGL Shader Example II的更多相关文章
- A Simple OpenGL Shader Example
A Simple OpenGL Shader Example eryar@163.com Abstract. OpenGL Shading Language, the high-level progr ...
- OpenGL Shader in OpenCASCADE
OpenGL Shader in OpenCASCADE eryar@163.com Abstract. As implementation of one of the strategic steps ...
- OpenGL Shader源码分享
Opengl shader程序,旗帜混合纹理加载,通过N张图片,能够组合出数百个:http://www.eyesourcecode.com/thread-39015-1-1.html 用GLSL做了一 ...
- OpenGL复习要点II
[OpenGL复习要点II] 1.视图变换必须出现在模型变换之前. 2.glMatrixMode()参数有三个,GL_MODELVIEW,GL_PROJECTION,GL_TEXTURE. 3.变换顺 ...
- 【玩转cocos2d-x之四十】怎样在Cocos2d-x 3.0中使用opengl shader?
有小伙伴提出了这个问题.事实上GLProgramCocos2d-x引擎自带了.全然能够直接拿来用. 先上图吧. 使用opengl前后的对照: watermark/2/text/aHR0cDovL2Js ...
- 「游戏引擎 浅入浅出」4.1 Unity Shader和OpenGL Shader
「游戏引擎 浅入浅出」从零编写游戏引擎教程,是一本开源电子书,PDF/随书代码/资源下载: https://github.com/ThisisGame/cpp-game-engine-book 4.1 ...
- OpenGL shader 中关于顶点坐标值的思考
今天工作中需要做一个事情: 在shader内部做一些空间距离上的计算,而且需要对所有的点进行计算,符合条件的显示,不符合条件的点不显示. 思路很简单,在vertex shader内知道顶点坐标,进行计 ...
- 【OpenGL】用OpenGL shader实现将YUV(YUV420,YV12)转RGB-(直接调用GPU实现,纯硬件方式,效率高)
这段时间一直在搞视频格式的转换问题,终于最近将一个图片的YUV格式转RGB格式转换成功了.下面就来介绍一下: 由于我的工程是在vs2008中的,其中包含一些相关头文件和库,所以下面只是列出部分核心代码 ...
- OpenGL shader渲染贴图
simple.vert #version core layout (location = ) in vec3 position; layout (location = ) in vec3 color; ...
随机推荐
- git flow工作流实际项目实践
公司项目的开发流程主要是这样 代码分为 develop分支 master分支 平时我开发的时候,主要在develop分支上改动 一般来讲,有以下几种改动方式 1.直接在develop上修改代码 这种一 ...
- HTML常用标签总结
HTML 的常用标签总结 <font size="字体大小1-7" color="red或0xff00ff" face="字体类型(楷体等)&q ...
- python 函数之装饰器,迭代器,生成器
装饰器 了解一点:写代码要遵循开发封闭原则,虽然这个原则是面向对象开发,但也适用于函数式编程,简单的来说,就是已经实现的功能代码不允许被修改但 可以被扩展即: 封闭:已实现功能的代码块 开发:对扩张开 ...
- Android 网络状态检测
package com.example.administrator.yunstore.net; import android.app.AlertDialog; import android.conte ...
- 在React 组件中使用Echarts
在完成一个需求的时候碰到一个场景需要使用柱状图.涉及到可视化,第一反应当然是Echarts了.平时用js加载Echarts组件很方便,但是在React中就要费下神了.各种连蒙带猜实现了.edmo里的E ...
- 关于mysql ERROR 1045 (28000)错误的解决办法
错误情景: 使用Navicat打开mysql的时候弹出错误框 错误代码: ERROR 1045 (28000): Access denied for user 'ODBC'@'localhost' ( ...
- FastReport.Net 常用功能总汇
一.常用控件 文本框:输入文字或表达式 表格:设置表格的行列数,输入数字或表达式 子报表:放置子报表后,系统会自动增加一个页面,你可以在此页面上设计需要的报表.系统在打印处理时,先按主报表打印,当碰到 ...
- USACO翻译:USACO 2014 FEB SILVER 三题
USACO 2014 FEB SILVER 一.题目概览 中文题目名称 自动打字 路障 神秘代码 英文题目名称 auto rblock scode 可执行文件名 auto rblock scode 输 ...
- Collections+Iterator 接口 | Map+HashMap+HashTable+TreeMap |
Collections+Iterator 接口 1. Collections 是一个操作 Set.List 和 Map 等集合的工具类 Collections 中提供了大量方法对集合元素进行排序.查询 ...
- HTML Help WorkShop 创作、调用方法和技巧
一.在CHM 文件中所用到的弹出式菜单: 二.在HTML Help WorkShop 中不用显示的样式 (1).从右到右阅读顺序. (2).对话框 (3).滚动条在左边 (4).仅展开单个标题 ...