Implement ability to render viewports directly to screen
This commit is contained in:
@@ -550,10 +550,12 @@ public:
|
||||
RENDER_TARGET_NO_SAMPLING,
|
||||
RENDER_TARGET_HDR,
|
||||
RENDER_TARGET_KEEP_3D_LINEAR,
|
||||
RENDER_TARGET_DIRECT_TO_SCREEN,
|
||||
RENDER_TARGET_FLAG_MAX
|
||||
};
|
||||
|
||||
virtual RID render_target_create() = 0;
|
||||
virtual void render_target_set_position(RID p_render_target, int p_x, int p_y) = 0;
|
||||
virtual void render_target_set_size(RID p_render_target, int p_width, int p_height) = 0;
|
||||
virtual RID render_target_get_texture(RID p_render_target) const = 0;
|
||||
virtual void render_target_set_external_texture(RID p_render_target, unsigned int p_texture_id) = 0;
|
||||
|
||||
@@ -454,6 +454,7 @@ public:
|
||||
BIND2(viewport_set_clear_mode, RID, ViewportClearMode)
|
||||
|
||||
BIND3(viewport_attach_to_screen, RID, const Rect2 &, int)
|
||||
BIND2(viewport_set_render_direct_to_screen, RID, bool)
|
||||
BIND1(viewport_detach, RID)
|
||||
|
||||
BIND2(viewport_set_update_mode, RID, ViewportUpdateMode)
|
||||
|
||||
@@ -343,7 +343,7 @@ void VisualServerViewport::draw_viewports() {
|
||||
vp->render_info[VS::VIEWPORT_RENDER_INFO_SURFACE_CHANGES_IN_FRAME] = VSG::storage->get_captured_render_info(VS::INFO_SURFACE_CHANGES_IN_FRAME);
|
||||
vp->render_info[VS::VIEWPORT_RENDER_INFO_DRAW_CALLS_IN_FRAME] = VSG::storage->get_captured_render_info(VS::INFO_DRAW_CALLS_IN_FRAME);
|
||||
|
||||
if (vp->viewport_to_screen_rect != Rect2()) {
|
||||
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);
|
||||
@@ -368,6 +368,7 @@ RID VisualServerViewport::viewport_create() {
|
||||
viewport->hide_canvas = false;
|
||||
viewport->render_target = VSG::storage->render_target_create();
|
||||
viewport->shadow_atlas = VSG::scene_render->shadow_atlas_create();
|
||||
viewport->viewport_render_direct_to_screen = false;
|
||||
|
||||
return rid;
|
||||
}
|
||||
@@ -424,14 +425,55 @@ void VisualServerViewport::viewport_attach_to_screen(RID p_viewport, const Rect2
|
||||
Viewport *viewport = viewport_owner.getornull(p_viewport);
|
||||
ERR_FAIL_COND(!viewport);
|
||||
|
||||
// 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
|
||||
if (VSG::rasterizer->is_low_end() && viewport->viewport_render_direct_to_screen) {
|
||||
|
||||
VSG::storage->render_target_set_size(viewport->render_target, p_rect.size.x, p_rect.size.y);
|
||||
VSG::storage->render_target_set_position(viewport->render_target, p_rect.position.x, p_rect.position.y);
|
||||
}
|
||||
|
||||
viewport->viewport_to_screen_rect = p_rect;
|
||||
viewport->viewport_to_screen = p_screen;
|
||||
}
|
||||
|
||||
void VisualServerViewport::viewport_set_render_direct_to_screen(RID p_viewport, bool p_enable) {
|
||||
Viewport *viewport = viewport_owner.getornull(p_viewport);
|
||||
ERR_FAIL_COND(!viewport);
|
||||
|
||||
if (p_enable == viewport->viewport_render_direct_to_screen)
|
||||
return;
|
||||
|
||||
// if disabled, reset render_target size and position
|
||||
if (!p_enable) {
|
||||
|
||||
VSG::storage->render_target_set_position(viewport->render_target, 0, 0);
|
||||
VSG::storage->render_target_set_size(viewport->render_target, viewport->size.x, viewport->size.y);
|
||||
}
|
||||
|
||||
VSG::storage->render_target_set_flag(viewport->render_target, RasterizerStorage::RENDER_TARGET_DIRECT_TO_SCREEN, p_enable);
|
||||
viewport->viewport_render_direct_to_screen = p_enable;
|
||||
|
||||
// if attached to screen already, setup screen size and position, this needs to happen after setting flag to avoid an unneccesary buffer allocation
|
||||
if (VSG::rasterizer->is_low_end() && viewport->viewport_to_screen_rect != Rect2() && p_enable) {
|
||||
|
||||
VSG::storage->render_target_set_size(viewport->render_target, viewport->viewport_to_screen_rect.size.x, viewport->viewport_to_screen_rect.size.y);
|
||||
VSG::storage->render_target_set_position(viewport->render_target, viewport->viewport_to_screen_rect.position.x, viewport->viewport_to_screen_rect.position.y);
|
||||
}
|
||||
}
|
||||
|
||||
void VisualServerViewport::viewport_detach(RID p_viewport) {
|
||||
|
||||
Viewport *viewport = viewport_owner.getornull(p_viewport);
|
||||
ERR_FAIL_COND(!viewport);
|
||||
|
||||
// if render_direct_to_screen was used, reset size and position
|
||||
if (VSG::rasterizer->is_low_end() && viewport->viewport_render_direct_to_screen) {
|
||||
|
||||
VSG::storage->render_target_set_position(viewport->render_target, 0, 0);
|
||||
VSG::storage->render_target_set_size(viewport->render_target, viewport->size.x, viewport->size.y);
|
||||
}
|
||||
|
||||
viewport->viewport_to_screen_rect = Rect2();
|
||||
viewport->viewport_to_screen = 0;
|
||||
}
|
||||
|
||||
@@ -58,6 +58,7 @@ public:
|
||||
|
||||
int viewport_to_screen;
|
||||
Rect2 viewport_to_screen_rect;
|
||||
bool viewport_render_direct_to_screen;
|
||||
|
||||
bool hide_scenario;
|
||||
bool hide_canvas;
|
||||
@@ -158,6 +159,7 @@ public:
|
||||
void viewport_set_size(RID p_viewport, int p_width, int p_height);
|
||||
|
||||
void viewport_attach_to_screen(RID p_viewport, const Rect2 &p_rect = Rect2(), int p_screen = 0);
|
||||
void viewport_set_render_direct_to_screen(RID p_viewport, bool p_enable);
|
||||
void viewport_detach(RID p_viewport);
|
||||
|
||||
void viewport_set_active(RID p_viewport, bool p_active);
|
||||
|
||||
@@ -381,6 +381,7 @@ public:
|
||||
FUNC2(viewport_set_clear_mode, RID, ViewportClearMode)
|
||||
|
||||
FUNC3(viewport_attach_to_screen, RID, const Rect2 &, int)
|
||||
FUNC2(viewport_set_render_direct_to_screen, RID, bool)
|
||||
FUNC1(viewport_detach, RID)
|
||||
|
||||
FUNC2(viewport_set_update_mode, RID, ViewportUpdateMode)
|
||||
|
||||
@@ -1876,6 +1876,7 @@ void VisualServer::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("viewport_set_active", "viewport", "active"), &VisualServer::viewport_set_active);
|
||||
ClassDB::bind_method(D_METHOD("viewport_set_parent_viewport", "viewport", "parent_viewport"), &VisualServer::viewport_set_parent_viewport);
|
||||
ClassDB::bind_method(D_METHOD("viewport_attach_to_screen", "viewport", "rect", "screen"), &VisualServer::viewport_attach_to_screen, DEFVAL(Rect2()), DEFVAL(0));
|
||||
ClassDB::bind_method(D_METHOD("viewport_set_render_direct_to_screen", "viewport", "enabled"), &VisualServer::viewport_set_render_direct_to_screen);
|
||||
ClassDB::bind_method(D_METHOD("viewport_detach", "viewport"), &VisualServer::viewport_detach);
|
||||
ClassDB::bind_method(D_METHOD("viewport_set_update_mode", "viewport", "update_mode"), &VisualServer::viewport_set_update_mode);
|
||||
ClassDB::bind_method(D_METHOD("viewport_set_vflip", "viewport", "enabled"), &VisualServer::viewport_set_vflip);
|
||||
|
||||
@@ -610,6 +610,7 @@ public:
|
||||
virtual void viewport_set_parent_viewport(RID p_viewport, RID p_parent_viewport) = 0;
|
||||
|
||||
virtual void viewport_attach_to_screen(RID p_viewport, const Rect2 &p_rect = Rect2(), int p_screen = 0) = 0;
|
||||
virtual void viewport_set_render_direct_to_screen(RID p_viewport, bool p_enable) = 0;
|
||||
virtual void viewport_detach(RID p_viewport) = 0;
|
||||
|
||||
enum ViewportUpdateMode {
|
||||
|
||||
Reference in New Issue
Block a user