我可以在桌面上使用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);
如果我发表评论,该程序将编译,但如果没有大量与gpu相关的错误(如下所示来自logcat),它将无法执行glDraw * Instaced调用。
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);
答案 0 :(得分:4)
您的部分location
限定符不符合300 es
着色器版本。您的顶点着色器包含以下定义:
layout (location = 0) out vec3 vPosition;
...
GLSL ES 3.00规范说:
顶点着色器不能有输出布局限定符。
此限制仅在版本3.10中解除,其中相应的措辞已更改为:
顶点和片段着色器允许在输出变量声明上使用位置布局限定符。
几乎相同的事情适用于你使用的制服:
layout (location = 0) uniform bool uInstanceRendering;
...
同样在这里,着色器版本3.00不允许layout
制服上的限定符:
布局限定符可用于统一块,但不能用于非块统一声明。
同样,此选项已在3.10版本中添加。
答案 1 :(得分:1)
我发现在顶点着色器中使用'glBindAttribLocation'代替布局限定符可以解决问题。我甚至使用了与布局限定符相同的编号方案。我想知道我是否可以只用4 vec4设置实例数据?我猜mat4会丢掉我的移动设备上的编号方案吗?