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";

并对片段着色器代码部分执行类似操作。