| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139 |
- #include "render_scene_impl.h"
- #include <glm/gtc/matrix_access.hpp>
- #include <glm/gtx/transform.hpp>
- namespace render_scene_impl {
- color_image_render image_render;
- void render_image(const render_request &req) {
- using info_type = scene_render_info::image_info;
- auto info = std::get<info_type>(req.item.info);
- // TODO: color with depth has not been implemented
- assert(info.depth == nullptr);
- auto ren_conf = color_image_render::config_type{
- .flip_y = info.flip_y,
- .alpha = req.item.alpha,
- .stream = req.stream,
- };
- image_render.render_v2(info.img, ren_conf);
- }
- void render_mesh(const render_request &req) {
- using info_type = scene_render_info::mesh_info;
- auto info = std::get<info_type>(req.item.info);
- auto mesh_conf = mesh_info_type{
- .mesh = info.mesh.get(),
- .transform = req.item.transform,
- .material = info.material,
- };
- auto ren_conf = mesh_render_info{
- .mode = MESH_NORMAL,
- .model = mesh_conf,
- .camera = req.camera,
- .light= req.light,
- };
- // depth alpha
- if (info.enable_depth_alpha) {
- ren_conf.mode = MESH_DEPTH_ALPHA;
- auto &extra = ren_conf.extra.depth_alpha;
- extra.alpha_factor = info.alpha_factor;
- }
- render_mesh(ren_conf);
- }
- void render_pc(const render_request &req) {
- using info_type = scene_render_info::pc_info;
- auto info = std::get<info_type>(req.item.info);
- auto ren_conf = pc_render::config_type{
- .stream = req.stream,
- };
- ren_conf.pc = {
- .transform = req.item.transform,
- .color = info.color,
- .point_size = info.point_size,
- };
- ren_conf.camera = {
- .transform = req.camera.transform,
- .fov = req.camera_raw.fov,
- .near = req.camera_raw.near,
- .far = req.camera_raw.far,
- };
- pc_render::render(info.pc, ren_conf);
- }
- // standard camera transform matrix ->
- // OpenGL 's camera transform matrix
- glm::mat4 cvt_camera_transform(const glm::mat4 &transform) {
- static constexpr auto default_focal_length = 8.0f; // 8mm
- auto trans_part = glm::vec3(transform[3]);
- auto rot_part = glm::mat3(transform);
- auto focal_point = trans_part + rot_part[2] * default_focal_length;
- auto view_up = -rot_part[1];
- return glm::lookAt(trans_part, focal_point, view_up);
- }
- }
- glm::mat4 camera_info::projection(float aspect) const {
- return glm::perspective(glm::radians(fov), aspect, near, far);
- }
- void render_scene(const scene_ptr &info_ptr) {
- auto vp_size = query_viewport_size();
- auto &info = *info_ptr;
- auto req = render_request{
- .camera_raw = info.camera,
- .stream = info.stream,
- };
- req.camera.transform =
- cvt_camera_transform(info.camera.transform);
- req.camera.project = info.camera.projection(vp_size.aspectRatio());
- if (info.light.follow_camera) {
- req.light.direction = glm::column(info.camera.transform, 2);
- } else {
- req.light.direction = info.light.direction;
- }
- for (auto &item: info.items) {
- req.item = item;
- using info_type = std::remove_cvref_t<typeof(item.info)>;
- switch (item.info.index()) {
- case 1: {
- static_assert(std::is_same_v<std::variant_alternative_t<1, info_type>,
- scene_render_info::image_info>);
- render_image(req);
- break;
- }
- case 2: {
- static_assert(std::is_same_v<std::variant_alternative_t<2, info_type>,
- scene_render_info::mesh_info>);
- render_mesh(req);
- break;
- }
- case 3: {
- static_assert(std::is_same_v<std::variant_alternative_t<3, info_type>,
- scene_render_info::pc_info>);
- render_pc(req);
- break;
- }
- case 4: {
- static_assert(std::is_same_v<std::variant_alternative_t<4, info_type>,
- scene_render_info::custom_info>);
- std::get<4>(item.info).func();
- break;
- }
- default: {
- RET_ERROR;
- }
- }
- }
- }
|