После вызова glLinkProgram приложение зависает

ОБНОВЛЕНО. Я пытаюсь нарисовать текстуру с помощью openGL ES3 и использовать инстансное рисование для своего приложения для рисования. Это мой вершинный шейдер

#version 300 es
precision highp float;

uniform mat3 u_Matrix;

in vec2 Position;
in vec2 TexPosition;

struct Data {
    vec2 pos;
    vec2 scale;
    uint color;
    float rotation;
};

layout(std140) uniform InstanceData {
    Data data[256];
};

out vec4 v_Color;
out vec2 v_TexPosition;

void main() {
vec2 endPos = Position * data[gl_InstanceID].scale;
if (data[gl_InstanceID].rotation != 0.0) {
    float cos = cos(data[gl_InstanceID].rotation);
    float sin = sin(data[gl_InstanceID].rotation);


    endPos = vec2(endPos.x * cos - endPos.y * sin, endPos.x * sin + 

    endPos.y * cos) + data[gl_InstanceID].pos;
    } else {
        endPos = endPos + data[gl_InstanceID].pos;
    }

    uint fColor = data[gl_InstanceID].color;
    v_Color.r = float((fColor & 0x00FF0000U) >> 16) / 255.0;
    v_Color.g = float((fColor & 0x0000FF00U) >> 8) / 255.0;
    v_Color.b = float(fColor & 0x000000FFU) / 255.0;
    v_Color.a = float((fColor & 0xFF000000U) >> 24) / 255.0;

    v_TexPosition = TexPosition;
    gl_Position = vec4(u_Matrix * vec3(endPos, 1.0), 1.0);
}

а это мой fragment_shader

#version 300 es
precision highp float;

in vec2 v_TexPosition;
in vec4 v_Color;

uniform sampler2D u_Texture2D;

out vec4 fragColor;

void main() {
    vec4 color = texture(u_Texture2D, v_TexPosition);
    fragColor = vec4(v_Color.rgb, color.a * v_Color.a);
}

Когда я создал программу, прикрепил шейдеры и пытаюсь связать программу, приложение зависает на строке glLinkProgram. Шейдеры и программа имеют нормальный id.

Это нормально работает на некоторых устройствах (sony xperia Z-android 5.0, smasung s7 edge android 7, nexus 5x - android 7, nexus 6p - android 7), но это не работает на других устройствах (motX-android 5.1, smasung с5 андроид 6.0). Все устройства имеют версию Android выше 5.0, и в коде я проверил поддержку opengl ES3.

Есть ли для этого какая-то причина? Это с устройства (как это проверить)? или я что-то не так сделал? Я передал данные в instanceBuffer следующим образом:

instanceBuffer.putFloat(posX);
instanceBuffer.putFloat(posY);
instanceBuffer.putFloat(scaleX);
instanceBuffer.putFloat(scaleY);
instanceBuffer.putInt(colorARGB);
instanceBuffer.putFloat((float) Math.toRadians(rotate));
instanceBuffer.position(instanceBuffer.position() + 8);

используется +8 смещений, потому что элементы чтения данных структуры имеют размер vec4 (16 байт)

Когда я пишу свою структуру только с одним vec4 :

struct Data {
    vec4 posAndScale;
};

и передать данные:

instanceBuffer.putFloat(posX);
instanceBuffer.putFloat(posY);
instanceBuffer.putFloat(scaleX);
instanceBuffer.putFloat(scaleY);

Это работает на всех устройствах, но когда я добавил еще один vec4 :

struct Data {
    vec4 posAndScale;
    vec4 color;
};

и передать данные

instanceBuffer.putFloat(posX);
instanceBuffer.putFloat(posY);
instanceBuffer.putFloat(scaleX);
instanceBuffer.putFloat(scaleY);
instanceBuffer.putFloat(color.r);
instanceBuffer.putFloat(color.g);
instanceBuffer.putFloat(color.b);
instanceBuffer.putFloat(color.a);

приложение не зависает, но ничего не происходит, когда я пытаюсь рисовать. Похоже, что на некоторых устройствах std140 работает по-другому или данные не передаются в шейдер при написании структуры с 2 vec4-s


person Levon Vardanyan    schedule 02.05.2017    source источник
comment
Есть ли пробел перед #version ? Это может вызвать ошибку на некоторых устройствах...   -  person andras    schedule 02.05.2017
comment
Нет, где-то нет лишних пробелов   -  person Levon Vardanyan    schedule 02.05.2017
comment
Что на самом деле висит? Вы упоминаете как glLinkProgram, так и instanceBuffer.putFloat, но, по-видимому, ваше приложение не должно даже доходить до instanceBuffer.putFloat, если программе не удалось связать...   -  person solidpixel    schedule 03.05.2017
comment
@solidpixel, вы правы, если приложение зависает в приложении glLinkProgram, оно не попадает в instanceBuffer.putFloat. Но когда я удалил float и uint из структуры, он попал в instnaceBuffer.   -  person Levon Vardanyan    schedule 04.05.2017
comment
Зависание компоновщика просто выглядит как ошибка в драйвере; драйвера никогда не должны просто так зависать...   -  person solidpixel    schedule 04.05.2017


Ответы (2)


Хорошо, я нашел какое-то решение. Это работает нормально, начиная с версии OpenGL 3.1. Я думаю, что версия 3.0 не поддерживает данные структуры, содержащие элементы с плавающей запятой или целое число.

person Levon Vardanyan    schedule 03.05.2017
comment
Зависание при связывании указывает на использование объекта opengl, который не был успешно создан или находится в недопустимом состоянии. Проверяли ли вы компиляцию и другие ошибки для всех созданных вами объектов? - person t.niese; 03.05.2017
comment
Да, проверил, ошибок нет, до строки glLinkProgram доходит нормально, ошибок нет. - person Levon Vardanyan; 04.05.2017

Я столкнулся с той же проблемой. Nexus 7 (2013) зависал, когда я вызывал gllinkprogram(). Я обнаружил, что это происходит только тогда, когда в моем шейдере есть операторы if. Я смог изменить оба моих оператора «если» на «условные операторы», и это сработало.

Например. (конд.)? конд1:конд2

person android    schedule 17.01.2018