flashsturz
flashsturz

Reputation: 13

OpenGL Shader Compilation Error Android 12 Samsung Galaxy S21

I have the following vertex and fragment shaders:

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);
}

Function to load the shaders:

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

When I try to compile the software and run it on my phone (Samsung Galaxy S21 5G, Exynos CPU, Mali-G78 GPU, Android 12), I get the following error:

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.

However, when I try to run the same code on a Samsung Galaxy Tab S7 (SM-T870, Snapdragon 865+) running Android 12, it works.

The error message hints at a syntax error, however I do not think that this is the issue since the software compiles fine on the Galaxy Tab S7.

I have tried different versions (#version 100/200/300 es/310 es/320 es) with the Samsung Galaxy S21 phone, but the code only compiled when using #version 100. However, the official ARM-Homepage states that the Galaxy S21 Mali-G78 GPU should support all these versions.

What can be causing this problem? Are there any Graphics Drivers that lack OpenGL support on Exynos Versions of Samsung Devices compared to their Snapdragon counterparts? I did not find related issues using Google or StackOverflow. The only other issue with OpenGL and Android 12 on Samsung Devices I found (here and here) were involving Emulators, which is not the case in my application.

Thank you for your help!

Upvotes: 1

Views: 866

Answers (1)

G.M.
G.M.

Reputation: 12909

As mentioned in the comment, the code...

std::string Line = "";
while (getline(VertexShaderStream, Line))
    VertexShaderCode += "\n" + Line;

adds a blank line at the beginning of the shader source VertexShaderCode. Hence the error message regarding the missing or misplaced version specifier. Just change the code to...

std::string Line = "";
while (getline(VertexShaderStream, Line))
    VertexShaderCode += Line + "\n";

and do similarly for the fragment shader code section.

Upvotes: 1

Related Questions