diff options
Diffstat (limited to 'servers/visual/visual_server_viewport.cpp')
-rw-r--r-- | servers/visual/visual_server_viewport.cpp | 193 |
1 files changed, 96 insertions, 97 deletions
diff --git a/servers/visual/visual_server_viewport.cpp b/servers/visual/visual_server_viewport.cpp index df9cef20f9..30fdef9325 100644 --- a/servers/visual/visual_server_viewport.cpp +++ b/servers/visual/visual_server_viewport.cpp @@ -63,16 +63,20 @@ static Transform2D _canvas_get_transform(VisualServerViewport::Viewport *p_viewp } void VisualServerViewport::_draw_3d(Viewport *p_viewport, ARVRInterface::Eyes p_eye) { + + RENDER_TIMESTAMP(">Begin Rendering 3D Scene"); + Ref<ARVRInterface> arvr_interface; if (ARVRServer::get_singleton() != NULL) { arvr_interface = ARVRServer::get_singleton()->get_primary_interface(); } 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); + VSG::scene->render_camera(p_viewport->render_buffers, 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); + VSG::scene->render_camera(p_viewport->render_buffers, p_viewport->camera, p_viewport->scenario, p_viewport->size, p_viewport->shadow_atlas); } + RENDER_TIMESTAMP("<End Rendering 3D Scene"); } void VisualServerViewport::_draw_viewport(Viewport *p_viewport, ARVRInterface::Eyes p_eye) { @@ -82,9 +86,11 @@ void VisualServerViewport::_draw_viewport(Viewport *p_viewport, ARVRInterface::E bool scenario_draw_canvas_bg = false; //draw canvas, or some layer of it, as BG for 3D instead of in front int scenario_canvas_max_layer = 0; + Color bgcolor = VSG::storage->get_default_clear_color(); + if (!p_viewport->hide_canvas && !p_viewport->disable_environment && VSG::scene->scenario_owner.owns(p_viewport->scenario)) { - VisualServerScene::Scenario *scenario = VSG::scene->scenario_owner.get(p_viewport->scenario); + VisualServerScene::Scenario *scenario = VSG::scene->scenario_owner.getornull(p_viewport->scenario); ERR_FAIL_COND(!scenario); if (VSG::scene_render->is_environment(scenario->environment)) { scenario_draw_canvas_bg = VSG::scene_render->environment_get_background(scenario->environment) == VS::ENV_BG_CANVAS; @@ -93,15 +99,25 @@ void VisualServerViewport::_draw_viewport(Viewport *p_viewport, ARVRInterface::E } } - bool can_draw_3d = !p_viewport->disable_3d && !p_viewport->disable_3d_by_usage && VSG::scene->camera_owner.owns(p_viewport->camera); + bool can_draw_3d = VSG::scene->camera_owner.owns(p_viewport->camera); if (p_viewport->clear_mode != VS::VIEWPORT_CLEAR_NEVER) { - VSG::rasterizer->clear_render_target(p_viewport->transparent_bg ? Color(0, 0, 0, 0) : clear_color); + if (p_viewport->transparent_bg) { + bgcolor = Color(0, 0, 0, 0); + } if (p_viewport->clear_mode == VS::VIEWPORT_CLEAR_ONLY_NEXT_FRAME) { p_viewport->clear_mode = VS::VIEWPORT_CLEAR_NEVER; } } + if ((scenario_draw_canvas_bg || can_draw_3d) && !p_viewport->render_buffers.is_valid()) { + //wants to draw 3D but there is no render buffer, create + p_viewport->render_buffers = VSG::scene_render->render_buffers_create(); + VSG::scene_render->render_buffers_configure(p_viewport->render_buffers, p_viewport->render_target, p_viewport->size.width, p_viewport->size.height, p_viewport->msaa); + } + + VSG::storage->render_target_request_clear(p_viewport->render_target, bgcolor); + if (!scenario_draw_canvas_bg && can_draw_3d) { _draw_3d(p_viewport, p_eye); } @@ -119,6 +135,7 @@ void VisualServerViewport::_draw_viewport(Viewport *p_viewport, ARVRInterface::E int light_count = 0; + RENDER_TIMESTAMP("Cull Canvas Lights"); for (Map<RID, Viewport::CanvasData>::Element *E = p_viewport->canvas_map.front(); E; E = E->next()) { VisualServerCanvas::Canvas *canvas = static_cast<VisualServerCanvas::Canvas *>(E->get().canvas); @@ -143,13 +160,13 @@ void VisualServerViewport::_draw_viewport(Viewport *p_viewport, ARVRInterface::E cl->filter_next_ptr = lights; lights = cl; - cl->texture_cache = NULL; + // cl->texture_cache = NULL; Transform2D scale; scale.scale(cl->rect_cache.size); scale.elements[2] = cl->rect_cache.position; - cl->light_shader_xform = (cl->xform_cache * scale).affine_inverse(); - cl->light_shader_pos = cl->xform_cache[2]; - if (cl->shadow_buffer.is_valid()) { + cl->light_shader_xform = cl->xform * scale; + //cl->light_shader_pos = cl->xform_cache[2]; + if (cl->use_shadow) { cl->shadows_next_ptr = lights_with_shadow; if (lights_with_shadow == NULL) { @@ -168,7 +185,8 @@ void VisualServerViewport::_draw_viewport(Viewport *p_viewport, ARVRInterface::E light_count++; } - VSG::canvas_render->light_internal_update(cl->light_internal, cl); + //guess this is not needed, but keeping because it may be + //VSG::canvas_render->light_internal_update(cl->light_internal, cl); } } @@ -180,6 +198,9 @@ void VisualServerViewport::_draw_viewport(Viewport *p_viewport, ARVRInterface::E RasterizerCanvas::LightOccluderInstance *occluders = NULL; + RENDER_TIMESTAMP(">Render 2D Shadows"); + RENDER_TIMESTAMP("Cull Occluders"); + //make list of occluders for (Map<RID, Viewport::CanvasData>::Element *E = p_viewport->canvas_map.front(); E; E = E->next()) { @@ -199,21 +220,23 @@ void VisualServerViewport::_draw_viewport(Viewport *p_viewport, ARVRInterface::E } } //update the light shadowmaps with them + RasterizerCanvas::Light *light = lights_with_shadow; while (light) { - VSG::canvas_render->canvas_light_shadow_buffer_update(light->shadow_buffer, light->xform_cache.affine_inverse(), light->item_shadow_mask, light->radius_cache / 1000.0, light->radius_cache * 1.1, occluders, &light->shadow_matrix_cache); + RENDER_TIMESTAMP("Render Shadow"); + + VSG::canvas_render->light_update_shadow(light->light_internal, light->xform_cache.affine_inverse(), light->item_shadow_mask, light->radius_cache / 1000.0, light->radius_cache * 1.1, occluders); light = light->shadows_next_ptr; } //VSG::canvas_render->reset_canvas(); + RENDER_TIMESTAMP("<End rendering 2D Shadows"); } - VSG::rasterizer->restore_render_target(!scenario_draw_canvas_bg && can_draw_3d); - if (scenario_draw_canvas_bg && canvas_map.front() && canvas_map.front()->key().get_layer() > scenario_canvas_max_layer) { if (!can_draw_3d) { - VSG::scene->render_empty_scene(p_viewport->scenario, p_viewport->shadow_atlas); + VSG::scene->render_empty_scene(p_viewport->render_buffers, p_viewport->scenario, p_viewport->shadow_atlas); } else { _draw_3d(p_viewport, p_eye); } @@ -237,12 +260,12 @@ void VisualServerViewport::_draw_viewport(Viewport *p_viewport, ARVRInterface::E ptr = ptr->filter_next_ptr; } - VSG::canvas->render_canvas(canvas, xform, canvas_lights, lights_with_mask, clip_rect); + VSG::canvas->render_canvas(p_viewport->render_target, canvas, xform, canvas_lights, lights_with_mask, clip_rect); i++; if (scenario_draw_canvas_bg && E->key().get_layer() >= scenario_canvas_max_layer) { if (!can_draw_3d) { - VSG::scene->render_empty_scene(p_viewport->scenario, p_viewport->shadow_atlas); + VSG::scene->render_empty_scene(p_viewport->render_buffers, p_viewport->scenario, p_viewport->shadow_atlas); } else { _draw_3d(p_viewport, p_eye); } @@ -253,7 +276,7 @@ void VisualServerViewport::_draw_viewport(Viewport *p_viewport, ARVRInterface::E if (scenario_draw_canvas_bg) { if (!can_draw_3d) { - VSG::scene->render_empty_scene(p_viewport->scenario, p_viewport->shadow_atlas); + VSG::scene->render_empty_scene(p_viewport->render_buffers, p_viewport->scenario, p_viewport->shadow_atlas); } else { _draw_3d(p_viewport, p_eye); } @@ -261,10 +284,16 @@ void VisualServerViewport::_draw_viewport(Viewport *p_viewport, ARVRInterface::E //VSG::canvas_render->canvas_debug_viewport_shadows(lights_with_shadow); } + + if (VSG::storage->render_target_is_clear_requested(p_viewport->render_target)) { + //was never cleared in the end, force clear it + VSG::storage->render_target_do_clear_request(p_viewport->render_target); + } } void VisualServerViewport::draw_viewports() { +#if 0 // get our arvr interface in case we need it Ref<ARVRInterface> arvr_interface; @@ -274,15 +303,19 @@ void VisualServerViewport::draw_viewports() { // process all our active interfaces ARVRServer::get_singleton()->_process(); } +#endif if (Engine::get_singleton()->is_editor_hint()) { - clear_color = GLOBAL_GET("rendering/environment/default_clear_color"); + set_default_clear_color(GLOBAL_GET("rendering/environment/default_clear_color")); } //sort viewports active_viewports.sort_custom<ViewportSort>(); + Map<int, Vector<Rasterizer::BlitToScreen> > blit_to_screen_list; //draw viewports + RENDER_TIMESTAMP(">Render Viewports"); + for (int i = 0; i < active_viewports.size(); i++) { Viewport *vp = active_viewports[i]; @@ -290,7 +323,10 @@ void VisualServerViewport::draw_viewports() { if (vp->update_mode == VS::VIEWPORT_UPDATE_DISABLED) continue; - ERR_CONTINUE(!vp->render_target.is_valid()); + if (!vp->render_target.is_valid()) { + continue; + } + //ERR_CONTINUE(!vp->render_target.is_valid()); bool visible = vp->viewport_to_screen_rect != Rect2() || vp->update_mode == VS::VIEWPORT_UPDATE_ALWAYS || vp->update_mode == VS::VIEWPORT_UPDATE_ONCE || (vp->update_mode == VS::VIEWPORT_UPDATE_WHEN_VISIBLE && VSG::storage->render_target_was_used(vp->render_target)); visible = visible && vp->size.x > 1 && vp->size.y > 1; @@ -298,8 +334,10 @@ void VisualServerViewport::draw_viewports() { if (!visible) continue; - VSG::storage->render_target_clear_used(vp->render_target); + RENDER_TIMESTAMP(">Rendering Viewport " + itos(i)); + VSG::storage->render_target_set_as_unused(vp->render_target); +#if 0 if (vp->use_arvr && arvr_interface.is_valid()) { // override our size, make sure it matches our required size vp->size = arvr_interface->get_render_targetsize(); @@ -333,8 +371,9 @@ void VisualServerViewport::draw_viewports() { // and for our frame timing, mark when we've finished committing our eyes ARVRServer::get_singleton()->_mark_commit(); } else { +#endif + { VSG::storage->render_target_set_external_texture(vp->render_target, 0); - 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(); @@ -352,15 +391,32 @@ void VisualServerViewport::draw_viewports() { if (vp->viewport_to_screen_rect != Rect2() && (!vp->viewport_render_direct_to_screen || !VSG::rasterizer->is_low_end())) { //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); + Rasterizer::BlitToScreen blit; + blit.render_target = vp->render_target; + blit.rect = vp->viewport_to_screen_rect; + + if (!blit_to_screen_list.has(vp->viewport_to_screen)) { + blit_to_screen_list[vp->viewport_to_screen] = Vector<Rasterizer::BlitToScreen>(); + } + + blit_to_screen_list[vp->viewport_to_screen].push_back(blit); } } if (vp->update_mode == VS::VIEWPORT_UPDATE_ONCE) { vp->update_mode = VS::VIEWPORT_UPDATE_DISABLED; } - VSG::scene_render->set_debug_draw_mode(VS::VIEWPORT_DEBUG_DRAW_DISABLED); + + RENDER_TIMESTAMP("<Rendering Viewport " + itos(i)); + } + VSG::scene_render->set_debug_draw_mode(VS::VIEWPORT_DEBUG_DRAW_DISABLED); + + RENDER_TIMESTAMP("<Render Viewports"); + //this needs to be called to make screen swapping more efficient + VSG::rasterizer->prepare_for_blitting_render_targets(); + + for (Map<int, Vector<Rasterizer::BlitToScreen> >::Element *E = blit_to_screen_list.front(); E; E = E->next()) { + VSG::rasterizer->blit_render_targets_to_screen(E->key(), E->get().ptr(), E->get().size()); } } @@ -394,8 +450,14 @@ void VisualServerViewport::viewport_set_size(RID p_viewport, int p_width, int p_ Viewport *viewport = viewport_owner.getornull(p_viewport); ERR_FAIL_COND(!viewport); + // if (viewport->size.width == p_width && viewport->size.height == p_height) { + // return; //nothing to do + // } viewport->size = Size2(p_width, p_height); VSG::storage->render_target_set_size(viewport->render_target, p_width, p_height); + if (viewport->render_buffers.is_valid()) { + VSG::scene_render->render_buffers_configure(viewport->render_buffers, viewport->render_target, viewport->size.width, viewport->size.height, viewport->msaa); + } } void VisualServerViewport::viewport_set_active(RID p_viewport, bool p_active) { @@ -492,13 +554,6 @@ void VisualServerViewport::viewport_set_update_mode(RID p_viewport, VS::Viewport viewport->update_mode = p_mode; } -void VisualServerViewport::viewport_set_vflip(RID p_viewport, bool p_enable) { - - Viewport *viewport = viewport_owner.getornull(p_viewport); - ERR_FAIL_COND(!viewport); - - VSG::storage->render_target_set_flag(viewport->render_target, RasterizerStorage::RENDER_TARGET_VFLIP, p_enable); -} RID VisualServerViewport::viewport_get_texture(RID p_viewport) const { @@ -530,25 +585,6 @@ void VisualServerViewport::viewport_set_disable_environment(RID p_viewport, bool viewport->disable_environment = p_disable; } -void VisualServerViewport::viewport_set_disable_3d(RID p_viewport, bool p_disable) { - - Viewport *viewport = viewport_owner.getornull(p_viewport); - ERR_FAIL_COND(!viewport); - - viewport->disable_3d = p_disable; - //VSG::storage->render_target_set_flag(viewport->render_target, RasterizerStorage::RENDER_TARGET_NO_3D, p_disable); - //this should be just for disabling rendering of 3D, to actually disable it, set usage -} - -void VisualServerViewport::viewport_set_keep_3d_linear(RID p_viewport, bool p_keep_3d_linear) { - - Viewport *viewport = viewport_owner.getornull(p_viewport); - ERR_FAIL_COND(!viewport); - - viewport->keep_3d_linear = p_keep_3d_linear; - VSG::storage->render_target_set_flag(viewport->render_target, RasterizerStorage::RENDER_TARGET_KEEP_3D_LINEAR, p_keep_3d_linear); -} - void VisualServerViewport::viewport_attach_camera(RID p_viewport, RID p_camera) { Viewport *viewport = viewport_owner.getornull(p_viewport); @@ -647,52 +683,12 @@ void VisualServerViewport::viewport_set_msaa(RID p_viewport, VS::ViewportMSAA p_ Viewport *viewport = viewport_owner.getornull(p_viewport); ERR_FAIL_COND(!viewport); - VSG::storage->render_target_set_msaa(viewport->render_target, p_msaa); -} - -void VisualServerViewport::viewport_set_hdr(RID p_viewport, bool p_enabled) { - - Viewport *viewport = viewport_owner.getornull(p_viewport); - ERR_FAIL_COND(!viewport); - - VSG::storage->render_target_set_flag(viewport->render_target, RasterizerStorage::RENDER_TARGET_HDR, p_enabled); -} - -void VisualServerViewport::viewport_set_usage(RID p_viewport, VS::ViewportUsage p_usage) { - - Viewport *viewport = viewport_owner.getornull(p_viewport); - ERR_FAIL_COND(!viewport); - - switch (p_usage) { - case VS::VIEWPORT_USAGE_2D: { - - VSG::storage->render_target_set_flag(viewport->render_target, RasterizerStorage::RENDER_TARGET_NO_3D, true); - VSG::storage->render_target_set_flag(viewport->render_target, RasterizerStorage::RENDER_TARGET_NO_3D_EFFECTS, true); - VSG::storage->render_target_set_flag(viewport->render_target, RasterizerStorage::RENDER_TARGET_NO_SAMPLING, false); - - viewport->disable_3d_by_usage = true; - } break; - case VS::VIEWPORT_USAGE_2D_NO_SAMPLING: { - - VSG::storage->render_target_set_flag(viewport->render_target, RasterizerStorage::RENDER_TARGET_NO_3D, true); - VSG::storage->render_target_set_flag(viewport->render_target, RasterizerStorage::RENDER_TARGET_NO_3D_EFFECTS, true); - VSG::storage->render_target_set_flag(viewport->render_target, RasterizerStorage::RENDER_TARGET_NO_SAMPLING, true); - viewport->disable_3d_by_usage = true; - } break; - case VS::VIEWPORT_USAGE_3D: { - - VSG::storage->render_target_set_flag(viewport->render_target, RasterizerStorage::RENDER_TARGET_NO_3D, false); - VSG::storage->render_target_set_flag(viewport->render_target, RasterizerStorage::RENDER_TARGET_NO_3D_EFFECTS, false); - VSG::storage->render_target_set_flag(viewport->render_target, RasterizerStorage::RENDER_TARGET_NO_SAMPLING, false); - viewport->disable_3d_by_usage = false; - } break; - case VS::VIEWPORT_USAGE_3D_NO_EFFECTS: { - - VSG::storage->render_target_set_flag(viewport->render_target, RasterizerStorage::RENDER_TARGET_NO_3D, false); - VSG::storage->render_target_set_flag(viewport->render_target, RasterizerStorage::RENDER_TARGET_NO_3D_EFFECTS, true); - VSG::storage->render_target_set_flag(viewport->render_target, RasterizerStorage::RENDER_TARGET_NO_SAMPLING, false); - viewport->disable_3d_by_usage = false; - } break; + if (viewport->msaa == p_msaa) { + return; + } + viewport->msaa = p_msaa; + if (viewport->render_buffers.is_valid()) { + VSG::scene_render->render_buffers_configure(viewport->render_buffers, viewport->render_target, viewport->size.width, viewport->size.height, p_msaa); } } @@ -723,6 +719,9 @@ bool VisualServerViewport::free(RID p_rid) { VSG::storage->free(viewport->render_target); VSG::scene_render->free(viewport->shadow_atlas); + if (viewport->render_buffers.is_valid()) { + VSG::scene_render->free(viewport->render_buffers); + } while (viewport->canvas_map.front()) { viewport_remove_canvas(p_rid, viewport->canvas_map.front()->key()); @@ -741,7 +740,7 @@ bool VisualServerViewport::free(RID p_rid) { } void VisualServerViewport::set_default_clear_color(const Color &p_color) { - clear_color = p_color; + VSG::storage->set_default_clear_color(p_color); } VisualServerViewport::VisualServerViewport() { |