1 /*************************************************************************/
2 /*  visual_server_viewport.cpp                                           */
3 /*************************************************************************/
4 /*                       This file is part of:                           */
5 /*                           GODOT ENGINE                                */
6 /*                      https://godotengine.org                          */
7 /*************************************************************************/
8 /* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.                 */
9 /* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).   */
10 /*                                                                       */
11 /* Permission is hereby granted, free of charge, to any person obtaining */
12 /* a copy of this software and associated documentation files (the       */
13 /* "Software"), to deal in the Software without restriction, including   */
14 /* without limitation the rights to use, copy, modify, merge, publish,   */
15 /* distribute, sublicense, and/or sell copies of the Software, and to    */
16 /* permit persons to whom the Software is furnished to do so, subject to */
17 /* the following conditions:                                             */
18 /*                                                                       */
19 /* The above copyright notice and this permission notice shall be        */
20 /* included in all copies or substantial portions of the Software.       */
21 /*                                                                       */
22 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
23 /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
24 /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
25 /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
26 /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
27 /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
28 /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
29 /*************************************************************************/
30 
31 #include "visual_server_viewport.h"
32 
33 #include "core/project_settings.h"
34 #include "visual_server_canvas.h"
35 #include "visual_server_globals.h"
36 #include "visual_server_scene.h"
37 
_canvas_get_transform(VisualServerViewport::Viewport * p_viewport,VisualServerCanvas::Canvas * p_canvas,VisualServerViewport::Viewport::CanvasData * p_canvas_data,const Vector2 & p_vp_size)38 static Transform2D _canvas_get_transform(VisualServerViewport::Viewport *p_viewport, VisualServerCanvas::Canvas *p_canvas, VisualServerViewport::Viewport::CanvasData *p_canvas_data, const Vector2 &p_vp_size) {
39 
40 	Transform2D xf = p_viewport->global_transform;
41 
42 	float scale = 1.0;
43 	if (p_viewport->canvas_map.has(p_canvas->parent)) {
44 		xf = xf * p_viewport->canvas_map[p_canvas->parent].transform;
45 		scale = p_canvas->parent_scale;
46 	}
47 
48 	xf = xf * p_canvas_data->transform;
49 
50 	if (scale != 1.0 && !VSG::canvas->disable_scale) {
51 		Vector2 pivot = p_vp_size * 0.5;
52 		Transform2D xfpivot;
53 		xfpivot.set_origin(pivot);
54 		Transform2D xfscale;
55 		xfscale.scale(Vector2(scale, scale));
56 
57 		xf = xfpivot.affine_inverse() * xf;
58 		xf = xfscale * xf;
59 		xf = xfpivot * xf;
60 	}
61 
62 	return xf;
63 }
64 
_draw_3d(Viewport * p_viewport,ARVRInterface::Eyes p_eye)65 void VisualServerViewport::_draw_3d(Viewport *p_viewport, ARVRInterface::Eyes p_eye) {
66 	Ref<ARVRInterface> arvr_interface;
67 	if (ARVRServer::get_singleton() != NULL) {
68 		arvr_interface = ARVRServer::get_singleton()->get_primary_interface();
69 	}
70 
71 	if (p_viewport->use_arvr && arvr_interface.is_valid()) {
72 		VSG::scene->render_camera(arvr_interface, p_eye, p_viewport->camera, p_viewport->scenario, p_viewport->size, p_viewport->shadow_atlas);
73 	} else {
74 		VSG::scene->render_camera(p_viewport->camera, p_viewport->scenario, p_viewport->size, p_viewport->shadow_atlas);
75 	}
76 }
77 
_draw_viewport(Viewport * p_viewport,ARVRInterface::Eyes p_eye)78 void VisualServerViewport::_draw_viewport(Viewport *p_viewport, ARVRInterface::Eyes p_eye) {
79 
80 	/* Camera should always be BEFORE any other 3D */
81 
82 	bool scenario_draw_canvas_bg = false; //draw canvas, or some layer of it, as BG for 3D instead of in front
83 	int scenario_canvas_max_layer = 0;
84 
85 	if (!p_viewport->hide_canvas && !p_viewport->disable_environment && VSG::scene->scenario_owner.owns(p_viewport->scenario)) {
86 
87 		VisualServerScene::Scenario *scenario = VSG::scene->scenario_owner.get(p_viewport->scenario);
88 		ERR_FAIL_COND(!scenario);
89 		if (VSG::scene_render->is_environment(scenario->environment)) {
90 			scenario_draw_canvas_bg = VSG::scene_render->environment_get_background(scenario->environment) == VS::ENV_BG_CANVAS;
91 
92 			scenario_canvas_max_layer = VSG::scene_render->environment_get_canvas_max_layer(scenario->environment);
93 		}
94 	}
95 
96 	bool can_draw_3d = !p_viewport->disable_3d && !p_viewport->disable_3d_by_usage && VSG::scene->camera_owner.owns(p_viewport->camera);
97 
98 	if (p_viewport->clear_mode != VS::VIEWPORT_CLEAR_NEVER) {
99 		VSG::rasterizer->clear_render_target(p_viewport->transparent_bg ? Color(0, 0, 0, 0) : clear_color);
100 		if (p_viewport->clear_mode == VS::VIEWPORT_CLEAR_ONLY_NEXT_FRAME) {
101 			p_viewport->clear_mode = VS::VIEWPORT_CLEAR_NEVER;
102 		}
103 	}
104 
105 	if (!scenario_draw_canvas_bg && can_draw_3d) {
106 		_draw_3d(p_viewport, p_eye);
107 	}
108 
109 	if (!p_viewport->hide_canvas) {
110 		int i = 0;
111 
112 		Map<Viewport::CanvasKey, Viewport::CanvasData *> canvas_map;
113 
114 		Rect2 clip_rect(0, 0, p_viewport->size.x, p_viewport->size.y);
115 		RasterizerCanvas::Light *lights = NULL;
116 		RasterizerCanvas::Light *lights_with_shadow = NULL;
117 		RasterizerCanvas::Light *lights_with_mask = NULL;
118 		Rect2 shadow_rect;
119 
120 		int light_count = 0;
121 
122 		for (Map<RID, Viewport::CanvasData>::Element *E = p_viewport->canvas_map.front(); E; E = E->next()) {
123 
124 			VisualServerCanvas::Canvas *canvas = static_cast<VisualServerCanvas::Canvas *>(E->get().canvas);
125 
126 			Transform2D xf = _canvas_get_transform(p_viewport, canvas, &E->get(), clip_rect.size);
127 
128 			//find lights in canvas
129 
130 			for (Set<RasterizerCanvas::Light *>::Element *F = canvas->lights.front(); F; F = F->next()) {
131 
132 				RasterizerCanvas::Light *cl = F->get();
133 				if (cl->enabled && cl->texture.is_valid()) {
134 					//not super efficient..
135 					Size2 tsize = VSG::storage->texture_size_with_proxy(cl->texture);
136 					tsize *= cl->scale;
137 
138 					Vector2 offset = tsize / 2.0;
139 					cl->rect_cache = Rect2(-offset + cl->texture_offset, tsize);
140 					cl->xform_cache = xf * cl->xform;
141 
142 					if (clip_rect.intersects_transformed(cl->xform_cache, cl->rect_cache)) {
143 
144 						cl->filter_next_ptr = lights;
145 						lights = cl;
146 						cl->texture_cache = NULL;
147 						Transform2D scale;
148 						scale.scale(cl->rect_cache.size);
149 						scale.elements[2] = cl->rect_cache.position;
150 						cl->light_shader_xform = (cl->xform_cache * scale).affine_inverse();
151 						cl->light_shader_pos = cl->xform_cache[2];
152 						if (cl->shadow_buffer.is_valid()) {
153 
154 							cl->shadows_next_ptr = lights_with_shadow;
155 							if (lights_with_shadow == NULL) {
156 								shadow_rect = cl->xform_cache.xform(cl->rect_cache);
157 							} else {
158 								shadow_rect = shadow_rect.merge(cl->xform_cache.xform(cl->rect_cache));
159 							}
160 							lights_with_shadow = cl;
161 							cl->radius_cache = cl->rect_cache.size.length();
162 						}
163 						if (cl->mode == VS::CANVAS_LIGHT_MODE_MASK) {
164 							cl->mask_next_ptr = lights_with_mask;
165 							lights_with_mask = cl;
166 						}
167 
168 						light_count++;
169 					}
170 
171 					VSG::canvas_render->light_internal_update(cl->light_internal, cl);
172 				}
173 			}
174 
175 			canvas_map[Viewport::CanvasKey(E->key(), E->get().layer, E->get().sublayer)] = &E->get();
176 		}
177 
178 		if (lights_with_shadow) {
179 			//update shadows if any
180 
181 			RasterizerCanvas::LightOccluderInstance *occluders = NULL;
182 
183 			//make list of occluders
184 			for (Map<RID, Viewport::CanvasData>::Element *E = p_viewport->canvas_map.front(); E; E = E->next()) {
185 
186 				VisualServerCanvas::Canvas *canvas = static_cast<VisualServerCanvas::Canvas *>(E->get().canvas);
187 				Transform2D xf = _canvas_get_transform(p_viewport, canvas, &E->get(), clip_rect.size);
188 
189 				for (Set<RasterizerCanvas::LightOccluderInstance *>::Element *F = canvas->occluders.front(); F; F = F->next()) {
190 
191 					if (!F->get()->enabled)
192 						continue;
193 					F->get()->xform_cache = xf * F->get()->xform;
194 					if (shadow_rect.intersects_transformed(F->get()->xform_cache, F->get()->aabb_cache)) {
195 
196 						F->get()->next = occluders;
197 						occluders = F->get();
198 					}
199 				}
200 			}
201 			//update the light shadowmaps with them
202 			RasterizerCanvas::Light *light = lights_with_shadow;
203 			while (light) {
204 
205 				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);
206 				light = light->shadows_next_ptr;
207 			}
208 
209 			//VSG::canvas_render->reset_canvas();
210 		}
211 
212 		VSG::rasterizer->restore_render_target(!scenario_draw_canvas_bg && can_draw_3d);
213 
214 		if (scenario_draw_canvas_bg && canvas_map.front() && canvas_map.front()->key().get_layer() > scenario_canvas_max_layer) {
215 			if (!can_draw_3d) {
216 				VSG::scene->render_empty_scene(p_viewport->scenario, p_viewport->shadow_atlas);
217 			} else {
218 				_draw_3d(p_viewport, p_eye);
219 			}
220 			scenario_draw_canvas_bg = false;
221 		}
222 
223 		for (Map<Viewport::CanvasKey, Viewport::CanvasData *>::Element *E = canvas_map.front(); E; E = E->next()) {
224 
225 			VisualServerCanvas::Canvas *canvas = static_cast<VisualServerCanvas::Canvas *>(E->get()->canvas);
226 
227 			Transform2D xform = _canvas_get_transform(p_viewport, canvas, E->get(), clip_rect.size);
228 
229 			RasterizerCanvas::Light *canvas_lights = NULL;
230 
231 			RasterizerCanvas::Light *ptr = lights;
232 			int canvas_layer_id = E->get()->layer;
233 			while (ptr) {
234 				if (canvas_layer_id >= ptr->layer_min && canvas_layer_id <= ptr->layer_max) {
235 					ptr->next_ptr = canvas_lights;
236 					canvas_lights = ptr;
237 				}
238 				ptr = ptr->filter_next_ptr;
239 			}
240 
241 			VSG::canvas->render_canvas(canvas, xform, canvas_lights, lights_with_mask, clip_rect, canvas_layer_id);
242 			i++;
243 
244 			if (scenario_draw_canvas_bg && E->key().get_layer() >= scenario_canvas_max_layer) {
245 				if (!can_draw_3d) {
246 					VSG::scene->render_empty_scene(p_viewport->scenario, p_viewport->shadow_atlas);
247 				} else {
248 					_draw_3d(p_viewport, p_eye);
249 				}
250 
251 				scenario_draw_canvas_bg = false;
252 			}
253 		}
254 
255 		if (scenario_draw_canvas_bg) {
256 			if (!can_draw_3d) {
257 				VSG::scene->render_empty_scene(p_viewport->scenario, p_viewport->shadow_atlas);
258 			} else {
259 				_draw_3d(p_viewport, p_eye);
260 			}
261 		}
262 
263 		//VSG::canvas_render->canvas_debug_viewport_shadows(lights_with_shadow);
264 	}
265 }
266 
draw_viewports()267 void VisualServerViewport::draw_viewports() {
268 
269 	// get our arvr interface in case we need it
270 	Ref<ARVRInterface> arvr_interface;
271 
272 	if (ARVRServer::get_singleton() != NULL) {
273 		arvr_interface = ARVRServer::get_singleton()->get_primary_interface();
274 
275 		// process all our active interfaces
276 		ARVRServer::get_singleton()->_process();
277 	}
278 
279 	if (Engine::get_singleton()->is_editor_hint()) {
280 		clear_color = GLOBAL_GET("rendering/environment/default_clear_color");
281 	}
282 
283 	//sort viewports
284 	active_viewports.sort_custom<ViewportSort>();
285 
286 	//draw viewports
287 	for (int i = 0; i < active_viewports.size(); i++) {
288 
289 		Viewport *vp = active_viewports[i];
290 
291 		if (vp->update_mode == VS::VIEWPORT_UPDATE_DISABLED)
292 			continue;
293 
294 		ERR_CONTINUE(!vp->render_target.is_valid());
295 
296 		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));
297 		visible = visible && vp->size.x > 1 && vp->size.y > 1;
298 
299 		if (!visible)
300 			continue;
301 
302 		VSG::storage->render_target_clear_used(vp->render_target);
303 
304 		if (vp->use_arvr && arvr_interface.is_valid()) {
305 			// override our size, make sure it matches our required size
306 			vp->size = arvr_interface->get_render_targetsize();
307 			VSG::storage->render_target_set_size(vp->render_target, vp->size.x, vp->size.y);
308 
309 			// render mono or left eye first
310 			ARVRInterface::Eyes leftOrMono = arvr_interface->is_stereo() ? ARVRInterface::EYE_LEFT : ARVRInterface::EYE_MONO;
311 
312 			// check for an external texture destination for our left eye/mono
313 			VSG::storage->render_target_set_external_texture(vp->render_target, arvr_interface->get_external_texture_for_eye(leftOrMono));
314 
315 			// set our render target as current
316 			VSG::rasterizer->set_current_render_target(vp->render_target);
317 
318 			// and draw left eye/mono
319 			_draw_viewport(vp, leftOrMono);
320 			arvr_interface->commit_for_eye(leftOrMono, vp->render_target, vp->viewport_to_screen_rect);
321 
322 			// render right eye
323 			if (leftOrMono == ARVRInterface::EYE_LEFT) {
324 				// check for an external texture destination for our right eye
325 				VSG::storage->render_target_set_external_texture(vp->render_target, arvr_interface->get_external_texture_for_eye(ARVRInterface::EYE_RIGHT));
326 
327 				// commit for eye may have changed the render target
328 				VSG::rasterizer->set_current_render_target(vp->render_target);
329 
330 				_draw_viewport(vp, ARVRInterface::EYE_RIGHT);
331 				arvr_interface->commit_for_eye(ARVRInterface::EYE_RIGHT, vp->render_target, vp->viewport_to_screen_rect);
332 			}
333 
334 			// and for our frame timing, mark when we've finished committing our eyes
335 			ARVRServer::get_singleton()->_mark_commit();
336 		} else {
337 			VSG::storage->render_target_set_external_texture(vp->render_target, 0);
338 			VSG::rasterizer->set_current_render_target(vp->render_target);
339 
340 			VSG::scene_render->set_debug_draw_mode(vp->debug_draw);
341 			VSG::storage->render_info_begin_capture();
342 
343 			// render standard mono camera
344 			_draw_viewport(vp);
345 
346 			VSG::storage->render_info_end_capture();
347 			vp->render_info[VS::VIEWPORT_RENDER_INFO_OBJECTS_IN_FRAME] = VSG::storage->get_captured_render_info(VS::INFO_OBJECTS_IN_FRAME);
348 			vp->render_info[VS::VIEWPORT_RENDER_INFO_VERTICES_IN_FRAME] = VSG::storage->get_captured_render_info(VS::INFO_VERTICES_IN_FRAME);
349 			vp->render_info[VS::VIEWPORT_RENDER_INFO_MATERIAL_CHANGES_IN_FRAME] = VSG::storage->get_captured_render_info(VS::INFO_MATERIAL_CHANGES_IN_FRAME);
350 			vp->render_info[VS::VIEWPORT_RENDER_INFO_SHADER_CHANGES_IN_FRAME] = VSG::storage->get_captured_render_info(VS::INFO_SHADER_CHANGES_IN_FRAME);
351 			vp->render_info[VS::VIEWPORT_RENDER_INFO_SURFACE_CHANGES_IN_FRAME] = VSG::storage->get_captured_render_info(VS::INFO_SURFACE_CHANGES_IN_FRAME);
352 			vp->render_info[VS::VIEWPORT_RENDER_INFO_DRAW_CALLS_IN_FRAME] = VSG::storage->get_captured_render_info(VS::INFO_DRAW_CALLS_IN_FRAME);
353 			vp->render_info[VS::VIEWPORT_RENDER_INFO_2D_ITEMS_IN_FRAME] = VSG::storage->get_captured_render_info(VS::INFO_2D_ITEMS_IN_FRAME);
354 			vp->render_info[VS::VIEWPORT_RENDER_INFO_2D_DRAW_CALLS_IN_FRAME] = VSG::storage->get_captured_render_info(VS::INFO_2D_DRAW_CALLS_IN_FRAME);
355 
356 			if (vp->viewport_to_screen_rect != Rect2() && (!vp->viewport_render_direct_to_screen || !VSG::rasterizer->is_low_end())) {
357 				//copy to screen if set as such
358 				VSG::rasterizer->set_current_render_target(RID());
359 				VSG::rasterizer->blit_render_target_to_screen(vp->render_target, vp->viewport_to_screen_rect, vp->viewport_to_screen);
360 			}
361 		}
362 
363 		if (vp->update_mode == VS::VIEWPORT_UPDATE_ONCE) {
364 			vp->update_mode = VS::VIEWPORT_UPDATE_DISABLED;
365 		}
366 		VSG::scene_render->set_debug_draw_mode(VS::VIEWPORT_DEBUG_DRAW_DISABLED);
367 	}
368 }
369 
viewport_create()370 RID VisualServerViewport::viewport_create() {
371 
372 	Viewport *viewport = memnew(Viewport);
373 
374 	RID rid = viewport_owner.make_rid(viewport);
375 
376 	viewport->self = rid;
377 	viewport->hide_scenario = false;
378 	viewport->hide_canvas = false;
379 	viewport->render_target = VSG::storage->render_target_create();
380 	viewport->shadow_atlas = VSG::scene_render->shadow_atlas_create();
381 	viewport->viewport_render_direct_to_screen = false;
382 
383 	return rid;
384 }
385 
viewport_set_use_arvr(RID p_viewport,bool p_use_arvr)386 void VisualServerViewport::viewport_set_use_arvr(RID p_viewport, bool p_use_arvr) {
387 	Viewport *viewport = viewport_owner.getornull(p_viewport);
388 	ERR_FAIL_COND(!viewport);
389 
390 	viewport->use_arvr = p_use_arvr;
391 }
392 
viewport_set_size(RID p_viewport,int p_width,int p_height)393 void VisualServerViewport::viewport_set_size(RID p_viewport, int p_width, int p_height) {
394 
395 	ERR_FAIL_COND(p_width < 0 && p_height < 0);
396 
397 	Viewport *viewport = viewport_owner.getornull(p_viewport);
398 	ERR_FAIL_COND(!viewport);
399 
400 	viewport->size = Size2(p_width, p_height);
401 	VSG::storage->render_target_set_size(viewport->render_target, p_width, p_height);
402 }
403 
viewport_set_active(RID p_viewport,bool p_active)404 void VisualServerViewport::viewport_set_active(RID p_viewport, bool p_active) {
405 
406 	Viewport *viewport = viewport_owner.getornull(p_viewport);
407 	ERR_FAIL_COND(!viewport);
408 
409 	if (p_active) {
410 		ERR_FAIL_COND(active_viewports.find(viewport) != -1); //already active
411 		active_viewports.push_back(viewport);
412 	} else {
413 		active_viewports.erase(viewport);
414 	}
415 }
416 
viewport_set_parent_viewport(RID p_viewport,RID p_parent_viewport)417 void VisualServerViewport::viewport_set_parent_viewport(RID p_viewport, RID p_parent_viewport) {
418 
419 	Viewport *viewport = viewport_owner.getornull(p_viewport);
420 	ERR_FAIL_COND(!viewport);
421 
422 	viewport->parent = p_parent_viewport;
423 }
424 
viewport_set_clear_mode(RID p_viewport,VS::ViewportClearMode p_clear_mode)425 void VisualServerViewport::viewport_set_clear_mode(RID p_viewport, VS::ViewportClearMode p_clear_mode) {
426 
427 	Viewport *viewport = viewport_owner.getornull(p_viewport);
428 	ERR_FAIL_COND(!viewport);
429 
430 	viewport->clear_mode = p_clear_mode;
431 }
432 
viewport_attach_to_screen(RID p_viewport,const Rect2 & p_rect,int p_screen)433 void VisualServerViewport::viewport_attach_to_screen(RID p_viewport, const Rect2 &p_rect, int p_screen) {
434 
435 	Viewport *viewport = viewport_owner.getornull(p_viewport);
436 	ERR_FAIL_COND(!viewport);
437 
438 	// If using GLES2 we can optimize this operation by rendering directly to system_fbo
439 	// instead of rendering to fbo and copying to system_fbo after
440 	if (VSG::rasterizer->is_low_end() && viewport->viewport_render_direct_to_screen) {
441 
442 		VSG::storage->render_target_set_size(viewport->render_target, p_rect.size.x, p_rect.size.y);
443 		VSG::storage->render_target_set_position(viewport->render_target, p_rect.position.x, p_rect.position.y);
444 	}
445 
446 	viewport->viewport_to_screen_rect = p_rect;
447 	viewport->viewport_to_screen = p_screen;
448 }
449 
viewport_set_render_direct_to_screen(RID p_viewport,bool p_enable)450 void VisualServerViewport::viewport_set_render_direct_to_screen(RID p_viewport, bool p_enable) {
451 	Viewport *viewport = viewport_owner.getornull(p_viewport);
452 	ERR_FAIL_COND(!viewport);
453 
454 	if (p_enable == viewport->viewport_render_direct_to_screen)
455 		return;
456 
457 	// if disabled, reset render_target size and position
458 	if (!p_enable) {
459 
460 		VSG::storage->render_target_set_position(viewport->render_target, 0, 0);
461 		VSG::storage->render_target_set_size(viewport->render_target, viewport->size.x, viewport->size.y);
462 	}
463 
464 	VSG::storage->render_target_set_flag(viewport->render_target, RasterizerStorage::RENDER_TARGET_DIRECT_TO_SCREEN, p_enable);
465 	viewport->viewport_render_direct_to_screen = p_enable;
466 
467 	// if attached to screen already, setup screen size and position, this needs to happen after setting flag to avoid an unnecessary buffer allocation
468 	if (VSG::rasterizer->is_low_end() && viewport->viewport_to_screen_rect != Rect2() && p_enable) {
469 
470 		VSG::storage->render_target_set_size(viewport->render_target, viewport->viewport_to_screen_rect.size.x, viewport->viewport_to_screen_rect.size.y);
471 		VSG::storage->render_target_set_position(viewport->render_target, viewport->viewport_to_screen_rect.position.x, viewport->viewport_to_screen_rect.position.y);
472 	}
473 }
474 
viewport_detach(RID p_viewport)475 void VisualServerViewport::viewport_detach(RID p_viewport) {
476 
477 	Viewport *viewport = viewport_owner.getornull(p_viewport);
478 	ERR_FAIL_COND(!viewport);
479 
480 	// if render_direct_to_screen was used, reset size and position
481 	if (VSG::rasterizer->is_low_end() && viewport->viewport_render_direct_to_screen) {
482 
483 		VSG::storage->render_target_set_position(viewport->render_target, 0, 0);
484 		VSG::storage->render_target_set_size(viewport->render_target, viewport->size.x, viewport->size.y);
485 	}
486 
487 	viewport->viewport_to_screen_rect = Rect2();
488 	viewport->viewport_to_screen = 0;
489 }
490 
viewport_set_update_mode(RID p_viewport,VS::ViewportUpdateMode p_mode)491 void VisualServerViewport::viewport_set_update_mode(RID p_viewport, VS::ViewportUpdateMode p_mode) {
492 
493 	Viewport *viewport = viewport_owner.getornull(p_viewport);
494 	ERR_FAIL_COND(!viewport);
495 
496 	viewport->update_mode = p_mode;
497 }
viewport_set_vflip(RID p_viewport,bool p_enable)498 void VisualServerViewport::viewport_set_vflip(RID p_viewport, bool p_enable) {
499 
500 	Viewport *viewport = viewport_owner.getornull(p_viewport);
501 	ERR_FAIL_COND(!viewport);
502 
503 	VSG::storage->render_target_set_flag(viewport->render_target, RasterizerStorage::RENDER_TARGET_VFLIP, p_enable);
504 }
505 
viewport_get_texture(RID p_viewport) const506 RID VisualServerViewport::viewport_get_texture(RID p_viewport) const {
507 
508 	const Viewport *viewport = viewport_owner.getornull(p_viewport);
509 	ERR_FAIL_COND_V(!viewport, RID());
510 
511 	return VSG::storage->render_target_get_texture(viewport->render_target);
512 }
513 
viewport_set_hide_scenario(RID p_viewport,bool p_hide)514 void VisualServerViewport::viewport_set_hide_scenario(RID p_viewport, bool p_hide) {
515 
516 	Viewport *viewport = viewport_owner.getornull(p_viewport);
517 	ERR_FAIL_COND(!viewport);
518 
519 	viewport->hide_scenario = p_hide;
520 }
viewport_set_hide_canvas(RID p_viewport,bool p_hide)521 void VisualServerViewport::viewport_set_hide_canvas(RID p_viewport, bool p_hide) {
522 
523 	Viewport *viewport = viewport_owner.getornull(p_viewport);
524 	ERR_FAIL_COND(!viewport);
525 
526 	viewport->hide_canvas = p_hide;
527 }
viewport_set_disable_environment(RID p_viewport,bool p_disable)528 void VisualServerViewport::viewport_set_disable_environment(RID p_viewport, bool p_disable) {
529 
530 	Viewport *viewport = viewport_owner.getornull(p_viewport);
531 	ERR_FAIL_COND(!viewport);
532 
533 	viewport->disable_environment = p_disable;
534 }
535 
viewport_set_disable_3d(RID p_viewport,bool p_disable)536 void VisualServerViewport::viewport_set_disable_3d(RID p_viewport, bool p_disable) {
537 
538 	Viewport *viewport = viewport_owner.getornull(p_viewport);
539 	ERR_FAIL_COND(!viewport);
540 
541 	viewport->disable_3d = p_disable;
542 	//VSG::storage->render_target_set_flag(viewport->render_target, RasterizerStorage::RENDER_TARGET_NO_3D, p_disable);
543 	//this should be just for disabling rendering of 3D, to actually disable it, set usage
544 }
545 
viewport_set_keep_3d_linear(RID p_viewport,bool p_keep_3d_linear)546 void VisualServerViewport::viewport_set_keep_3d_linear(RID p_viewport, bool p_keep_3d_linear) {
547 
548 	Viewport *viewport = viewport_owner.getornull(p_viewport);
549 	ERR_FAIL_COND(!viewport);
550 
551 	viewport->keep_3d_linear = p_keep_3d_linear;
552 	VSG::storage->render_target_set_flag(viewport->render_target, RasterizerStorage::RENDER_TARGET_KEEP_3D_LINEAR, p_keep_3d_linear);
553 }
554 
viewport_attach_camera(RID p_viewport,RID p_camera)555 void VisualServerViewport::viewport_attach_camera(RID p_viewport, RID p_camera) {
556 
557 	Viewport *viewport = viewport_owner.getornull(p_viewport);
558 	ERR_FAIL_COND(!viewport);
559 
560 	viewport->camera = p_camera;
561 }
viewport_set_scenario(RID p_viewport,RID p_scenario)562 void VisualServerViewport::viewport_set_scenario(RID p_viewport, RID p_scenario) {
563 
564 	Viewport *viewport = viewport_owner.getornull(p_viewport);
565 	ERR_FAIL_COND(!viewport);
566 
567 	viewport->scenario = p_scenario;
568 }
viewport_attach_canvas(RID p_viewport,RID p_canvas)569 void VisualServerViewport::viewport_attach_canvas(RID p_viewport, RID p_canvas) {
570 
571 	Viewport *viewport = viewport_owner.getornull(p_viewport);
572 	ERR_FAIL_COND(!viewport);
573 
574 	ERR_FAIL_COND(viewport->canvas_map.has(p_canvas));
575 	VisualServerCanvas::Canvas *canvas = VSG::canvas->canvas_owner.getornull(p_canvas);
576 	ERR_FAIL_COND(!canvas);
577 
578 	canvas->viewports.insert(p_viewport);
579 	viewport->canvas_map[p_canvas] = Viewport::CanvasData();
580 	viewport->canvas_map[p_canvas].layer = 0;
581 	viewport->canvas_map[p_canvas].sublayer = 0;
582 	viewport->canvas_map[p_canvas].canvas = canvas;
583 }
584 
viewport_remove_canvas(RID p_viewport,RID p_canvas)585 void VisualServerViewport::viewport_remove_canvas(RID p_viewport, RID p_canvas) {
586 
587 	Viewport *viewport = viewport_owner.getornull(p_viewport);
588 	ERR_FAIL_COND(!viewport);
589 
590 	VisualServerCanvas::Canvas *canvas = VSG::canvas->canvas_owner.getornull(p_canvas);
591 	ERR_FAIL_COND(!canvas);
592 
593 	viewport->canvas_map.erase(p_canvas);
594 	canvas->viewports.erase(p_viewport);
595 }
viewport_set_canvas_transform(RID p_viewport,RID p_canvas,const Transform2D & p_offset)596 void VisualServerViewport::viewport_set_canvas_transform(RID p_viewport, RID p_canvas, const Transform2D &p_offset) {
597 
598 	Viewport *viewport = viewport_owner.getornull(p_viewport);
599 	ERR_FAIL_COND(!viewport);
600 
601 	ERR_FAIL_COND(!viewport->canvas_map.has(p_canvas));
602 	viewport->canvas_map[p_canvas].transform = p_offset;
603 }
viewport_set_transparent_background(RID p_viewport,bool p_enabled)604 void VisualServerViewport::viewport_set_transparent_background(RID p_viewport, bool p_enabled) {
605 
606 	Viewport *viewport = viewport_owner.getornull(p_viewport);
607 	ERR_FAIL_COND(!viewport);
608 
609 	VSG::storage->render_target_set_flag(viewport->render_target, RasterizerStorage::RENDER_TARGET_TRANSPARENT, p_enabled);
610 	viewport->transparent_bg = p_enabled;
611 }
612 
viewport_set_global_canvas_transform(RID p_viewport,const Transform2D & p_transform)613 void VisualServerViewport::viewport_set_global_canvas_transform(RID p_viewport, const Transform2D &p_transform) {
614 
615 	Viewport *viewport = viewport_owner.getornull(p_viewport);
616 	ERR_FAIL_COND(!viewport);
617 
618 	viewport->global_transform = p_transform;
619 }
viewport_set_canvas_stacking(RID p_viewport,RID p_canvas,int p_layer,int p_sublayer)620 void VisualServerViewport::viewport_set_canvas_stacking(RID p_viewport, RID p_canvas, int p_layer, int p_sublayer) {
621 
622 	Viewport *viewport = viewport_owner.getornull(p_viewport);
623 	ERR_FAIL_COND(!viewport);
624 
625 	ERR_FAIL_COND(!viewport->canvas_map.has(p_canvas));
626 	viewport->canvas_map[p_canvas].layer = p_layer;
627 	viewport->canvas_map[p_canvas].sublayer = p_sublayer;
628 }
629 
viewport_set_shadow_atlas_size(RID p_viewport,int p_size)630 void VisualServerViewport::viewport_set_shadow_atlas_size(RID p_viewport, int p_size) {
631 
632 	Viewport *viewport = viewport_owner.getornull(p_viewport);
633 	ERR_FAIL_COND(!viewport);
634 
635 	viewport->shadow_atlas_size = p_size;
636 
637 	VSG::scene_render->shadow_atlas_set_size(viewport->shadow_atlas, viewport->shadow_atlas_size);
638 }
639 
viewport_set_shadow_atlas_quadrant_subdivision(RID p_viewport,int p_quadrant,int p_subdiv)640 void VisualServerViewport::viewport_set_shadow_atlas_quadrant_subdivision(RID p_viewport, int p_quadrant, int p_subdiv) {
641 
642 	Viewport *viewport = viewport_owner.getornull(p_viewport);
643 	ERR_FAIL_COND(!viewport);
644 
645 	VSG::scene_render->shadow_atlas_set_quadrant_subdivision(viewport->shadow_atlas, p_quadrant, p_subdiv);
646 }
647 
viewport_set_msaa(RID p_viewport,VS::ViewportMSAA p_msaa)648 void VisualServerViewport::viewport_set_msaa(RID p_viewport, VS::ViewportMSAA p_msaa) {
649 
650 	Viewport *viewport = viewport_owner.getornull(p_viewport);
651 	ERR_FAIL_COND(!viewport);
652 
653 	VSG::storage->render_target_set_msaa(viewport->render_target, p_msaa);
654 }
655 
viewport_set_hdr(RID p_viewport,bool p_enabled)656 void VisualServerViewport::viewport_set_hdr(RID p_viewport, bool p_enabled) {
657 
658 	Viewport *viewport = viewport_owner.getornull(p_viewport);
659 	ERR_FAIL_COND(!viewport);
660 
661 	VSG::storage->render_target_set_flag(viewport->render_target, RasterizerStorage::RENDER_TARGET_HDR, p_enabled);
662 }
663 
viewport_set_usage(RID p_viewport,VS::ViewportUsage p_usage)664 void VisualServerViewport::viewport_set_usage(RID p_viewport, VS::ViewportUsage p_usage) {
665 
666 	Viewport *viewport = viewport_owner.getornull(p_viewport);
667 	ERR_FAIL_COND(!viewport);
668 
669 	switch (p_usage) {
670 		case VS::VIEWPORT_USAGE_2D: {
671 
672 			VSG::storage->render_target_set_flag(viewport->render_target, RasterizerStorage::RENDER_TARGET_NO_3D, true);
673 			VSG::storage->render_target_set_flag(viewport->render_target, RasterizerStorage::RENDER_TARGET_NO_3D_EFFECTS, true);
674 			VSG::storage->render_target_set_flag(viewport->render_target, RasterizerStorage::RENDER_TARGET_NO_SAMPLING, false);
675 
676 			viewport->disable_3d_by_usage = true;
677 		} break;
678 		case VS::VIEWPORT_USAGE_2D_NO_SAMPLING: {
679 
680 			VSG::storage->render_target_set_flag(viewport->render_target, RasterizerStorage::RENDER_TARGET_NO_3D, true);
681 			VSG::storage->render_target_set_flag(viewport->render_target, RasterizerStorage::RENDER_TARGET_NO_3D_EFFECTS, true);
682 			VSG::storage->render_target_set_flag(viewport->render_target, RasterizerStorage::RENDER_TARGET_NO_SAMPLING, true);
683 			viewport->disable_3d_by_usage = true;
684 		} break;
685 		case VS::VIEWPORT_USAGE_3D: {
686 
687 			VSG::storage->render_target_set_flag(viewport->render_target, RasterizerStorage::RENDER_TARGET_NO_3D, false);
688 			VSG::storage->render_target_set_flag(viewport->render_target, RasterizerStorage::RENDER_TARGET_NO_3D_EFFECTS, false);
689 			VSG::storage->render_target_set_flag(viewport->render_target, RasterizerStorage::RENDER_TARGET_NO_SAMPLING, false);
690 			viewport->disable_3d_by_usage = false;
691 		} break;
692 		case VS::VIEWPORT_USAGE_3D_NO_EFFECTS: {
693 
694 			VSG::storage->render_target_set_flag(viewport->render_target, RasterizerStorage::RENDER_TARGET_NO_3D, false);
695 			VSG::storage->render_target_set_flag(viewport->render_target, RasterizerStorage::RENDER_TARGET_NO_3D_EFFECTS, true);
696 			VSG::storage->render_target_set_flag(viewport->render_target, RasterizerStorage::RENDER_TARGET_NO_SAMPLING, false);
697 			viewport->disable_3d_by_usage = false;
698 		} break;
699 	}
700 }
701 
viewport_get_render_info(RID p_viewport,VS::ViewportRenderInfo p_info)702 int VisualServerViewport::viewport_get_render_info(RID p_viewport, VS::ViewportRenderInfo p_info) {
703 
704 	ERR_FAIL_INDEX_V(p_info, VS::VIEWPORT_RENDER_INFO_MAX, -1);
705 
706 	Viewport *viewport = viewport_owner.getornull(p_viewport);
707 	if (!viewport)
708 		return 0; //there should be a lock here..
709 
710 	return viewport->render_info[p_info];
711 }
712 
viewport_set_debug_draw(RID p_viewport,VS::ViewportDebugDraw p_draw)713 void VisualServerViewport::viewport_set_debug_draw(RID p_viewport, VS::ViewportDebugDraw p_draw) {
714 
715 	Viewport *viewport = viewport_owner.getornull(p_viewport);
716 	ERR_FAIL_COND(!viewport);
717 
718 	viewport->debug_draw = p_draw;
719 }
720 
free(RID p_rid)721 bool VisualServerViewport::free(RID p_rid) {
722 
723 	if (viewport_owner.owns(p_rid)) {
724 
725 		Viewport *viewport = viewport_owner.getornull(p_rid);
726 
727 		VSG::storage->free(viewport->render_target);
728 		VSG::scene_render->free(viewport->shadow_atlas);
729 
730 		while (viewport->canvas_map.front()) {
731 			viewport_remove_canvas(p_rid, viewport->canvas_map.front()->key());
732 		}
733 
734 		viewport_set_scenario(p_rid, RID());
735 		active_viewports.erase(viewport);
736 
737 		viewport_owner.free(p_rid);
738 		memdelete(viewport);
739 
740 		return true;
741 	}
742 
743 	return false;
744 }
745 
set_default_clear_color(const Color & p_color)746 void VisualServerViewport::set_default_clear_color(const Color &p_color) {
747 	clear_color = p_color;
748 }
749 
VisualServerViewport()750 VisualServerViewport::VisualServerViewport() {
751 }
752