OpenGL着色语言(GLSL――OpenGL Shading Language)是用来在OpenGL中着色编程的语言,

也即开发人员写的短小的自定义程序,他们是在图形卡的GPU (Graphic Processor Unit图形处理单元)

上执行的,代替了固定的渲染管线的一部分。比如:视图转换、投影转换等。GLSL(GL Shading Language)

的着色器代码分成2个部分:Vertex Shader(顶点着色器)和Fragment(片断着色器)

,有时还会有Geometry Shader(几何着色器)。负责运行顶点着色的是顶点着色器。

它可以得到当前OpenGL 中的状态,GLSL内置变量进行传递。

先看下vertex shader,起设计目的是对应用层输入的顶点数据做处理,我们可以以一个简单的

代码来看下定点处理的过程,可以把下面的过程看成是显卡处理定点数据的过程:

void process( const Vertex& position,Vertex&  gl_Position)
{
gl_Position = gl_ModelViewProjectionMatrix * position;
} for (int i = ;i < vertexCnt ; ++ i )
{
Vertex gl_Position;
process( position[i],Vertex& gl_Position);
//! 对定点数据做其他的处理
}
 

上面的代码中process函数,就是我们要写的shader函数,里面对顶点数据进行处理,处理完成

后交给下一个渲染流程。下面的for循环函数,是又显卡内部控制,当然也是在显卡内完成,即当

我们在应用层调用OpenGL的函数 glVertex**或者glNormal等函数的时候,就是把顶点数据从

cpu传递给GPU,就会调用Process函数进行处理(实际远比我说的复杂)。假设应用层有10万

个顶点做计算,那么Process函数就会被调用10万次。试想这该是多么大的计算量,当然这个相比

纹理来说还是小意思,当我们绘制一个图片处理的时候,每一个像素的绘制都要调用一个类似的处理

过程函数进行处理,假设有一个1024 × 1024 的图片绘制出来,需要的计算量大家可想而知,说

这个的道理在于我们要认识到显卡的强大计算能力。

废话不说,看下面的一个代码片段,我们进行分析:

void main( void )
{
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}

上述的代码是一个最简单的顶点shader:

gl_Position:是GLSL的一个内置变量,即输出的丁点位置

gl_Vertex:是GLSL的一个内置变量,输入的顶点位置。

gl_ModelViewProjectionMatrix:GLSL的内置变量:

保存了 Project Matrix * View Matrix * Model Matrix的结果

Model Matrix:保存了当前对顶点数据的缩放,旋转,平移等操作

View Matrix :观察矩阵 ,

Project Matrix:就是正交投影,或者透视投影的矩阵(调用 :glOrtho,或者 gluPerspective)

通过上面的介绍,想必大家已经多shader的工作原理已经有所了解了,下面介绍shader的使用步骤:

1.首先编写一个shader,当然是文本方式(其实也可以是汇编方式,或者bin方式,后面介绍)

2.调用glCreateShaderObjectARB创建一个shader对象

3.将源文件(就是shader 的程序)给shader对象

4.进行编译

单独的一个shader对象还不能使用,要想使用它,还需要创建一个shader program 对象,然后进行关联

可以这样来理解,shader object 类似我们编译c++生成的obj文件,将obj文件连接生成一个exe.这个exe

就是shader program了。

5.建立一个shader program

6.关联shader object 到 shader program

7.进行链接

8.使用这个程序。

        const char *source[];
source[] = vertexShaderSource;
//1 创建一个定点shader,理解成对源码进行编译
g_vertexShader = glCreateShaderObjectARB( GL_VERTEX_SHADER_ARB );
//2 指定数据(就是代码)
glShaderSourceARB( g_vertexShader, , source, NULL );
//3 编译
glCompileShaderARB( g_vertexShader);
//4 看编译成功了没有
glGetObjectParameterivARB( g_vertexShader, GL_OBJECT_COMPILE_STATUS_ARB, &bVertCompiled );
//5 编译失败,打印错误的原因
if( bVertCompiled == false )
{
glGetInfoLogARB(g_vertexShader, sizeof(temp), NULL, temp);
MessageBoxA( NULL, temp, "Vertex Shader Compile Error", MB_OK|MB_ICONEXCLAMATION );
}
//6 创建一个程序对象,可以理解成exe
_programObj = glCreateProgramObjectARB();
//7 将顶点shader与程序绑定
glAttachObjectARB( _programObj, g_vertexShader );
//8 链接过程
glLinkProgramARB( _programObj );
glGetObjectParameterivARB( _programObj, GL_OBJECT_LINK_STATUS_ARB, &bLinked );

代码下载

