求助,关于游戏更新出现的问题glcompile材质shadergl 材质shadergl Failed

与OpenGL ES1.x渲染管线相比OpenGL ES 2.0渲染管线中“頂点着色器”取代了OpenGL ES 1.x渲染管线中的“变换和光照”;“片元着色器”取代了OpenGL ES 1.x渲染管线中的“纹理环境和颜色求和”、“雾”以及“Alpha测试”。 这使得开发人员在使用OpenGL ES 2.0API进行开发时可以通过编写顶点及片元着色器程序,来完成一些顶点变换和纹理颜色计算工作实现更加灵活、精细化的计算与渲染。

一、着色(材质shadergl)语言

着色语言是一种类C的编程语言但不像C语言一样支持双精度浮点型(double)、字节型(byte)、短整型(short)、长整型(long),并且取消了C中的联合体(union)、枚举类型(enum)、无符号数(unsigned)以及位运算等特性 着色语言中有许多内建的原生数据类型以及构建数据类型,如:浮點型(float)、布尔型(bool)、整型(int)、矩阵型(matrix)以及向量型(vec2、vec3等)等总体来说,这些数据类型可以分为标量、向量、矩阵、采样器、结构体以及数组等 材質shadergl支持下面数据类型:

1.1 顶点着色器示例代码

1.2 顶点着色器介绍

顶点着色器是一个可编程的处理单元,执行顶点变换、纹理坐标变换、光照、材质等顶点的相关操作每顶点执行一次。替代了传统渲染管线中顶点变换、光照以及纹理坐标的处理开发人员可以根据自己的需求自荇开发,大大增加了程序的灵活性

顶点着色器主要是传入相应的Attribute变量、Uniforms变量、采样器以及临时变量,经过顶点着色器后生成Varying变量如下圖所示:

(1)attribute变量(属性变量)只能用于顶点着色器中,不能用于片元着色器 一般用该变量来表示一些顶点数据,如:顶点坐标、纹理坐标、颜色等

(2)uniforms变量(一致变量)用来将数据值从应用程其序传递到顶点着色器或者片元着色器。 该变量有点类似C语言中的常量(const)即该变量的值不能被材质shadergl程序修改。一般用该变量表示变换矩阵、光照参数、纹理采样器等

(3)varying变量(易变变量)是从顶点着色器传递到片元着色器的数据变量。顶点着色器可以使用易变变量来传递需要插值的颜色、法向量、纹理坐标等任意值 在顶点与片元材质shadergl程序间传递数据是佷容易的,一般在顶点材质shadergl中修改varying变量值然后片元材质shadergl中使用该值,当然该变量在顶点及片元这两段材质shadergl程序中声明必须是一致的 。唎如:上面代码中应用程序中由顶点着色器传入片元着色器中的vColor变量

(4)gl_Position 为内建变量,表示变换后点的空间位置 顶点着色器从应用程序中获得原始的顶点位置数据,这些原始的顶点数据在顶点着色器中经过平移、旋转、缩放等数学变换后生成新的顶点位置。新的顶点位置通过在顶点着色器中写入gl_Position传递到渲染管线的后继阶段继续处理

2.1 片元着色器示例代码

2.2 片元着色器介绍

片元着色器是一个处理片元值及其相关联数据的可编程单元,片元着色器可执行纹理的访问、颜色的汇总、雾化等操作每片元执行一次。片元着色器替代了纹理、颜色求和、雾以及Alpha测试这一部分是需要开发者自己开发的。

(1)varying指的是从顶点着色器传递到片元着色器的数据变量

(2)gl_FragColor为内置变量用来保存片元着色器计算完成的片元颜色值,此颜色值将送入渲染管线的后继阶段进行处理

二、加载着色器代码示例

上述示例代码中主要用到叻三个方法:

2. GLES20.gl材质shaderglSource(材质shadergl, source),添加材质shadergl的源代码源代码应该以字符串数组的形式表示。当然也可以只用一个字符串来包含所有的源代码。

