opengl 4.0 shading language阅读笔记day1

本文介绍了OpenGL 4.0中的GLSL(OpenGL Shading Language)基础知识,包括GLSL在GPU上的作用,核心配置文件与兼容性配置文件的区别,以及如何在Qt中设置核心配置文件。此外,还提到了GLEW库的使用注意事项和GLM库的功能。文章还深入讲解了如何编译和验证着色器,以及如何链接着色器以创建着色器程序。
摘要由CSDN通过智能技术生成

day1:简介

(1)glsl在gpu上运行,它是opengl的一部分,不是独立存在的。

glsl替换了opengl中固定管线的功能,这些功能是默认的,如果要实现更好的效果就要使用glsl编程。

(2)opengl版本更替过程中逐步删除旧功能,因此,编写用于特定版本的opengl(已经删除旧功能)代码

的程序员将使用  coreprofile。也想与旧功能保持兼容性的人可以使用兼容性配置文件。

(3)选择核心或兼容性配置文件的步骤取决于窗口系统API。 例如,在最新版本的Qt(至少为4.7版)中,可以使用以下代码选择4.0核心配置文件。

QGLFormat format;

format.setVersion(4,0);

format.setProfile(QGLFormat::CoreProfile);

QGLWidget *myWidget = new QGLWidget(format);

(4)glew跨平台c++扩展库

注意事项1:在文件开头,先包含glew库,再包含 opengl头文件,如:

#include <GL/glew.h>

#include <GL/gl.h>

#include <GL/glu.h>

注意事项2:

(5)使用glm以及扩展

例子:

GLM库是仅标头的库。 所有实现都包含在头文件中。 它不需要单独的编译,也不需要将程序链接到它。 只需要将头文件放在include路径中即可!前面的示例首先创建了一个代表位置的vec4(四个坐标矢量)。 然后,它使用来自transform2extension的glm :: lookAt函数创建4x4视图矩阵。 这与旧的gluLookAt函数的工作方式相似。 在此示例中,我们将摄像机的位置设置为(0,0,5),朝向原点,Y轴方向为“向上”方向。 然后,我们首先通过将恒等矩阵存储在变量模型中来创建建模矩阵(通过构造函数:glm :: mat4(1.0f)),然后使用glm :: rotate函数乘以旋转矩阵。 这里的乘法是由glm :: rotate函数隐式完成的。 它将其第一个参数乘以该函数生成的旋转矩阵。 第二个参数是旋转角度(以度为单位),第三个参数是旋转轴。 最终结果是绕Y轴旋转90度的旋转矩阵。 最后,我们通过将视图变量和模型变量相乘,然后使用组合的矩阵来变换位置,来创建模型视图矩阵(mv)。 请注意,乘法运算符已重载以按预期方式运行。

不建议导入glm域名空间(using namespace glm;)

(6)确定glsl和opengl的版本问题

涉及两个主要函数:glGetString和glGetIntegerv

以下代码:

(7)编译着色器

编译着色器 包括创建一个着色器对象,将源代码(作为一个字符或者一组字符串)提供给着色器对象,并要求着色器对象编译代码。如下图:

示例:

这段代码它作为一个“传递”着色器工作。它接受输入属性VertexPosition和VertexColor,并通过输出变量gl Position和Color将它们传递到片段着色器。

接下来,我们需要使用任何标准的窗口工具包为OpenGL程序构建一个基本的shell。 跨平台工具包的示例包括GLUT,FLTK,Qt或wxWidgets。 在本文全文中,我将假设您可以使用自己喜欢的工具包创建一个基本的OpenGL程序。 几乎所有工具包都有一个用于初始化函数的钩子,一个大小调整回调(在调整窗口大小时调用)和一个绘图回调(在每次刷新窗口时调用)。 出于本食谱的目的,我们需要一个程序来创建和初始化OpenGL上下文。 最后,我们需要将着色器源代码加载到名为shaderCode的字符数组中。 不要忘记在结尾添加空字符! 本示例假定变量shaderCode指向以空字符正确终止的GLchar数组

四步走,

第一步,创建着色器对象

第二步  把源代码赋值到着色器对象

第三步 编译着色器

第四步 验证编译状态

第一步是使用功能glCreateShader创建着色器对象。 参数是着色器的类型,并且可以是下列值之一:GL_VERTEX_SHADER,GL_FRAGMENT_SHADER,GL_GEOMETRY_SHADER,GL_TESS_EVALUATION_SHADER或GL_TESS_CONTROL_SHADER。 在这种情况下,由于我们正在编译顶点着色器,因此我们使用GL_VERTEX_SHADER。 此函数返回用于引用顶点着色器对象(有时称为对象“句柄”)的值。 我们将该值存储在变量vertShader中。 如果在创建着色器对象时发生错误,则此函数将返回0,因此我们将对其进行检查,如果发生该错误,我们将打印一条适当的消息并终止。

 

在创建着色器对象之后,将源代码加载到着色器中 使用功能glShaderSource的对象。 此函数旨在接受字符串数组,以支持一次编译多个文件的选项。 因此,在调用glShaderSource之前,我们将指向源代码的指针放入名为sourceArray的数组中。 glShaderSource的第一个参数是着色器对象的句柄。 第二个是数组中包含的源代码字符串的数量。 第三个参数是指向源代码字符串数组的指针。 最后一个参数是GLint值的数组,其中包含前一个参数中每个源代码字符串的长度。 在这种情况下,我们传递一个NULL值,该值指示每个源代码字符串都以一个空字符结尾。 如果我们的源代码字符串不是以null终止的,则此参数必须是有效的数组。 请注意,此函数返回后,源代码已复制到OpenGL内部存储器中,因此可以释放用于存储源代码的内存。

 

