4
//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();

i do not know what is wrong with it , the memory of vaddr is wrong data,it is show nothing on the screen. but i use glTexImage2D and glReadPixels the result is right

Adi Shavit
  • 16,743
  • 5
  • 67
  • 137
Firemky
  • 163
  • 1
  • 1
  • 5
  • 1
    How did you get this to compile and build? The NDK does not include the `GraphicBuffer` headers. Only AOSP. – Adi Shavit Dec 11 '14 at 17:16
  • How did you upload the image to the texture? Were you able to upload using `glTexImage2D` and download using `memcpy` from the `GraphicBuffer`? – focs Jul 02 '15 at 16:26

1 Answers1

1

You need a glFinish() call to tell the driver to do the actual drawing. The glReadPixels() call is causing things to work because it forces the rendering to happen -- you've told the driver that you want to read the pixels back, so it pauses until rendering is complete.

fadden
  • 51,356
  • 5
  • 116
  • 166
  • @fadden I want to copy pixel, I has copied from PBO when the mobile phone support OpenGL es 3.0, and when they only support OpenGL es 2.0, I want use GraphicBufferAlloc in Android NDK proj. but I got an error "error: 'GraphicBufferAlloc' was not declared in this scope" when I compile the cpp file, I don't know which header file need import. Could u help me, plz? my include files are as follows: #include #include #include #include #include #include #include – dragonfly Dec 23 '15 at 13:38
  • GraphicBuffer is not a public class, so it isn't part of the NDK. You need the full AOSP sources, and will likely need to create different binaries for different versions of Android. I don't recommend doing things this way unless you're only targeting a specific device/version, or are creating a custom version of the Android OS. – fadden Dec 23 '15 at 15:51