目录
- 一、问题描述
- 二、分析错误
- 三、解决问题
- 三、总结
一、问题描述
今天编写一个OpenGL ES的demo,发现没有任何图元输出。
查看日志,发现报了如下错误:
2021-11-15 15:09:07.406 26065-26107/opengles3.book.hello_Triangle E/ESShader: ERROR: 0:2: '
' : #version directive must occur on the first line of the shader
ERROR: 0:9: 'in' : storage qualifier supported in GLSL ES 3.00 only
完整日志如下:
2021-11-15 15:09:07.393 26065-26107/opengles3.book.hello_Triangle I/System.out: vertShaderSrc = // 表示OpenGL ES着色器语言V3.00
2021-11-15 15:09:07.395 26065-26107/opengles3.book.hello_Triangle I/System.out: #version 300 es
2021-11-15 15:09:07.395 26065-26107/opengles3.book.hello_Triangle I/System.out: // 使用in关键字,在顶点着色器中声明所有的输入顶点属性(Input Vertex Attribute)。
2021-11-15 15:09:07.395 26065-26107/opengles3.book.hello_Triangle I/System.out: // 声明一个输入属性数组:一个名为vPosition的4分量向量
2021-11-15 15:09:07.395 26065-26107/opengles3.book.hello_Triangle I/System.out: // 在图形编程中我们经常会使用向量这个数学概念,因为它简明地表达了任意空间中的位置和方向,并且它有非常有用的数学属性。
2021-11-15 15:09:07.395 26065-26107/opengles3.book.hello_Triangle I/System.out: // 在GLSL中一个向量有最多4个分量,每个分量值都代表空间中的一个坐标,它们可以通过vec.x、vec.y、vec.z和vec.w来获取。
2021-11-15 15:09:07.396 26065-26107/opengles3.book.hello_Triangle I/System.out: //注意vec.w分量不是用作表达空间中的位置的(我们处理的是3D不是4D),而是用在所谓透视除法(Perspective Division)上。
2021-11-15 15:09:07.396 26065-26107/opengles3.book.hello_Triangle I/System.out: in vec4 vPosition;
2021-11-15 15:09:07.396 26065-26107/opengles3.book.hello_Triangle I/System.out: void main()
2021-11-15 15:09:07.396 26065-26107/opengles3.book.hello_Triangle I/System.out: {
2021-11-15 15:09:07.396 26065-26107/opengles3.book.hello_Triangle I/System.out: // 为了设置顶点着色器的输出,我们必须把位置数据赋值给预定义的gl_Position变量,它在幕后是vec4类型的。
2021-11-15 15:09:07.396 26065-26107/opengles3.book.hello_Triangle I/System.out: // 将vPosition输入属性拷贝到名为gl_Position的特殊输出变量
2021-11-15 15:09:07.396 26065-26107/opengles3.book.hello_Triangle I/System.out: // 每个顶点着色器必须在gl_Position变量中输出一个位置,这个位置传递到管线下一个阶段的位置
2021-11-15 15:09:07.396 26065-26107/opengles3.book.hello_Triangle I/System.out: gl_Position = vPosition;
2021-11-15 15:09:07.396 26065-26107/opengles3.book.hello_Triangle I/System.out: }
2021-11-15 15:09:07.399 2068-2295/com.android.systemui D/EGL_emulation: eglMakeCurrent: 0xe79a8e20: ver 3 1 (tinfo 0xd3aaa1d0)
2021-11-15 15:09:07.400 26065-26107/opengles3.book.hello_Triangle I/System.out: fragShaderSrc = // 表示OpenGL ES着色器语言V3.00
2021-11-15 15:09:07.400 26065-26107/opengles3.book.hello_Triangle I/System.out: #version 300 es
2021-11-15 15:09:07.400 26065-26107/opengles3.book.hello_Triangle I/System.out: // 声明着色器中浮点变量的默认精度
2021-11-15 15:09:07.400 26065-26107/opengles3.book.hello_Triangle I/System.out: precision mediump float;
2021-11-15 15:09:07.400 26065-26107/opengles3.book.hello_Triangle I/System.out: // 声明一个输出变量fragColor,这是一个4分量的向量,
2021-11-15 15:09:07.400 26065-26107/opengles3.book.hello_Triangle I/System.out: // 写入这个变量的值将被输出到颜色缓冲器
2021-11-15 15:09:07.400 26065-26107/opengles3.book.hello_Triangle I/System.out: out vec4 fragColor;
2021-11-15 15:09:07.401 26065-26107/opengles3.book.hello_Triangle I/System.out: void main()
2021-11-15 15:09:07.401 26065-26107/opengles3.book.hello_Triangle I/System.out: {
2021-11-15 15:09:07.401 26065-26107/opengles3.book.hello_Triangle I/System.out: // 所有片段的着色器输出都是红色( 1.0, 0.0, 0.0, 1.0 )
2021-11-15 15:09:07.401 26065-26107/opengles3.book.hello_Triangle I/System.out: fragColor = vec4 ( 1.0, 0.0, 0.0, 1.0 );
2021-11-15 15:09:07.401 26065-26107/opengles3.book.hello_Triangle I/System.out: // 会输出橘黄色
2021-11-15 15:09:07.401 26065-26107/opengles3.book.hello_Triangle I/System.out: // fragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);
2021-11-15 15:09:07.402 26065-26107/opengles3.book.hello_Triangle I/System.out: }
2021-11-15 15:09:07.406 3713-26124/com.google.android.ims I/CarrierServices: [292] awt.doInBackground: New operation mode: 2
2021-11-15 15:09:07.406 26065-26107/opengles3.book.hello_Triangle E/ESShader: ERROR: 0:2: '
' : #version directive must occur on the first line of the shader
ERROR: 0:9: 'in' : storage qualifier supported in GLSL ES 3.00 only
二、分析错误
shaders\fragmentShader.frag
// 表示OpenGL ES着色器语言V3.00
#version 300 es
// 声明着色器中浮点变量的默认精度
precision mediump float;
// 声明一个输出变量fragColor,这是一个4分量的向量,
// 写入这个变量的值将被输出到颜色缓冲器
out vec4 fragColor;
void main()
{
// 所有片段的着色器输出都是红色( 1.0, 0.0, 0.0, 1.0 )
fragColor = vec4 ( 1.0, 0.0, 0.0, 1.0 );
// 会输出橘黄色
// fragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);
}
shaders\vertexShader.vert
// 表示OpenGL ES着色器语言V3.00
#version 300 es
// 使用in关键字,在顶点着色器中声明所有的输入顶点属性(Input Vertex Attribute)。
// 声明一个输入属性数组:一个名为vPosition的4分量向量
// 在图形编程中我们经常会使用向量这个数学概念,因为它简明地表达了任意空间中的位置和方向,并且它有非常有用的数学属性。
// 在GLSL中一个向量有最多4个分量,每个分量值都代表空间中的一个坐标,它们可以通过vec.x、vec.y、vec.z和vec.w来获取。
//注意vec.w分量不是用作表达空间中的位置的(我们处理的是3D不是4D),而是用在所谓透视除法(Perspective Division)上。
in vec4 vPosition;
void main()
{
// 为了设置顶点着色器的输出,我们必须把位置数据赋值给预定义的gl_Position变量,它在幕后是vec4类型的。
// 将vPosition输入属性拷贝到名为gl_Position的特殊输出变量
// 每个顶点着色器必须在gl_Position变量中输出一个位置,这个位置传递到管线下一个阶段的位置
gl_Position = vPosition;
}
通过报错信息
2021-11-15 15:09:07.406 26065-26107/opengles3.book.hello_Triangle E/ESShader: ERROR: 0:2: '
' : #version directive must occur on the first line of the shader
ERROR: 0:9: 'in' : storage qualifier supported in GLSL ES 3.00 only
我们发现,#version 300 es
这行代码确实不是第一行,第一行是一行注释
三、解决问题
我们将#version 300 es
写在第一行,注释写第二行,重新修改下,如下所示:
shaders\fragmentShader.frag
#version 300 es
// 表示OpenGL ES着色器语言V3.00
// 声明着色器中浮点变量的默认精度
precision mediump float;
// 声明一个输出变量fragColor,这是一个4分量的向量,
// 写入这个变量的值将被输出到颜色缓冲器
out vec4 fragColor;
void main()
{
// 所有片段的着色器输出都是红色( 1.0, 0.0, 0.0, 1.0 )
fragColor = vec4 ( 1.0, 0.0, 0.0, 1.0 );
// 会输出橘黄色
// fragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);
}
shaders\vertexShader.vert
#version 300 es
// 表示OpenGL ES着色器语言V3.00
// 使用in关键字,在顶点着色器中声明所有的输入顶点属性(Input Vertex Attribute)。
// 声明一个输入属性数组:一个名为vPosition的4分量向量
// 在图形编程中我们经常会使用向量这个数学概念,因为它简明地表达了任意空间中的位置和方向,并且它有非常有用的数学属性。
// 在GLSL中一个向量有最多4个分量,每个分量值都代表空间中的一个坐标,它们可以通过vec.x、vec.y、vec.z和vec.w来获取。
//注意vec.w分量不是用作表达空间中的位置的(我们处理的是3D不是4D),而是用在所谓透视除法(Perspective Division)上。
in vec4 vPosition;
void main()
{
// 为了设置顶点着色器的输出,我们必须把位置数据赋值给预定义的gl_Position变量,它在幕后是vec4类型的。
// 将vPosition输入属性拷贝到名为gl_Position的特殊输出变量
// 每个顶点着色器必须在gl_Position变量中输出一个位置,这个位置传递到管线下一个阶段的位置
gl_Position = vPosition;
}
重新编译一下,三角形出来了,如下所示:
三、总结
在OpenGL ES的着色器语言的第一行,一定是#version 300 es
,不要写其他的内容,否则着色器语言会编译失败,无法显示图元。