2014-08-29 189 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替換NDK程序中的glreadpixels時出現什麼問題?

+1

你是如何得到這個編譯和構建的? NDK不包含'GraphicBuffer'頭文件。只有AOSP。 – 2014-12-11 17:16:10

+0

你是如何將圖像上傳到紋理的?您是否可以使用'glTexImage2D'上傳並使用'GraphicBuffer'中的'memcpy'下載? – focs 2015-07-02 16:26:40

回答

1

您需要調用glFinish()告訴驅動程序進行實際繪圖。調用glReadPixels()會導致事情發揮作用,因爲它會強制渲染 - 您已經告訴驅動程序您想要讀回像素,因此它會暫停,直到渲染完成。

+0

謝謝,它是效果! – Firemky 2014-08-30 01:08:43

+0

@fadden 我想複製像素,當手機支持OpenGL ES 3.0時,我從PBO複製過來,當他們只支持OpenGL ES 2.0時,我想在Android NDK proj中使用GraphicBufferAlloc。 但我得到一個錯誤「錯誤:'GraphicBufferAlloc'沒有在此範圍內聲明」當我編譯cpp文件時,我不知道哪個頭文件需要導入。 你能幫我嗎? 我的包括文件如下: 的#include 的#include 的#include 的#include 的#include 的#include 的#include dragonfly 2015-12-23 13:38:43

+0

GraphicBuffer不是公共類,所以它不是NDK的一部分。您需要完整的AOSP資源,並且可能需要爲不同版本的Android創建不同的二進制文件。我不建議這樣做,除非你只針對特定的設備/版本,或者正在創建一個定製版本的Android操作系統。 – fadden 2015-12-23 15:51:32

相關問題