augment_renderer.cpp 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. #include "augment_renderer.h"
  2. #include "cuda_helper.hpp"
  3. #include <cuda_gl_interop.h>
  4. #include <glad/gl.h>
  5. struct augment_renderer::impl {
  6. const cv::cuda::GpuMat *bg_img = nullptr;
  7. GLuint bg_tex = 0, bg_pbo = 0;
  8. cudaGraphicsResource *bg_res = nullptr;
  9. texture_renderer *tex_renderer = nullptr;
  10. const render_config *config = nullptr;
  11. ~impl() {
  12. cudaGraphicsUnregisterResource(bg_res);
  13. }
  14. bool initialize() {
  15. // generate and allocate pixel buffer
  16. glGenBuffers(1, &bg_pbo);
  17. glBindBuffer(GL_PIXEL_UNPACK_BUFFER, bg_pbo);
  18. glBufferStorage(GL_PIXEL_UNPACK_BUFFER, rgb_image_size, nullptr, GL_DYNAMIC_STORAGE_BIT);
  19. glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
  20. // generate and allocate texture
  21. glGenTextures(1, &bg_tex);
  22. glBindTexture(GL_TEXTURE_2D, bg_tex);
  23. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  24. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  25. glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, image_width, image_height);
  26. // register background pbo
  27. CUDA_API_CHECK(cudaGraphicsGLRegisterBuffer(&bg_res, bg_pbo,
  28. cudaGraphicsRegisterFlagsWriteDiscard));
  29. return true;
  30. }
  31. bool render_background() {
  32. if (bg_img == nullptr) return true;
  33. // upload background image to pbo
  34. void *pbo_ptr;
  35. size_t pbo_size;
  36. CUDA_API_CHECK(cudaGraphicsMapResources(1, &bg_res));
  37. CUDA_API_CHECK(cudaGraphicsResourceGetMappedPointer(&pbo_ptr, &pbo_size, bg_res));
  38. assert(pbo_size == rgb_image_size);
  39. CUDA_API_CHECK(cudaMemcpy2D(pbo_ptr, rgb_image_pitch, bg_img->cudaPtr(),
  40. bg_img->step, rgb_image_pitch, image_height, cudaMemcpyDeviceToDevice));
  41. CUDA_API_CHECK(cudaGraphicsUnmapResources(1, &bg_res));
  42. // unpack pbo to texture
  43. glBindBuffer(GL_PIXEL_UNPACK_BUFFER, bg_pbo);
  44. glBindTexture(GL_TEXTURE_2D, bg_tex);
  45. glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, image_width, image_height, GL_BGR, GL_UNSIGNED_BYTE, nullptr);
  46. glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
  47. // render texture
  48. assert(tex_renderer != nullptr);
  49. assert(config != nullptr);
  50. texture_renderer::render_config tex_config{
  51. .tex = bg_tex,
  52. .x = config->x,
  53. .y = config->y,
  54. .width = config->width,
  55. .height = config->height
  56. };
  57. tex_renderer->render(&tex_config);
  58. return true;
  59. }
  60. bool render() {
  61. CALL_CHECK(render_background());
  62. return true;
  63. }
  64. };
  65. augment_renderer::augment_renderer()
  66. : pimpl(std::make_unique<impl>()) {}
  67. augment_renderer::~augment_renderer() = default;
  68. bool augment_renderer::initialize(texture_renderer *renderer) {
  69. pimpl->tex_renderer = renderer;
  70. return pimpl->initialize();
  71. }
  72. void augment_renderer::set_background(const cv::cuda::GpuMat *background) {
  73. assert(background->rows == image_height);
  74. assert(background->cols == image_width);
  75. pimpl->bg_img = background;
  76. }
  77. bool augment_renderer::render(const render_config &config) {
  78. pimpl->config = &config;
  79. return pimpl->render();
  80. }