当前位置:   article > 正文

GLES学习笔记---EGLImage绑定纹理_opengl ahardwarebuffer

opengl ahardwarebuffer
  1. JNIEXPORT void JNICALL Java_com_sprd_opengl_test_MyNdk_processEglImage
  2. (JNIEnv *env, jobject obj, jobject bitmap) {
  3. LOGD("processEglImage1");
  4. glUseProgram(gl_cxt.program);
  5. AndroidBitmapInfo bitmapInfo;
  6. if (AndroidBitmap_getInfo(env, bitmap, &bitmapInfo) < 0) {
  7. LOGE("AndroidBitmap_getInfo() failed ! ");
  8. return;
  9. }
  10. void *bmpPixels;
  11. LOGD("processEglImage2, format: %d, stride: %d", bitmapInfo.format, bitmapInfo.stride);
  12. AndroidBitmap_lockPixels(env, bitmap, &bmpPixels);
  13. LOGD("processEglImage3");
  14. uint32_t width = bitmapInfo.width;
  15. uint32_t height = bitmapInfo.height;
  16. AHardwareBuffer_Desc desc = {width, height, 1,
  17. AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM,
  18. AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN|AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE,
  19. width, 0 ,0};
  20. AHardwareBuffer *inBuffer;
  21. int ret = AHardwareBuffer_allocate(&desc, &inBuffer);
  22. LOGD("AHardwareBuffer_allocate ret: %d", ret);
  23. // write data>>
  24. AHardwareBuffer_Planes planes_info = {0};
  25. LOGD("AHardwareBuffer_lockPlanes E");
  26. ret = AHardwareBuffer_lockPlanes(inBuffer,
  27. AHARDWAREBUFFER_USAGE_CPU_WRITE_MASK,
  28. -1,
  29. nullptr,
  30. &planes_info);
  31. LOGD("AHardwareBuffer_lockPlanes X");
  32. if (ret != 0) {
  33. LOGE("Failed to AHardwareBuffer_lockPlanes");
  34. } else {
  35. memcpy(planes_info.planes[0].data, bmpPixels, width * height * 4);
  36. // unsigned char *pData = static_cast<unsigned char *>(planes_info.planes[0].data);
  37. // for (int i = 0; i < width * height * 4; i++) {
  38. // pData[i] = i % 255;
  39. // }
  40. ret = AHardwareBuffer_unlock(inBuffer, nullptr);
  41. if (ret != 0) {
  42. LOGE("Failed to AHardwareBuffer_unlock");
  43. }
  44. }
  45. // write data<<
  46. EGLint eglImageAttributes[] = {EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE};
  47. EGLClientBuffer cb = eglGetNativeClientBufferANDROID(inBuffer);
  48. LOGD("eglGetNativeClientBufferANDROID cb: %p", cb);
  49. EGLImageKHR eglImageHandle = eglCreateImageKHR(eglGetDisplay(EGL_DEFAULT_DISPLAY), EGL_NO_CONTEXT,
  50. EGL_NATIVE_BUFFER_ANDROID,
  51. cb,
  52. reinterpret_cast<const EGLint *>(eglImageAttributes));
  53. LOGD("eglCreateImageKHR eglImageHandle: %p", eglImageHandle);
  54. LOGD("error: %d", eglGetError());
  55. unsigned int textureId;
  56. glGenTextures(1, &textureId);
  57. glActiveTexture(GL_TEXTURE0);
  58. glBindTexture(GL_TEXTURE_2D, textureId);
  59. LOGD("glEGLImageTargetTexture2DOES E");
  60. glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, eglImageHandle);
  61. LOGD("glEGLImageTargetTexture2DOES X");
  62. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  63. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
  64. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  65. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  66. glBindTexture(GL_TEXTURE_2D, 0);
  67. AndroidBitmap_unlockPixels(env, bitmap);
  68. /*顶点 纹理*/
  69. float vertices[] = {-1.0f, -1.0f, 0.0f, 0.0f, 0.0f,
  70. -1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
  71. 1.0f, -1.0f, 0.0f, 1.0f, 0.0f,
  72. 1.0f, 1.0f, 0.0f, 1.0f, 1.0f};
  73. unsigned int indices[] = {
  74. 0, 1, 2, // first triangle
  75. 1, 2, 3 // second triangle
  76. };
  77. // optimal
  78. unsigned int VBO, EBO, VAO;
  79. glGenVertexArrays(1, &VAO);
  80. glBindVertexArray(VAO);
  81. glGenBuffers(1, &VBO);
  82. glBindBuffer(GL_ARRAY_BUFFER, VBO);
  83. glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
  84. glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
  85. glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)((0 + 3)*sizeof(float)));
  86. glEnableVertexAttribArray(0);
  87. glEnableVertexAttribArray(1);
  88. glGenBuffers(1, &EBO);
  89. glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
  90. glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
  91. glBindVertexArray(0);
  92. glBindVertexArray(VAO);
  93. glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
  94. glClear(GL_COLOR_BUFFER_BIT);
  95. unsigned int fbo;
  96. glGenFramebuffers(1, &fbo);
  97. glBindFramebuffer(GL_FRAMEBUFFER, fbo);
  98. glActiveTexture(GL_TEXTURE0);
  99. glBindTexture(GL_TEXTURE_2D, textureId);
  100. glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureId, 0);
  101. glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, (void*)0);
  102. //glBindTexture(GL_TEXTURE_2D, 0);
  103. glBindFramebuffer(GL_FRAMEBUFFER, 0);
  104. glDisableVertexAttribArray(0);
  105. glDisableVertexAttribArray(1);
  106. glBindVertexArray(0);
  107. // must, 否则读不出绘制后数据
  108. glFinish();
  109. unsigned char *ptrReader = nullptr;
  110. unsigned char *dstBuffer = static_cast<unsigned char *>(malloc(width * height * 4));
  111. LOGD("AHardwareBuffer_lock E");
  112. AHardwareBuffer_lock(inBuffer, AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN, -1, nullptr,
  113. (void **) &ptrReader);
  114. LOGD("AHardwareBuffer_lock X");
  115. memcpy(dstBuffer, ptrReader, width * height * 4);
  116. AHardwareBuffer_unlock(inBuffer, nullptr);
  117. LOGD("%d, %d, %d, %d", *dstBuffer, *(dstBuffer+1), *(dstBuffer+2), *(dstBuffer+3));
  118. eglSwapBuffers(gl_cxt.display, gl_cxt.winSurface);
  119. LOGD("X");
  120. }
 
