2017-03-05 15:47:28 +01:00
/*************************************************************************/
2020-12-04 19:26:24 +01:00
/* renderer_viewport.cpp */
2017-03-05 15:47:28 +01:00
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
2017-08-27 14:16:55 +02:00
/* https://godotengine.org */
2017-03-05 15:47:28 +01:00
/*************************************************************************/
2021-01-01 20:13:46 +01:00
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
2017-03-05 15:47:28 +01:00
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
2018-01-05 00:50:27 +01:00
2020-12-04 19:26:24 +01:00
# include "renderer_viewport.h"
2017-08-27 21:07:15 +02:00
2020-11-07 23:33:38 +01:00
# include "core/config/project_settings.h"
2020-12-04 19:26:24 +01:00
# include "renderer_canvas_cull.h"
# include "renderer_scene_cull.h"
2020-03-27 19:21:27 +01:00
# include "rendering_server_globals.h"
2016-10-19 16:14:41 +02:00
2020-12-04 19:26:24 +01:00
static Transform2D _canvas_get_transform ( RendererViewport : : Viewport * p_viewport , RendererCanvasCull : : Canvas * p_canvas , RendererViewport : : Viewport : : CanvasData * p_canvas_data , const Vector2 & p_vp_size ) {
2019-04-05 15:24:54 +02:00
Transform2D xf = p_viewport - > global_transform ;
float scale = 1.0 ;
if ( p_viewport - > canvas_map . has ( p_canvas - > parent ) ) {
2020-10-29 22:09:16 +01:00
Transform2D c_xform = p_viewport - > canvas_map [ p_canvas - > parent ] . transform ;
if ( p_viewport - > snap_2d_transforms_to_pixel ) {
c_xform . elements [ 2 ] = c_xform . elements [ 2 ] . floor ( ) ;
}
xf = xf * c_xform ;
2019-04-05 15:24:54 +02:00
scale = p_canvas - > parent_scale ;
}
2020-10-29 22:09:16 +01:00
Transform2D c_xform = p_canvas_data - > transform ;
if ( p_viewport - > snap_2d_transforms_to_pixel ) {
c_xform . elements [ 2 ] = c_xform . elements [ 2 ] . floor ( ) ;
}
xf = xf * c_xform ;
2019-04-05 15:24:54 +02:00
2020-03-27 19:21:27 +01:00
if ( scale ! = 1.0 & & ! RSG : : canvas - > disable_scale ) {
2019-04-05 15:24:54 +02:00
Vector2 pivot = p_vp_size * 0.5 ;
Transform2D xfpivot ;
xfpivot . set_origin ( pivot ) ;
Transform2D xfscale ;
xfscale . scale ( Vector2 ( scale , scale ) ) ;
xf = xfpivot . affine_inverse ( ) * xf ;
xf = xfscale * xf ;
xf = xfpivot * xf ;
}
return xf ;
}
2020-12-04 19:26:24 +01:00
void RendererViewport : : _draw_3d ( Viewport * p_viewport , XRInterface : : Eyes p_eye ) {
2019-09-20 22:58:06 +02:00
RENDER_TIMESTAMP ( " >Begin Rendering 3D Scene " ) ;
2020-04-08 16:47:36 +02:00
Ref < XRInterface > xr_interface ;
if ( XRServer : : get_singleton ( ) ! = nullptr ) {
xr_interface = XRServer : : get_singleton ( ) - > get_primary_interface ( ) ;
2019-07-05 21:14:43 +02:00
}
2019-03-30 14:03:49 +01:00
2020-12-17 19:56:59 +01:00
float screen_lod_threshold = p_viewport - > lod_threshold / float ( p_viewport - > size . width ) ;
2020-04-08 16:47:36 +02:00
if ( p_viewport - > use_xr & & xr_interface . is_valid ( ) ) {
2020-12-17 19:56:59 +01:00
RSG : : scene - > render_camera ( p_viewport - > render_buffers , xr_interface , p_eye , p_viewport - > camera , p_viewport - > scenario , p_viewport - > size , screen_lod_threshold , p_viewport - > shadow_atlas ) ;
2019-03-30 14:03:49 +01:00
} else {
2020-12-17 19:56:59 +01:00
RSG : : scene - > render_camera ( p_viewport - > render_buffers , p_viewport - > camera , p_viewport - > scenario , p_viewport - > size , screen_lod_threshold , p_viewport - > shadow_atlas ) ;
2019-03-30 14:03:49 +01:00
}
2019-09-20 22:58:06 +02:00
RENDER_TIMESTAMP ( " <End Rendering 3D Scene " ) ;
2019-03-30 14:03:49 +01:00
}
2020-12-04 19:26:24 +01:00
void RendererViewport : : _draw_viewport ( Viewport * p_viewport , XRInterface : : Eyes p_eye ) {
2020-04-10 19:18:42 +02:00
if ( p_viewport - > measure_render_time ) {
String rt_id = " vp_begin_ " + itos ( p_viewport - > self . get_id ( ) ) ;
RSG : : storage - > capture_timestamp ( rt_id ) ;
timestamp_vp_map [ rt_id ] = p_viewport - > self ;
}
2017-06-24 13:58:27 +02:00
/* Camera should always be BEFORE any other 3D */
2016-10-03 21:33:42 +02:00
2017-06-24 13:58:27 +02:00
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 ;
2019-06-24 21:13:06 +02:00
2020-03-27 19:21:27 +01:00
Color bgcolor = RSG : : storage - > get_default_clear_color ( ) ;
2016-10-03 21:33:42 +02:00
2020-12-03 22:09:47 +01:00
if ( ! p_viewport - > hide_canvas & & ! p_viewport - > disable_environment & & RSG : : scene - > is_scenario ( p_viewport - > scenario ) ) {
RID environment = RSG : : scene - > scenario_get_environment ( p_viewport - > scenario ) ;
if ( RSG : : scene - > is_environment ( environment ) ) {
scenario_draw_canvas_bg = RSG : : scene - > environment_get_background ( environment ) = = RS : : ENV_BG_CANVAS ;
scenario_canvas_max_layer = RSG : : scene - > environment_get_canvas_max_layer ( environment ) ;
2016-10-03 21:33:42 +02:00
}
}
2020-12-03 22:09:47 +01:00
bool can_draw_3d = RSG : : scene - > is_camera ( p_viewport - > camera ) ;
2016-10-03 21:33:42 +02:00
2020-03-27 19:21:27 +01:00
if ( p_viewport - > clear_mode ! = RS : : VIEWPORT_CLEAR_NEVER ) {
2019-06-16 04:45:24 +02:00
if ( p_viewport - > transparent_bg ) {
bgcolor = Color ( 0 , 0 , 0 , 0 ) ;
}
2020-03-27 19:21:27 +01:00
if ( p_viewport - > clear_mode = = RS : : VIEWPORT_CLEAR_ONLY_NEXT_FRAME ) {
p_viewport - > clear_mode = RS : : VIEWPORT_CLEAR_NEVER ;
2016-10-05 06:26:35 +02:00
}
}
2016-10-03 21:33:42 +02:00
2019-08-19 00:40:52 +02:00
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
2020-12-03 22:09:47 +01:00
p_viewport - > render_buffers = RSG : : scene - > render_buffers_create ( ) ;
RSG : : scene - > render_buffers_configure ( p_viewport - > render_buffers , p_viewport - > render_target , p_viewport - > size . width , p_viewport - > size . height , p_viewport - > msaa , p_viewport - > screen_space_aa , p_viewport - > use_debanding ) ;
2019-08-19 00:40:52 +02:00
}
2020-03-27 19:21:27 +01:00
RSG : : storage - > render_target_request_clear ( p_viewport - > render_target , bgcolor ) ;
2019-06-24 21:13:06 +02:00
2017-06-24 13:58:27 +02:00
if ( ! scenario_draw_canvas_bg & & can_draw_3d ) {
2019-03-30 14:03:49 +01:00
_draw_3d ( p_viewport , p_eye ) ;
2016-10-19 16:14:41 +02:00
}
2016-10-03 21:33:42 +02:00
if ( ! p_viewport - > hide_canvas ) {
2017-03-05 16:44:50 +01:00
int i = 0 ;
2016-10-03 21:33:42 +02:00
2017-03-05 16:44:50 +01:00
Map < Viewport : : CanvasKey , Viewport : : CanvasData * > canvas_map ;
2016-10-03 21:33:42 +02:00
2017-03-05 16:44:50 +01:00
Rect2 clip_rect ( 0 , 0 , p_viewport - > size . x , p_viewport - > size . y ) ;
2020-12-04 19:26:24 +01:00
RendererCanvasRender : : Light * lights = nullptr ;
RendererCanvasRender : : Light * lights_with_shadow = nullptr ;
2020-11-03 20:51:53 +01:00
2020-12-04 19:26:24 +01:00
RendererCanvasRender : : Light * directional_lights = nullptr ;
RendererCanvasRender : : Light * directional_lights_with_shadow = nullptr ;
2020-11-03 20:51:53 +01:00
2020-11-26 13:50:21 +01:00
if ( p_viewport - > sdf_active ) {
//process SDF
Rect2 sdf_rect = RSG : : storage - > render_target_get_sdf_rect ( p_viewport - > render_target ) ;
2020-12-04 19:26:24 +01:00
RendererCanvasRender : : LightOccluderInstance * occluders = nullptr ;
2020-11-26 13:50:21 +01:00
//make list of occluders
for ( Map < RID , Viewport : : CanvasData > : : Element * E = p_viewport - > canvas_map . front ( ) ; E ; E = E - > next ( ) ) {
2020-12-04 19:26:24 +01:00
RendererCanvasCull : : Canvas * canvas = static_cast < RendererCanvasCull : : Canvas * > ( E - > get ( ) . canvas ) ;
2020-11-26 13:50:21 +01:00
Transform2D xf = _canvas_get_transform ( p_viewport , canvas , & E - > get ( ) , clip_rect . size ) ;
2020-12-04 19:26:24 +01:00
for ( Set < RendererCanvasRender : : LightOccluderInstance * > : : Element * F = canvas - > occluders . front ( ) ; F ; F = F - > next ( ) ) {
2020-11-26 13:50:21 +01:00
if ( ! F - > get ( ) - > enabled ) {
continue ;
}
F - > get ( ) - > xform_cache = xf * F - > get ( ) - > xform ;
if ( sdf_rect . intersects_transformed ( F - > get ( ) - > xform_cache , F - > get ( ) - > aabb_cache ) ) {
F - > get ( ) - > next = occluders ;
occluders = F - > get ( ) ;
}
}
}
RSG : : canvas_render - > render_sdf ( p_viewport - > render_target , occluders ) ;
p_viewport - > sdf_active = false ; // if used, gets set active again
}
2016-10-03 21:33:42 +02:00
Rect2 shadow_rect ;
2017-03-05 16:44:50 +01:00
int light_count = 0 ;
2020-10-24 17:15:43 +02:00
int shadow_count = 0 ;
2020-11-03 20:51:53 +01:00
int directional_light_count = 0 ;
2016-10-03 21:33:42 +02:00
2019-09-20 22:58:06 +02:00
RENDER_TIMESTAMP ( " Cull Canvas Lights " ) ;
2017-03-05 16:44:50 +01:00
for ( Map < RID , Viewport : : CanvasData > : : Element * E = p_viewport - > canvas_map . front ( ) ; E ; E = E - > next ( ) ) {
2020-12-04 19:26:24 +01:00
RendererCanvasCull : : Canvas * canvas = static_cast < RendererCanvasCull : : Canvas * > ( E - > get ( ) . canvas ) ;
2016-10-03 21:33:42 +02:00
2019-04-05 15:24:54 +02:00
Transform2D xf = _canvas_get_transform ( p_viewport , canvas , & E - > get ( ) , clip_rect . size ) ;
2016-10-03 21:33:42 +02:00
//find lights in canvas
2020-12-04 19:26:24 +01:00
for ( Set < RendererCanvasRender : : Light * > : : Element * F = canvas - > lights . front ( ) ; F ; F = F - > next ( ) ) {
RendererCanvasRender : : Light * cl = F - > get ( ) ;
2016-10-03 21:33:42 +02:00
if ( cl - > enabled & & cl - > texture . is_valid ( ) ) {
//not super efficient..
2020-03-27 19:21:27 +01:00
Size2 tsize = RSG : : storage - > texture_size_with_proxy ( cl - > texture ) ;
2017-03-05 16:44:50 +01:00
tsize * = cl - > scale ;
2016-10-03 21:33:42 +02:00
2017-03-05 16:44:50 +01:00
Vector2 offset = tsize / 2.0 ;
cl - > rect_cache = Rect2 ( - offset + cl - > texture_offset , tsize ) ;
cl - > xform_cache = xf * cl - > xform ;
2016-10-03 21:33:42 +02:00
2017-03-05 16:44:50 +01:00
if ( clip_rect . intersects_transformed ( cl - > xform_cache , cl - > rect_cache ) ) {
cl - > filter_next_ptr = lights ;
lights = cl ;
2020-04-02 01:20:12 +02:00
// cl->texture_cache = nullptr;
2017-01-11 04:52:51 +01:00
Transform2D scale ;
2016-10-03 21:33:42 +02:00
scale . scale ( cl - > rect_cache . size ) ;
2017-06-04 00:25:13 +02:00
scale . elements [ 2 ] = cl - > rect_cache . position ;
2019-07-05 03:54:32 +02:00
cl - > light_shader_xform = cl - > xform * scale ;
//cl->light_shader_pos = cl->xform_cache[2];
if ( cl - > use_shadow ) {
2017-03-05 16:44:50 +01:00
cl - > shadows_next_ptr = lights_with_shadow ;
2020-04-02 01:20:12 +02:00
if ( lights_with_shadow = = nullptr ) {
2016-10-03 21:33:42 +02:00
shadow_rect = cl - > xform_cache . xform ( cl - > rect_cache ) ;
} else {
2017-03-05 16:44:50 +01:00
shadow_rect = shadow_rect . merge ( cl - > xform_cache . xform ( cl - > rect_cache ) ) ;
2016-10-03 21:33:42 +02:00
}
2017-03-05 16:44:50 +01:00
lights_with_shadow = cl ;
cl - > radius_cache = cl - > rect_cache . size . length ( ) ;
2016-10-03 21:33:42 +02:00
}
light_count + + ;
}
2019-07-05 03:54:32 +02:00
//guess this is not needed, but keeping because it may be
2016-10-03 21:33:42 +02:00
}
}
2020-12-04 19:26:24 +01:00
for ( Set < RendererCanvasRender : : Light * > : : Element * F = canvas - > directional_lights . front ( ) ; F ; F = F - > next ( ) ) {
RendererCanvasRender : : Light * cl = F - > get ( ) ;
2020-11-03 20:51:53 +01:00
if ( cl - > enabled ) {
cl - > filter_next_ptr = directional_lights ;
directional_lights = cl ;
cl - > xform_cache = xf * cl - > xform ;
cl - > xform_cache . elements [ 2 ] = Vector2 ( ) ; //translation is pointless
if ( cl - > use_shadow ) {
cl - > shadows_next_ptr = directional_lights_with_shadow ;
directional_lights_with_shadow = cl ;
}
directional_light_count + + ;
if ( directional_light_count = = RS : : MAX_2D_DIRECTIONAL_LIGHTS ) {
break ;
}
}
}
2018-10-30 21:53:00 +01:00
canvas_map [ Viewport : : CanvasKey ( E - > key ( ) , E - > get ( ) . layer , E - > get ( ) . sublayer ) ] = & E - > get ( ) ;
2016-10-03 21:33:42 +02:00
}
if ( lights_with_shadow ) {
//update shadows if any
2020-12-04 19:26:24 +01:00
RendererCanvasRender : : LightOccluderInstance * occluders = nullptr ;
2016-10-03 21:33:42 +02:00
2019-09-20 22:58:06 +02:00
RENDER_TIMESTAMP ( " >Render 2D Shadows " ) ;
RENDER_TIMESTAMP ( " Cull Occluders " ) ;
2016-10-03 21:33:42 +02:00
//make list of occluders
2017-03-05 16:44:50 +01:00
for ( Map < RID , Viewport : : CanvasData > : : Element * E = p_viewport - > canvas_map . front ( ) ; E ; E = E - > next ( ) ) {
2020-12-04 19:26:24 +01:00
RendererCanvasCull : : Canvas * canvas = static_cast < RendererCanvasCull : : Canvas * > ( E - > get ( ) . canvas ) ;
2019-10-29 07:51:58 +01:00
Transform2D xf = _canvas_get_transform ( p_viewport , canvas , & E - > get ( ) , clip_rect . size ) ;
2016-10-03 21:33:42 +02:00
2020-12-04 19:26:24 +01:00
for ( Set < RendererCanvasRender : : LightOccluderInstance * > : : Element * F = canvas - > occluders . front ( ) ; F ; F = F - > next ( ) ) {
2020-05-14 16:41:43 +02:00
if ( ! F - > get ( ) - > enabled ) {
2016-10-03 21:33:42 +02:00
continue ;
2020-05-14 16:41:43 +02:00
}
2016-10-03 21:33:42 +02:00
F - > get ( ) - > xform_cache = xf * F - > get ( ) - > xform ;
2017-03-05 16:44:50 +01:00
if ( shadow_rect . intersects_transformed ( F - > get ( ) - > xform_cache , F - > get ( ) - > aabb_cache ) ) {
F - > get ( ) - > next = occluders ;
occluders = F - > get ( ) ;
2016-10-03 21:33:42 +02:00
}
}
}
//update the light shadowmaps with them
2019-09-20 22:58:06 +02:00
2020-12-04 19:26:24 +01:00
RendererCanvasRender : : Light * light = lights_with_shadow ;
2017-03-05 16:44:50 +01:00
while ( light ) {
2019-09-20 22:58:06 +02:00
RENDER_TIMESTAMP ( " Render Shadow " ) ;
2020-10-24 17:15:43 +02:00
RSG : : canvas_render - > light_update_shadow ( light - > light_internal , shadow_count + + , light - > xform_cache . affine_inverse ( ) , light - > item_shadow_mask , light - > radius_cache / 1000.0 , light - > radius_cache * 1.1 , occluders ) ;
2017-03-05 16:44:50 +01:00
light = light - > shadows_next_ptr ;
2016-10-03 21:33:42 +02:00
}
2019-09-20 22:58:06 +02:00
RENDER_TIMESTAMP ( " <End rendering 2D Shadows " ) ;
2016-10-03 21:33:42 +02:00
}
2020-11-03 20:51:53 +01:00
if ( directional_lights_with_shadow ) {
//update shadows if any
2020-12-04 19:26:24 +01:00
RendererCanvasRender : : Light * light = directional_lights_with_shadow ;
2020-11-03 20:51:53 +01:00
while ( light ) {
Vector2 light_dir = - light - > xform_cache . elements [ 1 ] . normalized ( ) ; // Y is light direction
float cull_distance = light - > directional_distance ;
Vector2 light_dir_sign ;
light_dir_sign . x = ( ABS ( light_dir . x ) < CMP_EPSILON ) ? 0.0 : ( ( light_dir . x > 0.0 ) ? 1.0 : - 1.0 ) ;
light_dir_sign . y = ( ABS ( light_dir . y ) < CMP_EPSILON ) ? 0.0 : ( ( light_dir . y > 0.0 ) ? 1.0 : - 1.0 ) ;
Vector2 points [ 6 ] ;
int point_count = 0 ;
for ( int j = 0 ; j < 4 ; j + + ) {
static const Vector2 signs [ 4 ] = { Vector2 ( 1 , 1 ) , Vector2 ( 1 , 0 ) , Vector2 ( 0 , 0 ) , Vector2 ( 0 , 1 ) } ;
Vector2 sign_cmp = signs [ j ] * 2.0 - Vector2 ( 1.0 , 1.0 ) ;
Vector2 point = clip_rect . position + clip_rect . size * signs [ j ] ;
if ( sign_cmp = = light_dir_sign ) {
//both point in same direction, plot offseted
points [ point_count + + ] = point + light_dir * cull_distance ;
} else if ( sign_cmp . x = = light_dir_sign . x | | sign_cmp . y = = light_dir_sign . y ) {
int next_j = ( j + 1 ) % 4 ;
Vector2 next_sign_cmp = signs [ next_j ] * 2.0 - Vector2 ( 1.0 , 1.0 ) ;
//one point in the same direction, plot segment
if ( next_sign_cmp . x = = light_dir_sign . x | | next_sign_cmp . y = = light_dir_sign . y ) {
if ( light_dir_sign . x ! = 0.0 | | light_dir_sign . y ! = 0.0 ) {
points [ point_count + + ] = point ;
}
points [ point_count + + ] = point + light_dir * cull_distance ;
} else {
points [ point_count + + ] = point + light_dir * cull_distance ;
if ( light_dir_sign . x ! = 0.0 | | light_dir_sign . y ! = 0.0 ) {
points [ point_count + + ] = point ;
}
}
} else {
//plot normally
points [ point_count + + ] = point ;
}
}
Vector2 xf_points [ 6 ] ;
2020-12-04 19:26:24 +01:00
RendererCanvasRender : : LightOccluderInstance * occluders = nullptr ;
2020-11-03 20:51:53 +01:00
RENDER_TIMESTAMP ( " >Render Directional 2D Shadows " ) ;
//make list of occluders
int occ_cullded = 0 ;
for ( Map < RID , Viewport : : CanvasData > : : Element * E = p_viewport - > canvas_map . front ( ) ; E ; E = E - > next ( ) ) {
2020-12-04 19:26:24 +01:00
RendererCanvasCull : : Canvas * canvas = static_cast < RendererCanvasCull : : Canvas * > ( E - > get ( ) . canvas ) ;
2020-11-03 20:51:53 +01:00
Transform2D xf = _canvas_get_transform ( p_viewport , canvas , & E - > get ( ) , clip_rect . size ) ;
2020-12-04 19:26:24 +01:00
for ( Set < RendererCanvasRender : : LightOccluderInstance * > : : Element * F = canvas - > occluders . front ( ) ; F ; F = F - > next ( ) ) {
2020-11-03 20:51:53 +01:00
if ( ! F - > get ( ) - > enabled ) {
continue ;
}
F - > get ( ) - > xform_cache = xf * F - > get ( ) - > xform ;
Transform2D localizer = F - > get ( ) - > xform_cache . affine_inverse ( ) ;
for ( int j = 0 ; j < point_count ; j + + ) {
xf_points [ j ] = localizer . xform ( points [ j ] ) ;
}
if ( F - > get ( ) - > aabb_cache . intersects_filled_polygon ( xf_points , point_count ) ) {
F - > get ( ) - > next = occluders ;
occluders = F - > get ( ) ;
occ_cullded + + ;
}
}
}
RSG : : canvas_render - > light_update_directional_shadow ( light - > light_internal , shadow_count + + , light - > xform_cache , light - > item_shadow_mask , cull_distance , clip_rect , occluders ) ;
light = light - > shadows_next_ptr ;
}
RENDER_TIMESTAMP ( " <Render Directional 2D Shadows " ) ;
}
2018-10-30 21:53:00 +01:00
if ( scenario_draw_canvas_bg & & canvas_map . front ( ) & & canvas_map . front ( ) - > key ( ) . get_layer ( ) > scenario_canvas_max_layer ) {
2018-04-30 14:30:11 +02:00
if ( ! can_draw_3d ) {
2020-03-27 19:21:27 +01:00
RSG : : scene - > render_empty_scene ( p_viewport - > render_buffers , p_viewport - > scenario , p_viewport - > shadow_atlas ) ;
2018-04-30 14:30:11 +02:00
} else {
2019-03-30 14:03:49 +01:00
_draw_3d ( p_viewport , p_eye ) ;
2017-06-24 13:58:27 +02:00
}
scenario_draw_canvas_bg = false ;
2016-10-03 21:33:42 +02:00
}
2016-10-05 06:26:35 +02:00
2017-03-05 16:44:50 +01:00
for ( Map < Viewport : : CanvasKey , Viewport : : CanvasData * > : : Element * E = canvas_map . front ( ) ; E ; E = E - > next ( ) ) {
2020-12-04 19:26:24 +01:00
RendererCanvasCull : : Canvas * canvas = static_cast < RendererCanvasCull : : Canvas * > ( E - > get ( ) - > canvas ) ;
2016-10-03 21:33:42 +02:00
2019-04-05 15:24:54 +02:00
Transform2D xform = _canvas_get_transform ( p_viewport , canvas , E - > get ( ) , clip_rect . size ) ;
2016-10-03 21:33:42 +02:00
2020-12-04 19:26:24 +01:00
RendererCanvasRender : : Light * canvas_lights = nullptr ;
RendererCanvasRender : : Light * canvas_directional_lights = nullptr ;
2016-10-03 21:33:42 +02:00
2020-12-04 19:26:24 +01:00
RendererCanvasRender : : Light * ptr = lights ;
2017-03-05 16:44:50 +01:00
while ( ptr ) {
if ( E - > get ( ) - > layer > = ptr - > layer_min & & E - > get ( ) - > layer < = ptr - > layer_max ) {
ptr - > next_ptr = canvas_lights ;
canvas_lights = ptr ;
2016-10-03 21:33:42 +02:00
}
2017-03-05 16:44:50 +01:00
ptr = ptr - > filter_next_ptr ;
2016-10-03 21:33:42 +02:00
}
2020-11-03 20:51:53 +01:00
ptr = directional_lights ;
while ( ptr ) {
if ( E - > get ( ) - > layer > = ptr - > layer_min & & E - > get ( ) - > layer < = ptr - > layer_max ) {
ptr - > next_ptr = canvas_directional_lights ;
canvas_directional_lights = ptr ;
}
ptr = ptr - > filter_next_ptr ;
}
RSG : : canvas - > render_canvas ( p_viewport - > render_target , canvas , xform , canvas_lights , canvas_directional_lights , clip_rect , p_viewport - > texture_filter , p_viewport - > texture_repeat , p_viewport - > snap_2d_transforms_to_pixel , p_viewport - > snap_2d_vertices_to_pixel ) ;
2020-11-26 13:50:21 +01:00
if ( RSG : : canvas - > was_sdf_used ( ) ) {
p_viewport - > sdf_active = true ;
}
2016-10-03 21:33:42 +02:00
i + + ;
2017-06-24 13:58:27 +02:00
2018-10-30 21:53:00 +01:00
if ( scenario_draw_canvas_bg & & E - > key ( ) . get_layer ( ) > = scenario_canvas_max_layer ) {
2018-04-30 14:30:11 +02:00
if ( ! can_draw_3d ) {
2020-03-27 19:21:27 +01:00
RSG : : scene - > render_empty_scene ( p_viewport - > render_buffers , p_viewport - > scenario , p_viewport - > shadow_atlas ) ;
2018-04-30 14:30:11 +02:00
} else {
2019-03-30 14:03:49 +01:00
_draw_3d ( p_viewport , p_eye ) ;
2017-06-24 13:58:27 +02:00
}
scenario_draw_canvas_bg = false ;
2016-10-03 21:33:42 +02:00
}
}
2017-06-24 13:58:27 +02:00
2016-10-03 21:33:42 +02:00
if ( scenario_draw_canvas_bg ) {
2018-04-30 14:30:11 +02:00
if ( ! can_draw_3d ) {
2020-03-27 19:21:27 +01:00
RSG : : scene - > render_empty_scene ( p_viewport - > render_buffers , p_viewport - > scenario , p_viewport - > shadow_atlas ) ;
2018-04-30 14:30:11 +02:00
} else {
2019-03-30 14:03:49 +01:00
_draw_3d ( p_viewport , p_eye ) ;
2017-06-24 13:58:27 +02:00
}
2016-10-03 21:33:42 +02:00
}
}
2019-06-25 03:24:07 +02:00
2020-03-27 19:21:27 +01:00
if ( RSG : : storage - > render_target_is_clear_requested ( p_viewport - > render_target ) ) {
2019-06-25 03:24:07 +02:00
//was never cleared in the end, force clear it
2020-03-27 19:21:27 +01:00
RSG : : storage - > render_target_do_clear_request ( p_viewport - > render_target ) ;
2019-06-25 03:24:07 +02:00
}
2020-04-10 19:18:42 +02:00
if ( p_viewport - > measure_render_time ) {
String rt_id = " vp_end_ " + itos ( p_viewport - > self . get_id ( ) ) ;
RSG : : storage - > capture_timestamp ( rt_id ) ;
timestamp_vp_map [ rt_id ] = p_viewport - > self ;
}
2016-10-03 21:33:42 +02:00
}
2020-12-04 19:26:24 +01:00
void RendererViewport : : draw_viewports ( ) {
2020-04-10 19:18:42 +02:00
timestamp_vp_map . clear ( ) ;
2020-04-08 16:47:36 +02:00
// get our xr interface in case we need it
Ref < XRInterface > xr_interface ;
2018-03-15 12:33:55 +01:00
2020-04-08 16:47:36 +02:00
if ( XRServer : : get_singleton ( ) ! = nullptr ) {
xr_interface = XRServer : : get_singleton ( ) - > get_primary_interface ( ) ;
2019-07-05 21:14:43 +02:00
// process all our active interfaces
2020-04-08 16:47:36 +02:00
XRServer : : get_singleton ( ) - > _process ( ) ;
2019-07-05 21:14:43 +02:00
}
2016-10-03 21:33:42 +02:00
2018-07-29 20:09:42 +02:00
if ( Engine : : get_singleton ( ) - > is_editor_hint ( ) ) {
2019-09-09 22:50:51 +02:00
set_default_clear_color ( GLOBAL_GET ( " rendering/environment/default_clear_color " ) ) ;
2018-07-29 20:09:42 +02:00
}
2016-10-05 06:26:35 +02:00
2017-04-23 14:10:41 +02:00
//sort viewports
2016-10-05 06:26:35 +02:00
active_viewports . sort_custom < ViewportSort > ( ) ;
2016-10-03 21:33:42 +02:00
2020-12-04 19:26:24 +01:00
Map < DisplayServer : : WindowID , Vector < RendererCompositor : : BlitToScreen > > blit_to_screen_list ;
2017-04-23 14:10:41 +02:00
//draw viewports
2019-09-20 22:58:06 +02:00
RENDER_TIMESTAMP ( " >Render Viewports " ) ;
2020-03-14 17:06:39 +01:00
//determine what is visible
draw_viewports_pass + + ;
for ( int i = active_viewports . size ( ) - 1 ; i > = 0 ; i - - ) { //to compute parent dependency, must go in reverse draw order
2016-10-03 21:33:42 +02:00
Viewport * vp = active_viewports [ i ] ;
2020-05-14 16:41:43 +02:00
if ( vp - > update_mode = = RS : : VIEWPORT_UPDATE_DISABLED ) {
2016-10-03 21:33:42 +02:00
continue ;
2020-05-14 16:41:43 +02:00
}
2016-10-03 21:33:42 +02:00
2019-06-07 18:07:57 +02:00
if ( ! vp - > render_target . is_valid ( ) ) {
continue ;
}
//ERR_CONTINUE(!vp->render_target.is_valid());
2016-10-03 21:33:42 +02:00
2020-03-14 17:06:39 +01:00
bool visible = vp - > viewport_to_screen_rect ! = Rect2 ( ) ;
2020-03-27 19:21:27 +01:00
if ( vp - > update_mode = = RS : : VIEWPORT_UPDATE_ALWAYS | | vp - > update_mode = = RS : : VIEWPORT_UPDATE_ONCE ) {
2020-03-14 17:06:39 +01:00
visible = true ;
}
2020-03-27 19:21:27 +01:00
if ( vp - > update_mode = = RS : : VIEWPORT_UPDATE_WHEN_VISIBLE & & RSG : : storage - > render_target_was_used ( vp - > render_target ) ) {
2020-03-14 17:06:39 +01:00
visible = true ;
}
2020-03-27 19:21:27 +01:00
if ( vp - > update_mode = = RS : : VIEWPORT_UPDATE_WHEN_PARENT_VISIBLE ) {
2020-03-14 17:06:39 +01:00
Viewport * parent = viewport_owner . getornull ( vp - > parent ) ;
if ( parent & & parent - > last_pass = = draw_viewports_pass ) {
visible = true ;
}
}
2018-07-08 00:10:32 +02:00
visible = visible & & vp - > size . x > 1 & & vp - > size . y > 1 ;
2016-10-19 16:14:41 +02:00
2020-03-14 17:06:39 +01:00
if ( visible ) {
vp - > last_pass = draw_viewports_pass ;
}
}
for ( int i = 0 ; i < active_viewports . size ( ) ; i + + ) {
Viewport * vp = active_viewports [ i ] ;
if ( vp - > last_pass ! = draw_viewports_pass ) {
continue ; //should not draw
}
2016-10-19 16:14:41 +02:00
2019-09-20 22:58:06 +02:00
RENDER_TIMESTAMP ( " >Rendering Viewport " + itos ( i ) ) ;
2020-03-27 19:21:27 +01:00
RSG : : storage - > render_target_set_as_unused ( vp - > render_target ) ;
2019-06-16 04:45:24 +02:00
#if 0
2020-04-08 16:47:36 +02:00
// TODO fix up this code after we change our commit_for_eye to accept our new render targets
if ( vp - > use_xr & & xr_interface . is_valid ( ) ) {
2017-04-23 14:10:41 +02:00
// override our size, make sure it matches our required size
2020-04-08 16:47:36 +02:00
vp - > size = xr_interface - > get_render_targetsize ( ) ;
2020-03-27 19:21:27 +01:00
RSG : : storage - > render_target_set_size ( vp - > render_target , vp - > size . x , vp - > size . y ) ;
2017-06-11 20:52:03 +02:00
2017-04-23 14:10:41 +02:00
// render mono or left eye first
2020-04-08 16:47:36 +02:00
XRInterface : : Eyes leftOrMono = xr_interface - > is_stereo ( ) ? XRInterface : : EYE_LEFT : XRInterface : : EYE_MONO ;
2019-03-30 14:03:49 +01:00
// check for an external texture destination for our left eye/mono
2020-04-08 16:47:36 +02:00
// TODO investigate how we're going to make external textures work
RSG : : storage - > render_target_set_external_texture ( vp - > render_target , xr_interface - > get_external_texture_for_eye ( leftOrMono ) ) ;
2019-03-30 14:03:49 +01:00
// set our render target as current
2020-03-27 19:21:27 +01:00
RSG : : rasterizer - > set_current_render_target ( vp - > render_target ) ;
2019-03-30 14:03:49 +01:00
// and draw left eye/mono
2017-04-23 14:10:41 +02:00
_draw_viewport ( vp , leftOrMono ) ;
2020-04-08 16:47:36 +02:00
xr_interface - > commit_for_eye ( leftOrMono , vp - > render_target , vp - > viewport_to_screen_rect ) ;
2016-10-03 21:33:42 +02:00
2017-04-23 14:10:41 +02:00
// render right eye
2020-04-08 16:47:36 +02:00
if ( leftOrMono = = XRInterface : : EYE_LEFT ) {
2019-03-30 14:03:49 +01:00
// check for an external texture destination for our right eye
2020-04-08 16:47:36 +02:00
RSG : : storage - > render_target_set_external_texture ( vp - > render_target , xr_interface - > get_external_texture_for_eye ( XRInterface : : EYE_RIGHT ) ) ;
2019-03-30 14:03:49 +01:00
2017-04-23 14:10:41 +02:00
// commit for eye may have changed the render target
2020-03-27 19:21:27 +01:00
RSG : : rasterizer - > set_current_render_target ( vp - > render_target ) ;
2017-06-11 23:13:04 +02:00
2020-04-08 16:47:36 +02:00
_draw_viewport ( vp , XRInterface : : EYE_RIGHT ) ;
xr_interface - > commit_for_eye ( XRInterface : : EYE_RIGHT , vp - > render_target , vp - > viewport_to_screen_rect ) ;
2017-04-23 14:10:41 +02:00
}
2018-03-15 12:33:55 +01:00
2018-09-13 03:38:39 +02:00
// and for our frame timing, mark when we've finished committing our eyes
2020-04-08 16:47:36 +02:00
XRServer : : get_singleton ( ) - > _mark_commit ( ) ;
2017-04-23 14:10:41 +02:00
} else {
2019-06-16 04:45:24 +02:00
# endif
{
2020-03-27 19:21:27 +01:00
RSG : : storage - > render_target_set_external_texture ( vp - > render_target , 0 ) ;
2017-04-23 14:10:41 +02:00
2020-12-03 22:09:47 +01:00
RSG : : scene - > set_debug_draw_mode ( vp - > debug_draw ) ;
2020-03-27 19:21:27 +01:00
RSG : : storage - > render_info_begin_capture ( ) ;
2017-04-23 14:10:41 +02:00
// render standard mono camera
_draw_viewport ( vp ) ;
2020-03-27 19:21:27 +01:00
RSG : : storage - > render_info_end_capture ( ) ;
vp - > render_info [ RS : : VIEWPORT_RENDER_INFO_OBJECTS_IN_FRAME ] = RSG : : storage - > get_captured_render_info ( RS : : INFO_OBJECTS_IN_FRAME ) ;
vp - > render_info [ RS : : VIEWPORT_RENDER_INFO_VERTICES_IN_FRAME ] = RSG : : storage - > get_captured_render_info ( RS : : INFO_VERTICES_IN_FRAME ) ;
vp - > render_info [ RS : : VIEWPORT_RENDER_INFO_MATERIAL_CHANGES_IN_FRAME ] = RSG : : storage - > get_captured_render_info ( RS : : INFO_MATERIAL_CHANGES_IN_FRAME ) ;
vp - > render_info [ RS : : VIEWPORT_RENDER_INFO_SHADER_CHANGES_IN_FRAME ] = RSG : : storage - > get_captured_render_info ( RS : : INFO_SHADER_CHANGES_IN_FRAME ) ;
vp - > render_info [ RS : : VIEWPORT_RENDER_INFO_SURFACE_CHANGES_IN_FRAME ] = RSG : : storage - > get_captured_render_info ( RS : : INFO_SURFACE_CHANGES_IN_FRAME ) ;
vp - > render_info [ RS : : VIEWPORT_RENDER_INFO_DRAW_CALLS_IN_FRAME ] = RSG : : storage - > get_captured_render_info ( RS : : INFO_DRAW_CALLS_IN_FRAME ) ;
2017-04-23 14:10:41 +02:00
2020-03-27 19:21:27 +01:00
if ( vp - > viewport_to_screen ! = DisplayServer : : INVALID_WINDOW_ID & & ( ! vp - > viewport_render_direct_to_screen | | ! RSG : : rasterizer - > is_low_end ( ) ) ) {
2017-04-23 14:10:41 +02:00
//copy to screen if set as such
2020-12-04 19:26:24 +01:00
RendererCompositor : : BlitToScreen blit ;
2019-06-16 04:45:24 +02:00
blit . render_target = vp - > render_target ;
2020-03-04 02:51:12 +01:00
if ( vp - > viewport_to_screen_rect ! = Rect2 ( ) ) {
blit . rect = vp - > viewport_to_screen_rect ;
} else {
blit . rect . position = Vector2 ( ) ;
blit . rect . size = vp - > size ;
}
2019-06-16 04:45:24 +02:00
if ( ! blit_to_screen_list . has ( vp - > viewport_to_screen ) ) {
2020-12-04 19:26:24 +01:00
blit_to_screen_list [ vp - > viewport_to_screen ] = Vector < RendererCompositor : : BlitToScreen > ( ) ;
2019-06-16 04:45:24 +02:00
}
blit_to_screen_list [ vp - > viewport_to_screen ] . push_back ( blit ) ;
2017-04-23 14:10:41 +02:00
}
2016-10-03 21:33:42 +02:00
}
2020-03-27 19:21:27 +01:00
if ( vp - > update_mode = = RS : : VIEWPORT_UPDATE_ONCE ) {
vp - > update_mode = RS : : VIEWPORT_UPDATE_DISABLED ;
2016-10-03 21:33:42 +02:00
}
2019-09-20 22:58:06 +02:00
RENDER_TIMESTAMP ( " <Rendering Viewport " + itos ( i ) ) ;
2019-06-16 04:45:24 +02:00
}
2020-12-03 22:09:47 +01:00
RSG : : scene - > set_debug_draw_mode ( RS : : VIEWPORT_DEBUG_DRAW_DISABLED ) ;
2019-06-16 04:45:24 +02:00
2019-09-20 22:58:06 +02:00
RENDER_TIMESTAMP ( " <Render Viewports " ) ;
2019-06-24 21:13:06 +02:00
//this needs to be called to make screen swapping more efficient
2020-03-27 19:21:27 +01:00
RSG : : rasterizer - > prepare_for_blitting_render_targets ( ) ;
2019-06-24 21:13:06 +02:00
2020-12-04 19:26:24 +01:00
for ( Map < int , Vector < RendererCompositor : : BlitToScreen > > : : Element * E = blit_to_screen_list . front ( ) ; E ; E = E - > next ( ) ) {
2020-03-27 19:21:27 +01:00
RSG : : rasterizer - > blit_render_targets_to_screen ( E - > key ( ) , E - > get ( ) . ptr ( ) , E - > get ( ) . size ( ) ) ;
2016-10-03 21:33:42 +02:00
}
}
2021-02-09 17:19:03 +01:00
RID RendererViewport : : viewport_allocate ( ) {
return viewport_owner . allocate_rid ( ) ;
}
2016-10-03 21:33:42 +02:00
2021-02-09 17:19:03 +01:00
void RendererViewport : : viewport_initialize ( RID p_rid ) {
Viewport * viewport = memnew ( Viewport ) ;
viewport - > self = p_rid ;
2017-03-05 16:44:50 +01:00
viewport - > hide_scenario = false ;
viewport - > hide_canvas = false ;
2020-03-27 19:21:27 +01:00
viewport - > render_target = RSG : : storage - > render_target_create ( ) ;
2020-12-03 22:09:47 +01:00
viewport - > shadow_atlas = RSG : : scene - > shadow_atlas_create ( ) ;
2019-05-08 20:25:34 +02:00
viewport - > viewport_render_direct_to_screen = false ;
2016-10-03 21:33:42 +02:00
2021-02-09 17:19:03 +01:00
viewport_owner . initialize_rid ( p_rid , viewport ) ;
2016-10-03 21:33:42 +02:00
}
2020-12-04 19:26:24 +01:00
void RendererViewport : : viewport_set_use_xr ( RID p_viewport , bool p_use_xr ) {
2017-04-23 14:10:41 +02:00
Viewport * viewport = viewport_owner . getornull ( p_viewport ) ;
ERR_FAIL_COND ( ! viewport ) ;
2020-04-08 16:47:36 +02:00
viewport - > use_xr = p_use_xr ;
2017-04-23 14:10:41 +02:00
}
2020-12-04 19:26:24 +01:00
void RendererViewport : : viewport_set_size ( RID p_viewport , int p_width , int p_height ) {
2017-03-05 16:44:50 +01:00
ERR_FAIL_COND ( p_width < 0 & & p_height < 0 ) ;
2016-10-03 21:33:42 +02:00
2017-03-05 16:44:50 +01:00
Viewport * viewport = viewport_owner . getornull ( p_viewport ) ;
2016-10-03 21:33:42 +02:00
ERR_FAIL_COND ( ! viewport ) ;
2017-03-05 16:44:50 +01:00
viewport - > size = Size2 ( p_width , p_height ) ;
2020-03-27 19:21:27 +01:00
RSG : : storage - > render_target_set_size ( viewport - > render_target , p_width , p_height ) ;
2019-08-19 00:40:52 +02:00
if ( viewport - > render_buffers . is_valid ( ) ) {
2020-03-04 02:51:12 +01:00
if ( p_width = = 0 | | p_height = = 0 ) {
2020-12-03 22:09:47 +01:00
RSG : : scene - > free ( viewport - > render_buffers ) ;
2020-03-04 02:51:12 +01:00
viewport - > render_buffers = RID ( ) ;
} else {
2020-12-03 22:09:47 +01:00
RSG : : scene - > render_buffers_configure ( viewport - > render_buffers , viewport - > render_target , viewport - > size . width , viewport - > size . height , viewport - > msaa , viewport - > screen_space_aa , viewport - > use_debanding ) ;
2020-03-04 02:51:12 +01:00
}
2019-08-19 00:40:52 +02:00
}
2016-10-03 21:33:42 +02:00
}
2020-12-04 19:26:24 +01:00
void RendererViewport : : viewport_set_active ( RID p_viewport , bool p_active ) {
2017-03-05 16:44:50 +01:00
Viewport * viewport = viewport_owner . getornull ( p_viewport ) ;
2016-10-03 21:33:42 +02:00
ERR_FAIL_COND ( ! viewport ) ;
if ( p_active ) {
2017-03-05 16:44:50 +01:00
ERR_FAIL_COND ( active_viewports . find ( viewport ) ! = - 1 ) ; //already active
2016-10-03 21:33:42 +02:00
active_viewports . push_back ( viewport ) ;
} else {
active_viewports . erase ( viewport ) ;
}
}
2020-12-04 19:26:24 +01:00
void RendererViewport : : viewport_set_parent_viewport ( RID p_viewport , RID p_parent_viewport ) {
2017-03-05 16:44:50 +01:00
Viewport * viewport = viewport_owner . getornull ( p_viewport ) ;
2016-10-05 06:26:35 +02:00
ERR_FAIL_COND ( ! viewport ) ;
2017-03-05 16:44:50 +01:00
viewport - > parent = p_parent_viewport ;
2016-10-05 06:26:35 +02:00
}
2020-12-04 19:26:24 +01:00
void RendererViewport : : viewport_set_clear_mode ( RID p_viewport , RS : : ViewportClearMode p_clear_mode ) {
2017-03-05 16:44:50 +01:00
Viewport * viewport = viewport_owner . getornull ( p_viewport ) ;
2016-10-03 21:33:42 +02:00
ERR_FAIL_COND ( ! viewport ) ;
2017-03-05 16:44:50 +01:00
viewport - > clear_mode = p_clear_mode ;
2016-10-03 21:33:42 +02:00
}
2020-12-04 19:26:24 +01:00
void RendererViewport : : viewport_attach_to_screen ( RID p_viewport , const Rect2 & p_rect , DisplayServer : : WindowID p_screen ) {
2017-03-05 16:44:50 +01:00
Viewport * viewport = viewport_owner . getornull ( p_viewport ) ;
2016-10-03 21:33:42 +02:00
ERR_FAIL_COND ( ! viewport ) ;
2020-03-04 02:51:12 +01:00
if ( p_screen ! = DisplayServer : : INVALID_WINDOW_ID ) {
// If using GLES2 we can optimize this operation by rendering directly to system_fbo
// instead of rendering to fbo and copying to system_fbo after
2020-03-27 19:21:27 +01:00
if ( RSG : : rasterizer - > is_low_end ( ) & & viewport - > viewport_render_direct_to_screen ) {
RSG : : storage - > render_target_set_size ( viewport - > render_target , p_rect . size . x , p_rect . size . y ) ;
RSG : : storage - > render_target_set_position ( viewport - > render_target , p_rect . position . x , p_rect . position . y ) ;
2020-03-04 02:51:12 +01:00
}
2019-05-08 20:25:34 +02:00
2020-03-04 02:51:12 +01:00
viewport - > viewport_to_screen_rect = p_rect ;
viewport - > viewport_to_screen = p_screen ;
} else {
// if render_direct_to_screen was used, reset size and position
2020-03-27 19:21:27 +01:00
if ( RSG : : rasterizer - > is_low_end ( ) & & viewport - > viewport_render_direct_to_screen ) {
RSG : : storage - > render_target_set_position ( viewport - > render_target , 0 , 0 ) ;
RSG : : storage - > render_target_set_size ( viewport - > render_target , viewport - > size . x , viewport - > size . y ) ;
2020-03-04 02:51:12 +01:00
}
viewport - > viewport_to_screen_rect = Rect2 ( ) ;
viewport - > viewport_to_screen = DisplayServer : : INVALID_WINDOW_ID ;
}
2016-10-03 21:33:42 +02:00
}
2019-05-08 20:25:34 +02:00
2020-12-04 19:26:24 +01:00
void RendererViewport : : viewport_set_render_direct_to_screen ( RID p_viewport , bool p_enable ) {
2019-05-08 20:25:34 +02:00
Viewport * viewport = viewport_owner . getornull ( p_viewport ) ;
ERR_FAIL_COND ( ! viewport ) ;
2020-05-14 16:41:43 +02:00
if ( p_enable = = viewport - > viewport_render_direct_to_screen ) {
2019-05-08 20:25:34 +02:00
return ;
2020-05-14 16:41:43 +02:00
}
2019-05-08 20:25:34 +02:00
// if disabled, reset render_target size and position
if ( ! p_enable ) {
2020-03-27 19:21:27 +01:00
RSG : : storage - > render_target_set_position ( viewport - > render_target , 0 , 0 ) ;
RSG : : storage - > render_target_set_size ( viewport - > render_target , viewport - > size . x , viewport - > size . y ) ;
2019-05-08 20:25:34 +02:00
}
2020-12-04 19:26:24 +01:00
RSG : : storage - > render_target_set_flag ( viewport - > render_target , RendererStorage : : RENDER_TARGET_DIRECT_TO_SCREEN , p_enable ) ;
2019-05-08 20:25:34 +02:00
viewport - > viewport_render_direct_to_screen = p_enable ;
Fix misc. source comment typos
Found using `codespell -q 3 -S ./thirdparty,*.po -L ang,ba,cas,dof,doubleclick,fave,hist,leapyear,lod,nd,numer,ois,paket,seeked,sinc,switchs,te,uint -D ~/Projects/codespell/codespell_lib/data/dictionary.txt `
2019-09-19 20:36:39 +02:00
// if attached to screen already, setup screen size and position, this needs to happen after setting flag to avoid an unnecessary buffer allocation
2020-03-27 19:21:27 +01:00
if ( RSG : : rasterizer - > is_low_end ( ) & & viewport - > viewport_to_screen_rect ! = Rect2 ( ) & & p_enable ) {
RSG : : storage - > render_target_set_size ( viewport - > render_target , viewport - > viewport_to_screen_rect . size . x , viewport - > viewport_to_screen_rect . size . y ) ;
RSG : : storage - > render_target_set_position ( viewport - > render_target , viewport - > viewport_to_screen_rect . position . x , viewport - > viewport_to_screen_rect . position . y ) ;
2019-05-08 20:25:34 +02:00
}
}
2020-12-04 19:26:24 +01:00
void RendererViewport : : viewport_set_update_mode ( RID p_viewport , RS : : ViewportUpdateMode p_mode ) {
2017-03-05 16:44:50 +01:00
Viewport * viewport = viewport_owner . getornull ( p_viewport ) ;
2016-10-03 21:33:42 +02:00
ERR_FAIL_COND ( ! viewport ) ;
2017-03-05 16:44:50 +01:00
viewport - > update_mode = p_mode ;
2016-10-03 21:33:42 +02:00
}
2020-12-04 19:26:24 +01:00
RID RendererViewport : : viewport_get_texture ( RID p_viewport ) const {
2017-03-05 16:44:50 +01:00
const Viewport * viewport = viewport_owner . getornull ( p_viewport ) ;
ERR_FAIL_COND_V ( ! viewport , RID ( ) ) ;
2016-10-03 21:33:42 +02:00
2020-03-27 19:21:27 +01:00
return RSG : : storage - > render_target_get_texture ( viewport - > render_target ) ;
2016-10-03 21:33:42 +02:00
}
2020-12-04 19:26:24 +01:00
void RendererViewport : : viewport_set_hide_scenario ( RID p_viewport , bool p_hide ) {
2017-03-05 16:44:50 +01:00
Viewport * viewport = viewport_owner . getornull ( p_viewport ) ;
2016-10-03 21:33:42 +02:00
ERR_FAIL_COND ( ! viewport ) ;
2017-03-05 16:44:50 +01:00
viewport - > hide_scenario = p_hide ;
2016-10-03 21:33:42 +02:00
}
2020-05-14 14:29:06 +02:00
2020-12-04 19:26:24 +01:00
void RendererViewport : : viewport_set_hide_canvas ( RID p_viewport , bool p_hide ) {
2017-03-05 16:44:50 +01:00
Viewport * viewport = viewport_owner . getornull ( p_viewport ) ;
2016-10-03 21:33:42 +02:00
ERR_FAIL_COND ( ! viewport ) ;
2017-03-05 16:44:50 +01:00
viewport - > hide_canvas = p_hide ;
2016-10-03 21:33:42 +02:00
}
2020-05-14 14:29:06 +02:00
2020-12-04 19:26:24 +01:00
void RendererViewport : : viewport_set_disable_environment ( RID p_viewport , bool p_disable ) {
2017-03-05 16:44:50 +01:00
Viewport * viewport = viewport_owner . getornull ( p_viewport ) ;
2016-10-03 21:33:42 +02:00
ERR_FAIL_COND ( ! viewport ) ;
2017-03-05 16:44:50 +01:00
viewport - > disable_environment = p_disable ;
2016-10-03 21:33:42 +02:00
}
2020-12-04 19:26:24 +01:00
void RendererViewport : : viewport_attach_camera ( RID p_viewport , RID p_camera ) {
2017-03-05 16:44:50 +01:00
Viewport * viewport = viewport_owner . getornull ( p_viewport ) ;
2016-10-03 21:33:42 +02:00
ERR_FAIL_COND ( ! viewport ) ;
2017-03-05 16:44:50 +01:00
viewport - > camera = p_camera ;
2016-10-03 21:33:42 +02:00
}
2020-05-14 14:29:06 +02:00
2020-12-04 19:26:24 +01:00
void RendererViewport : : viewport_set_scenario ( RID p_viewport , RID p_scenario ) {
2017-03-05 16:44:50 +01:00
Viewport * viewport = viewport_owner . getornull ( p_viewport ) ;
2016-10-03 21:33:42 +02:00
ERR_FAIL_COND ( ! viewport ) ;
2017-03-05 16:44:50 +01:00
viewport - > scenario = p_scenario ;
2016-10-03 21:33:42 +02:00
}
2020-05-14 14:29:06 +02:00
2020-12-04 19:26:24 +01:00
void RendererViewport : : viewport_attach_canvas ( RID p_viewport , RID p_canvas ) {
2017-03-05 16:44:50 +01:00
Viewport * viewport = viewport_owner . getornull ( p_viewport ) ;
2016-10-03 21:33:42 +02:00
ERR_FAIL_COND ( ! viewport ) ;
ERR_FAIL_COND ( viewport - > canvas_map . has ( p_canvas ) ) ;
2020-12-04 19:26:24 +01:00
RendererCanvasCull : : Canvas * canvas = RSG : : canvas - > canvas_owner . getornull ( p_canvas ) ;
2016-10-03 21:33:42 +02:00
ERR_FAIL_COND ( ! canvas ) ;
canvas - > viewports . insert ( p_viewport ) ;
2017-03-05 16:44:50 +01:00
viewport - > canvas_map [ p_canvas ] = Viewport : : CanvasData ( ) ;
viewport - > canvas_map [ p_canvas ] . layer = 0 ;
2018-10-30 21:53:00 +01:00
viewport - > canvas_map [ p_canvas ] . sublayer = 0 ;
2017-03-05 16:44:50 +01:00
viewport - > canvas_map [ p_canvas ] . canvas = canvas ;
2016-10-03 21:33:42 +02:00
}
2020-12-04 19:26:24 +01:00
void RendererViewport : : viewport_remove_canvas ( RID p_viewport , RID p_canvas ) {
2017-03-05 16:44:50 +01:00
Viewport * viewport = viewport_owner . getornull ( p_viewport ) ;
2016-10-03 21:33:42 +02:00
ERR_FAIL_COND ( ! viewport ) ;
2020-12-04 19:26:24 +01:00
RendererCanvasCull : : Canvas * canvas = RSG : : canvas - > canvas_owner . getornull ( p_canvas ) ;
2016-10-03 21:33:42 +02:00
ERR_FAIL_COND ( ! canvas ) ;
viewport - > canvas_map . erase ( p_canvas ) ;
canvas - > viewports . erase ( p_viewport ) ;
}
2020-05-14 14:29:06 +02:00
2020-12-04 19:26:24 +01:00
void RendererViewport : : viewport_set_canvas_transform ( RID p_viewport , RID p_canvas , const Transform2D & p_offset ) {
2017-03-05 16:44:50 +01:00
Viewport * viewport = viewport_owner . getornull ( p_viewport ) ;
2016-10-03 21:33:42 +02:00
ERR_FAIL_COND ( ! viewport ) ;
ERR_FAIL_COND ( ! viewport - > canvas_map . has ( p_canvas ) ) ;
2017-03-05 16:44:50 +01:00
viewport - > canvas_map [ p_canvas ] . transform = p_offset ;
2016-10-03 21:33:42 +02:00
}
2020-05-14 14:29:06 +02:00
2020-12-04 19:26:24 +01:00
void RendererViewport : : viewport_set_transparent_background ( RID p_viewport , bool p_enabled ) {
2017-03-05 16:44:50 +01:00
Viewport * viewport = viewport_owner . getornull ( p_viewport ) ;
2016-10-03 21:33:42 +02:00
ERR_FAIL_COND ( ! viewport ) ;
2020-12-04 19:26:24 +01:00
RSG : : storage - > render_target_set_flag ( viewport - > render_target , RendererStorage : : RENDER_TARGET_TRANSPARENT , p_enabled ) ;
2018-01-18 19:11:07 +01:00
viewport - > transparent_bg = p_enabled ;
2016-10-03 21:33:42 +02:00
}
2020-12-04 19:26:24 +01:00
void RendererViewport : : viewport_set_global_canvas_transform ( RID p_viewport , const Transform2D & p_transform ) {
2017-03-05 16:44:50 +01:00
Viewport * viewport = viewport_owner . getornull ( p_viewport ) ;
2016-10-03 21:33:42 +02:00
ERR_FAIL_COND ( ! viewport ) ;
2017-03-05 16:44:50 +01:00
viewport - > global_transform = p_transform ;
2016-10-03 21:33:42 +02:00
}
2020-05-14 14:29:06 +02:00
2020-12-04 19:26:24 +01:00
void RendererViewport : : viewport_set_canvas_stacking ( RID p_viewport , RID p_canvas , int p_layer , int p_sublayer ) {
2017-03-05 16:44:50 +01:00
Viewport * viewport = viewport_owner . getornull ( p_viewport ) ;
2016-10-03 21:33:42 +02:00
ERR_FAIL_COND ( ! viewport ) ;
ERR_FAIL_COND ( ! viewport - > canvas_map . has ( p_canvas ) ) ;
2017-03-05 16:44:50 +01:00
viewport - > canvas_map [ p_canvas ] . layer = p_layer ;
2018-10-30 21:53:00 +01:00
viewport - > canvas_map [ p_canvas ] . sublayer = p_sublayer ;
2016-10-03 21:33:42 +02:00
}
2021-01-24 20:00:20 +01:00
void RendererViewport : : viewport_set_shadow_atlas_size ( RID p_viewport , int p_size , bool p_16_bits ) {
2017-03-05 16:44:50 +01:00
Viewport * viewport = viewport_owner . getornull ( p_viewport ) ;
2016-11-10 03:55:06 +01:00
ERR_FAIL_COND ( ! viewport ) ;
2017-03-05 16:44:50 +01:00
viewport - > shadow_atlas_size = p_size ;
2021-01-24 20:00:20 +01:00
viewport - > shadow_atlas_16_bits = p_16_bits ;
2016-11-10 03:55:06 +01:00
2021-01-24 20:00:20 +01:00
RSG : : scene - > shadow_atlas_set_size ( viewport - > shadow_atlas , viewport - > shadow_atlas_size , viewport - > shadow_atlas_16_bits ) ;
2016-11-10 03:55:06 +01:00
}
2020-12-04 19:26:24 +01:00
void RendererViewport : : viewport_set_shadow_atlas_quadrant_subdivision ( RID p_viewport , int p_quadrant , int p_subdiv ) {
2017-03-05 16:44:50 +01:00
Viewport * viewport = viewport_owner . getornull ( p_viewport ) ;
2016-11-10 03:55:06 +01:00
ERR_FAIL_COND ( ! viewport ) ;
2020-12-03 22:09:47 +01:00
RSG : : scene - > shadow_atlas_set_quadrant_subdivision ( viewport - > shadow_atlas , p_quadrant , p_subdiv ) ;
2016-11-10 03:55:06 +01:00
}
2020-12-04 19:26:24 +01:00
void RendererViewport : : viewport_set_msaa ( RID p_viewport , RS : : ViewportMSAA p_msaa ) {
2017-03-05 16:44:50 +01:00
Viewport * viewport = viewport_owner . getornull ( p_viewport ) ;
2017-01-02 02:16:52 +01:00
ERR_FAIL_COND ( ! viewport ) ;
2019-08-19 00:40:52 +02:00
if ( viewport - > msaa = = p_msaa ) {
return ;
}
viewport - > msaa = p_msaa ;
if ( viewport - > render_buffers . is_valid ( ) ) {
2020-12-03 22:09:47 +01:00
RSG : : scene - > render_buffers_configure ( viewport - > render_buffers , viewport - > render_target , viewport - > size . width , viewport - > size . height , p_msaa , viewport - > screen_space_aa , viewport - > use_debanding ) ;
2020-04-12 06:49:10 +02:00
}
}
2020-12-04 19:26:24 +01:00
void RendererViewport : : viewport_set_screen_space_aa ( RID p_viewport , RS : : ViewportScreenSpaceAA p_mode ) {
2020-04-12 06:49:10 +02:00
Viewport * viewport = viewport_owner . getornull ( p_viewport ) ;
ERR_FAIL_COND ( ! viewport ) ;
if ( viewport - > screen_space_aa = = p_mode ) {
return ;
}
viewport - > screen_space_aa = p_mode ;
if ( viewport - > render_buffers . is_valid ( ) ) {
2020-12-03 22:09:47 +01:00
RSG : : scene - > render_buffers_configure ( viewport - > render_buffers , viewport - > render_target , viewport - > size . width , viewport - > size . height , viewport - > msaa , p_mode , viewport - > use_debanding ) ;
2020-04-20 23:34:47 +02:00
}
}
2020-12-04 19:26:24 +01:00
void RendererViewport : : viewport_set_use_debanding ( RID p_viewport , bool p_use_debanding ) {
2020-04-20 23:34:47 +02:00
Viewport * viewport = viewport_owner . getornull ( p_viewport ) ;
ERR_FAIL_COND ( ! viewport ) ;
if ( viewport - > use_debanding = = p_use_debanding ) {
return ;
}
viewport - > use_debanding = p_use_debanding ;
if ( viewport - > render_buffers . is_valid ( ) ) {
2020-12-03 22:09:47 +01:00
RSG : : scene - > render_buffers_configure ( viewport - > render_buffers , viewport - > render_target , viewport - > size . width , viewport - > size . height , viewport - > msaa , viewport - > screen_space_aa , p_use_debanding ) ;
2017-06-09 05:23:50 +02:00
}
}
2020-12-17 19:56:59 +01:00
void RendererViewport : : viewport_set_lod_threshold ( RID p_viewport , float p_pixels ) {
Viewport * viewport = viewport_owner . getornull ( p_viewport ) ;
ERR_FAIL_COND ( ! viewport ) ;
viewport - > lod_threshold = p_pixels ;
}
2020-12-04 19:26:24 +01:00
int RendererViewport : : viewport_get_render_info ( RID p_viewport , RS : : ViewportRenderInfo p_info ) {
2020-03-27 19:21:27 +01:00
ERR_FAIL_INDEX_V ( p_info , RS : : VIEWPORT_RENDER_INFO_MAX , - 1 ) ;
2017-06-11 23:13:04 +02:00
2017-06-11 20:52:03 +02:00
Viewport * viewport = viewport_owner . getornull ( p_viewport ) ;
2020-05-14 16:41:43 +02:00
if ( ! viewport ) {
2017-06-11 23:13:04 +02:00
return 0 ; //there should be a lock here..
2020-05-14 16:41:43 +02:00
}
2017-06-11 20:52:03 +02:00
return viewport - > render_info [ p_info ] ;
}
2020-12-04 19:26:24 +01:00
void RendererViewport : : viewport_set_debug_draw ( RID p_viewport , RS : : ViewportDebugDraw p_draw ) {
2017-06-11 20:52:03 +02:00
Viewport * viewport = viewport_owner . getornull ( p_viewport ) ;
ERR_FAIL_COND ( ! viewport ) ;
viewport - > debug_draw = p_draw ;
}
2020-12-04 19:26:24 +01:00
void RendererViewport : : viewport_set_measure_render_time ( RID p_viewport , bool p_enable ) {
2020-04-10 19:18:42 +02:00
Viewport * viewport = viewport_owner . getornull ( p_viewport ) ;
ERR_FAIL_COND ( ! viewport ) ;
viewport - > measure_render_time = p_enable ;
}
2020-12-04 19:26:24 +01:00
float RendererViewport : : viewport_get_measured_render_time_cpu ( RID p_viewport ) const {
2020-04-10 19:18:42 +02:00
Viewport * viewport = viewport_owner . getornull ( p_viewport ) ;
ERR_FAIL_COND_V ( ! viewport , 0 ) ;
return double ( viewport - > time_cpu_end - viewport - > time_cpu_begin ) / 1000.0 ;
}
2020-12-04 19:26:24 +01:00
float RendererViewport : : viewport_get_measured_render_time_gpu ( RID p_viewport ) const {
2020-04-10 19:18:42 +02:00
Viewport * viewport = viewport_owner . getornull ( p_viewport ) ;
ERR_FAIL_COND_V ( ! viewport , 0 ) ;
return double ( ( viewport - > time_gpu_end - viewport - > time_gpu_begin ) / 1000 ) / 1000.0 ;
}
2020-12-04 19:26:24 +01:00
void RendererViewport : : viewport_set_snap_2d_transforms_to_pixel ( RID p_viewport , bool p_enabled ) {
2020-10-29 22:09:16 +01:00
Viewport * viewport = viewport_owner . getornull ( p_viewport ) ;
ERR_FAIL_COND ( ! viewport ) ;
viewport - > snap_2d_transforms_to_pixel = p_enabled ;
}
2020-12-04 19:26:24 +01:00
void RendererViewport : : viewport_set_snap_2d_vertices_to_pixel ( RID p_viewport , bool p_enabled ) {
2020-10-29 22:09:16 +01:00
Viewport * viewport = viewport_owner . getornull ( p_viewport ) ;
ERR_FAIL_COND ( ! viewport ) ;
viewport - > snap_2d_vertices_to_pixel = p_enabled ;
}
2020-12-04 19:26:24 +01:00
void RendererViewport : : viewport_set_default_canvas_item_texture_filter ( RID p_viewport , RS : : CanvasItemTextureFilter p_filter ) {
2020-10-24 17:15:43 +02:00
ERR_FAIL_COND_MSG ( p_filter = = RS : : CANVAS_ITEM_TEXTURE_FILTER_DEFAULT , " Viewport does not accept DEFAULT as texture filter (it's the topmost choice already).) " ) ;
Viewport * viewport = viewport_owner . getornull ( p_viewport ) ;
ERR_FAIL_COND ( ! viewport ) ;
viewport - > texture_filter = p_filter ;
}
2020-12-04 19:26:24 +01:00
void RendererViewport : : viewport_set_default_canvas_item_texture_repeat ( RID p_viewport , RS : : CanvasItemTextureRepeat p_repeat ) {
2020-10-24 17:15:43 +02:00
ERR_FAIL_COND_MSG ( p_repeat = = RS : : CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT , " Viewport does not accept DEFAULT as texture repeat (it's the topmost choice already).) " ) ;
Viewport * viewport = viewport_owner . getornull ( p_viewport ) ;
ERR_FAIL_COND ( ! viewport ) ;
viewport - > texture_repeat = p_repeat ;
}
2020-12-04 19:26:24 +01:00
void RendererViewport : : viewport_set_sdf_oversize_and_scale ( RID p_viewport , RS : : ViewportSDFOversize p_size , RS : : ViewportSDFScale p_scale ) {
2020-11-26 13:50:21 +01:00
Viewport * viewport = viewport_owner . getornull ( p_viewport ) ;
ERR_FAIL_COND ( ! viewport ) ;
RSG : : storage - > render_target_set_sdf_size_and_scale ( viewport - > render_target , p_size , p_scale ) ;
}
2020-12-04 19:26:24 +01:00
bool RendererViewport : : free ( RID p_rid ) {
2016-11-19 17:23:37 +01:00
if ( viewport_owner . owns ( p_rid ) ) {
2017-03-05 16:44:50 +01:00
Viewport * viewport = viewport_owner . getornull ( p_rid ) ;
2016-10-03 21:33:42 +02:00
2020-03-27 19:21:27 +01:00
RSG : : storage - > free ( viewport - > render_target ) ;
2020-12-03 22:09:47 +01:00
RSG : : scene - > free ( viewport - > shadow_atlas ) ;
2019-08-19 00:40:52 +02:00
if ( viewport - > render_buffers . is_valid ( ) ) {
2020-12-03 22:09:47 +01:00
RSG : : scene - > free ( viewport - > render_buffers ) ;
2019-08-19 00:40:52 +02:00
}
2016-11-19 17:23:37 +01:00
2017-03-05 16:44:50 +01:00
while ( viewport - > canvas_map . front ( ) ) {
viewport_remove_canvas ( p_rid , viewport - > canvas_map . front ( ) - > key ( ) ) ;
2016-11-19 17:23:37 +01:00
}
2016-10-03 21:33:42 +02:00
2017-03-05 16:44:50 +01:00
viewport_set_scenario ( p_rid , RID ( ) ) ;
2016-11-19 17:23:37 +01:00
active_viewports . erase ( viewport ) ;
viewport_owner . free ( p_rid ) ;
memdelete ( viewport ) ;
2016-10-03 21:33:42 +02:00
2016-11-19 17:23:37 +01:00
return true ;
}
2016-10-03 21:33:42 +02:00
2016-11-19 17:23:37 +01:00
return false ;
2016-10-03 21:33:42 +02:00
}
2020-12-04 19:26:24 +01:00
void RendererViewport : : handle_timestamp ( String p_timestamp , uint64_t p_cpu_time , uint64_t p_gpu_time ) {
2020-04-10 19:18:42 +02:00
RID * vp = timestamp_vp_map . getptr ( p_timestamp ) ;
if ( ! vp ) {
return ;
}
Viewport * viewport = viewport_owner . getornull ( * vp ) ;
if ( ! viewport ) {
return ;
}
if ( p_timestamp . begins_with ( " vp_begin " ) ) {
viewport - > time_cpu_begin = p_cpu_time ;
viewport - > time_gpu_begin = p_gpu_time ;
}
if ( p_timestamp . begins_with ( " vp_end " ) ) {
viewport - > time_cpu_end = p_cpu_time ;
viewport - > time_gpu_end = p_gpu_time ;
}
}
2020-12-04 19:26:24 +01:00
void RendererViewport : : set_default_clear_color ( const Color & p_color ) {
2020-03-27 19:21:27 +01:00
RSG : : storage - > set_default_clear_color ( p_color ) ;
2018-07-29 20:09:42 +02:00
}
2021-02-09 17:19:03 +01:00
//workaround for setting this on thread
void RendererViewport : : call_set_use_vsync ( bool p_enable ) {
DisplayServer : : get_singleton ( ) - > _set_use_vsync ( p_enable ) ;
}
2020-12-04 19:26:24 +01:00
RendererViewport : : RendererViewport ( ) {
2016-10-03 21:33:42 +02:00
}