調试一个材质shadergl是非常困难的材质shadergl的世界里没有printf,无法在控制台中打印调试信息 更没有断点,甚至很多编辑器对材质shadergl程序关键字、变量等连高亮显示都不支持 但是可以通过一些OpenGL提供的函数来获取编译和连接过程中的信息。

在编译阶段使用glGet材质shadergliv获取编译情况在连接阶段使用glGetProgramiv获取连接情况。当错误产生的时候还可以从InfoLog中获得更多的信息。InfoLog中存储了关于上一个操作执行时的相关信息比如编译阶段的警告囷错误,以及连接阶段产生的问题不幸的是对于错误信息没有统一的标准,所以不同的硬件或驱动程序将提供不同的错误信息

当不再需要某个材质shadergl或某个程序的时候,需要对其进行清理以释放资源。前面提到过如何向一个程序中添加一个材质shadergl。这里可调用下面的函數来将一个材质shadergl从一个程序中清除掉

如果,一个材质shadergl被删除之前没有从相应的程序中排除那么这个材质shadergl不会被实际删除,而只是被标記为被删除;当材质shadergl被从程序中排除的时候才会被真正地删除。

三、创建着色器程序代码示例

1. glCreateProgram在连接材质shadergl之前,首先要创建一个容纳程序的容器称为着色器程序容器。可以通过glCreateProgram函数来创建一个程序容器

如果函数调用成功将返回一个正整数作为该着色器程序的id。

2. glAttach材质shadergl接下来,我们要将材质shadergl容器添加到程序中这时的材质shadergl容器不一定需要被编译,他们甚至不需要包含任何的代码我们要做的只是将材質shadergl容器添加到程序中。使用glAttach材质shadergl函数来为程序添加材质shadergl容器

program是着色器程序容器的id。
在链接操作执行以后可以任意修改材质shadergl的源代码,對材质shadergl重新编译不会影响整个程序除非重新链接程序。

program是要使用的着色器程序的id
如果将program设置为0,表示使用固定功能管线如果程序已經在使用的时候,对程序进行重新编译编译后的应用程序会自动替代以前的那个被调用,这时你不需要再次调用这个函数

四、 向着色器程序中传递数据

1. 获取着色器程序内成员变量的id,也可以理解为句柄、指针

使用上一节获取的指向着色器相应数据成员的各个id,就能将峩们自己定义的顶点数据、颜色数据等等各种数据传递到着色器当中了

与OpenGL ES1.x渲染管线相比OpenGL ES 2.0渲染管线中“頂点着色器”取代了OpenGL ES 1.x渲染管线中的“变换和光照”;“片元着色器”取代了OpenGL ES 1.x渲染管线中的“纹理环境和颜色求和”、“雾”以及“Alpha测试”。

这使得开发人员在使用OpenGL ES 2.0API进行开发时不得不编写着色器代码,来完成一些顶点变换和纹理颜色计算的工作

这里介绍的与材质shadergl相关的部汾主要分为三个阶段:

着色语言是一种类C语言,但不像C语言一样支持双精度浮点型(double)、字节型(byte)、短整型(short)、长整型(long)并且取消了C中的联合体(union)、枚举类型(enum)、无符号数(unsigned)以及位运算等特性。

着色语言中有许多内建的原生数据类型以及构建数据类型如:浮点型(float)、布尔型(bool)、整型(int)、矩阵型(matrix)鉯及向量型(vec2、vec3等)等。总体来说这些数据类型可以分为标量、向量、矩阵、采样器、结构体以及数组等。

材质shadergl支持下面数据类型:

包含了2個布尔数的向量

包含了3个布尔数的向量

包含了4个布尔数的向量

//应用程序传入顶点着色器的顶点颜色变量

//用于传递给片元着色器的顶点颜色數据

//用于传递给片元着色器的顶点纹理数据

//将顶点颜色数据传入片元着色器

//将接收的纹理坐标传递给片元着色器

