我的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.02D纹理3D纹理处理分别使用texture2Dtexture3D方法,而在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版本

3.2 GLSL 2.0中attribute和varying、uniform等属性到 GLSL 3.0的改变

  • 关于attribute的变化
    OpenGL ES 3.0中将OpenGL ES 2.0attribute改成了in

  • 关于varying的变化

    • 顶点着色器的varying改成out
    • 片段着色器的varying改成了in,也就是说顶点着色器的输出就是片段着色器的输入
  • 关于uniform的变化
    uniformOpenGL 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.02D纹理3D纹理处理分别使用texture2Dtexture3D方法

  • 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

我的OpenGL学习进阶之旅着色器和程序(下)------ 程序对象