赞
踩
- JNIEXPORT void JNICALL Java_com_sprd_opengl_test_MyNdk_processEglImage
- (JNIEnv *env, jobject obj, jobject bitmap) {
- LOGD("processEglImage1");
- glUseProgram(gl_cxt.program);
- AndroidBitmapInfo bitmapInfo;
- if (AndroidBitmap_getInfo(env, bitmap, &bitmapInfo) < 0) {
- LOGE("AndroidBitmap_getInfo() failed ! ");
- return;
- }
- void *bmpPixels;
- LOGD("processEglImage2, format: %d, stride: %d", bitmapInfo.format, bitmapInfo.stride);
- AndroidBitmap_lockPixels(env, bitmap, &bmpPixels);
- LOGD("processEglImage3");
-
- uint32_t width = bitmapInfo.width;
- uint32_t height = bitmapInfo.height;
-
- AHardwareBuffer_Desc desc = {width, height, 1,
- AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM,
- AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN|AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE,
- width, 0 ,0};
- AHardwareBuffer *inBuffer;
- int ret = AHardwareBuffer_allocate(&desc, &inBuffer);
- LOGD("AHardwareBuffer_allocate ret: %d", ret);
-
- // write data>>
- AHardwareBuffer_Planes planes_info = {0};
- LOGD("AHardwareBuffer_lockPlanes E");
- ret = AHardwareBuffer_lockPlanes(inBuffer,
- AHARDWAREBUFFER_USAGE_CPU_WRITE_MASK,
- -1,
- nullptr,
- &planes_info);
- LOGD("AHardwareBuffer_lockPlanes X");
- if (ret != 0) {
- LOGE("Failed to AHardwareBuffer_lockPlanes");
- } else {
- memcpy(planes_info.planes[0].data, bmpPixels, width * height * 4);
- // unsigned char *pData = static_cast<unsigned char *>(planes_info.planes[0].data);
- // for (int i = 0; i < width * height * 4; i++) {
- // pData[i] = i % 255;
- // }
- ret = AHardwareBuffer_unlock(inBuffer, nullptr);
- if (ret != 0) {
- LOGE("Failed to AHardwareBuffer_unlock");
- }
- }
- // write data<<
-
- EGLint eglImageAttributes[] = {EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE};
-
- EGLClientBuffer cb = eglGetNativeClientBufferANDROID(inBuffer);
- LOGD("eglGetNativeClientBufferANDROID cb: %p", cb);
- EGLImageKHR eglImageHandle = eglCreateImageKHR(eglGetDisplay(EGL_DEFAULT_DISPLAY), EGL_NO_CONTEXT,
- EGL_NATIVE_BUFFER_ANDROID,
- cb,
- reinterpret_cast<const EGLint *>(eglImageAttributes));
- LOGD("eglCreateImageKHR eglImageHandle: %p", eglImageHandle);
- LOGD("error: %d", eglGetError());
-
- unsigned int textureId;
- glGenTextures(1, &textureId);
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, textureId);
-
- LOGD("glEGLImageTargetTexture2DOES E");
- glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, eglImageHandle);
- LOGD("glEGLImageTargetTexture2DOES X");
-
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-
- glBindTexture(GL_TEXTURE_2D, 0);
-
- AndroidBitmap_unlockPixels(env, bitmap);
-
- /*顶点 纹理*/
- float vertices[] = {-1.0f, -1.0f, 0.0f, 0.0f, 0.0f,
- -1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
- 1.0f, -1.0f, 0.0f, 1.0f, 0.0f,
- 1.0f, 1.0f, 0.0f, 1.0f, 1.0f};
-
- unsigned int indices[] = {
- 0, 1, 2, // first triangle
- 1, 2, 3 // second triangle
- };
-
- // optimal
- unsigned int VBO, EBO, VAO;
- glGenVertexArrays(1, &VAO);
- glBindVertexArray(VAO);
-
- glGenBuffers(1, &VBO);
- glBindBuffer(GL_ARRAY_BUFFER, VBO);
- glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
-
- glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
- glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)((0 + 3)*sizeof(float)));
- glEnableVertexAttribArray(0);
- glEnableVertexAttribArray(1);
-
- glGenBuffers(1, &EBO);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
- glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
-
- glBindVertexArray(0);
-
-
- glBindVertexArray(VAO);
- glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
- glClear(GL_COLOR_BUFFER_BIT);
-
- unsigned int fbo;
- glGenFramebuffers(1, &fbo);
- glBindFramebuffer(GL_FRAMEBUFFER, fbo);
-
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, textureId);
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureId, 0);
-
- glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, (void*)0);
- //glBindTexture(GL_TEXTURE_2D, 0);
- glBindFramebuffer(GL_FRAMEBUFFER, 0);
-
- glDisableVertexAttribArray(0);
- glDisableVertexAttribArray(1);
- glBindVertexArray(0);
-
- // must, 否则读不出绘制后数据
- glFinish();
- unsigned char *ptrReader = nullptr;
- unsigned char *dstBuffer = static_cast<unsigned char *>(malloc(width * height * 4));
- LOGD("AHardwareBuffer_lock E");
- AHardwareBuffer_lock(inBuffer, AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN, -1, nullptr,
- (void **) &ptrReader);
- LOGD("AHardwareBuffer_lock X");
- memcpy(dstBuffer, ptrReader, width * height * 4);
- AHardwareBuffer_unlock(inBuffer, nullptr);
- LOGD("%d, %d, %d, %d", *dstBuffer, *(dstBuffer+1), *(dstBuffer+2), *(dstBuffer+3));
-
- eglSwapBuffers(gl_cxt.display, gl_cxt.winSurface);
-
- LOGD("X");
- }

EGLClientBuffer cb = eglGetNativeClientBufferANDROID(inBuffer);
将HardwareBuffer转换成 eglCreateImageKHR需要的格式
- EGLImageKHR eglImageHandle = eglCreateImageKHR(eglGetDisplay(EGL_DEFAULT_DISPLAY), EGL_NO_CONTEXT,
- EGL_NATIVE_BUFFER_ANDROID,
- cb,
- reinterpret_cast<const EGLint *>(eglImageAttributes));
创建EGLImage
glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, eglImageHandle);
绑定EGLImage到纹理
- glBindFramebuffer(GL_FRAMEBUFFER, fbo);
-
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, textureId);
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureId, 0);
-
- glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, (void*)0);
- //glBindTexture(GL_TEXTURE_2D, 0);
- glBindFramebuffer(GL_FRAMEBUFFER, 0);
离屏渲染,绘制到fbo对应的纹理上(不是屏幕)
- glFinish();
- unsigned char *ptrReader = nullptr;
- unsigned char *dstBuffer = static_cast<unsigned char *>(malloc(width * height * 4));
- LOGD("AHardwareBuffer_lock E");
- AHardwareBuffer_lock(inBuffer, AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN, -1, nullptr,
- (void **) &ptrReader);
- LOGD("AHardwareBuffer_lock X");
- memcpy(dstBuffer, ptrReader, width * height * 4);
- AHardwareBuffer_unlock(inBuffer, nullptr);
绘制完了glFinish一下,AHardwareBuffer_lock就能将绘制好的内容读出来。
为啥需要glFinish暂时还不清楚,没有glFinish的话ptrReader里面的像素值还是输入的inBuffer的值。
还有就是不清楚为啥绘制完了,绘制的结果就到了HardwareBuffer里面了,HardwareBuffer是输入啊
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。