2014-08-29 3 views
3
//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. Результат правильныйЧто не так, когда я использую Eglimage вместо glreadpixels в программе NDK?

+1

Как вам это удалось собрать и построить? NDK не включает заголовки «GraphicBuffer». Только AOSP. –

+0

Как вы загрузили изображение в текстуру? Вы могли загружать с помощью 'glTexImage2D' и загружать с помощью' memcpy' из 'GraphicBuffer'? – focs

ответ

1

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

+0

спасибо, это эффект! – Firemky

+0

@fadden Я хочу скопировать пиксель, я скопировал его из PBO, когда мобильный телефон поддерживает OpenGL es 3.0, а когда они поддерживают OpenGL es 2.0, я хочу использовать GraphicBufferAlloc в Android NDK proj. но ошибка «Ошибка:« GraphicBufferAlloc »не был объявлен в этой области», когда я компилирую файл cpp, я не знаю, какой файл заголовка нужно импортировать. Не могли бы вы помочь мне, плз? Мои файлы включают в себя следующие: #include #include #include #include #include #include #include dragonfly

+0

GraphicBuffer не является публичным классом, поэтому он не является частью NDK. Вам нужны полные источники AOSP, и, вероятно, вам придется создавать разные бинарные файлы для разных версий Android. Я не рекомендую так поступать, если только вы не нацеливаетесь на конкретное устройство/версию или не создаете пользовательскую версию ОС Android. – fadden

 Смежные вопросы

  • Нет связанных вопросов^_^