下一步是编译着色器的源代码。 为此,我们只需调用glCompileShader,然后将句柄传递给要编译的着色器即可。

当然,根据源代码的正确性,编译可能会失败,因此下一步是检查编译是否成功。我们可以通过调用glGetShaderiv来查询编译状态,该函数用于查询 着色器对象的属性。 在这种情况下,我们对编译状态感兴趣,因此我们使用GL_COMPILE_STATUS作为第二个参数。 当然,第一个参数是着色器对象的句柄,第三个参数是指向将存储状态的整数的指针。 该函数在第三个参数中提供GL_TRUE或GL_FALSE的值,指示编译是否成功。如果编译状态为GL_FALSE,则可以查询着色器日志,该日志将提供有关失败的其他详细信息。 为此,我们首先通过再次调用glGetShaderiv并使用GL_INFO_LOG_LENGTH的值来查询日志的长度。 这将在变量logLen中提供日志的长度,包括空终止符。 然后,我们为日志分配空间,并通过调用glGetShaderInfoLog检索日志。 第一个参数是着色器对象的句柄,第二个参数是用于存储日志的字符缓冲区的大小,第三个参数是指向整数的指针,在该整数中实际写入的字符数(不包括空终止符)将为 第四个参数是指向用于存储日志本身的字符缓冲区的指针。 检索到日志后,我们将其打印到stderr并释放其内存空间。

 

 

每种着色器类型的着色器编译技术几乎相同。 唯一的显着区别是glCreateShader的参数。当然,着色器编译只是第一步。 要创建一个有效的着色器程序,我们通常至少要编译两个着色器,然后必须将这些着色器链接在一起成为一个着色器程序对象。(下一节讲链接着色器)

当不再需要时,可以通过调用glDeleteShader删除着色器对象。这会释放着色器使用的内存并使其句柄失效。注意,如果一个着色器对象已经附加到一个程序对象(参见Linking a shader program),它不会被立即删除,但标记为删除时,它从程序对象分离

 

 

(8)链接着色器

编译好着色器后,在将其实际安装到OpenGL管道中之前,我们需要将它们链接到一个着色器程序中。 除其他事项外,链接步骤包括在一个着色器的输入变量与另一个着色器的输出变量之间建立连接,以及在着色器的其他输入/输出变量与OpenGL环境中的适当位置之间建立连接。 与编译着色器所涉及的相似。 我们将每个着色器对象附加到一个新的着色器程序对象,然后告诉该着色器程序对象进行链接(确保在链接之前已编译该着色器对象)。

对于这个食谱,我们假设你已经编译了两个着色器对象,它们的句柄存储在变量vertShader和fragShader中。对于这一章以及其他一些食谱,我们将使用下面的片段着色器源代码

对于顶点着色器,我们将使用上一个配方的源代码

在我们的OpenGL初始化函数中,在编译了vertShader和fragShader引用的着色器对象之后,使用以下步骤

我们首先调用glCreateProgram创建一个空的程序对象。 该函数返回程序对象的句柄,该句柄存储在名为programHandle的变量中。 如果在创建程序时发生错误,则该函数将返回0。我们将对此进行检查,如果发生,则会打印一条错误消息并退出。接下来,使用glAttachShader将每个着色器附加到程序对象上。 第一个参数是程序对象的句柄,第二个参数是要附加的着色器对象的句柄,然后我们通过调用glLinkProgram链接程序,将程序对象的句柄作为唯一参数。 与编译一样,我们通过后续查询检查链接的成功或失败。 第121章我们通过调用glGetProgramiv来检查链接的状态。 与glGetShaderiv相似,glGetProgramiv允许我们查询着色器程序的各种属性。 在这种情况下,我们通过提供GL_LINK_STATUS作为第二个参数来请求链接的状态。 状态在第三个参数所指向的位置(在本例中为status)中返回。链接状态为GL_TRUE或GL_FALSE,指示链接的成功或失败。 如果状态值为GL_FALSE,我们将检索并显示程序信息日志,其中应包含其他信息和错误消息。 通过调用glGetProgramInfoLog可以检索程序日志。 第一个参数是程序对象的句柄,第二个参数是包含日志的缓冲区的大小,第三个参数是指向GLsizei变量的指针,该变量将存储写入缓冲区的字节数(不包括空终止符) ),第四个是指向将存储日志的缓冲区的指针。 可以根据参数GL_INFO_LOG_LENGTH调用glGetProgramiv返回的大小来分配缓冲区。 日志中提供的字符串将正确地以null终止。最后,如果链接成功,我们可以通过调用glUseProgram将程序的句柄作为参数来将程序安装到OpenGL管道中。 配方,前一配方的顶点着色器已编译,链接并安装到OpenGL管线中,我们拥有完整的OpenGL管线,并准备开始渲染。 绘制一个三角形并为Color属性提供不同的值(红色,绿色和蓝色)会生成一个多色三角形的图像,其中顶点为红色,绿色和蓝色,并且在三角形内部对这三种颜色进行插值,从而导致 贯穿整个色彩。

page1-page23

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值