这篇文章主要是根据《OpenGL Shading Language Cookbook》一书翻译整理而得,介绍了环境的安装和一些基础知识。下面涉及到的库也可以到这里下载(Windows版)。

2014年9月26日更新:

擦!每次弄OpenGL光配置都弄得很头大。。。由于换了Mac电脑,下面补充了Mac下的注意事项(这时候突然觉得Windows这么方便。。。)

-----------------------------------------------------------------分割线-------------------------------------------------------------------



什么是GLSL


GLSL是OpenGL Shading Language的缩写,顾名思义就是OpenGL渲染语言,它允许我们通过一些接口直接利用现代的图形处理单元(GPUs)进行图形绘制等工作。GLSL语言必须协同OpenGL语言才可以工作。它们嵌入在更庞大的OpenGL语言里,这些迷你的代码通常被称为shader,它们运行在GPU而不是CPU上。从名字上可以看出来,GLSL大多跟3D图像的灯光、渲染等工作有关,但它们的能力绝不仅仅如此。它们还可以用于动画、曲面计算等更深的应用。

Shader语言被设计成可以直接运行在GPU上,并且通常是并行的。例如,对于每个像素,一个fragment shader,片段着色器,可能执行一次,并且是同时在不同的GPU单元上同时执行。显卡上处理器的数量决定了同时可以允许多少个同时执行。这样的特性使得shader具有很好的性能,并允许程序员进行并行运算。
现代显卡的计算能力是让人印象深刻的,下面的表格显示了NVIDIA GeForce 400系列显卡上处理器的数量:

设计者希望Shader程序可以替换传统OpenGL体系结构中的fixed-function pipeline,固定功能管道,部分。在之前,默认的灯光/阴影计算是这个管道的一个核心部分。但是,但我们想要它们实现更多更高级的功能时,我们就需要做非常的工作来实现,而实际上很多是它们无法做到的。GLSL的出现改变了这样的境地,它允许我们使用GLSL语言代替以前的“硬编码”,从而提供了更灵活、更高级的功能。

OpenGL 3.0进入了一个弃用的模型,也就是逐渐被OpenGL规格移除的功能。一些功能和特性可以说是被标志为被弃用了,这意味着它们在未来的OpenGL版本里将会被移除。例如,使用glBegin/glEnd的快速模式渲染在OpenGL 3.0中被标为弃用,在3.1版本里被移除。(我们现在上课还讲来着。。。)
而为了保持向后兼容性,OpenGL 3.2介绍了compatibility profiles,兼容配置文件的概念。如果程序员想要使用特定版本的OpenGL代码(不需要兼容),就可以使用所谓的core profile。而一些人可能希望可以向后兼容,那么就可以使用compatibility profiles。

选择一个a core profile或者a compatibility profile的步骤是跟窗口系统有关的。例如,在最新的Qt版本(现在最新的是5.0)中,我们可以使用下面的代码来选择一个 4.0 core profile :
  1. QGLFormat format;
  2. format.setVersion(4,0);
  3. format.setProfile(QGLFormat::CoreProfile);
  4. QGLWidget *myWidget = new QGLWidget(format);

GLEW


在Windows平台上OpenGL的版本被固定在1.1,这使得Windows平台的开发者不能直接访问最新的OpenGL版本的接口。我们需要进行一系列冗繁的工作来在运行时刻得到一个函数调用的指针,而且还会影响代码的整洁。而且,Windows自带的头文件是遵循OpenGL1.1版本,据称,Windows也不准备更新自带的gl.h和opengl32.lib。幸运的是,有人为我们做了这些事情还提供了相应的库和接口。GLEW就是其中一个。


安装GLEW


为了安装GLEW,以WIndows平台为例,我们可以到http://glew.sourceforge.net下载最新的glew版本,将其中的glew.h和wglew.h文件复制到编译器的对应文件夹下(例如VS的include文件夹),把glew32.lib文件复制到对应的库文件夹下(如VS的lib文件夹),以及glew32.dll复制到系统的根目录下(如system32/下)。

MAC版下的安装(以Qt为例):

Mac下没有现成的编译好的文件,需要下载源码然后用makefile。具体可以参见这里。也就是下面的做法:
  1. 下载 GLEW源码。
  2. 解压 GLEW。
  3. 打开命令行窗口,使用"cd"命令进入解压后的 GLEW 目录。
  4. 执行"make"命令,编译 GLEW。(注:要执行 make 命令,必须先确保 XCode 安装了 Command Line Tools)。
  5. 执行"sudo -s",进入管理员权限。
  6. 执行"make install",将 GLEW 的头文件和库文件分别复制到 /usr/include 和 /usr/include/GL 目录中。
  7. 在 Qt 工程中,右击项目图标,在弹出的快捷菜单中选择"Add Library..."命令。在弹出的向导对话框中选择"External Library",指定 GLEW 库文件和头文件的目录位置,在"Platform"中只勾选"Mac"一项。完成 GLEW 库的导入。
  8. 在 Qt 工程中,右击项目图标,在弹出的快捷菜单中选择"Add Library..."命令。在弹出的向导对话框中选择"System Library",指定 OpenGL.framework 的目录位置(在 /System/Library/Frameworks 目录下),在"Platform"中只勾选"Mac"一项。完成 OpenGL.framework 库的导入。
  9. 在 Qt 工程中,右击项目图标,在弹出的快捷菜单中选择"Add Library..."命令。在弹出的向导对话框中选择"System Library",指定 QtOpenGL.framework 的目录位置(在 Qt 安装目录的 lib 目录下),在"Platform"中只勾选"Mac"一项。完成 QtOpenGL.framework 库的导入。因为即使不使用
    QtOpenGL 库中的 API,在使用 Qt 窗口框架时,还是会用到 QGLWidget 类的。


