glCheckFramebufferStatus возвращает 36054 GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT

Это просто, чтобы поделиться тем, что мне потребовалось много времени, чтобы понять. Если вам не нужен буфер глубины или у вас нет точки присоединения буфера глубины в EGL, это может помочь.

По какой-то причине я не мог заставить работать рендеринг в текстуру, устанавливая объект буфера рендеринга RBO в буфер глубины: вот так

    GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER, 
            GLES20.GL_COLOR_ATTACHMENT0, GLES20.GL_TEXTURE_2D, 
            juliaTex[0], 0);
    rain.checkGlError("glFramebufferTexture2D");
    GLES20.glFramebufferRenderbuffer(GLES20.GL_FRAMEBUFFER, 
            GLES20.GL_DEPTH_ATTACHMENT, GLES20.GL_RENDERBUFFER, 
            juliaRBO[0]);
    rain.checkGlError("glFramebufferRenderbuffer");

    int status = GLES20.glCheckFramebufferStatus(GLES20.GL_FRAMEBUFFER);

Вызывает ошибку status == GLES20.GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT

Если я изменю хранилище буфера рендеринга на GLES20.GL_RGBA4, а не на GLES20.DEPTH_COMPONENT16, и изменю GLES20.GL_DEPTH_ATTACHMENT на GLES20.GL_COLOR_ATTACHMENT0, то ошибка исчезнет,

Изменить это

    // create render buffer and bind 16-bit depth buffer
    GLES20.glBindRenderbuffer(GLES20.GL_RENDERBUFFER, juliaRBO[0]);
    rain.checkGlError("glBindRenderBuffer");
    GLES20.glRenderbufferStorage(GLES20.GL_RENDERBUFFER, GLES20.DEPTH_COMPONENT16, 
            rain.width, rain.height);

к этому

    // create render buffer and bind 16-bit depth buffer
    GLES20.glBindRenderbuffer(GLES20.GL_RENDERBUFFER, juliaRBO[0]);
    rain.checkGlError("glBindRenderBuffer");
    GLES20.glRenderbufferStorage(GLES20.GL_RENDERBUFFER, GLES20.GL_RGBA4, 
            rain.width, rain.height);

И исходный код к этому:

    GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER, 
            GLES20.GL_COLOR_ATTACHMENT0, GLES20.GL_TEXTURE_2D, 
            juliaTex[0], 0);
    rain.checkGlError("glFramebufferTexture2D");
    GLES20.glFramebufferRenderbuffer(GLES20.GL_FRAMEBUFFER, 
            GLES20.GL_COLOR_ATTACHMENT0, GLES20.GL_RENDERBUFFER, 
            juliaRBO[0]);
    rain.checkGlError("glFramebufferRenderbuffer");

затем status == GLES20.GL_FRAMEBUFFER_COMPLETE

Но текстура пустая.

вот вызов для создания текстуры хранилища

    // bind texture
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, juliaTex[0]);

    // clamp texture to edges
    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S,
            GLES20.GL_CLAMP_TO_EDGE);
    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T,
            GLES20.GL_CLAMP_TO_EDGE);
    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER,
            GLES20.GL_LINEAR);
    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER,
            GLES20.GL_LINEAR);
    rain.checkGlError("glTexParameter JuliaTex");

    // create it
    /*
    int[] buf = new int[rain.width * rain.height];
    juliaTexBuff = ByteBuffer.allocateDirect(buf.length
            * rain.FLOAT_SIZE_BYTES).order(ByteOrder.nativeOrder()).asIntBuffer();
     */
    // generate the textures
    GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, 
            rain.width, rain.height, 0, GLES20.GL_RGBA, 
            GLES20.GL_UNSIGNED_SHORT_4_4_4_4, null);

person HPP    schedule 21.01.2014    source источник


Ответы (1)


Чтобы заставить это работать в дополнение к присоединению буфера рендеринга к точке присоединения цвета, я поменял местами порядок прикрепления буфера кадра:

    GLES20.glFramebufferRenderbuffer(GLES20.GL_FRAMEBUFFER, 
            GLES20.GL_COLOR_ATTACHMENT0, GLES20.GL_RENDERBUFFER, 
            juliaRBO[0]);
    rain.checkGlError("glFramebufferRenderbuffer");
    GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER, 
            GLES20.GL_COLOR_ATTACHMENT0, GLES20.GL_TEXTURE_2D, 
            juliaTex[0], 0);
    rain.checkGlError("glFramebufferTexture2D");

Так что Texture2D прикрепляется к цветовому слою Framebuffer после Renderbuffer. Я предполагаю, что последней точкой соединения является точка, которую использует OpenGL ES.

person HPP    schedule 21.01.2014
comment
-1: в этом коде вы сделали больше, чем просто прикрепили текстуру последней. Фактически вы прикрепили буфер рендеринга к точке присоединения 0, а затем заменили это присоединение своим изображением текстуры. Это сильно отличается от того, что вы пробовали изначально. Пожалуйста, обновите свой вопрос, чтобы показать, как вы выделяете хранилище для своей текстуры и вашего буфера рендеринга, так как это почти наверняка является причиной вашей ошибки фактически. С этой текущей настройкой у вас нет буфера глубины. - person Andon M. Coleman; 21.01.2014
comment
Я не думаю, что в моей установке EGL есть точка присоединения буфера глубины. Что и вызывало ошибку. Вы, вероятно, знаете об этом намного больше, чем я, и это решение может показаться глупым, но это всего лишь обходной путь, который, вероятно, поможет большему количеству хакеров, чем возиться с точкой присоединения компонента глубины. каждому свое - person HPP; 22.01.2014
comment
Все FBO имеют точку присоединения буфера глубины, но формат и размеры изображения RBO/текстуры, которые вам разрешено прикреплять туда, могут быть очень ограничивающими. Основная проблема, которую я вижу прямо сейчас, заключается в том, что ваша текстура juliaTex [0], вероятно, не имеет тех же размеров, что и ваш RBO, поэтому я попросил посмотреть, как вы выделили память для этой текстуры. Нет смысла даже создавать/прикреплять RBO, делая то, что вы делаете прямо сейчас, потому что вы сразу привязываете что-то еще поверх RBO. - person Andon M. Coleman; 22.01.2014
comment
Статус буфера кадра возвращается неполным, если я пытаюсь обойти привязку буфера рендеринга. добавление вызова хранилища текстур - person HPP; 22.01.2014