给定一个textureId,我需要从纹理中提取像素数据。
glReadPixels 可以工作,但在某些设备上速度非常慢,即使使用 FBO/PBO 也是如此。 (在小米 5 上,为 65 毫秒,使用 PBO 时甚至更慢)。所以我决定使用
Hardwarebuffer
和eglImageKHR
,这应该会快得多。但是,我无法让它工作。屏幕变黑,没有读取任何数据。
//attach inputTexture to FBO
glBindFrameBuffer(GL_FRAMEBUFFER, fbo)
glFrameBufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureId, 0)
//allocate hardware buffer
AHardwareBuffer* buffer = nullptr;
AHardwareBuffer_Desc desc = {};
desc.width = width;
desc.height = height;
desc.layers = 1;
desc.usage = AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN | AHARDWAREBUFFER_USAGE_CPU_WRITE_NEVER
| AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT ;
desc.format = AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM;
//create eglImageKHR
EGLint eglAttributes[] = {EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE};
EGLClientBuffer clientBuffer = eglGetNativeClientBufferANDROID(buffer);
EGLImageKHR eglImageKhr = eglCreateImageKHR(eglDisplay, eglContext,
EGL_NATIVE_BUFFER_ANDROID, clientBuffer, eglAttributes);
//read pixels to hardware buffer ????
glBindTexture(GL_TEXTURE_2D, textureId);
glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, eglImageKhr);
//copy pixels into memory
void *readPtr;
AHardwareBuffer_lock(buffer, AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN, -1, nullptr, (void**)&readPtr);
memcpy(writePtr, readPtr, width * 4);
AHardwareBuffer_unlock(buffer, nullptr);
这是我使用
glReadPixels
的代码,它只能在将纹理附加到帧缓冲区后获取像素。
GLES30.glBindFramebuffer(GLES30.GL_FRAMEBUFFER, fboBuffer!![0])
GLES30.glFramebufferTexture2D(GLES30.GL_FRAMEBUFFER,
GLES30.GL_COLOR_ATTACHMENT0,
GLES30.GL_TEXTURE_2D,
inputTextureId,
0)
GLES30.glReadPixels(0, 0, width, height, GLES30.GL_RGBA, GLES30.GL_UNSIGNED_BYTE, byteBuffer)
请告诉我哪里做错了:(
//read pixels to hardware buffer ????
glBindTexture(GL_TEXTURE_2D, textureId);
glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, eglImageKhr);
这不会读取任何数据。这只是设置纹理来引用 EGLImage。如果您希望将数据复制到其中,您需要执行
glCopyTexImage2D()
或将其绑定到帧缓冲区并渲染到其中。
我有同样的问题,数据中没有读取任何内容。你的问题解决了吗?