我的OpenGL学习进阶之旅解决着色器运行报错:ERROR: 0:32: ‘texture2D‘ : type is for Vulkan api only
Posted 欧阳鹏
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了我的OpenGL学习进阶之旅解决着色器运行报错:ERROR: 0:32: ‘texture2D‘ : type is for Vulkan api only相关的知识,希望对你有一定的参考价值。
一、问题描述
在将一份OpenGL ES的片段着色器从 GLSL 2.0 改成 GLSL 3.0语法的时候,编译完之后运行,报错了,如下所示:
2021-11-28 17:13:18.898 14115-14199/com.oyp.openglesdemo I/AdrenoGLES-0: ERROR: 0:32: 'texture2D' : type is for Vulkan api only
ERROR: 0:32: 'texture2D' : cannot construct this type
ERROR: 0:32: 'constructor' : too many arguments
ERROR: 0:32: 'assign' : cannot convert from 'float' to 'fragout 4-component vector of float'
ERROR: 4 compilation errors. No code generated.
2021-11-28 17:13:18.899 14115-14199/com.oyp.openglesdemo E/NDK_JNI_LOG_TAG: [GLUtils.cpp][loadShader][121]: GLUtils::loadShader error compiling shader:
ERROR: 0:32: 'texture2D' : type is for Vulkan api only
ERROR: 0:32: 'texture2D' : cannot construct this type
ERROR: 0:32: 'constructor' : too many arguments
ERROR: 0:32: 'assign' : cannot convert from 'float' to 'fragout 4-component vector of float'
ERROR: 4 compilation errors. No code generated.
二、分析错误
2.1 错误代码如下:
#version 300 es
precision mediump float; // Set the default precision to medium. We don't need as high of a
// precision in the fragment shader.
uniform vec3 u_LightPos; // The position of the light in eye space.
uniform sampler2D u_Texture; // The input texture.
in vec3 v_Position; // Interpolated position for this fragment.
in vec3 v_Normal; // Interpolated normal for this fragment.
in vec2 v_TexCoordinate; // Interpolated texture coordinate per fragment.
out vec4 v_Color;
// The entry point for our fragment shader.
void main()
// Will be used for attenuation.
float distance = length(u_LightPos - v_Position);
// Get a lighting direction vector from the light to the vertex.
vec3 lightVector = normalize(u_LightPos - v_Position);
// Calculate the dot product of the light vector and vertex normal. If the normal and light vector are
// pointing in the same direction then it will get max illumination.
float diffuse = max(dot(v_Normal, lightVector), 0.0);
// Add attenuation.
diffuse = diffuse * (1.0 / (1.0 + (0.25 * distance)));
// Add ambient lighting
diffuse = diffuse + 0.7;
// Multiply the color by the diffuse illumination level and texture value to get final output color.
v_Color = (diffuse * texture2D(u_Texture, v_TexCoordinate));
2.2 错误原因
GLSL 3.0
中将纹理的处理方法统一为texture
在GLSL 2.0
中2D纹理
和3D纹理
处理分别使用texture2D
和texture3D
方法,而在GLSL 3.0
后使用texture
统一处理。
2.3 修改
我们将texture2D
改成 texture
即可。
#version 300 es
precision mediump float; // Set the default precision to medium. We don't need as high of a
// precision in the fragment shader.
uniform vec3 u_LightPos; // The position of the light in eye space.
uniform sampler2D u_Texture; // The input texture.
in vec3 v_Position; // Interpolated position for this fragment.
in vec3 v_Normal; // Interpolated normal for this fragment.
in vec2 v_TexCoordinate; // Interpolated texture coordinate per fragment.
out vec4 v_Color;
// The entry point for our fragment shader.
void main()
// Will be used for attenuation.
float distance = length(u_LightPos - v_Position);
// Get a lighting direction vector from the light to the vertex.
vec3 lightVector = normalize(u_LightPos - v_Position);
// Calculate the dot product of the light vector and vertex normal. If the normal and light vector are
// pointing in the same direction then it will get max illumination.
float diffuse = max(dot(v_Normal, lightVector), 0.0);
// Add attenuation.
diffuse = diffuse * (1.0 / (1.0 + (0.25 * distance)));
// Add ambient lighting
diffuse = diffuse + 0.7;
// Multiply the color by the diffuse illumination level and texture value to get final output color.
v_Color = (diffuse * texture(u_Texture, v_TexCoordinate));
三、OpenGLES从2.0到3.0的变化
3.1 没有在着色器文件中标明使用版本的时候默认使用2.0版本。
在上面的着色器文件中添加#version 300 es
即表明使用GLSL 3.0
版本,如果不添加则使用默认GLSL 2.0
版本
- 注意此行必须放在第一行,如果不这样会报错,参考博客: 【我的OpenGL学习进阶之旅】解决着色器编译错误:#version directive must occur on the first line of the shader
- 同时注意使用3.0的api的时候必须添加此行。
3.2 GLSL 2.0
中attribute和varying、uniform等属性到 GLSL 3.0
的改变
-
关于
attribute
的变化
OpenGL ES 3.0
中将OpenGL ES 2.0
的attribute
改成了in
-
关于
varying
的变化- 顶点着色器的
varying
改成out
- 片段着色器的
varying
改成了in
,也就是说顶点着色器的输出就是片段着色器的输入。
- 顶点着色器的
-
关于
uniform
的变化
uniform
跟OpenGL ES 2.0
用法一样。
3.3 OpenGL ES 3.0中使用内置参数gl_FragColor会出问题
在 GLSL 2.0
这样定义一个片段着色器
precision mediump float;
void main()
// 白色
gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
那么在 GLSL 3.0
得这样定义一个片段着色器,只能自定义颜色向量out vec4 vFragColor;
#version 300 es
precision mediump float;
out vec4 vFragColor;
void main()
// 白色
vFragColor= vec4(1.0, 1.0, 1.0, 1.0);
3.4 GLSL 3.0
中将GL_OES_EGL_image_external变为了GL_OES_EGL_image_external_essl3
在使用纹理扩展的时候,也就是uniform samplerExternalOES sTexture
的时候。
在GLSL 3.0
中我们使用GL_OES_EGL_image_external_essl3
而不是GL_OES_EGL_image_external
。
3.5 GLSL 3.0
中将纹理的处理方法统一为texture
-
GLSL 2.0
中将纹理的处理方法
GLSL 2.0
中2D纹理
和3D纹理
处理分别使用texture2D
和texture3D
方法 -
GLSL 3.0
中将纹理的处理方法
GLSL 3.0
后使用texture
统一处理。
3.6 in或者out变量等不能在函数内(如main函数内)声明
3.7 GLSL 3.0
中可以加上 类似 layout(location = n)
的方式直接定位
在 GLSL 2.0
这样定义一个顶点着色器的片段
attribute vec4 a_Position; // Per-vertex position information we will pass in.
attribute vec3 a_Normal; // Per-vertex normal information we will pass in.
attribute vec2 a_TexCoordinate; // Per-vertex texture coordinate information we will pass in.
然后需要在程序中,通过glGetAttribLocation
来找到位置
mPositionHandle = glGetAttribLocation(mProgram, "a_Position");
mNormalHandle = glGetAttribLocation(mProgram, "a_Normal");
mTextureCoordinateHandle = glGetAttribLocation(mProgram, "a_TexCoordinate");
在 GLSL 3.0
这样定义一个顶点着色器的片段
layout(location = 0) in vec4 a_Position; // Per-vertex position information we will pass in.
layout(location = 1) in vec3 a_Normal; // Per-vertex normal information we will pass in.
layout(location = 2) in vec2 a_TexCoordinate; // Per-vertex texture coordinate information we will pass in.
还有一些其他的变化,这里暂不细说。后面再补充。
以上是关于我的OpenGL学习进阶之旅解决着色器运行报错:ERROR: 0:32: ‘texture2D‘ : type is for Vulkan api only的主要内容,如果未能解决你的问题,请参考以下文章
我的OpenGL学习进阶之旅解决着色器语法错误:ERROR: 0:36: ‘*‘ : wrong operand types no operation ‘*‘ exists
我的OpenGL学习进阶之旅着色器GLSL运行时报错: ERROR: 0:40: ‘gl_FragColor‘ : undeclared identifier
我的OpenGL学习进阶之旅着色器GLSL运行时报错: ERROR: 0:40: ‘gl_FragColor‘ : undeclared identifier
我的OpenGL学习进阶之旅着色器GLSL运行时报错 GLSL compile error: Premature end of line
我的OpenGL学习进阶之旅着色器GLSL运行时报错 GLSL compile error: Premature end of line