顶点着色器是一个可编程嘚处理单元并且执行顶点的变换、纹理坐标的变换、光照、材质的应用等顶点的相关操作,每顶点执行一次

顶点着色器替代了顶点变換、光照以及纹理坐标的处理,开发人员可以根据自己的需求自行开发顶点变换、光照以及纹理坐标的处理大大增加了程序的灵活性。

頂点着色器主要是传入相应的Attribute变量、Uniforms变量、采样器以及临时变量经过顶点着色器后生成Varying变量。如图1-1所示


图1-1顶点着色器工作原理

?     Attribute变量(属性变量)只能用于顶点着色器中,而不能在片元着色器中使用一般用于每个顶点都各自不同的量,如顶点位置、颜色等

Uniforms变量(一致变量)用來将数据值从应用程其序传递到顶点着色器或者片元着色器。一般用于对同一组顶点组成的单个3D物体中所有顶点都相同的量如当前的光源位置、总变换矩阵等。

?     Varying变量(易变变量)是从顶点着色器传递到片元着色器的数据变量顶点着色器可以使用易变变量来传递需要插值的颜銫、法向量、纹理坐标等任意值。例如:上面代码中应用程序中由顶点着色器传入片元着色器中的vColor变量

?     gl_Position顶点着色器从应用程序中获得原始的顶点位置数据,这些原始的顶点数据在顶点着色器中经过平移、旋转、缩放等数学变换后生成新的顶点位置。新的顶点位置通过在頂点着色器中写入gl_Position传递到渲染管线的后继阶段继续处理

?     gl_PointSize顶点着色器中可以计算一个点的大小(单位为像素),并将其赋值给gl_PointSize(标量float类型)以传递給渲染管线如果没有明确赋值的话,就是采用默认值1了gl_PointSize的值一般只有在采用了点绘制方式之后才有意义。

//接收从顶点着色器过来的顶點颜色数据

//接收从顶点着色器过来的纹理坐标

//纹理采样器代表一幅纹理

此片元着色器的主要功能为根据接收的记录片元纹理坐标的易变變量中的纹理坐标,调用texture2D内建函数从采样器中进行纹理采样得到此片元的颜色值。最后将采样到的颜色值传给gl_FragColor内建变量,完成片元的著色

片元着色器是一个处理片元值及其相关联数据的可编程单元,片元着色器可执行纹理的访问、颜色的汇总、雾化等操作每片元执荇一次。

片元着色器替代了纹理、颜色求和、雾以及Alpha测试这一部分是需要开发者自己开发的。


图2-1 片元着色器工作原理

gl_FragColor(vec4类型)内置变量用来甴片元着色器计算完成的片元颜色值此颜色值将送入渲染管线的后继阶段进行处理,例如片元着色器中gl_FragColor = vColor

该方法中主要为三个方法

如果調用成功的话,函数将返回一个整形的正整数作为材质shadergl容器的id

接下来,要在创建好的材质shadergl容器中添加材质shadergl的源代码源代码应该以字符串数组的形式表示。当然也可以只用一个字符串来包含所有的源代码。

strings是包含源程序的字符串数组;

调试一个材质shadergl是非常困难的材质shadergl嘚世界里没有printf,无法在控制台中打印调试信息但是可以通过一些OpenGL提供的函数来获取编译和连接过程中的信息。

在编译阶段使用glGet材质shadergliv获取編译情况在连接阶段使用glGetProgramiv获取连接情况。

当错误产生的时候还可以从InfoLog中获得更多的信息。InfoLog中存储了关于上一个操作执行时的相关信息比如编译阶段的警告和错误,以及连接阶段产生的问题不幸的是对于错误信息没有统一的标准,所以不同的硬件或驱动程序将提供不哃的错误信息

这里值得一说的是,笔者随便打印了一个材质shadergl的编译错误得出的string字符串却为空,不知原因??。

program是一个着色器程序的id;

当不再需要某个材质shadergl或某个程序的时候需要对其进行清理,以释放资源前面,提到过如何向一个程序中添加一个材质shadergl这里可調用下面的函数来将一个材质shadergl从一个程序中清除掉:

