android - OpenGL ES 3 实例渲染失败,但在桌面上工作

标签 android c++ opengl opengl-es android-ndk

我能够在具有 GLSL 330 核心的桌面上使用实例渲染,但我无法在 Android 上运行相同的 C++ 代码(使用 SDL2 和 NDK 构建系统以及 Android Studio)。

logcat报错如下:

-18 15:49:57.264 20996-21026/package I/SDL/APP: shaders/mobile/sceneShader.frag.glsl compiled successfully
10-18 15:49:57.274 20996-21026/package I/SDL/APP: Program link failed: --From Vertex Shader:
10-18 15:49:57.274 20996-21026/packageI/SDL/APP: linker error: multiple attribute attempt to bind at same location 
10-18 15:49:57.274 20996-21026/packageI/SDL/APP: --From Fragment Shader:
10-18 15:49:57.274 20996-21026/package I/SDL/APP: linker error: multiple attribute attempt to bind at same location 

除了文件顶部的#version 行(分别指定 es 或桌面版本)外,我的桌面和移动着色器代码完全相同。

我的移动着色器代码显示在这里:

#version 300 es

precision mediump float;

// attribute data
layout (location = 0) in vec3 VertexPosition;
layout (location = 1) in vec2 VertexTexCoord;
layout (location = 2) in vec3 VertexNormal;
layout (location = 3) in mat4 InstanceTransform; // used for translating the positions of instance renders

// varying data
layout (location = 0) out vec3 vPosition;
layout (location = 1) out vec2 vTexCoord0;
layout (location = 2) out vec2 vTexCoord1;
layout (location = 3) out vec3 vTexSkyboxCoord;
layout (location = 4) out vec3 vNormal;
layout (location = 5) out vec3 vClampColor;

// uniform data
layout (location = 0) uniform bool uInstanceRendering;

layout (location = 1) uniform mat4 uModelViewMatrix;
layout (location = 2) uniform mat4 uProjectionMatrix;
layout (location = 3) uniform mat3 uNormalMatrix;

layout (location = 4) uniform vec2 uTexOffset0;
layout (location = 5) uniform vec2 uTexOffset1;

void main(void)
{
    vec4 mvPosition;

    if (uInstanceRendering)
    {
        mvPosition = uModelViewMatrix * InstanceTransform * vec4(VertexPosition, 1.0);
    }
    else
    {
        mvPosition = uModelViewMatrix * vec4(VertexPosition, 1.0);
    }

    vTexSkyboxCoord = VertexPosition; // for skybox rendering

    const float atlasRows = 6.0f;
    vTexCoord0 = (VertexTexCoord / atlasRows) + uTexOffset0;
    vTexCoord1 = (VertexTexCoord / atlasRows) + uTexOffset1;

    vPosition = mvPosition.xyz;

    vNormal = normalize(uNormalMatrix * VertexNormal);

    vClampColor = clamp(VertexPosition, 0.0, 1.0);

    gl_Position = uProjectionMatrix * mvPosition;

#ifdef GL_ES
    gl_PointSize = 10.0f;
#endif
}

在 C++ 端和 GLSL 端繁琐地使用注释之后,我将错误指出到这行代码:

mvPosition = uModelViewMatrix * InstanceTransform * vec4(VertexPosition, 1.0);

如果我将其注释掉,程序将编译但它将无法执行 glDraw*Instaced 调用而不会出现大量与 gpu 相关的错误(如下所示,来自 logcat)。

10-18 15:58:42.504 29196-29238/package W/Adreno-GSL: <gsl_ldd_control:408>: ioctl fd 49 code 0xc02c093d (IOCTL_KGSL_SUBMIT_COMMANDS) failed: errno 35 Resource deadlock would occur
10-18 15:58:42.504 29196-29238/package W/Adreno-GSL: <log_gpu_snapshot:323>: panel.gpuSnapshotPath is not set.not generating user snapshot
10-18 15:58:42.504 29196-29238/packageW/Adreno-GSL: <gsl_ldd_control:408>: ioctl fd 49 code 0xc02c093d (IOCTL_KGSL_SUBMIT_COMMANDS) failed: errno 35 Resource deadlock would occur
10-18 15:58:42.504 29196-29238/packageW/Adreno-GSL: <log_gpu_snapshot:323>: panel.gpuSnapshotPath is not set.not generating user snapshot
10-18 15:58:42.504 29196-29238/packageW/Adreno-GSL: <gsl_ldd_control:408>: ioctl fd 49 code 0xc02c093d (IOCTL_KGSL_SUBMIT_COMMANDS) failed: errno 35 Resource deadlock would occur
10-18 15:58:42.504 29196-29238/packageW/Adreno-GSL: <log_gpu_snapshot:323>: panel.gpuSnapshotPath is not set.not generating user snapshot
10-18 15:58:42.504 29196-29238/packageW/Adreno-GSL: <gsl_ldd_control:408>: ioctl fd 49 code 0xc02c093d (IOCTL_KGSL_SUBMIT_COMMANDS) failed: errno 35 Resource deadlock would occur
10-18 15:58:42.504 29196-29238/packageW/Adreno-GSL: <log_gpu_snapshot:323>: panel.gpuSnapshotPath is not set.not generating user snapshot
10-18 15:58:42.504 29196-29238/packageW/Adreno-GSL: <gsl_ldd_control:408>: ioctl fd 49 code 0xc02c093d (IOCTL_KGSL_SUBMIT_COMMANDS) failed: errno 35 Resource deadlock would occur
10-18 15:58:42.504 29196-29238/packageW/Adreno-GSL: <log_gpu_snapshot:323>: panel.gpuSnapshotPath is not set.not generating user snapshot
10-18 15:58:42.504 29196-29238/packageW/Adreno-ES20: <finish_current_fbo_rendering:315>: GL_OUT_OF_MEMORY