OpenGL12-shader(GLSL)着色语言1(代码已上传)的更多相关文章

  1. OpenGL12-shader(GLSL)着色语言3-(属性参数)(代码已上传)

    上一个例程中,使用了uniform 类型的变量,uniform可以理解为全局变量,这一节中使用 的是attribute类型的变量,翻译过来就是属性,他是与顶点绑定的,就意味着一个顶点可以 有很多个属性 ...

  2. OpenGL12-shader(GLSL)着色语言4-广告版的实现

    之前介绍了vertex shader的基本原理,现在我们来做一个简单的实践,在游戏中广告版(布告版) 随处可见,而且效率很高,现在我们就使用shader来实现这一过程,首先我们要知道布告版的原理 实际 ...

  3. C++向main函数传递参数的方法(实例已上传至github)

    通常情况下,我们定义的main函数都只有空形参列表: int main(){...} 然而,有时我们确实需要给mian传递实参,一种常见的情况是用户设置一组选项来确定函数所要执行的操作.例如,假定ma ...

  4. SWFUpload 已上传成功数量控制 插件(用于解决队列满问题)

    当我们在使用 SWFUpload 做文件上传时,我们需要把已经上传的文件列表做一个删除, 但在我们把已上传列表删除后,再重新上传时,会发现提示 上传队列满 的问题,原因就是有一个状态对象中的一个 成功 ...

  5. python代码git上传

    python代码git上传 1.每次上传代码之前需要先拉取线上的代码 操作如下:

  6. OpenGL12-shader(GLSL)着色语言2-(参数传递)(代码以上传)

    上一篇中介绍了如何使用shader,用来一个最简单的shader,计算顶点的位置,调用了 OpenGL 顶点着色语言中的内置变量对顶点进行操作,这一例程中,将展示如何将应用层 的数据传递到shader ...

  7. GLSL着色语言学习。橙皮书第一个例子GLSL+OpenTK+F#的实现。

    Opengl红皮书有选择的看了一些,最后的讲着色语言GLSL的部分看的甚为不理解,然后找到Opengl橙皮书,然后就容易理解多了. 在前面,我们或多或少接触到Opengl的处理过程,只说前面一些处理, ...

  8. OpenGL10-骨骼动画原理篇(3)-Shader版本代码已经上传

    视频教程请关注 http://edu.csdn.net/lecturer/lecturer_detail?lecturer_id=440 接上一个例程OpenGL10-骨骼动画原理篇(2),对骨骼动画 ...

  9. 利用git工具将自己的代码文件上传到Github

    GitHub 是一个面向开源及私有软件项目的托管平台,作为开源代码库以及版本控制系统,Github拥有超过900万开发者用户.随着越来越多的应用程序转移到了云上,Github已经成为了管理软件开发以及 ...

随机推荐

  1. 使用Revel(go)开发网站

    Revel很好的利用了Go语言的goroutine,把每一个request都分配到了goroutine里.不用再写一大堆的回调.如果你写过nodejs的话就会深刻的体会到callback hell是什 ...

  2. hibernate的一级缓存问题

    1.证明一级缓存的问题 输出结果: 只发出一条查询语句  第二条查询语句没有执行 因为第一条查询语句缓存的存在 2. 移除缓存: 输出结果: 3.一级缓存的快照 就是对一级缓存的数据备份 保证数据库的 ...

  3. 20155320 2016-2017-2 《Java程序设计》第五周学习总结

    20155320 2016-2017-2 <Java程序设计>第五周学习总结 教材学习内容总结 错误处理 java中所有错误都会被打包为对象,可以通过try catch 代表错误的对象后做 ...

  4. .NET在IE10下的回传BUG修复

    以前我也没注意到,直到有次公司新配了台机器做测试服务器,在测试过程中意外发现凡是涉及PostBack的操作仅在IE10下都无效,其他版本浏览器都没有问题,本机调试也没有问题. 这也就是说在程序相同的情 ...

  5. LinkServer--在Job中使用Linkserver注意事项

    如果要使用job来调用link server的话,不能使用作业步骤属性高级选项中”作为以下用户运行“来以本地登录用户模拟远程用户访问远程服务器.会报”无法建立安全上下文“的错误. 将Job中代码封装到 ...

  6. .Net Core在Middleware中解析RouteData

    在ASP.Net Core中,如果直接在Middleware中获取RouteData返回的是空值,这是因为RouterMiddleware还没执行.但有些情况下需要获取RouteData,这要怎么做呢 ...

  7. win 10 mysql8.0安装

    1.解压缩安装包(记住自己的解压到那个目录,后面需要) 2.找到此电脑,然后找到属性(小编这里win10) 3.点击左侧高级系统设置 4.选择下面的环境变量 5.选择下面的新建,然后看图片,上面输入M ...

  8. .net core获取appsettings CustomSettings

    private static string GetCustomSettings(string key) { var config = new ConfigurationBuilder() .AddIn ...

  9. 上云、微服务化和DevOps,少走弯路的办法

    本文由  网易云发布. 作者:张亮 如果说一个项目的发展历程就像一段未知的旅程,那<云原生应用架构实践>就像一张地图,基于前人的探索标明了在这段旅途中将会碰到的障碍,并注明了越过这些障碍的 ...

  10. 程序媛计划——python初级课时3~5

    产生1-10中的随机数: for 循环:所有可遍历对象都能用于for循环,如一个字符串. len(list),list中的元素类型可以各不相同:可以直接用下标对list元素赋值来更新列表 对字符串可以 ...