summaryrefslogtreecommitdiff
path: root/servers/visual
diff options
context:
space:
mode:
Diffstat (limited to 'servers/visual')
-rw-r--r--servers/visual/visual_server_raster.h1
-rw-r--r--servers/visual/visual_server_scene.cpp20
-rw-r--r--servers/visual/visual_server_scene.h2
-rw-r--r--servers/visual/visual_server_viewport.cpp82
-rw-r--r--servers/visual/visual_server_viewport.h8
-rw-r--r--servers/visual/visual_server_wrap_mt.h2
6 files changed, 92 insertions, 23 deletions
diff --git a/servers/visual/visual_server_raster.h b/servers/visual/visual_server_raster.h
index 58481fc3f6..b13bb904ab 100644
--- a/servers/visual/visual_server_raster.h
+++ b/servers/visual/visual_server_raster.h
@@ -908,6 +908,7 @@ public:
BIND0R(RID, viewport_create)
+ BIND2(viewport_set_use_arvr, RID, bool)
BIND3(viewport_set_size, RID, int, int)
BIND2(viewport_set_active, RID, bool)
diff --git a/servers/visual/visual_server_scene.cpp b/servers/visual/visual_server_scene.cpp
index c383be549b..87431a2ce4 100644
--- a/servers/visual/visual_server_scene.cpp
+++ b/servers/visual/visual_server_scene.cpp
@@ -1658,6 +1658,7 @@ void VisualServerScene::_light_instance_update_shadow(Instance *p_instance, cons
}
void VisualServerScene::render_camera(RID p_camera, RID p_scenario, Size2 p_viewport_size, RID p_shadow_atlas) {
+ // render to mono camera
Camera *camera = camera_owner.getornull(p_camera);
ERR_FAIL_COND(!camera);
@@ -1697,6 +1698,25 @@ void VisualServerScene::render_camera(RID p_camera, RID p_scenario, Size2 p_view
_render_scene(camera->transform, camera_matrix, ortho, camera->env, camera->visible_layers, p_scenario, p_shadow_atlas, RID(), -1);
}
+void VisualServerScene::render_camera(Ref<ARVRInterface> &p_interface, ARVRInterface::Eyes p_eye, RID p_camera, RID p_scenario, Size2 p_viewport_size, RID p_shadow_atlas) {
+ // render for AR/VR interface
+
+ Camera *camera = camera_owner.getornull(p_camera);
+ ERR_FAIL_COND(!camera);
+
+ /* SETUP CAMERA, we are ignoring type and FOV here */
+ bool ortho = false;
+ float aspect = p_viewport_size.width / (float)p_viewport_size.height;
+ CameraMatrix camera_matrix = p_interface->get_projection_for_eye(p_eye, aspect, camera->znear, camera->zfar);
+
+ // We also ignore our camera position, it will have been positioned with a slightly old tracking position.
+ // Instead we take our origin point and have our ar/vr interface add fresh tracking data! Whoohoo!
+ Transform world_origin = ARVRServer::get_singleton()->get_world_origin();
+ Transform cam_transform = p_interface->get_transform_for_eye(p_eye, world_origin);
+
+ _render_scene(cam_transform, camera_matrix, ortho, camera->env, camera->visible_layers, p_scenario, p_shadow_atlas, RID(), -1);
+};
+
void VisualServerScene::_render_scene(const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, RID p_force_environment, uint32_t p_visible_layers, RID p_scenario, RID p_shadow_atlas, RID p_reflection_probe, int p_reflection_probe_pass) {
Scenario *scenario = scenario_owner.getornull(p_scenario);
diff --git a/servers/visual/visual_server_scene.h b/servers/visual/visual_server_scene.h
index 168dfddfd4..17b95946b3 100644
--- a/servers/visual/visual_server_scene.h
+++ b/servers/visual/visual_server_scene.h
@@ -38,6 +38,7 @@
#include "os/semaphore.h"
#include "os/thread.h"
#include "self_list.h"
+#include "servers/arvr/arvr_interface.h"
class VisualServerScene {
public:
@@ -521,6 +522,7 @@ public:
void render_empty_scene(RID p_scenario, RID p_shadow_atlas);
void render_camera(RID p_camera, RID p_scenario, Size2 p_viewport_size, RID p_shadow_atlas);
+ void render_camera(Ref<ARVRInterface> &p_interface, ARVRInterface::Eyes p_eye, RID p_camera, RID p_scenario, Size2 p_viewport_size, RID p_shadow_atlas);
void update_dirty_instances();
//probes
diff --git a/servers/visual/visual_server_viewport.cpp b/servers/visual/visual_server_viewport.cpp
index 2a37b64759..ad9dec090a 100644
--- a/servers/visual/visual_server_viewport.cpp
+++ b/servers/visual/visual_server_viewport.cpp
@@ -33,7 +33,7 @@
#include "visual_server_global.h"
#include "visual_server_scene.h"
-void VisualServerViewport::_draw_viewport(Viewport *p_viewport) {
+void VisualServerViewport::_draw_viewport(Viewport *p_viewport, ARVRInterface::Eyes p_eye) {
/* Camera should always be BEFORE any other 3D */
@@ -90,8 +90,13 @@ void VisualServerViewport::_draw_viewport(Viewport *p_viewport) {
}
if (!scenario_draw_canvas_bg && can_draw_3d) {
+ Ref<ARVRInterface> arvr_interface = ARVRServer::get_singleton()->get_primary_interface();
- VSG::scene->render_camera(p_viewport->camera, p_viewport->scenario, p_viewport->size, p_viewport->shadow_atlas);
+ if (p_viewport->use_arvr && arvr_interface.is_valid()) {
+ VSG::scene->render_camera(arvr_interface, p_eye, p_viewport->camera, p_viewport->scenario, p_viewport->size, p_viewport->shadow_atlas);
+ } else {
+ VSG::scene->render_camera(p_viewport->camera, p_viewport->scenario, p_viewport->size, p_viewport->shadow_atlas);
+ }
}
if (!p_viewport->hide_canvas) {
@@ -260,15 +265,19 @@ void VisualServerViewport::_draw_viewport(Viewport *p_viewport) {
}
void VisualServerViewport::draw_viewports() {
-
- //sort viewports
-
- //draw viewports
+ // get our arvr interface in case we need it
+ Ref<ARVRInterface> arvr_interface = ARVRServer::get_singleton()->get_primary_interface();
+ if (arvr_interface.is_valid()) {
+ // update our positioning information as late as possible...
+ arvr_interface->process();
+ }
clear_color = GLOBAL_GET("rendering/environment/default_clear_color");
+ //sort viewports
active_viewports.sort_custom<ViewportSort>();
+ //draw viewports
for (int i = 0; i < active_viewports.size(); i++) {
Viewport *vp = active_viewports[i];
@@ -286,25 +295,47 @@ void VisualServerViewport::draw_viewports() {
VSG::storage->render_target_clear_used(vp->render_target);
- VSG::rasterizer->set_current_render_target(vp->render_target);
+ if (vp->use_arvr && arvr_interface.is_valid()) {
+ // override our size, make sure it matches our required size
+ Size2 size = arvr_interface->get_recommended_render_targetsize();
+ VSG::storage->render_target_set_size(vp->render_target, size.x, size.y);
- VSG::scene_render->set_debug_draw_mode(vp->debug_draw);
- VSG::storage->render_info_begin_capture();
+ // render mono or left eye first
+ ARVRInterface::Eyes leftOrMono = arvr_interface->is_stereo() ? ARVRInterface::EYE_LEFT : ARVRInterface::EYE_MONO;
+ VSG::rasterizer->set_current_render_target(vp->render_target);
+ _draw_viewport(vp, leftOrMono);
+ arvr_interface->commit_for_eye(leftOrMono, vp->render_target, vp->viewport_to_screen_rect);
- _draw_viewport(vp);
+ // render right eye
+ if (leftOrMono == ARVRInterface::EYE_LEFT) {
+ // commit for eye may have changed the render target
+ VSG::rasterizer->set_current_render_target(vp->render_target);
- VSG::storage->render_info_end_capture();
- vp->render_info[VS::VIEWPORT_RENDER_INFO_OBJECTS_IN_FRAME] = VSG::storage->get_captured_render_info(VS::INFO_OBJECTS_IN_FRAME);
- vp->render_info[VS::VIEWPORT_RENDER_INFO_VERTICES_IN_FRAME] = VSG::storage->get_captured_render_info(VS::INFO_VERTICES_IN_FRAME);
- vp->render_info[VS::VIEWPORT_RENDER_INFO_MATERIAL_CHANGES_IN_FRAME] = VSG::storage->get_captured_render_info(VS::INFO_MATERIAL_CHANGES_IN_FRAME);
- vp->render_info[VS::VIEWPORT_RENDER_INFO_SHADER_CHANGES_IN_FRAME] = VSG::storage->get_captured_render_info(VS::INFO_SHADER_CHANGES_IN_FRAME);
- vp->render_info[VS::VIEWPORT_RENDER_INFO_SURFACE_CHANGES_IN_FRAME] = VSG::storage->get_captured_render_info(VS::INFO_SURFACE_CHANGES_IN_FRAME);
- vp->render_info[VS::VIEWPORT_RENDER_INFO_DRAW_CALLS_IN_FRAME] = VSG::storage->get_captured_render_info(VS::INFO_DRAW_CALLS_IN_FRAME);
-
- if (vp->viewport_to_screen_rect != Rect2()) {
- //copy to screen if set as such
- VSG::rasterizer->set_current_render_target(RID());
- VSG::rasterizer->blit_render_target_to_screen(vp->render_target, vp->viewport_to_screen_rect, vp->viewport_to_screen);
+ _draw_viewport(vp, ARVRInterface::EYE_RIGHT);
+ arvr_interface->commit_for_eye(ARVRInterface::EYE_RIGHT, vp->render_target, vp->viewport_to_screen_rect);
+ }
+ } else {
+ VSG::rasterizer->set_current_render_target(vp->render_target);
+
+ VSG::scene_render->set_debug_draw_mode(vp->debug_draw);
+ VSG::storage->render_info_begin_capture();
+
+ // render standard mono camera
+ _draw_viewport(vp);
+
+ VSG::storage->render_info_end_capture();
+ vp->render_info[VS::VIEWPORT_RENDER_INFO_OBJECTS_IN_FRAME] = VSG::storage->get_captured_render_info(VS::INFO_OBJECTS_IN_FRAME);
+ vp->render_info[VS::VIEWPORT_RENDER_INFO_VERTICES_IN_FRAME] = VSG::storage->get_captured_render_info(VS::INFO_VERTICES_IN_FRAME);
+ vp->render_info[VS::VIEWPORT_RENDER_INFO_MATERIAL_CHANGES_IN_FRAME] = VSG::storage->get_captured_render_info(VS::INFO_MATERIAL_CHANGES_IN_FRAME);
+ vp->render_info[VS::VIEWPORT_RENDER_INFO_SHADER_CHANGES_IN_FRAME] = VSG::storage->get_captured_render_info(VS::INFO_SHADER_CHANGES_IN_FRAME);
+ vp->render_info[VS::VIEWPORT_RENDER_INFO_SURFACE_CHANGES_IN_FRAME] = VSG::storage->get_captured_render_info(VS::INFO_SURFACE_CHANGES_IN_FRAME);
+ vp->render_info[VS::VIEWPORT_RENDER_INFO_DRAW_CALLS_IN_FRAME] = VSG::storage->get_captured_render_info(VS::INFO_DRAW_CALLS_IN_FRAME);
+
+ if (vp->viewport_to_screen_rect != Rect2()) {
+ //copy to screen if set as such
+ VSG::rasterizer->set_current_render_target(RID());
+ VSG::rasterizer->blit_render_target_to_screen(vp->render_target, vp->viewport_to_screen_rect, vp->viewport_to_screen);
+ }
}
if (vp->update_mode == VS::VIEWPORT_UPDATE_ONCE) {
@@ -329,6 +360,13 @@ RID VisualServerViewport::viewport_create() {
return rid;
}
+void VisualServerViewport::viewport_set_use_arvr(RID p_viewport, bool p_use_arvr) {
+ Viewport *viewport = viewport_owner.getornull(p_viewport);
+ ERR_FAIL_COND(!viewport);
+
+ viewport->use_arvr = p_use_arvr;
+}
+
void VisualServerViewport::viewport_set_size(RID p_viewport, int p_width, int p_height) {
ERR_FAIL_COND(p_width < 0 && p_height < 0);
diff --git a/servers/visual/visual_server_viewport.h b/servers/visual/visual_server_viewport.h
index f963ce4aa3..93227d1c31 100644
--- a/servers/visual/visual_server_viewport.h
+++ b/servers/visual/visual_server_viewport.h
@@ -32,6 +32,7 @@
#include "rasterizer.h"
#include "self_list.h"
+#include "servers/arvr/arvr_interface.h"
#include "servers/visual_server.h"
class VisualServerViewport {
@@ -44,6 +45,8 @@ public:
RID self;
RID parent;
+ bool use_arvr; /* use arvr interface to override camera positioning and projection matrices and control output */
+
Size2i size;
RID camera;
RID scenario;
@@ -107,6 +110,7 @@ public:
for (int i = 0; i < VS::VIEWPORT_RENDER_INFO_MAX; i++) {
render_info[i] = 0;
}
+ use_arvr = false;
}
};
@@ -131,11 +135,13 @@ public:
private:
Color clear_color;
- void _draw_viewport(Viewport *p_viewport);
+ void _draw_viewport(Viewport *p_viewport, ARVRInterface::Eyes p_eye = ARVRInterface::EYE_MONO);
public:
RID viewport_create();
+ void viewport_set_use_arvr(RID p_viewport, bool p_use_arvr);
+
void viewport_set_size(RID p_viewport, int p_width, int p_height);
void viewport_attach_to_screen(RID p_viewport, const Rect2 &p_rect = Rect2(), int p_screen = 0);
diff --git a/servers/visual/visual_server_wrap_mt.h b/servers/visual/visual_server_wrap_mt.h
index 4567d87706..e6ce3f6a54 100644
--- a/servers/visual/visual_server_wrap_mt.h
+++ b/servers/visual/visual_server_wrap_mt.h
@@ -344,6 +344,8 @@ public:
FUNC0R(RID, viewport_create)
+ FUNC2(viewport_set_use_arvr, RID, bool)
+
FUNC3(viewport_set_size, RID, int, int)
FUNC2(viewport_set_active, RID, bool)