我做了一个简单的示例来简单地测试实例渲染,OpenGL ES 3(仍然使用 SDL)也出现了同样的问题。

#version 300 es
precision mediump float;

// attribute data
layout (location = 0) in vec3 aVertexPosition;
layout (location = 1) in vec2 aVertexTexCoord;
layout (location = 2) in vec3 aVertexNormal;
layout (location = 3) in mat4 aInstanceTransform;

// varying data
out vec3 vPosition;
out vec2 vTexCoord;
out vec3 vNormal;

// uniform data
uniform mat4 uModelViewMatrix;
uniform mat4 uProjectionMatrix;
uniform mat3 uNormalMatrix;

void main(void)
{
    vec4 mvTransform = uModelViewMatrix * aInstanceTransform * vec4(aVertexPosition, 1.0);

    vTexCoord = aVertexTexCoord;

    vPosition = mvTransform.xyz;

    vNormal = normalize(uNormalMatrix * aVertexNormal);

    gl_Position = uProjectionMatrix * mvTransform;
}

这里是我设置顶点数据的地方:

glBindBuffer(GL_ARRAY_BUFFER, mVBO_InstanceData);
glBufferData(GL_ARRAY_BUFFER, instanceData.size() * sizeof(glm::mat4), instanceData.data(), GL_STATIC_DRAW);

glEnableVertexAttribArray(3);
glVertexAttribPointer(3, 4, GL_FLOAT, GL_FALSE, sizeof(glm::mat4), reinterpret_cast<GLvoid*>(0));
glVertexAttribDivisor(3, 1); // increment instance data by 1 each iteration

glEnableVertexAttribArray(4);
glVertexAttribPointer(4, 4, GL_FLOAT, GL_FALSE, sizeof(glm::mat4), reinterpret_cast<GLvoid*>(sizeof(glm::vec4)));
glVertexAttribDivisor(4, 1);

glEnableVertexAttribArray(5);
glVertexAttribPointer(5, 4, GL_FLOAT, GL_FALSE, sizeof(glm::mat4), reinterpret_cast<GLvoid*>(2 * sizeof(glm::vec4)));
glVertexAttribDivisor(5, 1);

glEnableVertexAttribArray(6);
glVertexAttribPointer(6, 4, GL_FLOAT, GL_FALSE, sizeof(glm::mat4), reinterpret_cast<GLvoid*>(3 * sizeof(glm::vec4)));
glVertexAttribDivisor(6, 1);

最佳答案

您的某些 location 限定符不符合 300 es 着色器版本。您的顶点着色器包含这些定义:

layout (location = 0) out vec3 vPosition;
...

GLSL ES 3.00 规范说:

Vertex shaders cannot have output layout qualifiers.

这个限制在3.10版本才解除,对应的写法改为:

Vertex and fragment shaders allow location layout qualifiers on output variable declarations.

几乎同样的事情适用于你使用的制服:

layout (location = 0) uniform bool uInstanceRendering;
...

此外,着色器版本 3.00 不允许在制服上使用 layout 限定符:

Layout qualifiers can be used for uniform blocks, but not for non-block uniform declarations.

同样,这个选项是在 3.10 版本中添加的。

关于android - OpenGL ES 3 实例渲染失败,但在桌面上工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33204217/

相关文章:

java - 在android中的Socket通信中写入十六进制字符串

java - 我获得了 listView 中每个项目的 key 并将其保存到 Firebase 我想将该 key 发送到另一个 Activity ,但每次我获得相同的 key

c++ - 函数模板特化编译错误

c++ - "= default"是否允许离线实现?

c++ - 检查 Windows 7 上是否有另一个进程可识别 DPI

c++ - 了解 GLSL 统一缓冲区 block 对齐

java - 从现有模型创建 OpenCV Haar 分类器

android - 如何获取 View 在坐标中的位置?

linux - OpenGL Linux 不读取 GL_VERSION

c++ - OpenGL中VAO的目的是什么