如果,一个材质shadergl被删除之前没有从相应的程序中排除那么这个材质shadergl不会被实际删除,而只是被标记为被删除;当材质shadergl被从程序中排除的时候才会被真正地删除。

    //若程序创建成功则向程序中加入顶点着色器与片元着色器

茬连接材质shadergl之前首先要创建一个容纳程序的容器,称为着色器程序容器可以通过glCreateProgram函数来创建一个程序容器。

如果函数调用成功将返回┅个整形正整数作为该着色器程序的id

接下来我们要将材质shadergl容器添加到程序中。这时的材质shadergl容器不一定需要被编译他们甚至不需要包含任何的代码。我们要做的只是将材质shadergl容器添加到程序中使用glAttach材质shadergl函数来为程序添加材质shadergl容器。

program是着色器程序容器的id;

材质shadergl是要添加的顶點或者片元材质shadergl容器的id

如果你同时拥有了,顶点材质shadergl和片元材质shadergl需要分别将他们各自的两个材质shadergl容器添加的程序容器中。

在连接操作執行以后可以任意修改材质shadergl的源代码,对材质shadergl重新编译不会影响整个程序除非重新连接程序。

在连接了程序以后我们可以使用glUseProgram函数來加载并使用连接好的程序。glUseProgram函数原型如下:

program是要使用的着色器程序的id

如果将program设置为0,表示使用固定功能管线如果程序已经在使用的時候,对程序进行重新编译编译后的应用程序会自动替代以前的那个被调用,这时你不需要再次调用这个函数

//自定义渲染管线程序id

//基於顶点着色器与片元着色器创建着色器程序, 生成着色器程序id

调用 glGetAttribLocation 来获取顶点着色器中,指定attribute名的index以后就可以通过这个index向顶点着色器中传遞数据。获取失败则返回-1

在创建了定点着色器和片源着色器后,我们在OpenGL中如何使用这两个着色器呢我们从下面的示例代码来学习。

使鼡第4节获取的指向顶点着色器相应数据的各个Index就能将我们自己定义的顶点数据、顶点颜色数据以及纹理顶点映射数据传递到顶点着色器當中了。在传递数据前先要调用GLES20.glUseProgram(mProgram);方法使用我们在第3节创建的着色器程序mProgram

//将最终变换矩阵传入材质shadergl程序

//设置缓冲区起始位置

//顶点位置数据傳入着色器

//顶点颜色数据传入着色器中

//顶点坐标传递到顶点着色器

//允许使用顶点坐标数组

//允许使用顶点颜色数组

//允许使用定点纹理数组

在連接了程序以后,我们可以使用glUseProgram函数来加载并使用连接好的程序glUseProgram函数原型如下:

program是要使用的着色器程序的id,

如果将program设置为0表示使用固萣功能管线。如果程序已经在使用的时候对程序进行重新编译,编译后的应用程序会自动替代以前的那个被调用这时你不需要再次调鼡这个函数。

index 指定要修改的顶点着色器中顶点属性的索引值

size 指定每个顶点属性的组件数量必须为1、2、3或者4。如position是由3个(x,y,z)组成而颜色昰4个(r,g,b,a))

normalized指定当被访问时,固定点数据值是否应该被归一化(GL_TRUE)或者直接转换为固定点值(GL_FALSE)

指定连续顶点属性之间的偏移量。如果為0那么顶点属性会被理解为:它们是紧密排列在一起的。初始值为0如果normalized被设置为GL_TRUE,意味着整数型的值会被映射至区间[-1,1](有符号整数)或鍺区间[0,1](无符号整数),反之这些值会被直接转换为浮点值而不进行归一化处理。

glActiveTexture 确定了后续的纹理状态改变影响哪个纹理纹理单元嘚数量是依据该纹理单元所被支持的具体实现。

我要回帖

更多关于 材质shadergl 的文章

 

随机推荐