OpenGL 着色器编译错误 Android 12 Samsung Galaxy S21
OpenGL Shader Compilation Error Android 12 Samsung Galaxy S21
我有以下顶点和片段着色器:
SimpleFragmentShader.fragmentshader:
#version 300 es
precision highp float;
out vec4 FragColor;
uniform vec4 vertexColor;
void main()
{
FragColor = vertexColor;
}
SimpleVertexShader.vertexshader:
#version 300 es
layout (location = 0) in vec3 aPos;
uniform mat4 MVP;
void main()
{
gl_Position = MVP * vec4(aPos, 1.0);
}
加载着色器的函数:
GLuint LoadShaderProgram(const char* vertex_file_path,
const char* fragment_file_path) {
// Create the shaders
GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER);
GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
// Read the Vertex Shader code from the file
std::string VertexShaderCode;
std::ifstream VertexShaderStream(vertex_file_path, std::ios::in);
CHECK(VertexShaderStream.is_open())
<< "Unable to open shader at " << vertex_file_path;
std::string Line = "";
while (getline(VertexShaderStream, Line)) VertexShaderCode += "\n" + Line;
VertexShaderStream.close();
// Read the Fragment Shader code from the file
std::string FragmentShaderCode;
std::ifstream FragmentShaderStream(fragment_file_path, std::ios::in);
if (FragmentShaderStream.is_open()) {
std::string Line = "";
while (getline(FragmentShaderStream, Line))
FragmentShaderCode += "\n" + Line;
FragmentShaderStream.close();
}
GLint Result = GL_FALSE;
int InfoLogLength;
// Compile Vertex Shader
printf("Compiling shader : %s\n", vertex_file_path);
char const* VertexSourcePointer = VertexShaderCode.c_str();
glShaderSource(VertexShaderID, 1, &VertexSourcePointer, NULL);
glCompileShader(VertexShaderID);
// Check Vertex Shader
glGetShaderiv(VertexShaderID, GL_COMPILE_STATUS, &Result);
glGetShaderiv(VertexShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
if (InfoLogLength > 0) {
std::vector<char> VertexShaderErrorMessage(InfoLogLength + 1);
glGetShaderInfoLog(VertexShaderID, InfoLogLength, NULL,
&VertexShaderErrorMessage[0]);
printf("%s\n", &VertexShaderErrorMessage[0]);
}
// Compile Fragment Shader
printf("Compiling shader : %s\n", fragment_file_path);
char const* FragmentSourcePointer = FragmentShaderCode.c_str();
glShaderSource(FragmentShaderID, 1, &FragmentSourcePointer, NULL);
glCompileShader(FragmentShaderID);
// Check Fragment Shader
glGetShaderiv(FragmentShaderID, GL_COMPILE_STATUS, &Result);
glGetShaderiv(FragmentShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
if (InfoLogLength > 0) {
std::vector<char> FragmentShaderErrorMessage(InfoLogLength + 1);
glGetShaderInfoLog(FragmentShaderID, InfoLogLength, NULL,
&FragmentShaderErrorMessage[0]);
printf("%s\n", &FragmentShaderErrorMessage[0]);
}
// Link the program
printf("Linking program\n");
GLuint ProgramID = glCreateProgram();
glAttachShader(ProgramID, VertexShaderID);
glAttachShader(ProgramID, FragmentShaderID);
glLinkProgram(ProgramID);
// Check the program
glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result);
glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength);
if (InfoLogLength > 0) {
std::vector<char> ProgramErrorMessage(InfoLogLength + 1);
glGetProgramInfoLog(ProgramID, InfoLogLength, NULL,
&ProgramErrorMessage[0]);
printf("%s\n", &ProgramErrorMessage[0]);
}
glDeleteShader(VertexShaderID);
glDeleteShader(FragmentShaderID);
return ProgramID;
}
build.gradle: targetSdkVersion 31, minSdkVersion 26
当我尝试在我的phone(三星 Galaxy S21 5G、Exynos CPU、Mali-G78 GPU、Android 12 上编译软件并运行它时),我收到以下错误:
D/native: Compiling shader : /data/user/0/app/files/shaders/SimpleVertexShader.vertexshader
D/native: 0:2: P0005: #version must be on the first line in a program and only whitespace are allowed in the declaration
Compiling shader
D/native: : /data/user/0/app/files/shaders/SimpleFragmentShader.fragmentshader
D/native: 0:2: P0005: #version must be on the first line in a program and only whitespace are allowed in the declaration
Linking program
D/native: Link failed because of invalid vertex shader.
但是,当我尝试 运行 Samsung Galaxy Tab S7(SM-T870,Snapdragon 865+)运行ning Android 12 上的相同代码时,它起作用了。
错误消息提示存在语法错误,但我认为这不是问题所在,因为该软件在 Galaxy Tab S7 上编译正常。
我在三星 Galaxy S21 phone 上尝试了不同的版本 (#version 100/200/300 es/310 es/320 es
),但代码仅在使用 #version 100
时编译。但是,官方 ARM-Homepage 指出 Galaxy S21 Mali-G78 GPU 应该支持所有这些版本。
是什么导致了这个问题?与 Snapdragon 同类产品相比,是否有任何图形驱动程序在三星设备的 Exynos 版本上缺乏 OpenGL 支持?我没有使用 Google 或 Whosebug 找到相关问题。我发现 (here and here) 三星设备上的 OpenGL 和 Android12 的唯一其他问题涉及模拟器,但在我的应用程序中并非如此。
感谢您的帮助!
如评论中所述,代码...
std::string Line = "";
while (getline(VertexShaderStream, Line))
VertexShaderCode += "\n" + Line;
在着色器源代码的开头添加一个空行VertexShaderCode
。因此,有关版本说明符丢失或放错位置的错误消息。只需将代码更改为...
std::string Line = "";
while (getline(VertexShaderStream, Line))
VertexShaderCode += Line + "\n";
并对片段着色器代码部分执行类似操作。
我有以下顶点和片段着色器:
SimpleFragmentShader.fragmentshader:
#version 300 es
precision highp float;
out vec4 FragColor;
uniform vec4 vertexColor;
void main()
{
FragColor = vertexColor;
}
SimpleVertexShader.vertexshader:
#version 300 es
layout (location = 0) in vec3 aPos;
uniform mat4 MVP;
void main()
{
gl_Position = MVP * vec4(aPos, 1.0);
}
加载着色器的函数:
GLuint LoadShaderProgram(const char* vertex_file_path,
const char* fragment_file_path) {
// Create the shaders
GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER);
GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
// Read the Vertex Shader code from the file
std::string VertexShaderCode;
std::ifstream VertexShaderStream(vertex_file_path, std::ios::in);
CHECK(VertexShaderStream.is_open())
<< "Unable to open shader at " << vertex_file_path;
std::string Line = "";
while (getline(VertexShaderStream, Line)) VertexShaderCode += "\n" + Line;
VertexShaderStream.close();
// Read the Fragment Shader code from the file
std::string FragmentShaderCode;
std::ifstream FragmentShaderStream(fragment_file_path, std::ios::in);
if (FragmentShaderStream.is_open()) {
std::string Line = "";
while (getline(FragmentShaderStream, Line))
FragmentShaderCode += "\n" + Line;
FragmentShaderStream.close();
}
GLint Result = GL_FALSE;
int InfoLogLength;
// Compile Vertex Shader
printf("Compiling shader : %s\n", vertex_file_path);
char const* VertexSourcePointer = VertexShaderCode.c_str();
glShaderSource(VertexShaderID, 1, &VertexSourcePointer, NULL);
glCompileShader(VertexShaderID);
// Check Vertex Shader
glGetShaderiv(VertexShaderID, GL_COMPILE_STATUS, &Result);
glGetShaderiv(VertexShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
if (InfoLogLength > 0) {
std::vector<char> VertexShaderErrorMessage(InfoLogLength + 1);
glGetShaderInfoLog(VertexShaderID, InfoLogLength, NULL,
&VertexShaderErrorMessage[0]);
printf("%s\n", &VertexShaderErrorMessage[0]);
}
// Compile Fragment Shader
printf("Compiling shader : %s\n", fragment_file_path);
char const* FragmentSourcePointer = FragmentShaderCode.c_str();
glShaderSource(FragmentShaderID, 1, &FragmentSourcePointer, NULL);
glCompileShader(FragmentShaderID);
// Check Fragment Shader
glGetShaderiv(FragmentShaderID, GL_COMPILE_STATUS, &Result);
glGetShaderiv(FragmentShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
if (InfoLogLength > 0) {
std::vector<char> FragmentShaderErrorMessage(InfoLogLength + 1);
glGetShaderInfoLog(FragmentShaderID, InfoLogLength, NULL,
&FragmentShaderErrorMessage[0]);
printf("%s\n", &FragmentShaderErrorMessage[0]);
}
// Link the program
printf("Linking program\n");
GLuint ProgramID = glCreateProgram();
glAttachShader(ProgramID, VertexShaderID);
glAttachShader(ProgramID, FragmentShaderID);
glLinkProgram(ProgramID);
// Check the program
glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result);
glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength);
if (InfoLogLength > 0) {
std::vector<char> ProgramErrorMessage(InfoLogLength + 1);
glGetProgramInfoLog(ProgramID, InfoLogLength, NULL,
&ProgramErrorMessage[0]);
printf("%s\n", &ProgramErrorMessage[0]);
}
glDeleteShader(VertexShaderID);
glDeleteShader(FragmentShaderID);
return ProgramID;
}
build.gradle: targetSdkVersion 31, minSdkVersion 26
当我尝试在我的phone(三星 Galaxy S21 5G、Exynos CPU、Mali-G78 GPU、Android 12 上编译软件并运行它时),我收到以下错误:
D/native: Compiling shader : /data/user/0/app/files/shaders/SimpleVertexShader.vertexshader
D/native: 0:2: P0005: #version must be on the first line in a program and only whitespace are allowed in the declaration
Compiling shader
D/native: : /data/user/0/app/files/shaders/SimpleFragmentShader.fragmentshader
D/native: 0:2: P0005: #version must be on the first line in a program and only whitespace are allowed in the declaration
Linking program
D/native: Link failed because of invalid vertex shader.
但是,当我尝试 运行 Samsung Galaxy Tab S7(SM-T870,Snapdragon 865+)运行ning Android 12 上的相同代码时,它起作用了。
错误消息提示存在语法错误,但我认为这不是问题所在,因为该软件在 Galaxy Tab S7 上编译正常。
我在三星 Galaxy S21 phone 上尝试了不同的版本 (#version 100/200/300 es/310 es/320 es
),但代码仅在使用 #version 100
时编译。但是,官方 ARM-Homepage 指出 Galaxy S21 Mali-G78 GPU 应该支持所有这些版本。
是什么导致了这个问题?与 Snapdragon 同类产品相比,是否有任何图形驱动程序在三星设备的 Exynos 版本上缺乏 OpenGL 支持?我没有使用 Google 或 Whosebug 找到相关问题。我发现 (here and here) 三星设备上的 OpenGL 和 Android12 的唯一其他问题涉及模拟器,但在我的应用程序中并非如此。
感谢您的帮助!
如评论中所述,代码...
std::string Line = "";
while (getline(VertexShaderStream, Line))
VertexShaderCode += "\n" + Line;
在着色器源代码的开头添加一个空行VertexShaderCode
。因此,有关版本说明符丢失或放错位置的错误消息。只需将代码更改为...
std::string Line = "";
while (getline(VertexShaderStream, Line))
VertexShaderCode += Line + "\n";
并对片段着色器代码部分执行类似操作。