render_scene.cpp 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. #include "render_scene_impl.h"
  2. #include <glm/gtc/matrix_access.hpp>
  3. #include <glm/gtx/transform.hpp>
  4. namespace render_scene_impl {
  5. color_image_render image_render;
  6. void render_image(const render_request &req) {
  7. using info_type = scene_render_info::image_info;
  8. auto info = std::get<info_type>(req.item.info);
  9. // TODO: color with depth has not been implemented
  10. assert(info.depth == nullptr);
  11. auto ren_conf = color_image_render::config_type{
  12. .flip_y = info.flip_y,
  13. .alpha = req.item.alpha,
  14. .stream = req.stream,
  15. };
  16. image_render.render_v2(info.img, ren_conf);
  17. }
  18. void render_mesh(const render_request &req) {
  19. using info_type = scene_render_info::mesh_info;
  20. auto info = std::get<info_type>(req.item.info);
  21. auto mesh_conf = mesh_info_type{
  22. .mesh = info.mesh.get(),
  23. .transform = req.item.transform,
  24. .material = info.material,
  25. };
  26. auto ren_conf = mesh_render_info{
  27. .mode = MESH_NORMAL,
  28. .model = mesh_conf,
  29. .camera = req.camera,
  30. .light= req.light,
  31. };
  32. // depth alpha
  33. if (info.enable_depth_alpha) {
  34. ren_conf.mode = MESH_DEPTH_ALPHA;
  35. auto &extra = ren_conf.extra.depth_alpha;
  36. extra.alpha_factor = info.alpha_factor;
  37. }
  38. render_mesh(ren_conf);
  39. }
  40. void render_pc(const render_request &req) {
  41. using info_type = scene_render_info::pc_info;
  42. auto info = std::get<info_type>(req.item.info);
  43. auto ren_conf = pc_render::config_type{
  44. .stream = req.stream,
  45. };
  46. ren_conf.pc = {
  47. .transform = req.item.transform,
  48. .color = info.color,
  49. .point_size = info.point_size,
  50. };
  51. ren_conf.camera = {
  52. .transform = req.camera.transform,
  53. .fov = req.camera_raw.fov,
  54. .near = req.camera_raw.near,
  55. .far = req.camera_raw.far,
  56. };
  57. pc_render::render(info.pc, ren_conf);
  58. }
  59. // standard camera transform matrix ->
  60. // OpenGL 's camera transform matrix
  61. glm::mat4 cvt_camera_transform(const glm::mat4 &transform) {
  62. static constexpr auto default_focal_length = 8.0f; // 8mm
  63. auto trans_part = glm::vec3(transform[3]);
  64. auto rot_part = glm::mat3(transform);
  65. auto focal_point = trans_part + rot_part[2] * default_focal_length;
  66. auto view_up = -rot_part[1];
  67. return glm::lookAt(trans_part, focal_point, view_up);
  68. }
  69. }
  70. glm::mat4 camera_info::projection(float aspect) const {
  71. return glm::perspective(glm::radians(fov), aspect, near, far);
  72. }
  73. void render_scene(const scene_ptr &info_ptr) {
  74. auto vp_size = query_viewport_size();
  75. auto &info = *info_ptr;
  76. auto req = render_request{
  77. .camera_raw = info.camera,
  78. .stream = info.stream,
  79. };
  80. req.camera.transform =
  81. cvt_camera_transform(info.camera.transform);
  82. req.camera.project = info.camera.projection(vp_size.aspectRatio());
  83. if (info.light.follow_camera) {
  84. req.light.direction = glm::column(info.camera.transform, 2);
  85. } else {
  86. req.light.direction = info.light.direction;
  87. }
  88. for (auto &item: info.items) {
  89. req.item = item;
  90. using info_type = std::remove_cvref_t<typeof(item.info)>;
  91. switch (item.info.index()) {
  92. case 1: {
  93. static_assert(std::is_same_v<std::variant_alternative_t<1, info_type>,
  94. scene_render_info::image_info>);
  95. render_image(req);
  96. break;
  97. }
  98. case 2: {
  99. static_assert(std::is_same_v<std::variant_alternative_t<2, info_type>,
  100. scene_render_info::mesh_info>);
  101. render_mesh(req);
  102. break;
  103. }
  104. case 3: {
  105. static_assert(std::is_same_v<std::variant_alternative_t<3, info_type>,
  106. scene_render_info::pc_info>);
  107. render_pc(req);
  108. break;
  109. }
  110. case 4: {
  111. static_assert(std::is_same_v<std::variant_alternative_t<4, info_type>,
  112. scene_render_info::custom_info>);
  113. std::get<4>(item.info).func();
  114. break;
  115. }
  116. default: {
  117. RET_ERROR;
  118. }
  119. }
  120. }
  121. }