EGLClientBuffer cb = eglGetNativeClientBufferANDROID(inBuffer);

将HardwareBuffer转换成 eglCreateImageKHR需要的格式

  1. EGLImageKHR eglImageHandle = eglCreateImageKHR(eglGetDisplay(EGL_DEFAULT_DISPLAY), EGL_NO_CONTEXT,
  2. EGL_NATIVE_BUFFER_ANDROID,
  3. cb,
  4. reinterpret_cast<const EGLint *>(eglImageAttributes));

创建EGLImage

glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, eglImageHandle);

绑定EGLImage到纹理

  1. glBindFramebuffer(GL_FRAMEBUFFER, fbo);
  2. glActiveTexture(GL_TEXTURE0);
  3. glBindTexture(GL_TEXTURE_2D, textureId);
  4. glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureId, 0);
  5. glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, (void*)0);
  6. //glBindTexture(GL_TEXTURE_2D, 0);
  7. glBindFramebuffer(GL_FRAMEBUFFER, 0);

离屏渲染,绘制到fbo对应的纹理上(不是屏幕)

  1. glFinish();
  2. unsigned char *ptrReader = nullptr;
  3. unsigned char *dstBuffer = static_cast<unsigned char *>(malloc(width * height * 4));
  4. LOGD("AHardwareBuffer_lock E");
  5. AHardwareBuffer_lock(inBuffer, AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN, -1, nullptr,
  6. (void **) &ptrReader);
  7. LOGD("AHardwareBuffer_lock X");
  8. memcpy(dstBuffer, ptrReader, width * height * 4);
  9. AHardwareBuffer_unlock(inBuffer, nullptr);

绘制完了glFinish一下,AHardwareBuffer_lock就能将绘制好的内容读出来。

为啥需要glFinish暂时还不清楚,没有glFinish的话ptrReader里面的像素值还是输入的inBuffer的值。

还有就是不清楚为啥绘制完了,绘制的结果就到了HardwareBuffer里面了,HardwareBuffer是输入啊

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/article/detail/46060
推荐阅读
相关标签
  

闽ICP备14008679号