diff options
Diffstat (limited to 'servers/visual')
-rw-r--r-- | servers/visual/rasterizer.h | 5 | ||||
-rw-r--r-- | servers/visual/shader_language.cpp | 6 | ||||
-rw-r--r-- | servers/visual/visual_server_canvas.cpp | 69 | ||||
-rw-r--r-- | servers/visual/visual_server_canvas.h | 17 | ||||
-rw-r--r-- | servers/visual/visual_server_raster.h | 5 | ||||
-rw-r--r-- | servers/visual/visual_server_scene.cpp | 50 | ||||
-rw-r--r-- | servers/visual/visual_server_scene.h | 6 | ||||
-rw-r--r-- | servers/visual/visual_server_viewport.cpp | 86 | ||||
-rw-r--r-- | servers/visual/visual_server_viewport.h | 1 | ||||
-rw-r--r-- | servers/visual/visual_server_wrap_mt.h | 5 |
10 files changed, 183 insertions, 67 deletions
diff --git a/servers/visual/rasterizer.h b/servers/visual/rasterizer.h index dd54698471..b22e26f903 100644 --- a/servers/visual/rasterizer.h +++ b/servers/visual/rasterizer.h @@ -554,6 +554,7 @@ public: virtual RID render_target_create() = 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; virtual void render_target_set_flag(RID p_render_target, RenderTargetFlags p_flag, bool p_value) = 0; virtual bool render_target_was_used(RID p_render_target) = 0; virtual void render_target_clear_used(RID p_render_target) = 0; @@ -788,6 +789,8 @@ public: RID mesh; RID texture; RID normal_map; + Transform2D transform; + Color modulate; CommandMesh() { type = TYPE_MESH; } }; @@ -1101,7 +1104,7 @@ public: virtual void initialize() = 0; virtual void begin_frame(double frame_step) = 0; virtual void set_current_render_target(RID p_render_target) = 0; - virtual void restore_render_target() = 0; + virtual void restore_render_target(bool p_3d) = 0; virtual void clear_render_target(const Color &p_color) = 0; virtual void blit_render_target_to_screen(RID p_render_target, const Rect2 &p_screen_rect, int p_screen = 0) = 0; virtual void output_lens_distorted_to_screen(RID p_render_target, const Rect2 &p_screen_rect, float p_k1, float p_k2, const Vector2 &p_eye_center, float p_oversample) = 0; diff --git a/servers/visual/shader_language.cpp b/servers/visual/shader_language.cpp index 1f9d263354..33714a79b2 100644 --- a/servers/visual/shader_language.cpp +++ b/servers/visual/shader_language.cpp @@ -3620,7 +3620,8 @@ ShaderLanguage::Node *ShaderLanguage::_reduce_expression(BlockNode *p_block, Sha case TYPE_FLOAT: { nv.real = -cn->values[i].real; } break; - default: {} + default: { + } } values.push_back(nv); @@ -4822,7 +4823,8 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct case TYPE_MAT2: limit = 2; break; case TYPE_MAT3: limit = 3; break; case TYPE_MAT4: limit = 4; break; - default: {} + default: { + } } for (int i = 0; i < limit; i++) { diff --git a/servers/visual/visual_server_canvas.cpp b/servers/visual/visual_server_canvas.cpp index 85dcaa6b03..d5e154a7fc 100644 --- a/servers/visual/visual_server_canvas.cpp +++ b/servers/visual/visual_server_canvas.cpp @@ -33,11 +33,9 @@ #include "visual_server_raster.h" #include "visual_server_viewport.h" -void VisualServerCanvas::_render_canvas_item_tree(Item *p_canvas_item, const Transform2D &p_transform, const Rect2 &p_clip_rect, const Color &p_modulate, RasterizerCanvas::Light *p_lights) { +static const int z_range = VS::CANVAS_ITEM_Z_MAX - VS::CANVAS_ITEM_Z_MIN + 1; - static const int z_range = VS::CANVAS_ITEM_Z_MAX - VS::CANVAS_ITEM_Z_MIN + 1; - RasterizerCanvas::Item *z_list[z_range]; - RasterizerCanvas::Item *z_last_list[z_range]; +void VisualServerCanvas::_render_canvas_item_tree(Item *p_canvas_item, const Transform2D &p_transform, const Rect2 &p_clip_rect, const Color &p_modulate, RasterizerCanvas::Light *p_lights) { memset(z_list, 0, z_range * sizeof(RasterizerCanvas::Item *)); memset(z_last_list, 0, z_range * sizeof(RasterizerCanvas::Item *)); @@ -51,20 +49,23 @@ void VisualServerCanvas::_render_canvas_item_tree(Item *p_canvas_item, const Tra } } -void _collect_ysort_children(VisualServerCanvas::Item *p_canvas_item, Transform2D p_transform, VisualServerCanvas::Item **r_items, int &r_index) { +void _collect_ysort_children(VisualServerCanvas::Item *p_canvas_item, Transform2D p_transform, VisualServerCanvas::Item *p_material_owner, VisualServerCanvas::Item **r_items, int &r_index) { int child_item_count = p_canvas_item->child_items.size(); VisualServerCanvas::Item **child_items = p_canvas_item->child_items.ptrw(); for (int i = 0; i < child_item_count; i++) { - if (r_items) { - r_items[r_index] = child_items[i]; - child_items[i]->ysort_xform = p_transform; - child_items[i]->ysort_pos = p_transform.xform(child_items[i]->xform.elements[2]); - } + if (child_items[i]->visible) { + if (r_items) { + r_items[r_index] = child_items[i]; + child_items[i]->ysort_xform = p_transform; + child_items[i]->ysort_pos = p_transform.xform(child_items[i]->xform.elements[2]); + child_items[i]->material_owner = child_items[i]->use_parent_material ? p_material_owner : NULL; + } - r_index++; + r_index++; - if (child_items[i]->sort_y) - _collect_ysort_children(child_items[i], p_transform * child_items[i]->xform, r_items, r_index); + if (child_items[i]->sort_y) + _collect_ysort_children(child_items[i], p_transform * child_items[i]->xform, child_items[i]->use_parent_material ? p_material_owner : child_items[i], r_items, r_index); + } } } @@ -124,14 +125,14 @@ void VisualServerCanvas::_render_canvas_item(Item *p_canvas_item, const Transfor if (ci->ysort_children_count == -1) { ci->ysort_children_count = 0; - _collect_ysort_children(ci, Transform2D(), NULL, ci->ysort_children_count); + _collect_ysort_children(ci, Transform2D(), p_material_owner, NULL, ci->ysort_children_count); } child_item_count = ci->ysort_children_count; child_items = (Item **)alloca(child_item_count * sizeof(Item *)); int i = 0; - _collect_ysort_children(ci, Transform2D(), child_items, i); + _collect_ysort_children(ci, Transform2D(), p_material_owner, child_items, i); SortArray<Item *, ItemPtrSort> sorter; sorter.sort(child_items, child_item_count); @@ -147,7 +148,7 @@ void VisualServerCanvas::_render_canvas_item(Item *p_canvas_item, const Transfor if (!child_items[i]->behind || (ci->sort_y && child_items[i]->sort_y)) continue; if (ci->sort_y) { - _render_canvas_item(child_items[i], xform * child_items[i]->ysort_xform, p_clip_rect, modulate, p_z, z_list, z_last_list, (Item *)ci->final_clip_owner, p_material_owner); + _render_canvas_item(child_items[i], xform * child_items[i]->ysort_xform, p_clip_rect, modulate, p_z, z_list, z_last_list, (Item *)ci->final_clip_owner, (Item *)child_items[i]->material_owner); } else { _render_canvas_item(child_items[i], xform, p_clip_rect, modulate, p_z, z_list, z_last_list, (Item *)ci->final_clip_owner, p_material_owner); } @@ -189,7 +190,7 @@ void VisualServerCanvas::_render_canvas_item(Item *p_canvas_item, const Transfor if (child_items[i]->behind || (ci->sort_y && child_items[i]->sort_y)) continue; if (ci->sort_y) { - _render_canvas_item(child_items[i], xform * child_items[i]->ysort_xform, p_clip_rect, modulate, p_z, z_list, z_last_list, (Item *)ci->final_clip_owner, p_material_owner); + _render_canvas_item(child_items[i], xform * child_items[i]->ysort_xform, p_clip_rect, modulate, p_z, z_list, z_last_list, (Item *)ci->final_clip_owner, (Item *)child_items[i]->material_owner); } else { _render_canvas_item(child_items[i], xform, p_clip_rect, modulate, p_z, z_list, z_last_list, (Item *)ci->final_clip_owner, p_material_owner); } @@ -319,6 +320,19 @@ void VisualServerCanvas::canvas_set_modulate(RID p_canvas, const Color &p_color) canvas->modulate = p_color; } +void VisualServerCanvas::canvas_set_disable_scale(bool p_disable) { + disable_scale = p_disable; +} + +void VisualServerCanvas::canvas_set_parent(RID p_canvas, RID p_parent, float p_scale) { + + Canvas *canvas = canvas_owner.get(p_canvas); + ERR_FAIL_COND(!canvas); + + canvas->parent = p_parent; + canvas->parent_scale = p_scale; +} + RID VisualServerCanvas::canvas_item_create() { Item *canvas_item = memnew(Item); @@ -380,6 +394,10 @@ void VisualServerCanvas::canvas_item_set_visible(RID p_item, bool p_visible) { ERR_FAIL_COND(!canvas_item); canvas_item->visible = p_visible; + + if (canvas_item->parent.is_valid() && canvas_item_owner.owns(canvas_item->parent)) { + _mark_ysort_dirty(canvas_item_owner.get(canvas_item->parent), canvas_item_owner); + } } void VisualServerCanvas::canvas_item_set_light_mask(RID p_item, int p_mask) { @@ -616,7 +634,7 @@ void VisualServerCanvas::canvas_item_add_texture_rect(RID p_item, const Rect2 &p if (p_tile) { rect->flags |= RasterizerCanvas::CANVAS_RECT_TILE; rect->flags |= RasterizerCanvas::CANVAS_RECT_REGION; - rect->source = Rect2(0, 0, p_rect.size.width, p_rect.size.height); + rect->source = Rect2(0, 0, fabsf(p_rect.size.width), fabsf(p_rect.size.height)); } if (p_rect.size.x < 0) { @@ -810,7 +828,7 @@ void VisualServerCanvas::canvas_item_add_set_transform(RID p_item, const Transfo canvas_item->commands.push_back(tr); } -void VisualServerCanvas::canvas_item_add_mesh(RID p_item, const RID &p_mesh, RID p_texture, RID p_normal_map) { +void VisualServerCanvas::canvas_item_add_mesh(RID p_item, const RID &p_mesh, const Transform2D &p_transform, const Color &p_modulate, RID p_texture, RID p_normal_map) { Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); @@ -820,6 +838,8 @@ void VisualServerCanvas::canvas_item_add_mesh(RID p_item, const RID &p_mesh, RID m->mesh = p_mesh; m->texture = p_texture; m->normal_map = p_normal_map; + m->transform = p_transform; + m->modulate = p_modulate; canvas_item->commands.push_back(m); } @@ -1434,4 +1454,15 @@ bool VisualServerCanvas::free(RID p_rid) { } VisualServerCanvas::VisualServerCanvas() { + + z_list = (RasterizerCanvas::Item **)memalloc(z_range * sizeof(RasterizerCanvas::Item *)); + z_last_list = (RasterizerCanvas::Item **)memalloc(z_range * sizeof(RasterizerCanvas::Item *)); + + disable_scale = false; +} + +VisualServerCanvas::~VisualServerCanvas() { + + memfree(z_list); + memfree(z_last_list); } diff --git a/servers/visual/visual_server_canvas.h b/servers/visual/visual_server_canvas.h index 7d788cbe14..26424f927e 100644 --- a/servers/visual/visual_server_canvas.h +++ b/servers/visual/visual_server_canvas.h @@ -82,7 +82,7 @@ public: _FORCE_INLINE_ bool operator()(const Item *p_left, const Item *p_right) const { - if (Math::abs(p_left->ysort_pos.y - p_right->ysort_pos.y) < CMP_EPSILON) + if (Math::is_equal_approx(p_left->ysort_pos.y, p_right->ysort_pos.y)) return p_left->ysort_pos.x < p_right->ysort_pos.x; else return p_left->ysort_pos.y < p_right->ysort_pos.y; @@ -126,6 +126,8 @@ public: bool children_order_dirty; Vector<ChildItem> child_items; Color modulate; + RID parent; + float parent_scale; int find_item(Item *p_item) { for (int i = 0; i < child_items.size(); i++) { @@ -143,24 +145,32 @@ public: Canvas() { modulate = Color(1, 1, 1, 1); children_order_dirty = true; + parent_scale = 1.0; } }; - RID_Owner<Canvas> canvas_owner; + mutable RID_Owner<Canvas> canvas_owner; RID_Owner<Item> canvas_item_owner; RID_Owner<RasterizerCanvas::Light> canvas_light_owner; + bool disable_scale; + private: void _render_canvas_item_tree(Item *p_canvas_item, const Transform2D &p_transform, const Rect2 &p_clip_rect, const Color &p_modulate, RasterizerCanvas::Light *p_lights); void _render_canvas_item(Item *p_canvas_item, const Transform2D &p_transform, const Rect2 &p_clip_rect, const Color &p_modulate, int p_z, RasterizerCanvas::Item **z_list, RasterizerCanvas::Item **z_last_list, Item *p_canvas_clip, Item *p_material_owner); void _light_mask_canvas_items(int p_z, RasterizerCanvas::Item *p_canvas_item, RasterizerCanvas::Light *p_masked_lights); + RasterizerCanvas::Item **z_list; + RasterizerCanvas::Item **z_last_list; + public: void render_canvas(Canvas *p_canvas, const Transform2D &p_transform, RasterizerCanvas::Light *p_lights, RasterizerCanvas::Light *p_masked_lights, const Rect2 &p_clip_rect); RID canvas_create(); void canvas_set_item_mirroring(RID p_canvas, RID p_item, const Point2 &p_mirroring); void canvas_set_modulate(RID p_canvas, const Color &p_color); + void canvas_set_parent(RID p_canvas, RID p_parent, float p_scale); + void canvas_set_disable_scale(bool p_disable); RID canvas_item_create(); void canvas_item_set_parent(RID p_item, RID p_parent); @@ -190,7 +200,7 @@ public: void canvas_item_add_primitive(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, RID p_texture, float p_width = 1.0, RID p_normal_map = RID()); void canvas_item_add_polygon(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), RID p_texture = RID(), RID p_normal_map = RID(), bool p_antialiased = false); void canvas_item_add_triangle_array(RID p_item, const Vector<int> &p_indices, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), const Vector<int> &p_bones = Vector<int>(), const Vector<float> &p_weights = Vector<float>(), RID p_texture = RID(), int p_count = -1, RID p_normal_map = RID()); - void canvas_item_add_mesh(RID p_item, const RID &p_mesh, RID p_texture = RID(), RID p_normal_map = RID()); + void canvas_item_add_mesh(RID p_item, const RID &p_mesh, const Transform2D &p_transform = Transform2D(), const Color &p_modulate = Color(1, 1, 1), RID p_texture = RID(), RID p_normal_map = RID()); void canvas_item_add_multimesh(RID p_item, RID p_mesh, RID p_texture = RID(), RID p_normal_map = RID()); void canvas_item_add_particles(RID p_item, RID p_particles, RID p_texture, RID p_normal); void canvas_item_add_set_transform(RID p_item, const Transform2D &p_transform); @@ -247,6 +257,7 @@ public: bool free(RID p_rid); VisualServerCanvas(); + ~VisualServerCanvas(); }; #endif // VISUALSERVERCANVAS_H diff --git a/servers/visual/visual_server_raster.h b/servers/visual/visual_server_raster.h index a1204c7573..efe2a99d2e 100644 --- a/servers/visual/visual_server_raster.h +++ b/servers/visual/visual_server_raster.h @@ -430,6 +430,7 @@ public: BIND0R(RID, camera_create) BIND4(camera_set_perspective, RID, float, float, float) BIND4(camera_set_orthogonal, RID, float, float, float) + BIND5(camera_set_frustum, RID, float, Vector2, float, float) BIND2(camera_set_transform, RID, const Transform &) BIND2(camera_set_cull_mask, RID, uint32_t) BIND2(camera_set_environment, RID, RID) @@ -569,6 +570,8 @@ public: BIND0R(RID, canvas_create) BIND3(canvas_set_item_mirroring, RID, RID, const Point2 &) BIND2(canvas_set_modulate, RID, const Color &) + BIND3(canvas_set_parent, RID, RID, float) + BIND1(canvas_set_disable_scale, bool) BIND0R(RID, canvas_item_create) BIND2(canvas_item_set_parent, RID, RID) @@ -598,7 +601,7 @@ public: BIND7(canvas_item_add_primitive, RID, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, RID, float, RID) BIND7(canvas_item_add_polygon, RID, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, RID, RID, bool) BIND10(canvas_item_add_triangle_array, RID, const Vector<int> &, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, const Vector<int> &, const Vector<float> &, RID, int, RID) - BIND4(canvas_item_add_mesh, RID, const RID &, RID, RID) + BIND6(canvas_item_add_mesh, RID, const RID &, const Transform2D &, const Color &, RID, RID) BIND4(canvas_item_add_multimesh, RID, RID, RID, RID) BIND4(canvas_item_add_particles, RID, RID, RID, RID) BIND2(canvas_item_add_set_transform, RID, const Transform2D &) diff --git a/servers/visual/visual_server_scene.cpp b/servers/visual/visual_server_scene.cpp index 2590e29aef..af580d6794 100644 --- a/servers/visual/visual_server_scene.cpp +++ b/servers/visual/visual_server_scene.cpp @@ -61,6 +61,16 @@ void VisualServerScene::camera_set_orthogonal(RID p_camera, float p_size, float camera->zfar = p_z_far; } +void VisualServerScene::camera_set_frustum(RID p_camera, float p_size, Vector2 p_offset, float p_z_near, float p_z_far) { + Camera *camera = camera_owner.get(p_camera); + ERR_FAIL_COND(!camera); + camera->type = Camera::FRUSTUM; + camera->size = p_size; + camera->offset = p_offset; + camera->znear = p_z_near; + camera->zfar = p_z_far; +} + void VisualServerScene::camera_set_transform(RID p_camera, const Transform &p_transform) { Camera *camera = camera_owner.get(p_camera); @@ -399,7 +409,8 @@ void VisualServerScene::instance_set_base(RID p_instance, RID p_base) { VSG::scene_render->free(gi_probe->probe_instance); } break; - default: {} + default: { + } } if (instance->base_data) { @@ -476,7 +487,8 @@ void VisualServerScene::instance_set_base(RID p_instance, RID p_base) { gi_probe->probe_instance = VSG::scene_render->gi_probe_instance_create(); } break; - default: {} + default: { + } } VSG::storage->instance_add_dependency(p_base, instance); @@ -524,7 +536,8 @@ void VisualServerScene::instance_set_scenario(RID p_instance, RID p_scenario) { gi_probe_update_list.remove(&gi_probe->update_element); } } break; - default: {} + default: { + } } instance->scenario = NULL; @@ -556,7 +569,8 @@ void VisualServerScene::instance_set_scenario(RID p_instance, RID p_scenario) { gi_probe_update_list.add(&gi_probe->update_element); } } break; - default: {} + default: { + } } _instance_queue_update(instance, true, true); @@ -671,7 +685,8 @@ void VisualServerScene::instance_set_visible(RID p_instance, bool p_visible) { } } break; - default: {} + default: { + } } } inline bool is_geometry_instance(VisualServer::InstanceType p_type) { @@ -848,7 +863,8 @@ void VisualServerScene::instance_geometry_set_flag(RID p_instance, VS::InstanceF instance->redraw_if_visible = p_enabled; } break; - default: {} + default: { + } } } void VisualServerScene::instance_geometry_set_cast_shadows_setting(RID p_instance, VS::ShadowCastingSetting p_shadow_casting_setting) { @@ -1040,7 +1056,8 @@ void VisualServerScene::_update_instance_aabb(Instance *p_instance) { new_aabb = VSG::storage->lightmap_capture_get_bounds(p_instance->base); } break; - default: {} + default: { + } } // <Zylann> This is why I didn't re-use Instance::aabb to implement custom AABBs @@ -1723,6 +1740,17 @@ void VisualServerScene::render_camera(RID p_camera, RID p_scenario, Size2 p_view ortho = false; } break; + case Camera::FRUSTUM: { + + camera_matrix.set_frustum( + camera->size, + p_viewport_size.width / (float)p_viewport_size.height, + camera->offset, + camera->znear, + camera->zfar, + camera->vaspect); + ortho = false; + } break; } _prepare_scene(camera->transform, camera_matrix, ortho, camera->env, camera->visible_layers, p_scenario, p_shadow_atlas, RID()); @@ -1864,7 +1892,7 @@ void VisualServerScene::_prepare_scene(const Transform p_cam_transform, const Ca //failure } else if (ins->base_type == VS::INSTANCE_LIGHT && ins->visible) { - if (ins->visible && light_cull_count < MAX_LIGHTS_CULLED) { + if (light_cull_count < MAX_LIGHTS_CULLED) { InstanceLightData *light = static_cast<InstanceLightData *>(ins->base_data); @@ -1881,7 +1909,7 @@ void VisualServerScene::_prepare_scene(const Transform p_cam_transform, const Ca } } else if (ins->base_type == VS::INSTANCE_REFLECTION_PROBE && ins->visible) { - if (ins->visible && reflection_probe_cull_count < MAX_REFLECTION_PROBES_CULLED) { + if (reflection_probe_cull_count < MAX_REFLECTION_PROBES_CULLED) { InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(ins->base_data); @@ -2626,7 +2654,7 @@ void VisualServerScene::_bake_gi_probe_light(const GIProbeDataHeader *header, co for (int i = 0; i < 3; i++) { - if (ABS(light_axis[i]) < CMP_EPSILON) + if (Math::is_zero_approx(light_axis[i])) continue; clip[clip_planes].normal[i] = 1.0; @@ -2761,7 +2789,7 @@ void VisualServerScene::_bake_gi_probe_light(const GIProbeDataHeader *header, co for (int c = 0; c < 3; c++) { - if (ABS(light_axis[c]) < CMP_EPSILON) + if (Math::is_zero_approx(light_axis[c])) continue; clip[clip_planes].normal[c] = 1.0; diff --git a/servers/visual/visual_server_scene.h b/servers/visual/visual_server_scene.h index 7583acd88f..2c2ba7e15f 100644 --- a/servers/visual/visual_server_scene.h +++ b/servers/visual/visual_server_scene.h @@ -77,12 +77,14 @@ public: enum Type { PERSPECTIVE, - ORTHOGONAL + ORTHOGONAL, + FRUSTUM }; Type type; float fov; float znear, zfar; float size; + Vector2 offset; uint32_t visible_layers; bool vaspect; RID env; @@ -97,6 +99,7 @@ public: znear = 0.05; zfar = 100; size = 1.0; + offset = Vector2(); vaspect = false; } }; @@ -106,6 +109,7 @@ public: virtual RID camera_create(); virtual void camera_set_perspective(RID p_camera, float p_fovy_degrees, float p_z_near, float p_z_far); virtual void camera_set_orthogonal(RID p_camera, float p_size, float p_z_near, float p_z_far); + virtual void camera_set_frustum(RID p_camera, float p_size, Vector2 p_offset, float p_z_near, float p_z_far); virtual void camera_set_transform(RID p_camera, const Transform &p_transform); virtual void camera_set_cull_mask(RID p_camera, uint32_t p_layers); virtual void camera_set_environment(RID p_camera, RID p_env); diff --git a/servers/visual/visual_server_viewport.cpp b/servers/visual/visual_server_viewport.cpp index 2c6709662f..e7f60c2c1f 100644 --- a/servers/visual/visual_server_viewport.cpp +++ b/servers/visual/visual_server_viewport.cpp @@ -35,6 +35,43 @@ #include "visual_server_globals.h" #include "visual_server_scene.h" +static Transform2D _canvas_get_transform(VisualServerViewport::Viewport *p_viewport, VisualServerCanvas::Canvas *p_canvas, VisualServerViewport::Viewport::CanvasData *p_canvas_data, const Vector2 &p_vp_size) { + + Transform2D xf = p_viewport->global_transform; + + float scale = 1.0; + if (p_viewport->canvas_map.has(p_canvas->parent)) { + xf = xf * p_viewport->canvas_map[p_canvas->parent].transform; + scale = p_canvas->parent_scale; + } + + xf = xf * p_canvas_data->transform; + + if (scale != 1.0 && !VSG::canvas->disable_scale) { + 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; +} + +void VisualServerViewport::_draw_3d(Viewport *p_viewport, ARVRInterface::Eyes p_eye) { + Ref<ARVRInterface> arvr_interface = ARVRServer::get_singleton()->get_primary_interface(); + + if (p_viewport->use_arvr && arvr_interface.is_valid()) { + VSG::scene->render_camera(arvr_interface, p_eye, p_viewport->camera, p_viewport->scenario, p_viewport->size, p_viewport->shadow_atlas); + } else { + VSG::scene->render_camera(p_viewport->camera, p_viewport->scenario, p_viewport->size, p_viewport->shadow_atlas); + } +} + void VisualServerViewport::_draw_viewport(Viewport *p_viewport, ARVRInterface::Eyes p_eye) { /* Camera should always be BEFORE any other 3D */ @@ -62,13 +99,7 @@ void VisualServerViewport::_draw_viewport(Viewport *p_viewport, ARVRInterface::E } if (!scenario_draw_canvas_bg && can_draw_3d) { - Ref<ARVRInterface> arvr_interface = ARVRServer::get_singleton()->get_primary_interface(); - - if (p_viewport->use_arvr && arvr_interface.is_valid()) { - VSG::scene->render_camera(arvr_interface, p_eye, p_viewport->camera, p_viewport->scenario, p_viewport->size, p_viewport->shadow_atlas); - } else { - VSG::scene->render_camera(p_viewport->camera, p_viewport->scenario, p_viewport->size, p_viewport->shadow_atlas); - } + _draw_3d(p_viewport, p_eye); } if (!p_viewport->hide_canvas) { @@ -86,10 +117,10 @@ void VisualServerViewport::_draw_viewport(Viewport *p_viewport, ARVRInterface::E for (Map<RID, Viewport::CanvasData>::Element *E = p_viewport->canvas_map.front(); E; E = E->next()) { - Transform2D xf = p_viewport->global_transform * E->get().transform; - VisualServerCanvas::Canvas *canvas = static_cast<VisualServerCanvas::Canvas *>(E->get().canvas); + Transform2D xf = _canvas_get_transform(p_viewport, canvas, &E->get(), clip_rect.size); + //find lights in canvas for (Set<RasterizerCanvas::Light *>::Element *F = canvas->lights.front(); F; F = F->next()) { @@ -174,17 +205,13 @@ void VisualServerViewport::_draw_viewport(Viewport *p_viewport, ARVRInterface::E //VSG::canvas_render->reset_canvas(); } - VSG::rasterizer->restore_render_target(); + VSG::rasterizer->restore_render_target(!scenario_draw_canvas_bg && can_draw_3d); if (scenario_draw_canvas_bg && canvas_map.front() && canvas_map.front()->key().get_layer() > scenario_canvas_max_layer) { - Ref<ARVRInterface> arvr_interface = ARVRServer::get_singleton()->get_primary_interface(); - if (!can_draw_3d) { VSG::scene->render_empty_scene(p_viewport->scenario, p_viewport->shadow_atlas); - } else if (p_viewport->use_arvr && arvr_interface.is_valid()) { - VSG::scene->render_camera(arvr_interface, p_eye, p_viewport->camera, p_viewport->scenario, p_viewport->size, p_viewport->shadow_atlas); } else { - VSG::scene->render_camera(p_viewport->camera, p_viewport->scenario, p_viewport->size, p_viewport->shadow_atlas); + _draw_3d(p_viewport, p_eye); } scenario_draw_canvas_bg = false; } @@ -193,7 +220,7 @@ void VisualServerViewport::_draw_viewport(Viewport *p_viewport, ARVRInterface::E VisualServerCanvas::Canvas *canvas = static_cast<VisualServerCanvas::Canvas *>(E->get()->canvas); - Transform2D xform = p_viewport->global_transform * E->get()->transform; + Transform2D xform = _canvas_get_transform(p_viewport, canvas, E->get(), clip_rect.size); RasterizerCanvas::Light *canvas_lights = NULL; @@ -210,14 +237,10 @@ void VisualServerViewport::_draw_viewport(Viewport *p_viewport, ARVRInterface::E i++; if (scenario_draw_canvas_bg && E->key().get_layer() >= scenario_canvas_max_layer) { - Ref<ARVRInterface> arvr_interface = ARVRServer::get_singleton()->get_primary_interface(); - if (!can_draw_3d) { VSG::scene->render_empty_scene(p_viewport->scenario, p_viewport->shadow_atlas); - } else if (p_viewport->use_arvr && arvr_interface.is_valid()) { - VSG::scene->render_camera(arvr_interface, p_eye, p_viewport->camera, p_viewport->scenario, p_viewport->size, p_viewport->shadow_atlas); } else { - VSG::scene->render_camera(p_viewport->camera, p_viewport->scenario, p_viewport->size, p_viewport->shadow_atlas); + _draw_3d(p_viewport, p_eye); } scenario_draw_canvas_bg = false; @@ -225,14 +248,10 @@ void VisualServerViewport::_draw_viewport(Viewport *p_viewport, ARVRInterface::E } if (scenario_draw_canvas_bg) { - Ref<ARVRInterface> arvr_interface = ARVRServer::get_singleton()->get_primary_interface(); - if (!can_draw_3d) { VSG::scene->render_empty_scene(p_viewport->scenario, p_viewport->shadow_atlas); - } else if (p_viewport->use_arvr && arvr_interface.is_valid()) { - VSG::scene->render_camera(arvr_interface, p_eye, p_viewport->camera, p_viewport->scenario, p_viewport->size, p_viewport->shadow_atlas); } else { - VSG::scene->render_camera(p_viewport->camera, p_viewport->scenario, p_viewport->size, p_viewport->shadow_atlas); + _draw_3d(p_viewport, p_eye); } scenario_draw_canvas_bg = false; @@ -276,17 +295,27 @@ void VisualServerViewport::draw_viewports() { if (vp->use_arvr && arvr_interface.is_valid()) { // override our size, make sure it matches our required size - Size2 size = arvr_interface->get_render_targetsize(); - VSG::storage->render_target_set_size(vp->render_target, size.x, size.y); + vp->size = arvr_interface->get_render_targetsize(); + VSG::storage->render_target_set_size(vp->render_target, vp->size.x, vp->size.y); // render mono or left eye first ARVRInterface::Eyes leftOrMono = arvr_interface->is_stereo() ? ARVRInterface::EYE_LEFT : ARVRInterface::EYE_MONO; + + // check for an external texture destination for our left eye/mono + VSG::storage->render_target_set_external_texture(vp->render_target, arvr_interface->get_external_texture_for_eye(leftOrMono)); + + // set our render target as current VSG::rasterizer->set_current_render_target(vp->render_target); + + // and draw left eye/mono _draw_viewport(vp, leftOrMono); arvr_interface->commit_for_eye(leftOrMono, vp->render_target, vp->viewport_to_screen_rect); // render right eye if (leftOrMono == ARVRInterface::EYE_LEFT) { + // check for an external texture destination for our right eye + VSG::storage->render_target_set_external_texture(vp->render_target, arvr_interface->get_external_texture_for_eye(ARVRInterface::EYE_RIGHT)); + // commit for eye may have changed the render target VSG::rasterizer->set_current_render_target(vp->render_target); @@ -297,6 +326,7 @@ void VisualServerViewport::draw_viewports() { // and for our frame timing, mark when we've finished committing our eyes ARVRServer::get_singleton()->_mark_commit(); } else { + VSG::storage->render_target_set_external_texture(vp->render_target, 0); VSG::rasterizer->set_current_render_target(vp->render_target); VSG::scene_render->set_debug_draw_mode(vp->debug_draw); diff --git a/servers/visual/visual_server_viewport.h b/servers/visual/visual_server_viewport.h index 5176551540..555b40a103 100644 --- a/servers/visual/visual_server_viewport.h +++ b/servers/visual/visual_server_viewport.h @@ -147,6 +147,7 @@ public: private: Color clear_color; + void _draw_3d(Viewport *p_viewport, ARVRInterface::Eyes p_eye); void _draw_viewport(Viewport *p_viewport, ARVRInterface::Eyes p_eye = ARVRInterface::EYE_MONO); public: diff --git a/servers/visual/visual_server_wrap_mt.h b/servers/visual/visual_server_wrap_mt.h index c6da6799a5..3e451511cd 100644 --- a/servers/visual/visual_server_wrap_mt.h +++ b/servers/visual/visual_server_wrap_mt.h @@ -360,6 +360,7 @@ public: FUNCRID(camera) FUNC4(camera_set_perspective, RID, float, float, float) FUNC4(camera_set_orthogonal, RID, float, float, float) + FUNC5(camera_set_frustum, RID, float, Vector2, float, float) FUNC2(camera_set_transform, RID, const Transform &) FUNC2(camera_set_cull_mask, RID, uint32_t) FUNC2(camera_set_environment, RID, RID) @@ -487,6 +488,8 @@ public: FUNCRID(canvas) FUNC3(canvas_set_item_mirroring, RID, RID, const Point2 &) FUNC2(canvas_set_modulate, RID, const Color &) + FUNC3(canvas_set_parent, RID, RID, float) + FUNC1(canvas_set_disable_scale, bool) FUNCRID(canvas_item) FUNC2(canvas_item_set_parent, RID, RID) @@ -516,7 +519,7 @@ public: FUNC7(canvas_item_add_primitive, RID, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, RID, float, RID) FUNC7(canvas_item_add_polygon, RID, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, RID, RID, bool) FUNC10(canvas_item_add_triangle_array, RID, const Vector<int> &, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, const Vector<int> &, const Vector<float> &, RID, int, RID) - FUNC4(canvas_item_add_mesh, RID, const RID &, RID, RID) + FUNC6(canvas_item_add_mesh, RID, const RID &, const Transform2D &, const Color &, RID, RID) FUNC4(canvas_item_add_multimesh, RID, RID, RID, RID) FUNC4(canvas_item_add_particles, RID, RID, RID, RID) FUNC2(canvas_item_add_set_transform, RID, const Transform2D &) |