что не так, когда я использую Eglimage вместо glreadpixels в программе NDK?

//step 2. Create the Android Graphic Buffer
GraphicBuffer* buffer = new GraphicBuffer(w, h,
   HAL_PIXEL_FORMAT_RGBA_8888,
   GraphicBuffer::USAGE_HW_TEXTURE |
   GraphicBuffer::USAGE_HW_2D |
   GRALLOC_USAGE_SW_READ_OFTEN |
   GRALLOC_USAGE_SW_WRITE_OFTEN);
// Init the buffer
status_t err = buffer->initCheck();
if (err != NO_ERROR)
{
  LOGE("Error: %s\n", strerror(-err));
  return ;
}

// Retrieve andorid native buffer
android_native_buffer_t* anb = buffer->getNativeBuffer();

//step 3. Create the EGLImage
const EGLint attrs[] = {
   EGL_IMAGE_PRESERVED_KHR, EGL_TRUE,
   EGL_NONE, EGL_NONE
};
EGLImageKHR pEGLImage = _eglCreateImageKHR(eglGetCurrentDisplay(), EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID, (EGLClientBuffer)anb, attrs);
if (pEGLImage == EGL_NO_IMAGE_KHR) {
  EGLint error = eglGetError();
  LOGE("Error (%#x): Creating EGLImageKHR at %s:%i\n", error, __FILE__, __LINE__);
}

// Create GL texture, bind to GL_TEXTURE_2D, etc.
GLuint texture, renderBuffer, frameBuffer;
    printGLString("Version", GL_VERSION);
    printGLString("Vendor", GL_VENDOR);
    printGLString("Renderer", GL_RENDERER);

    //lglActiveTexture(GL_TEXTURE0);
    glGenTextures(1, &texture);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    LOG_INFO("Input Image Texture id %d\n", texture);
    glBindTexture(GL_TEXTURE_2D, texture);

    //glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);

// Attach the EGLImage to whatever texture is bound to GL_TEXTURE_2D
    _glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, pEGLImage);
    LOGE("glEGLImageTargetTexture2DOES");



    glGenFramebuffers(1, &frameBuffer);
    glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);

    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,texture, 0);
    if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
        glDeleteTextures(1, &texture);
        glDeleteFramebuffers(1, &frameBuffer);
        glDeleteRenderbuffers(1, &renderBuffer);
        LOG_ERROR("Image Handler initImageFBO failed!\n");
        return;
    }
    glViewport(0, 0, w, h);

    ////////////////////////////////////
    GLuint vsh, fsh, program;
    vsh = glCreateShader(GL_VERTEX_SHADER);
    fsh = glCreateShader(GL_FRAGMENT_SHADER);
    program = glCreateProgram();
    glShaderSource(vsh, 1, (const GLchar**)&g_defaultVertexShaderString, NULL);
    glShaderSource(fsh, 1, (const GLchar**)&g_defaultFragmentShaderString, NULL);
    glCompileShader(vsh);
    glCompileShader(fsh);
    glAttachShader(program, vsh);
    glAttachShader(program, fsh);
    glLinkProgram(program);
    glDeleteShader(vsh);
    glDeleteShader(fsh);
    glUseProgram(program);
    GLuint vPosition = glGetAttribLocation(program, "vPosition");
    checkGLError("glGetAttribLocation");
    LOG_INFO("glGetAttribLocation(\"vPosition\") = %d\n", vPosition);
    glVertexAttribPointer(vPosition, 2, GL_FLOAT, GL_FALSE, 0, g_vertices);
    glEnableVertexAttribArray(vPosition);
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);


//glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, row);



void* vaddr = NULL;
buffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN, &vaddr);
if(vaddr)
{
    memcpy(row, vaddr, w * h * 4);
    LOGE("copy memory");
}
buffer->unlock();

я не знаю, что с ним не так, память vaddr - это неправильные данные, на экране ничего не отображается. но я использую glTexImage2D и glReadPixels, результат правильный


person Firemky    schedule 29.08.2014    source источник
comment
Как вы заставили это скомпилировать и построить? NDK не включает заголовки GraphicBuffer. Только АОСП.   -  person Adi Shavit    schedule 11.12.2014
comment
Как вы загрузили изображение в текстуру? Удалось ли вам загрузить с помощью glTexImage2D и загрузить с помощью memcpy из GraphicBuffer?   -  person focs    schedule 02.07.2015


Ответы (1)


Вам нужен вызов glFinish(), чтобы сказать драйверу, чтобы он сделал фактическое рисование. Вызов glReadPixels() заставляет вещи работать, потому что он заставляет рендеринг произойти — вы сказали драйверу, что хотите прочитать пиксели обратно, поэтому он приостанавливается до завершения рендеринга.

person fadden    schedule 29.08.2014
comment
@fadden Я хочу скопировать пиксель, я скопировал из PBO, когда мобильный телефон поддерживает OpenGL es 3.0, и когда они поддерживают только OpenGL es 2.0, я хочу использовать GraphicBufferAlloc в Android NDK proj. но я получил сообщение об ошибке: «GraphicBufferAlloc» не был объявлен в этой области, когда я компилирую файл cpp, я не знаю, какой файл заголовка нужно импортировать. Не могли бы вы мне помочь, плз? мои включаемые файлы выглядят следующим образом: ‹GLES2/gl2.h› #include ‹GLES2/gl2ext.h› - person dragonfly; 23.12.2015
comment
GraphicBuffer не является общедоступным классом, поэтому он не является частью NDK. Вам нужны полные исходные коды AOSP, и, вероятно, вам потребуется создать разные двоичные файлы для разных версий Android. Я не рекомендую делать что-то таким образом, если только вы не ориентируетесь только на конкретное устройство/версию или создаете пользовательскую версию ОС Android. - person fadden; 23.12.2015