使用GLEW


为了使用glew,请确保在包含OpenGL头文件之前包含glew.h:
  1. #include <GL/glew.h>
  2. #include <GL/gl.h>
  3. #include <GL/glu.h>

在初始化GL后、调用任何OpenGL代码前,加入以下代码:

  1. GLenum err = glewInit();
  2. if( GLEW_OK != err )
  3. {
  4. fprintf(stderr, "Error initializing GLEW: %s\n",
  5. glewGetErrorString(err) );
  6. }

其他库


另一个管理OpenGL扩展的库时GLEE,具体信息可见http://www.elf-stone.com/glee.php。它和GLEW类似,但是不需要在运行时刻初始化。


使用GLM库进行数学运算


在计算机图形学中,计算是一个核心的功能。以前的OpenGL版本提供了进行坐标变换和投影的标准矩阵栈(GL_MODELVIEW and GL_PROJECTION)。在最新的OpenGL 4.0里,这些功能都被移除了。因此,需要我们自己提供坐标和投影变换矩阵,然后将它们传递给shader。当然你还是可以自己写一个库来管理这些,但是不推荐这样。
一个类似的库时Christophe Riccio编写的GLM。它的设计是基于GLSL规则的,因此它的语法和GLSL语言很相似。同时,它提供了一些OpenGL扩展来弥补缺失的那些OpenGL功能,例如glOrtho,,glRotate, gluLookAt。


安装GLM

你可以在http://glm.g-truc.net网站下载安装包,解压后将glm文件夹复制到编译器对应的文件夹下(例如VS的include文件)。Mac下要把头文件放到usr/include下,然后在Qt项目的.pro文件中添加头文件目录。


使用GLM

和普通的核心头文件相似,你可以使用下面的代码来包含矩阵变换和transform2扩展:
  1. #include <glm/glm.hpp>
  2. #include <glm/gtc/matrix_transform.hpp>
  3. #include <glm/gtx/transform2.hpp>

然后你就可以使用glm命名空间进行编码了。下面是一个例子:

  1. glm::vec4 position = glm::vec4( 1.0f, 0.0f, 0.0f, 1.0f );
  2. glm::mat4 view = glm::lookAt( glm::vec3(0.0,0.0,5.0),
  3. glm::vec3(0.0,0.0,0.0),
  4. glm::vec3(0.0,1.0,0.0) );
  5. glm::mat4 model = glm::mat4(1.0f);
  6. model = glm::rotate( model, 90.0f, glm::vec3(0.0f,1.0f,0.0) );
  7. glm::mat4 mv = view * model;
  8. glm::vec4 transformed = mv * position;

不要使用下面的代码来引入glm的命名空间:

  1. using namespace glm;

这通常会引起命名空间的冲突。相反,你应该使用下面的代码来包含某一个符号:

  1. #include <glm/glm.hpp>
  2. using glm::vec3;
  3. using glm::mat4;

使用GLM作为OpenGL的输入


GLM支持使用OpenGL的向量函数(以"v"为后缀)直接向OpenGL传递一个GLM类型(通常是为了向shader传递参数)。例如:
  1. #include <glm/glm.hpp>
  2. #include <glm/gtc/matrix_transform.hpp>
  3. ...
  4. glm::mat4 proj = glm::perspective( viewAngle, aspect,
  5. nearDist, farDist );
  6. glUniformMatrix4fv(location, 1, GL_FALSE, &proj[0][0]);

更多文档可以详见http://glm.g-truc.net(需要翻墙)。



使用GLFW进行窗口管理



这里再介绍一个库GLFW。在以前的OpenGL版本里我们通常会使用glut来进行窗口的创建、按键监听等工作,但据说这个库已经很久没更新了,那么glfw就是一个可以作为替代的库。它是网址是http://www.glfw.org/。安装方法和上面两个库类似。使用方法可以详见自带的文档。

MAC下安装:

比较复杂,可以看Youtube上的一个视频。大概方法也是要生成头文件和库文件。然后在Qt中配置、包含进去。

