在 OpenGL es 中编译片段着色器程序时出错,Android
Error in Compiling Fragment Shader Program in OpenGL es , Android
我是 OpenGL 的新手,今天我试图在 android OS 中为 OpenGL 的 GPGPU 使用编译一些着色器程序。
我有两个问题:
1)我只想编写片段着色器,是否也需要编写顶点着色器?
2) 我在编译着色器源代码时遇到了一些错误。
我的源代码定义为:
final String src = "#version 310 es\n" +
"uniform sampler2D texUnit;\n" +
"uniform int sequence;\n" +
"void main(void)\n" +
"{\n" +
"const vec3 DotValue = {0.299f , 0.587f , 0.114f};\n" +
"vec2 texCoord = gl_TexCoord[0].xy;\n" +
"vec4 CurrentPixelData = texture2D(texUnit, texCoord);\n" +
"float temp = CurrentPixelData.x * DotValue.x + CurrentPixelData.y * DotValue.y + CurrentPixelData.z * DotValue.z;\n" +
"vec4 result = {temp,temp,temp,CurrentPixelData.w};\n" +
"gl_FragColor = result;\n" +
"}\n";
创建着色器的代码是:
int fragment = GLES20.glCreateShader(GLES20.GL_FRAGMENT_SHADER);
GLES20.glShaderSource(fragment,src);
GLES20.glCompileShader(fragment);
int[] compiled = new int[1];
GLES20.glGetShaderiv(fragment, GLES20.GL_COMPILE_STATUS, compiled, 0); //compile[0] != 0 : compiled successfully
if (compiled[0] == 0) {
Log.e(TAG, "Could not compile shader: ");
Log.e(TAG, GLES20.glGetShaderInfoLog(fragment));
GLES20.glDeleteShader(fragment);
fragment = 0;
} else {
Log.i(TAG, "Compiled shader with source length " + src.length());
}
但是当我尝试调试我的应用程序时,logcat:
中有几个关于着色器编译的错误
0:6: L0001: Expected token ';', found '{'
0:7: L0002: Undeclared variable 'gl_TexCoord'
0:8: L0002: No matching function for call to 'texture2D'
0:9: L0002: Undeclared variable 'CurrentPixelData'
0:10: L0001: Expected token ';', found '{'
0:11: L0002: Undeclared variable 'gl_FragColor'
任何人都可以帮我看看我的代码有什么问题吗?
提前致谢。
您必须编写顶点着色器。 gl_Position 必须赋值才能创建三角形,然后是像素(片段)。
如果您正在使用纹理贴图,则需要分配一个可变变量,其中纹理坐标分配给顶点。
稍后,这些坐标会为每个片段进行插值。
最基本的顶点着色器是:
const char* simpleVertexShader=
"attribute vec4 position;"
"attribute vec4 inputTextureCoordinate;
"varying vec2 textureCoordinate;"
"void main(){"
"gl_Position = position;"
"textureCoordinate = inputTextureCoordinate.xy;"
"}";
在你的片段着色器中,你在 vec3 和 vec4 init 中有语法错误。
应该这样做:
"const vec3 DotValue = vec3(0.299 , 0.587 , 0.114);\n"
和
"vec4 result = vec4(temp,temp,temp,CurrentPixelData.w);\n"
注意浮点文字在 glsl 中不需要 'f' 后缀。
您的固定密码:
final String src = "#version 310 es\n" +
"precision highp float;"
"uniform sampler2D texUnit;\n" +
"varying vec2 textureCoordinate" +
"void main(void)\n" +
"{\n" +
"const vec3 DotValue = vec3(0.299 , 0.587 , 0.114);\n" +
"vec2 texCoord = textureCoordinate;\n" +
"vec4 CurrentPixelData = texture2D(texUnit, texCoord);\n" +
"float temp = CurrentPixelData.x * DotValue.x + CurrentPixelData.y * DotValue.y + CurrentPixelData.z * DotValue.z;\n" +
"vec4 result = vec4(temp,temp,temp,CurrentPixelData.w);\n" +
"gl_FragColor = result;\n" +
"}\n";
如果你从一个好的 openGL 教程开始,对你来说会容易得多。
祝你好运!
您确实需要顶点着色器和片段着色器。
语法错误已在您捕获的着色器编译日志中突出显示。提供更多关于它们的细节:
您需要使用构造函数语法来初始化向量:
const vec3 DotValue = vec3(0.299 , 0.587, 0.114);
gl_TexCoord
不是内置变量。您可能已经在桌面 OpenGL 的代码示例中看到过它,它曾经存在于其中。但即使在那里它也被弃用了,并且从未出现在 OpenGL ES 中。需要自己将纹理坐标传入shader
texture2D()
不是内置函数。用于采样 2D 纹理的函数在旧的 GLSL 版本中曾经这样命名,但现在以名称 texture()
:
为各种采样器类型重载
vec4 CurrentPixelData = texture(texUnit, texCoord);
看起来只是上一个错误的后续错误。
同错误一:
vec4 result = vec4(temp, temp, temp, CurrentPixelData.w);
gl_FragColor
曾经是旧 GLSL 版本中的内置变量,但现在已弃用并删除。您需要使用限定符 out
定义自己的变量,以定义用作着色器输出的变量。
我是 OpenGL 的新手,今天我试图在 android OS 中为 OpenGL 的 GPGPU 使用编译一些着色器程序。 我有两个问题: 1)我只想编写片段着色器,是否也需要编写顶点着色器? 2) 我在编译着色器源代码时遇到了一些错误。 我的源代码定义为:
final String src = "#version 310 es\n" +
"uniform sampler2D texUnit;\n" +
"uniform int sequence;\n" +
"void main(void)\n" +
"{\n" +
"const vec3 DotValue = {0.299f , 0.587f , 0.114f};\n" +
"vec2 texCoord = gl_TexCoord[0].xy;\n" +
"vec4 CurrentPixelData = texture2D(texUnit, texCoord);\n" +
"float temp = CurrentPixelData.x * DotValue.x + CurrentPixelData.y * DotValue.y + CurrentPixelData.z * DotValue.z;\n" +
"vec4 result = {temp,temp,temp,CurrentPixelData.w};\n" +
"gl_FragColor = result;\n" +
"}\n";
创建着色器的代码是:
int fragment = GLES20.glCreateShader(GLES20.GL_FRAGMENT_SHADER);
GLES20.glShaderSource(fragment,src);
GLES20.glCompileShader(fragment);
int[] compiled = new int[1];
GLES20.glGetShaderiv(fragment, GLES20.GL_COMPILE_STATUS, compiled, 0); //compile[0] != 0 : compiled successfully
if (compiled[0] == 0) {
Log.e(TAG, "Could not compile shader: ");
Log.e(TAG, GLES20.glGetShaderInfoLog(fragment));
GLES20.glDeleteShader(fragment);
fragment = 0;
} else {
Log.i(TAG, "Compiled shader with source length " + src.length());
}
但是当我尝试调试我的应用程序时,logcat:
中有几个关于着色器编译的错误 0:6: L0001: Expected token ';', found '{'
0:7: L0002: Undeclared variable 'gl_TexCoord'
0:8: L0002: No matching function for call to 'texture2D'
0:9: L0002: Undeclared variable 'CurrentPixelData'
0:10: L0001: Expected token ';', found '{'
0:11: L0002: Undeclared variable 'gl_FragColor'
任何人都可以帮我看看我的代码有什么问题吗? 提前致谢。
您必须编写顶点着色器。 gl_Position 必须赋值才能创建三角形,然后是像素(片段)。 如果您正在使用纹理贴图,则需要分配一个可变变量,其中纹理坐标分配给顶点。 稍后,这些坐标会为每个片段进行插值。 最基本的顶点着色器是:
const char* simpleVertexShader=
"attribute vec4 position;"
"attribute vec4 inputTextureCoordinate;
"varying vec2 textureCoordinate;"
"void main(){"
"gl_Position = position;"
"textureCoordinate = inputTextureCoordinate.xy;"
"}";
在你的片段着色器中,你在 vec3 和 vec4 init 中有语法错误。 应该这样做:
"const vec3 DotValue = vec3(0.299 , 0.587 , 0.114);\n"
和
"vec4 result = vec4(temp,temp,temp,CurrentPixelData.w);\n"
注意浮点文字在 glsl 中不需要 'f' 后缀。
您的固定密码:
final String src = "#version 310 es\n" +
"precision highp float;"
"uniform sampler2D texUnit;\n" +
"varying vec2 textureCoordinate" +
"void main(void)\n" +
"{\n" +
"const vec3 DotValue = vec3(0.299 , 0.587 , 0.114);\n" +
"vec2 texCoord = textureCoordinate;\n" +
"vec4 CurrentPixelData = texture2D(texUnit, texCoord);\n" +
"float temp = CurrentPixelData.x * DotValue.x + CurrentPixelData.y * DotValue.y + CurrentPixelData.z * DotValue.z;\n" +
"vec4 result = vec4(temp,temp,temp,CurrentPixelData.w);\n" +
"gl_FragColor = result;\n" +
"}\n";
如果你从一个好的 openGL 教程开始,对你来说会容易得多。
祝你好运!
您确实需要顶点着色器和片段着色器。
语法错误已在您捕获的着色器编译日志中突出显示。提供更多关于它们的细节:
您需要使用构造函数语法来初始化向量:
const vec3 DotValue = vec3(0.299 , 0.587, 0.114);
gl_TexCoord
不是内置变量。您可能已经在桌面 OpenGL 的代码示例中看到过它,它曾经存在于其中。但即使在那里它也被弃用了,并且从未出现在 OpenGL ES 中。需要自己将纹理坐标传入shader
为各种采样器类型重载texture2D()
不是内置函数。用于采样 2D 纹理的函数在旧的 GLSL 版本中曾经这样命名,但现在以名称texture()
:vec4 CurrentPixelData = texture(texUnit, texCoord);
看起来只是上一个错误的后续错误。
同错误一:
vec4 result = vec4(temp, temp, temp, CurrentPixelData.w);
gl_FragColor
曾经是旧 GLSL 版本中的内置变量,但现在已弃用并删除。您需要使用限定符out
定义自己的变量,以定义用作着色器输出的变量。