【OpenGL】初识OpenGL4.0的更多相关文章

  1. 【AR实验室】OpenGL ES绘制相机(OpenGL ES 1.0版本)

    0x00 - 前言 之前做一些移动端的AR应用以及目前看到的一些AR应用,基本上都是这样一个套路:手机背景显示现实场景,然后在该背景上进行图形学绘制.至于图形学绘制时,相机外参的解算使用的是V-SLA ...

  2. 在 OpenGL ES 2.0 上实现视差贴图(Parallax Mapping)

    在 OpenGL ES 2.0 上实现视差贴图(Parallax Mapping) 视差贴图 最近一直在研究如何在我的 iPad 2(只支持 OpenGL ES 2.0, 不支持 3.0) 上实现 视 ...

  3. Beginning OpenGL ES 2.0 with GLKit Part 1

    Update 10/24/12: If you’d like a new version of this tutorial fully updated for iOS 6 and Xcode 4.5, ...

  4. OpenGL ES 3.0 基础知识

    首先要了解OpenGL的图形管线有哪些内容,再分别去了解其中的相关的关系: 管线分别包括了顶点缓冲区/数组对象,定点着色器,纹理,片段着色器,变换反馈,图元装配,光栅化,逐片段操作,帧缓冲区.其中顶点 ...

  5. OpenGL ES 3.0 点,线,三角形绘制形式总结

    OpenGL ES 3.0 顶点     -1,  1, 0, -0.5f,  0, 0,     0, -1, 0,    -1,  0, 0, 0.5f,   0, 0,     1, -1,   ...

  6. Android OpenGL ES 3.0 纹理应用

    本文主要演示OpenGL ES 3.0 纹理演示.接口大部分和2.0没什么区别,脚本稍微有了点变化而已. 扩展GLSurfaceView package com.example.gles300; im ...

  7. OpenGL ES 2.0 混合

    混合技术 混合技术就是将俩个片元调和,主要用于将通过各项测试准备进入帧缓冲的片元(源片元)与原有片元按照设定的比例加权计算出最终片元的颜色值. OpenGL ES 2.0中是通过设置混合因子来指定两个 ...

  8. OpenGL研究2.0 计算圆

    OpenGL研究2.0 计算圆 DionysosLai2014-06-18 在游戏中.常常有些地方涉及到一些圆的轨迹计算,例如一些转轴类的游戏,人物一般在角色转轴上面运动.这时,我们就要时刻计算角色的 ...

  9. WebGL是一种3D绘图标准,这种绘图技术标准允许把JavaScript和OpenGL ES 2.0结合在一起

    WebGL是一种3D绘图标准,这种绘图技术标准允许把JavaScript和OpenGL ES 2.0结合在一起,通过增加OpenGL ES 2.0的一个JavaScript绑定,WebGL可以为HTM ...

随机推荐

  1. BZOJ 1420: Discrete Root (原根+BSGS)

    题意 已知kkk, aaa, ppp. 求 xk≡a (mod p)x^k\equiv a\ (mod\ p)xk≡a (mod p) 的所有根. 根的范围[0,p−1][0,p-1][0,p−1]. ...

  2. Error from server (ServiceUnavailable): the server is currently unable to handle the request

    grep image /root/kubernetes-metrics-server/kubernetes-metrics-server/metrics-server-deployment.yaml ...

  3. SSH端口转发详解

    正文 一.SSH端口转发简介 SSH会自动加密和解密所有SSH客户端与服务端之间的网络数据.但是,SSH还能够将其他TCP端口的网络数据通SSH链接来转发,并且自动提供了相应的加密及解密服务.这一过程 ...

  4. 线程系列4--Java线程范围内的共享数据(一)

    这张图片是我看传智播客的视频时的截屏,这个图片很直观的展示了线程范围内的数据共享.当同一个线程在执行三个不同业务模块时,这三个业务模块访问的数据是共享的.更直白的说,当一个执行线索在穿个每个业务模块时 ...

  5. SQL复杂查询语句-SELECT * FROM cs WHERE score>70 GROUP BY s_id HAVING COUNT(*)>1

    如果同时存在where,group by,的时候的执行顺序应该是这样的: 1,首先where后面添加条件把数据进行了过滤,返回一个结果集 2,然后group by将上面返回的结果集进行分组,返回一个结 ...

  6. nginx返回固定字符串

    在系统还没有做集群的情况下,直接重启项目时刚好用户在使用的话,一般都会受到投诉,那么使用nginx返回类似“系统维护”的提示信息并且提前在应用上面做通知才是合适的做法 那么记录一下nginx里面的配置 ...

  7. (十四)C语言之一维数组、二维数组

  8. mybatis延迟加载(Collection)

    上篇讲了assocation,同样我们也可以在一对多关系配置的结点中配置延迟加载策略. 结点中也有 select 属性,column 属性. 需求: 完成加载用户对象时,查询该用户所拥有的账户信息. ...

  9. Python dictionary 字典

    Python字典是另一种可变容器模型,且可存储任意类型对象,如字符串.数字.元组等其他容器模型. 一.创建字典字典由键和对应值成对组成.字典也被称作关联数组或哈希表.基本语法如下: dict = {' ...

  10. window7上爬虫框架Scrapy的安装 --错误分析lxml

    本文讲解的是python已经安装成功的情况下,且pip可以使用 版本:python2.7.10 #安装 pip install Scrapy 在安装Scrapy框架时总会报lxml安装不了的各种错误, ...