From a8b318871c016a9ece8964daf02f4e85d31824ad Mon Sep 17 00:00:00 2001 From: Carl Olsson Date: Mon, 19 Jan 2015 23:07:25 +1000 Subject: Prep for tile transpose transform. --- core/object.h | 14 ++--- core/variant.h | 2 +- demos/2d/polygon_path_finder_demo/.fscache | 8 +-- scene/2d/tile_map.cpp | 33 +++++++++-- scene/2d/tile_map.h | 4 +- tools/editor/icons/icon_rotate_0.png | Bin 0 -> 207 bytes tools/editor/icons/icon_rotate_180.png | Bin 0 -> 303 bytes tools/editor/icons/icon_rotate_270.png | Bin 0 -> 343 bytes tools/editor/icons/icon_rotate_90.png | Bin 0 -> 256 bytes tools/editor/icons/icon_transpose.png | Bin 0 -> 258 bytes tools/editor/plugins/tile_map_editor_plugin.cpp | 72 +++++++++++++++++++----- tools/editor/plugins/tile_map_editor_plugin.h | 11 +++- 12 files changed, 109 insertions(+), 35 deletions(-) create mode 100644 tools/editor/icons/icon_rotate_0.png create mode 100644 tools/editor/icons/icon_rotate_180.png create mode 100644 tools/editor/icons/icon_rotate_270.png create mode 100644 tools/editor/icons/icon_rotate_90.png create mode 100644 tools/editor/icons/icon_transpose.png diff --git a/core/object.h b/core/object.h index 97ca50cb1a..3c493de157 100644 --- a/core/object.h +++ b/core/object.h @@ -35,13 +35,13 @@ #include "map.h" #include "vmap.h" -#define VARIANT_ARG_LIST const Variant& p_arg1=Variant(),const Variant& p_arg2=Variant(),const Variant& p_arg3=Variant(),const Variant& p_arg4=Variant(),const Variant& p_arg5=Variant() -#define VARIANT_ARG_PASS p_arg1,p_arg2,p_arg3,p_arg4,p_arg5 -#define VARIANT_ARG_DECLARE const Variant& p_arg1,const Variant& p_arg2,const Variant& p_arg3,const Variant& p_arg4,const Variant& p_arg5 -#define VARIANT_ARG_MAX 5 -#define VARIANT_ARGPTRS const Variant *argptr[5]={&p_arg1,&p_arg2,&p_arg3,&p_arg4,&p_arg5}; -#define VARIANT_ARGPTRS_PASS *argptr[0],*argptr[1],*argptr[2],*argptr[3],*argptr[4] -#define VARIANT_ARGS_FROM_ARRAY(m_arr) m_arr[0],m_arr[1],m_arr[2],m_arr[3],m_arr[4] +#define VARIANT_ARG_LIST const Variant& p_arg1=Variant(),const Variant& p_arg2=Variant(),const Variant& p_arg3=Variant(),const Variant& p_arg4=Variant(),const Variant& p_arg5=Variant(),const Variant& p_arg6=Variant() +#define VARIANT_ARG_PASS p_arg1,p_arg2,p_arg3,p_arg4,p_arg5,p_arg6 +#define VARIANT_ARG_DECLARE const Variant& p_arg1,const Variant& p_arg2,const Variant& p_arg3,const Variant& p_arg4,const Variant& p_arg5,const Variant& p_arg6 +#define VARIANT_ARG_MAX 6 +#define VARIANT_ARGPTRS const Variant *argptr[6]={&p_arg1,&p_arg2,&p_arg3,&p_arg4,&p_arg5,&p_arg6}; +#define VARIANT_ARGPTRS_PASS *argptr[0],*argptr[1],*argptr[2],*argptr[3],*argptr[4],*argptr[5] +#define VARIANT_ARGS_FROM_ARRAY(m_arr) m_arr[0],m_arr[1],m_arr[2],m_arr[3],m_arr[4],m_arr[5] /** @author Juan Linietsky diff --git a/core/variant.h b/core/variant.h index 47fc3f43ac..a3efc34452 100644 --- a/core/variant.h +++ b/core/variant.h @@ -387,7 +387,7 @@ public: }; Variant call(const StringName& p_method,const Variant** p_args,int p_argcount,CallError &r_error); - Variant call(const StringName& p_method,const Variant& p_arg1=Variant(),const Variant& p_arg2=Variant(),const Variant& p_arg3=Variant(),const Variant& p_arg4=Variant(),const Variant& p_arg5=Variant()); + Variant call(const StringName& p_method,const Variant& p_arg1=Variant(),const Variant& p_arg2=Variant(),const Variant& p_arg3=Variant(),const Variant& p_arg4=Variant(),const Variant& p_arg5=Variant(),const Variant& p_arg6=Variant()); static Variant construct(const Variant::Type,const Variant** p_args,int p_argcount,CallError &r_error); void get_method_list(List *p_list) const; diff --git a/demos/2d/polygon_path_finder_demo/.fscache b/demos/2d/polygon_path_finder_demo/.fscache index f699ca5849..bcec2f7a47 100644 --- a/demos/2d/polygon_path_finder_demo/.fscache +++ b/demos/2d/polygon_path_finder_demo/.fscache @@ -1,4 +1,4 @@ -::res://::1421147952 -icon.png::ImageTexture::1420046079:: -new_scene_poly_with_holes.scn::PackedScene::1421147952:: -polygonpathfinder.gd::GDScript::1421146502:: +::res://::1421669411 +icon.png::ImageTexture::1421499066:: +new_scene_poly_with_holes.scn::PackedScene::1421499066:: +polygonpathfinder.gd::GDScript::1421669411:: diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp index 9fcf34cee6..63a2867dac 100644 --- a/scene/2d/tile_map.cpp +++ b/scene/2d/tile_map.cpp @@ -29,6 +29,7 @@ #include "tile_map.h" #include "io/marshalls.h" #include "servers/physics_2d_server.h" +#include "method_bind_ext.inc" void TileMap::_notification(int p_what) { switch(p_what) { @@ -221,6 +222,10 @@ void TileMap::_update_dirty_quadrants() { rect.size.x=-rect.size.x; if (c.flip_v) rect.size.y=-rect.size.y; + if (c.transpose) { + //TODO + } + rect.pos+=tile_ofs; @@ -257,6 +262,11 @@ void TileMap::_update_dirty_quadrants() { xform.elements[2].y+=shape_ofs.y; } + if (c.transpose) { + //TODO + } else { + } + ps->body_add_shape(q.static_body,shape->get_rid(),xform); @@ -385,7 +395,7 @@ void TileMap::_make_quadrant_dirty(Map::Element *Q) { } -void TileMap::set_cell(int p_x,int p_y,int p_tile,bool p_flip_x,bool p_flip_y) { +void TileMap::set_cell(int p_x,int p_y,int p_tile,bool p_flip_x,bool p_flip_y,bool p_transpose) { PosKey pk(p_x,p_y); @@ -421,7 +431,7 @@ void TileMap::set_cell(int p_x,int p_y,int p_tile,bool p_flip_x,bool p_flip_y) { } else { ERR_FAIL_COND(!Q); // quadrant should exist... - if (E->get().id==p_tile && E->get().flip_h==p_flip_x && E->get().flip_v==p_flip_y) + if (E->get().id==p_tile && E->get().flip_h==p_flip_x && E->get().flip_v==p_flip_y && E->get().transpose==p_transpose) return; //nothing changed } @@ -432,6 +442,7 @@ void TileMap::set_cell(int p_x,int p_y,int p_tile,bool p_flip_x,bool p_flip_y) { c.id=p_tile; c.flip_h=p_flip_x; c.flip_v=p_flip_y; + c.transpose=p_transpose; _make_quadrant_dirty(Q); @@ -471,6 +482,17 @@ bool TileMap::is_cell_y_flipped(int p_x,int p_y) const { return E->get().flip_v; } +bool TileMap::is_cell_transposed(int p_x,int p_y) const { + + PosKey pk(p_x,p_y); + + const Map::Element *E=tile_map.find(pk); + + if (!E) + return false; + + return E->get().transpose; +} void TileMap::_recreate_quadrants() { @@ -535,11 +557,12 @@ void TileMap::_set_tile_data(const DVector& p_data) { uint32_t v = decode_uint32(&local[4]); bool flip_h = v&(1<<29); bool flip_v = v&(1<<30); + bool transpose = v&(1<<31); v&=(1<<29)-1; // if (x<-20 || y <-20 || x>4000 || y>4000) // continue; - set_cell(x,y,v,flip_h,flip_v); + set_cell(x,y,v,flip_h,flip_v,transpose); } @@ -562,6 +585,8 @@ DVector TileMap::_get_tile_data() const { val|=(1<<29); if (E->get().flip_v) val|=(1<<30); + if (E->get().transpose) + val|=(1<<31); encode_uint32(val,&ptr[4]); idx+=2; @@ -813,7 +838,7 @@ void TileMap::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_collision_bounce","value"),&TileMap::set_collision_bounce); ObjectTypeDB::bind_method(_MD("get_collision_bounce"),&TileMap::get_collision_bounce); - ObjectTypeDB::bind_method(_MD("set_cell","x","y","tile","flip_x","flip_y"),&TileMap::set_cell,DEFVAL(false),DEFVAL(false)); + ObjectTypeDB::bind_method(_MD("set_cell","x","y","tile","flip_x","flip_y","transpose"),&TileMap::set_cell,DEFVAL(false),DEFVAL(false),DEFVAL(false)); ObjectTypeDB::bind_method(_MD("get_cell","x","y"),&TileMap::get_cell); ObjectTypeDB::bind_method(_MD("is_cell_x_flipped","x","y"),&TileMap::is_cell_x_flipped); ObjectTypeDB::bind_method(_MD("is_cell_y_flipped","x","y"),&TileMap::is_cell_y_flipped); diff --git a/scene/2d/tile_map.h b/scene/2d/tile_map.h index 4e9e2e7e97..2809cdb378 100644 --- a/scene/2d/tile_map.h +++ b/scene/2d/tile_map.h @@ -85,6 +85,7 @@ private: int32_t id:24; bool flip_h:1; bool flip_v:1; + bool transpose:1; }; uint32_t _u32t; @@ -167,10 +168,11 @@ public: void set_center_y(bool p_enable); bool get_center_y() const; - void set_cell(int p_x,int p_y,int p_tile,bool p_flip_x=false,bool p_flip_y=false); + void set_cell(int p_x,int p_y,int p_tile,bool p_flip_x=false,bool p_flip_y=false,bool p_transpose=false); int get_cell(int p_x,int p_y) const; bool is_cell_x_flipped(int p_x,int p_y) const; bool is_cell_y_flipped(int p_x,int p_y) const; + bool is_cell_transposed(int p_x,int p_y) const; Rect2 get_item_rect() const; diff --git a/tools/editor/icons/icon_rotate_0.png b/tools/editor/icons/icon_rotate_0.png new file mode 100644 index 0000000000..85a4b4c420 Binary files /dev/null and b/tools/editor/icons/icon_rotate_0.png differ diff --git a/tools/editor/icons/icon_rotate_180.png b/tools/editor/icons/icon_rotate_180.png new file mode 100644 index 0000000000..c4c516cff5 Binary files /dev/null and b/tools/editor/icons/icon_rotate_180.png differ diff --git a/tools/editor/icons/icon_rotate_270.png b/tools/editor/icons/icon_rotate_270.png new file mode 100644 index 0000000000..6e0f2e62b8 Binary files /dev/null and b/tools/editor/icons/icon_rotate_270.png differ diff --git a/tools/editor/icons/icon_rotate_90.png b/tools/editor/icons/icon_rotate_90.png new file mode 100644 index 0000000000..f25b0e99a3 Binary files /dev/null and b/tools/editor/icons/icon_rotate_90.png differ diff --git a/tools/editor/icons/icon_transpose.png b/tools/editor/icons/icon_transpose.png new file mode 100644 index 0000000000..fab253c504 Binary files /dev/null and b/tools/editor/icons/icon_transpose.png differ diff --git a/tools/editor/plugins/tile_map_editor_plugin.cpp b/tools/editor/plugins/tile_map_editor_plugin.cpp index ce5ea58124..e387125b56 100644 --- a/tools/editor/plugins/tile_map_editor_plugin.cpp +++ b/tools/editor/plugins/tile_map_editor_plugin.cpp @@ -44,6 +44,11 @@ void TileMapEditor::_notification(int p_what) { mirror_x->set_icon( get_icon("MirrorX","EditorIcons")); mirror_y->set_icon( get_icon("MirrorY","EditorIcons")); + transpose->set_icon( get_icon("Transpose","EditorIcons")); + rotate_0->set_icon( get_icon("Rotate0","EditorIcons")); + rotate_90->set_icon( get_icon("Rotate90","EditorIcons")); + rotate_180->set_icon( get_icon("Rotate180","EditorIcons")); + rotate_270->set_icon( get_icon("Rotate270","EditorIcons")); } break; } @@ -85,24 +90,25 @@ void TileMapEditor::set_selected_tile(int p_tile) { } } -void TileMapEditor::_set_cell(const Point2i& p_pos,int p_value,bool p_flip_h, bool p_flip_v,bool p_with_undo) { +void TileMapEditor::_set_cell(const Point2i& p_pos,int p_value,bool p_flip_h, bool p_flip_v, bool p_transpose,bool p_with_undo) { ERR_FAIL_COND(!node); bool prev_flip_h=node->is_cell_x_flipped(p_pos.x,p_pos.y); bool prev_flip_v=node->is_cell_y_flipped(p_pos.x,p_pos.y); + bool prev_transpose=node->is_cell_transposed(p_pos.x,p_pos.y); int prev_val=node->get_cell(p_pos.x,p_pos.y); - if (p_value==prev_val && p_flip_h==prev_flip_h && p_flip_v==prev_flip_v) + if (p_value==prev_val && p_flip_h==prev_flip_h && p_flip_v==prev_transpose && p_flip_v==prev_transpose) return; //check that it's actually different if (p_with_undo) { - undo_redo->add_do_method(node,"set_cell",p_pos.x,p_pos.y,p_value,p_flip_h,p_flip_v); - undo_redo->add_undo_method(node,"set_cell",p_pos.x,p_pos.y,prev_val,prev_flip_h,prev_flip_v); + undo_redo->add_do_method(node,"set_cell",p_pos.x,p_pos.y,p_value,p_flip_h,p_flip_v,p_transpose); + undo_redo->add_undo_method(node,"set_cell",p_pos.x,p_pos.y,prev_val,prev_flip_h,prev_flip_v,prev_transpose); } else { - node->set_cell(p_pos.x,p_pos.y,p_value,p_flip_h,p_flip_v); + node->set_cell(p_pos.x,p_pos.y,p_value,p_flip_h,p_flip_v,p_transpose); } @@ -168,6 +174,7 @@ struct _TileMapEditorCopyData { int cell; bool flip_h; bool flip_v; + bool transpose; }; bool TileMapEditor::forward_input_event(const InputEvent& p_event) { @@ -214,7 +221,7 @@ bool TileMapEditor::forward_input_event(const InputEvent& p_event) { for (List<_TileMapEditorCopyData>::Element *E=dupdata.front();E;E=E->next()) { - _set_cell(E->get().pos+ofs,E->get().cell,E->get().flip_h,E->get().flip_v,true); + _set_cell(E->get().pos+ofs,E->get().cell,E->get().flip_h,E->get().flip_v,E->get().transpose,true); } undo_redo->commit_action(); @@ -239,6 +246,9 @@ bool TileMapEditor::forward_input_event(const InputEvent& p_event) { } else if (mb.mod.control) { tool=TOOL_PICKING; set_selected_tile(node->get_cell(over_tile.x, over_tile.y)); + mirror_x->set_pressed(node->is_cell_x_flipped(over_tile.x, over_tile.y)); + mirror_y->set_pressed(node->is_cell_y_flipped(over_tile.x, over_tile.y)); + transpose->set_pressed(node->is_cell_transposed(over_tile.x, over_tile.y)); canvas_item_editor->update(); return true; } else { @@ -248,7 +258,7 @@ bool TileMapEditor::forward_input_event(const InputEvent& p_event) { Point2i local =node->world_to_map((xform_inv.xform(Point2(mb.x,mb.y)))); paint_undo.clear(); paint_undo[local]=_get_op_from_cell(local); - node->set_cell(local.x,local.y,id,mirror_x->is_pressed(),mirror_y->is_pressed()); + node->set_cell(local.x,local.y,id,mirror_x->is_pressed(),mirror_y->is_pressed(),transpose->is_pressed()); return true; } } @@ -263,8 +273,8 @@ bool TileMapEditor::forward_input_event(const InputEvent& p_event) { for(Map::Element *E=paint_undo.front();E;E=E->next()) { Point2i p=E->key(); - undo_redo->add_do_method(node,"set_cell",p.x,p.y,node->get_cell(p.x,p.y),node->is_cell_x_flipped(p.x,p.y),node->is_cell_y_flipped(p.x,p.y)); - undo_redo->add_undo_method(node,"set_cell",p.x,p.y,E->get().idx,E->get().xf,E->get().yf); + undo_redo->add_do_method(node,"set_cell",p.x,p.y,node->get_cell(p.x,p.y),node->is_cell_x_flipped(p.x,p.y),node->is_cell_y_flipped(p.x,p.y),node->is_cell_transposed(p.x,p.y)); + undo_redo->add_undo_method(node,"set_cell",p.x,p.y,E->get().idx,E->get().xf,E->get().yf,E->get().tr); } undo_redo->commit_action(); @@ -289,7 +299,7 @@ bool TileMapEditor::forward_input_event(const InputEvent& p_event) { Point2i local =node->world_to_map(xform_inv.xform(Point2(mb.x,mb.y))); paint_undo.clear(); paint_undo[local]=_get_op_from_cell(local); - //node->set_cell(local.x,local.y,id,mirror_x->is_pressed(),mirror_y->is_pressed()); + //node->set_cell(local.x,local.y,id,mirror_x->is_pressed(),mirror_y->is_pressed(),transpose->is_pressed()); //return true; _set_cell(local,TileMap::INVALID_CELL); return true; @@ -302,9 +312,9 @@ bool TileMapEditor::forward_input_event(const InputEvent& p_event) { for(Map::Element *E=paint_undo.front();E;E=E->next()) { Point2i p=E->key(); - //undo_redo->add_do_method(node,"set_cell",p.x,p.y,node->get_cell(p.x,p.y),node->is_cell_x_flipped(p.x,p.y),node->is_cell_y_flipped(p.x,p.y)); - _set_cell(p,TileMap::INVALID_CELL,false,false,true); - undo_redo->add_undo_method(node,"set_cell",p.x,p.y,E->get().idx,E->get().xf,E->get().yf); + //undo_redo->add_do_method(node,"set_cell",p.x,p.y,node->get_cell(p.x,p.y),node->is_cell_x_flipped(p.x,p.y),node->is_cell_y_flipped(p.x,p.y),node->is_cell_transposed(p.x,p.y)); + _set_cell(p,TileMap::INVALID_CELL,false,false,false,true); + undo_redo->add_undo_method(node,"set_cell",p.x,p.y,E->get().idx,E->get().xf,E->get().yf,E->get().tr); } undo_redo->commit_action(); @@ -340,7 +350,7 @@ bool TileMapEditor::forward_input_event(const InputEvent& p_event) { paint_undo[over_tile]=_get_op_from_cell(over_tile); } - node->set_cell(over_tile.x,over_tile.y,id,mirror_x->is_pressed(),mirror_y->is_pressed()); + node->set_cell(over_tile.x,over_tile.y,id,mirror_x->is_pressed(),mirror_y->is_pressed(),transpose->is_pressed()); return true; } @@ -373,13 +383,16 @@ bool TileMapEditor::forward_input_event(const InputEvent& p_event) { if (!paint_undo.has(over_tile)) { paint_undo[over_tile]=_get_op_from_cell(over_tile); } - //node->set_cell(over_tile.x,over_tile.y,id,mirror_x->is_pressed(),mirror_y->is_pressed()); + //node->set_cell(over_tile.x,over_tile.y,id,mirror_x->is_pressed(),mirror_y->is_pressed(),transpose->is_pressed()); _set_cell(local,TileMap::INVALID_CELL); return true; } if (tool==TOOL_PICKING) { set_selected_tile(node->get_cell(over_tile.x, over_tile.y)); + mirror_x->set_pressed(node->is_cell_x_flipped(over_tile.x, over_tile.y)); + mirror_y->set_pressed(node->is_cell_y_flipped(over_tile.x, over_tile.y)); + transpose->set_pressed(node->is_cell_transposed(over_tile.x, over_tile.y)); canvas_item_editor->update(); return true; } @@ -625,6 +638,9 @@ void TileMapEditor::_canvas_draw() { sc.x*=-1.0; if (mirror_y->is_pressed()) sc.y*=-1.0; + if (transpose->is_pressed()) { + //TODO + } if (r==Rect2()) { canvas_item_editor->draw_texture_rect(t,Rect2(from,t->get_size()*sc),false,Color(1,1,1,0.5)); @@ -744,6 +760,32 @@ TileMapEditor::TileMapEditor(EditorNode *p_editor) { mirror_y->set_tooltip("Mirror Y (S)"); mirror_y->set_focus_mode(FOCUS_NONE); canvas_item_editor_hb->add_child(mirror_y); + transpose = memnew( ToolButton ); + transpose->set_toggle_mode(true); + transpose->set_tooltip("Transpose"); + transpose->set_focus_mode(FOCUS_NONE); + canvas_item_editor_hb->add_child(transpose); + canvas_item_editor_hb->add_child(memnew(VSeparator)); + rotate_0 = memnew( ToolButton ); + rotate_0->set_toggle_mode(true); + rotate_0->set_tooltip("Rotate 0 degrees"); + rotate_0->set_focus_mode(FOCUS_NONE); + canvas_item_editor_hb->add_child(rotate_0); + rotate_90 = memnew( ToolButton ); + rotate_90->set_toggle_mode(true); + rotate_90->set_tooltip("Rotate 90 degrees"); + rotate_90->set_focus_mode(FOCUS_NONE); + canvas_item_editor_hb->add_child(rotate_90); + rotate_180 = memnew( ToolButton ); + rotate_180->set_toggle_mode(true); + rotate_180->set_tooltip("Rotate 180 degrees"); + rotate_180->set_focus_mode(FOCUS_NONE); + canvas_item_editor_hb->add_child(rotate_180); + rotate_270 = memnew( ToolButton ); + rotate_270->set_toggle_mode(true); + rotate_270->set_tooltip("Rotate 270 degrees"); + rotate_270->set_focus_mode(FOCUS_NONE); + canvas_item_editor_hb->add_child(rotate_270); canvas_item_editor_hb->hide(); tool=TOOL_NONE; diff --git a/tools/editor/plugins/tile_map_editor_plugin.h b/tools/editor/plugins/tile_map_editor_plugin.h index f3c590e228..dd278be2c8 100644 --- a/tools/editor/plugins/tile_map_editor_plugin.h +++ b/tools/editor/plugins/tile_map_editor_plugin.h @@ -73,6 +73,11 @@ class TileMapEditor : public VBoxContainer { Label *mirror_label; ToolButton *mirror_x; ToolButton *mirror_y; + ToolButton *transpose; + ToolButton *rotate_0; + ToolButton *rotate_90; + ToolButton *rotate_180; + ToolButton *rotate_270; HBoxContainer *canvas_item_editor_hb; @@ -81,8 +86,8 @@ class TileMapEditor : public VBoxContainer { int idx; bool xf; bool yf; - CellOp() { idx=-1; xf=false; yf=false; } - CellOp(const CellOp& p_other) : idx(p_other.idx), xf(p_other.xf), yf(p_other.yf) {} + bool tr; + CellOp() { idx=-1; xf=false; yf=false; tr=false; } }; Map paint_undo; @@ -94,7 +99,7 @@ class TileMapEditor : public VBoxContainer { void _canvas_draw(); void _menu_option(int p_option); - void _set_cell(const Point2i& p_pos, int p_value, bool p_flip_h=false, bool p_flip_v=false, bool p_with_undo=false); + void _set_cell(const Point2i& p_pos, int p_value, bool p_flip_h=false, bool p_flip_v=false, bool p_transpose=false, bool p_with_undo=false); void _canvas_mouse_enter(); void _canvas_mouse_exit(); -- cgit v1.2.3 From c5bf43f6eb8aa9815362b1f771396e68c7f26f0f Mon Sep 17 00:00:00 2001 From: Carl Olsson Date: Mon, 2 Feb 2015 21:27:48 +1000 Subject: Working TileMap tile transpose transform. --- drivers/gles2/rasterizer_gles2.cpp | 9 ++-- drivers/gles2/rasterizer_gles2.h | 2 +- scene/2d/canvas_item.cpp | 8 ++-- scene/2d/canvas_item.h | 4 +- scene/2d/tile_map.cpp | 27 ++++------- scene/resources/texture.cpp | 59 ++++++++++++------------ scene/resources/texture.h | 25 +++++----- servers/visual/rasterizer.h | 3 +- servers/visual/visual_server_raster.cpp | 13 +++++- servers/visual/visual_server_raster.h | 4 +- servers/visual/visual_server_wrap_mt.h | 5 +- servers/visual_server.cpp | 6 ++- servers/visual_server.h | 4 +- tools/editor/icons/icon_transpose.png | Bin 258 -> 244 bytes tools/editor/plugins/tile_map_editor_plugin.cpp | 29 +++++++++--- tools/editor/plugins/tile_map_editor_plugin.h | 1 + 16 files changed, 110 insertions(+), 89 deletions(-) diff --git a/drivers/gles2/rasterizer_gles2.cpp b/drivers/gles2/rasterizer_gles2.cpp index 9375532f07..6e0eae1c52 100644 --- a/drivers/gles2/rasterizer_gles2.cpp +++ b/drivers/gles2/rasterizer_gles2.cpp @@ -8076,7 +8076,7 @@ void RasterizerGLES2::_draw_gui_primitive2(int p_points, const Vector2 *p_vertic _rinfo.ci_draw_commands++; } -void RasterizerGLES2::_draw_textured_quad(const Rect2& p_rect, const Rect2& p_src_region, const Size2& p_tex_size,bool p_h_flip, bool p_v_flip ) { +void RasterizerGLES2::_draw_textured_quad(const Rect2& p_rect, const Rect2& p_src_region, const Size2& p_tex_size,bool p_h_flip, bool p_v_flip, bool p_transpose ) { Vector2 texcoords[4]= { Vector2( p_src_region.pos.x/p_tex_size.width, @@ -8100,6 +8100,9 @@ void RasterizerGLES2::_draw_textured_quad(const Rect2& p_rect, const Rect2& p_sr SWAP( texcoords[1], texcoords[2] ); SWAP( texcoords[0], texcoords[3] ); } + if (p_transpose) { + SWAP( texcoords[1], texcoords[3] ); + } Vector2 coords[4]= { Vector2( p_rect.pos.x, p_rect.pos.y ), @@ -8139,11 +8142,11 @@ void RasterizerGLES2::canvas_draw_rect(const Rect2& p_rect, int p_flags, const R if (!(p_flags&CANVAS_RECT_REGION)) { Rect2 region = Rect2(0,0,texture->width,texture->height); - _draw_textured_quad(p_rect,region,region.size,p_flags&CANVAS_RECT_FLIP_H,p_flags&CANVAS_RECT_FLIP_V); + _draw_textured_quad(p_rect,region,region.size,p_flags&CANVAS_RECT_FLIP_H,p_flags&CANVAS_RECT_FLIP_V,p_flags&CANVAS_RECT_TRANSPOSE); } else { - _draw_textured_quad(p_rect, p_source, Size2(texture->width,texture->height),p_flags&CANVAS_RECT_FLIP_H,p_flags&CANVAS_RECT_FLIP_V ); + _draw_textured_quad(p_rect, p_source, Size2(texture->width,texture->height),p_flags&CANVAS_RECT_FLIP_H,p_flags&CANVAS_RECT_FLIP_V,p_flags&CANVAS_RECT_TRANSPOSE); } } else { diff --git a/drivers/gles2/rasterizer_gles2.h b/drivers/gles2/rasterizer_gles2.h index 0f77d18dee..37f740b747 100644 --- a/drivers/gles2/rasterizer_gles2.h +++ b/drivers/gles2/rasterizer_gles2.h @@ -1218,7 +1218,7 @@ class RasterizerGLES2 : public Rasterizer { void _draw_primitive(int p_points, const Vector3 *p_vertices, const Vector3 *p_normals, const Color* p_colors, const Vector3 *p_uvs,const Plane *p_tangents=NULL,int p_instanced=1); _FORCE_INLINE_ void _draw_gui_primitive(int p_points, const Vector2 *p_vertices, const Color* p_colors, const Vector2 *p_uvs); _FORCE_INLINE_ void _draw_gui_primitive2(int p_points, const Vector2 *p_vertices, const Color* p_colors, const Vector2 *p_uvs, const Vector2 *p_uvs2); - void _draw_textured_quad(const Rect2& p_rect, const Rect2& p_src_region, const Size2& p_tex_size,bool p_h_flip=false, bool p_v_flip=false ); + void _draw_textured_quad(const Rect2& p_rect, const Rect2& p_src_region, const Size2& p_tex_size,bool p_h_flip=false, bool p_v_flip=false, bool p_transpose=false ); void _draw_quad(const Rect2& p_rect); void _copy_screen_quad(); void _copy_to_texscreen(); diff --git a/scene/2d/canvas_item.cpp b/scene/2d/canvas_item.cpp index ae857bbce9..740d400aef 100644 --- a/scene/2d/canvas_item.cpp +++ b/scene/2d/canvas_item.cpp @@ -511,7 +511,7 @@ void CanvasItem::draw_texture(const Ref& p_texture,const Point2& p_pos) p_texture->draw(canvas_item,p_pos); } -void CanvasItem::draw_texture_rect(const Ref& p_texture,const Rect2& p_rect, bool p_tile,const Color& p_modulate) { +void CanvasItem::draw_texture_rect(const Ref& p_texture,const Rect2& p_rect, bool p_tile,const Color& p_modulate, bool p_transpose) { if (!drawing) { ERR_EXPLAIN("Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal."); @@ -519,17 +519,17 @@ void CanvasItem::draw_texture_rect(const Ref& p_texture,const Rect2& p_ } ERR_FAIL_COND(p_texture.is_null()); - p_texture->draw_rect(canvas_item,p_rect,p_tile,p_modulate); + p_texture->draw_rect(canvas_item,p_rect,p_tile,p_modulate,p_transpose); } -void CanvasItem::draw_texture_rect_region(const Ref& p_texture,const Rect2& p_rect, const Rect2& p_src_rect,const Color& p_modulate) { +void CanvasItem::draw_texture_rect_region(const Ref& p_texture,const Rect2& p_rect, const Rect2& p_src_rect,const Color& p_modulate, bool p_transpose) { if (!drawing) { ERR_EXPLAIN("Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal."); ERR_FAIL(); } ERR_FAIL_COND(p_texture.is_null()); - p_texture->draw_rect_region(canvas_item,p_rect,p_src_rect,p_modulate); + p_texture->draw_rect_region(canvas_item,p_rect,p_src_rect,p_modulate,p_transpose); } void CanvasItem::draw_style_box(const Ref& p_style_box,const Rect2& p_rect) { diff --git a/scene/2d/canvas_item.h b/scene/2d/canvas_item.h index ed3ade9df2..d1c7941fbf 100644 --- a/scene/2d/canvas_item.h +++ b/scene/2d/canvas_item.h @@ -170,8 +170,8 @@ public: void draw_rect(const Rect2& p_rect, const Color& p_color); void draw_circle(const Point2& p_pos, float p_radius, const Color& p_color); void draw_texture(const Ref& p_texture,const Point2& p_pos); - void draw_texture_rect(const Ref& p_texture, const Rect2& p_rect, bool p_tile=false,const Color& p_modulate=Color(1,1,1)); - void draw_texture_rect_region(const Ref& p_texture,const Rect2& p_rect, const Rect2& p_src_rect,const Color& p_modulate=Color(1,1,1)); + void draw_texture_rect(const Ref& p_texture, const Rect2& p_rect, bool p_tile=false,const Color& p_modulate=Color(1,1,1), bool p_transpose=false); + void draw_texture_rect_region(const Ref& p_texture,const Rect2& p_rect, const Rect2& p_src_rect,const Color& p_modulate=Color(1,1,1), bool p_transpose=false); void draw_style_box(const Ref& p_style_box,const Rect2& p_rect); void draw_primitive(const Vector& p_points, const Vector& p_colors,const Vector& p_uvs, Ref p_texture=Ref(),float p_width=1); void draw_polygon(const Vector& p_points, const Vector& p_colors,const Vector& p_uvs=Vector(), Ref p_texture=Ref()); diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp index 63a2867dac..0b123bfa1c 100644 --- a/scene/2d/tile_map.cpp +++ b/scene/2d/tile_map.cpp @@ -222,19 +222,13 @@ void TileMap::_update_dirty_quadrants() { rect.size.x=-rect.size.x; if (c.flip_v) rect.size.y=-rect.size.y; - if (c.transpose) { - //TODO - } - rect.pos+=tile_ofs; if (r==Rect2()) { - - tex->draw_rect(q.canvas_item,rect); + tex->draw_rect(q.canvas_item,rect,false,Color(1,1,1),c.transpose); } else { - - tex->draw_rect_region(q.canvas_item,rect,r); + tex->draw_rect_region(q.canvas_item,rect,r,Color(1,1,1),c.transpose); } Vector< Ref > shapes = tile_set->tile_get_shapes(c.id); @@ -250,22 +244,19 @@ void TileMap::_update_dirty_quadrants() { xform.set_origin(offset.floor()); if (c.flip_h) { xform.elements[0]=-xform.elements[0]; - xform.elements[2].x+=s.x-shape_ofs.x; - } else { - - xform.elements[2].x+=shape_ofs.x; + shape_ofs.x=s.x-shape_ofs.x; } if (c.flip_v) { xform.elements[1]=-xform.elements[1]; - xform.elements[2].y+=s.y-shape_ofs.y; - } else { - - xform.elements[2].y+=shape_ofs.y; + shape_ofs.y=s.y-shape_ofs.y; } if (c.transpose) { - //TODO - } else { + SWAP(xform.elements[0].x, xform.elements[0].y); + SWAP(xform.elements[1].x, xform.elements[1].y); + SWAP(shape_ofs.x, shape_ofs.y); } + xform.elements[2].x+=shape_ofs.x; + xform.elements[2].y+=shape_ofs.y; diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp index dae055890b..22f62c2f67 100644 --- a/scene/resources/texture.cpp +++ b/scene/resources/texture.cpp @@ -38,19 +38,19 @@ Size2 Texture::get_size() const { } -void Texture::draw(RID p_canvas_item, const Point2& p_pos, const Color& p_modulate) const { +void Texture::draw(RID p_canvas_item, const Point2& p_pos, const Color& p_modulate, bool p_transpose) const { - VisualServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item,Rect2( p_pos, get_size()),get_rid(),false,p_modulate); + VisualServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item,Rect2( p_pos, get_size()),get_rid(),false,p_modulate,p_transpose); } -void Texture::draw_rect(RID p_canvas_item,const Rect2& p_rect, bool p_tile,const Color& p_modulate) const { +void Texture::draw_rect(RID p_canvas_item,const Rect2& p_rect, bool p_tile,const Color& p_modulate, bool p_transpose) const { - VisualServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item,p_rect,get_rid(),p_tile,p_modulate); + VisualServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item,p_rect,get_rid(),p_tile,p_modulate,p_transpose); } -void Texture::draw_rect_region(RID p_canvas_item,const Rect2& p_rect, const Rect2& p_src_rect,const Color& p_modulate) const{ +void Texture::draw_rect_region(RID p_canvas_item,const Rect2& p_rect, const Rect2& p_src_rect,const Color& p_modulate, bool p_transpose) const{ - VisualServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item,p_rect,get_rid(),p_src_rect,p_modulate); + VisualServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item,p_rect,get_rid(),p_src_rect,p_modulate,p_transpose); } bool Texture::get_rect_region(const Rect2& p_rect, const Rect2& p_src_rect,Rect2& r_rect,Rect2& r_src_rect) const { @@ -70,9 +70,9 @@ void Texture::_bind_methods() { ObjectTypeDB::bind_method(_MD("has_alpha"),&Texture::has_alpha); ObjectTypeDB::bind_method(_MD("set_flags","flags"),&Texture::set_flags); ObjectTypeDB::bind_method(_MD("get_flags"),&Texture::get_flags); - ObjectTypeDB::bind_method(_MD("draw","canvas_item","pos","modulate"),&Texture::draw,DEFVAL(Color(1,1,1))); - ObjectTypeDB::bind_method(_MD("draw_rect","canvas_item","rect","tile","modulate"),&Texture::draw_rect,DEFVAL(Color(1,1,1))); - ObjectTypeDB::bind_method(_MD("draw_rect_region","canvas_item","rect","src_rect","modulate"),&Texture::draw_rect_region,DEFVAL(Color(1,1,1))); + ObjectTypeDB::bind_method(_MD("draw","canvas_item","pos","modulate"),&Texture::draw,DEFVAL(Color(1,1,1)),DEFVAL(false)); + ObjectTypeDB::bind_method(_MD("draw_rect","canvas_item","rect","tile","modulate"),&Texture::draw_rect,DEFVAL(Color(1,1,1)),DEFVAL(false)); + ObjectTypeDB::bind_method(_MD("draw_rect_region","canvas_item","rect","src_rect","modulate"),&Texture::draw_rect_region,DEFVAL(Color(1,1,1)),DEFVAL(false)); BIND_CONSTANT( FLAG_MIPMAPS ); BIND_CONSTANT( FLAG_REPEAT ); @@ -327,28 +327,27 @@ bool ImageTexture::has_alpha() const { } -void ImageTexture::draw(RID p_canvas_item, const Point2& p_pos, const Color& p_modulate) const { +void ImageTexture::draw(RID p_canvas_item, const Point2& p_pos, const Color& p_modulate, bool p_transpose) const { if ((w|h)==0) return; - VisualServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item,Rect2( p_pos, Size2(w,h)),texture,false,p_modulate); + VisualServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item,Rect2( p_pos, Size2(w,h)),texture,false,p_modulate,p_transpose); } -void ImageTexture::draw_rect(RID p_canvas_item,const Rect2& p_rect, bool p_tile,const Color& p_modulate) const { +void ImageTexture::draw_rect(RID p_canvas_item,const Rect2& p_rect, bool p_tile,const Color& p_modulate, bool p_transpose) const { if ((w|h)==0) return; - VisualServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item,p_rect,texture,p_tile,p_modulate); + VisualServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item,p_rect,texture,p_tile,p_modulate,p_transpose); } -void ImageTexture::draw_rect_region(RID p_canvas_item,const Rect2& p_rect, const Rect2& p_src_rect,const Color& p_modulate) const{ +void ImageTexture::draw_rect_region(RID p_canvas_item,const Rect2& p_rect, const Rect2& p_src_rect,const Color& p_modulate, bool p_transpose) const{ if ((w|h)==0) return; - VisualServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item,p_rect,texture,p_src_rect,p_modulate); + VisualServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item,p_rect,texture,p_src_rect,p_modulate,p_transpose); } - void ImageTexture::set_size_override(const Size2& p_size) { Size2 s=p_size; @@ -546,7 +545,7 @@ void AtlasTexture::_bind_methods() { -void AtlasTexture::draw(RID p_canvas_item, const Point2& p_pos, const Color& p_modulate) const { +void AtlasTexture::draw(RID p_canvas_item, const Point2& p_pos, const Color& p_modulate, bool p_transpose) const { Rect2 rc=region; @@ -561,10 +560,10 @@ void AtlasTexture::draw(RID p_canvas_item, const Point2& p_pos, const Color& p_m rc.size.height=atlas->get_height(); } - VS::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item,Rect2(p_pos+margin.pos,rc.size),atlas->get_rid(),rc,p_modulate); + VS::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item,Rect2(p_pos+margin.pos,rc.size),atlas->get_rid(),rc,p_modulate,p_transpose); } -void AtlasTexture::draw_rect(RID p_canvas_item,const Rect2& p_rect, bool p_tile,const Color& p_modulate) const { +void AtlasTexture::draw_rect(RID p_canvas_item,const Rect2& p_rect, bool p_tile,const Color& p_modulate, bool p_transpose) const { Rect2 rc=region; @@ -582,10 +581,10 @@ void AtlasTexture::draw_rect(RID p_canvas_item,const Rect2& p_rect, bool p_tile, Vector2 scale = p_rect.size / (region.size+margin.size); Rect2 dr( p_rect.pos+margin.pos*scale,rc.size*scale ); - VS::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item,dr,atlas->get_rid(),rc,p_modulate); + VS::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item,dr,atlas->get_rid(),rc,p_modulate,p_transpose); } -void AtlasTexture::draw_rect_region(RID p_canvas_item,const Rect2& p_rect, const Rect2& p_src_rect,const Color& p_modulate) const { +void AtlasTexture::draw_rect_region(RID p_canvas_item,const Rect2& p_rect, const Rect2& p_src_rect,const Color& p_modulate, bool p_transpose) const { //this might not necesarily work well if using a rect, needs to be fixed properly Rect2 rc=region; @@ -615,7 +614,7 @@ void AtlasTexture::draw_rect_region(RID p_canvas_item,const Rect2& p_rect, const } Rect2 dr( p_rect.pos+ofs*scale,src_c.size*scale ); - VS::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item,dr,atlas->get_rid(),src_c,p_modulate); + VS::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item,dr,atlas->get_rid(),src_c,p_modulate,p_transpose); } bool AtlasTexture::get_rect_region(const Rect2& p_rect, const Rect2& p_src_rect,Rect2& r_rect,Rect2& r_src_rect) const { @@ -801,15 +800,16 @@ void LargeTexture::_bind_methods() { -void LargeTexture::draw(RID p_canvas_item, const Point2& p_pos, const Color& p_modulate) const { +void LargeTexture::draw(RID p_canvas_item, const Point2& p_pos, const Color& p_modulate, bool p_transpose) const { for(int i=0;idraw(p_canvas_item,pieces[i].offset+p_pos,p_modulate); + // TODO + pieces[i].texture->draw(p_canvas_item,pieces[i].offset+p_pos,p_modulate,p_transpose); } } -void LargeTexture::draw_rect(RID p_canvas_item,const Rect2& p_rect, bool p_tile,const Color& p_modulate) const { +void LargeTexture::draw_rect(RID p_canvas_item,const Rect2& p_rect, bool p_tile,const Color& p_modulate, bool p_transpose) const { //tiling not supported for this if (size.x==0 || size.y==0) @@ -819,11 +819,11 @@ void LargeTexture::draw_rect(RID p_canvas_item,const Rect2& p_rect, bool p_tile, for(int i=0;idraw_rect(p_canvas_item,Rect2(pieces[i].offset*scale+p_rect.pos,pieces[i].texture->get_size()*scale),false,p_modulate); + // TODO + pieces[i].texture->draw_rect(p_canvas_item,Rect2(pieces[i].offset*scale+p_rect.pos,pieces[i].texture->get_size()*scale),false,p_modulate,p_transpose); } - } -void LargeTexture::draw_rect_region(RID p_canvas_item,const Rect2& p_rect, const Rect2& p_src_rect,const Color& p_modulate) const { +void LargeTexture::draw_rect_region(RID p_canvas_item,const Rect2& p_rect, const Rect2& p_src_rect,const Color& p_modulate, bool p_transpose) const { //tiling not supported for this @@ -834,6 +834,7 @@ void LargeTexture::draw_rect_region(RID p_canvas_item,const Rect2& p_rect, const for(int i=0;iget_size()); if (!p_src_rect.intersects(rect)) continue; @@ -842,7 +843,7 @@ void LargeTexture::draw_rect_region(RID p_canvas_item,const Rect2& p_rect, const target.size*=scale; target.pos=p_rect.pos+(p_src_rect.pos+rect.pos)*scale; local.pos-=rect.pos; - pieces[i].texture->draw_rect_region(p_canvas_item,target,local,p_modulate); + pieces[i].texture->draw_rect_region(p_canvas_item,target,local,p_modulate,p_transpose); } } diff --git a/scene/resources/texture.h b/scene/resources/texture.h index 4bb2f6d979..c1122b005d 100644 --- a/scene/resources/texture.h +++ b/scene/resources/texture.h @@ -69,9 +69,9 @@ public: virtual void set_flags(uint32_t p_flags)=0; virtual uint32_t get_flags() const=0; - virtual void draw(RID p_canvas_item, const Point2& p_pos, const Color& p_modulate=Color(1,1,1)) const; - virtual void draw_rect(RID p_canvas_item,const Rect2& p_rect, bool p_tile=false,const Color& p_modulate=Color(1,1,1)) const; - virtual void draw_rect_region(RID p_canvas_item,const Rect2& p_rect, const Rect2& p_src_rect,const Color& p_modulate=Color(1,1,1)) const; + virtual void draw(RID p_canvas_item, const Point2& p_pos, const Color& p_modulate=Color(1,1,1), bool p_transpose=false) const; + virtual void draw_rect(RID p_canvas_item,const Rect2& p_rect, bool p_tile=false,const Color& p_modulate=Color(1,1,1), bool p_transpose=false) const; + virtual void draw_rect_region(RID p_canvas_item,const Rect2& p_rect, const Rect2& p_src_rect,const Color& p_modulate=Color(1,1,1), bool p_transpose=false) const; virtual bool get_rect_region(const Rect2& p_rect, const Rect2& p_src_rect,Rect2& r_rect,Rect2& r_src_rect) const; @@ -135,10 +135,9 @@ public: virtual RID get_rid() const; bool has_alpha() const; - virtual void draw(RID p_canvas_item, const Point2& p_pos, const Color& p_modulate=Color(1,1,1)) const; - virtual void draw_rect(RID p_canvas_item,const Rect2& p_rect, bool p_tile=false,const Color& p_modulate=Color(1,1,1)) const; - virtual void draw_rect_region(RID p_canvas_item,const Rect2& p_rect, const Rect2& p_src_rect,const Color& p_modulate=Color(1,1,1)) const; - + virtual void draw(RID p_canvas_item, const Point2& p_pos, const Color& p_modulate=Color(1,1,1), bool p_transpose=false) const; + virtual void draw_rect(RID p_canvas_item,const Rect2& p_rect, bool p_tile=false,const Color& p_modulate=Color(1,1,1), bool p_transpose=false) const; + virtual void draw_rect_region(RID p_canvas_item,const Rect2& p_rect, const Rect2& p_src_rect,const Color& p_modulate=Color(1,1,1), bool p_transpose=false) const; void set_storage(Storage p_storage); Storage get_storage() const; @@ -191,9 +190,9 @@ public: void set_margin(const Rect2& p_margin); Rect2 get_margin() const ; - virtual void draw(RID p_canvas_item, const Point2& p_pos, const Color& p_modulate=Color(1,1,1)) const; - virtual void draw_rect(RID p_canvas_item,const Rect2& p_rect, bool p_tile=false,const Color& p_modulate=Color(1,1,1)) const; - virtual void draw_rect_region(RID p_canvas_item,const Rect2& p_rect, const Rect2& p_src_rect,const Color& p_modulate=Color(1,1,1)) const; + virtual void draw(RID p_canvas_item, const Point2& p_pos, const Color& p_modulate=Color(1,1,1), bool p_transpose=false) const; + virtual void draw_rect(RID p_canvas_item,const Rect2& p_rect, bool p_tile=false,const Color& p_modulate=Color(1,1,1), bool p_transpose=false) const; + virtual void draw_rect_region(RID p_canvas_item,const Rect2& p_rect, const Rect2& p_src_rect,const Color& p_modulate=Color(1,1,1), bool p_transpose=false) const; virtual bool get_rect_region(const Rect2& p_rect, const Rect2& p_src_rect,Rect2& r_rect,Rect2& r_src_rect) const; @@ -241,9 +240,9 @@ public: Vector2 get_piece_offset(int p_idx) const; Ref get_piece_texture(int p_idx) const; - virtual void draw(RID p_canvas_item, const Point2& p_pos, const Color& p_modulate=Color(1,1,1)) const; - virtual void draw_rect(RID p_canvas_item,const Rect2& p_rect, bool p_tile=false,const Color& p_modulate=Color(1,1,1)) const; - virtual void draw_rect_region(RID p_canvas_item,const Rect2& p_rect, const Rect2& p_src_rect,const Color& p_modulate=Color(1,1,1)) const; + virtual void draw(RID p_canvas_item, const Point2& p_pos, const Color& p_modulate=Color(1,1,1), bool p_transpose=false) const; + virtual void draw_rect(RID p_canvas_item,const Rect2& p_rect, bool p_tile=false,const Color& p_modulate=Color(1,1,1), bool p_transpose=false) const; + virtual void draw_rect_region(RID p_canvas_item,const Rect2& p_rect, const Rect2& p_src_rect,const Color& p_modulate=Color(1,1,1), bool p_transpose=false) const; LargeTexture(); diff --git a/servers/visual/rasterizer.h b/servers/visual/rasterizer.h index 92c7b8ac14..40ce7984ec 100644 --- a/servers/visual/rasterizer.h +++ b/servers/visual/rasterizer.h @@ -564,7 +564,8 @@ public: CANVAS_RECT_REGION=1, CANVAS_RECT_TILE=2, CANVAS_RECT_FLIP_H=4, - CANVAS_RECT_FLIP_V=8 + CANVAS_RECT_FLIP_V=8, + CANVAS_RECT_TRANSPOSE=16 }; struct CanvasItem { diff --git a/servers/visual/visual_server_raster.cpp b/servers/visual/visual_server_raster.cpp index a3aa573e35..118ea3b8e1 100644 --- a/servers/visual/visual_server_raster.cpp +++ b/servers/visual/visual_server_raster.cpp @@ -3470,7 +3470,7 @@ void VisualServerRaster::canvas_item_add_circle(RID p_item, const Point2& p_pos, } -void VisualServerRaster::canvas_item_add_texture_rect(RID p_item, const Rect2& p_rect, RID p_texture,bool p_tile,const Color& p_modulate) { +void VisualServerRaster::canvas_item_add_texture_rect(RID p_item, const Rect2& p_rect, RID p_texture,bool p_tile,const Color& p_modulate,bool p_transpose) { VS_CHANGED; CanvasItem *canvas_item = canvas_item_owner.get( p_item ); ERR_FAIL_COND(!canvas_item); @@ -3493,12 +3493,16 @@ void VisualServerRaster::canvas_item_add_texture_rect(RID p_item, const Rect2& p rect->flags|=Rasterizer::CANVAS_RECT_FLIP_V; rect->rect.size.y = -rect->rect.size.y; } + if (p_transpose) { + rect->flags|=Rasterizer::CANVAS_RECT_TRANSPOSE; + SWAP(rect->rect.size.x, rect->rect.size.y); + } rect->texture=p_texture; canvas_item->rect_dirty=true; canvas_item->commands.push_back(rect); } -void VisualServerRaster::canvas_item_add_texture_rect_region(RID p_item, const Rect2& p_rect, RID p_texture,const Rect2& p_src_rect,const Color& p_modulate) { +void VisualServerRaster::canvas_item_add_texture_rect_region(RID p_item, const Rect2& p_rect, RID p_texture,const Rect2& p_src_rect,const Color& p_modulate,bool p_transpose) { VS_CHANGED; CanvasItem *canvas_item = canvas_item_owner.get( p_item ); ERR_FAIL_COND(!canvas_item); @@ -3521,12 +3525,17 @@ void VisualServerRaster::canvas_item_add_texture_rect_region(RID p_item, const R rect->flags|=Rasterizer::CANVAS_RECT_FLIP_V; rect->rect.size.y = -rect->rect.size.y; } + if (p_transpose) { + rect->flags|=Rasterizer::CANVAS_RECT_TRANSPOSE; + SWAP(rect->rect.size.x, rect->rect.size.y); + } canvas_item->rect_dirty=true; canvas_item->commands.push_back(rect); } + void VisualServerRaster::canvas_item_add_style_box(RID p_item, const Rect2& p_rect, RID p_texture,const Vector2& p_topleft, const Vector2& p_bottomright, bool p_draw_center,const Color& p_modulate) { VS_CHANGED; diff --git a/servers/visual/visual_server_raster.h b/servers/visual/visual_server_raster.h index 6c4e15827a..e270ec1a4a 100644 --- a/servers/visual/visual_server_raster.h +++ b/servers/visual/visual_server_raster.h @@ -1102,8 +1102,8 @@ public: virtual void canvas_item_add_line(RID p_item, const Point2& p_from, const Point2& p_to,const Color& p_color,float p_width=1.0); virtual void canvas_item_add_rect(RID p_item, const Rect2& p_rect, const Color& p_color); virtual void canvas_item_add_circle(RID p_item, const Point2& p_pos, float p_radius,const Color& p_color); - virtual void canvas_item_add_texture_rect(RID p_item, const Rect2& p_rect, RID p_texture,bool p_tile=false,const Color& p_modulate=Color(1,1,1)); - virtual void canvas_item_add_texture_rect_region(RID p_item, const Rect2& p_rect, RID p_texture,const Rect2& p_src_rect,const Color& p_modulate=Color(1,1,1)); + virtual void canvas_item_add_texture_rect(RID p_item, const Rect2& p_rect, RID p_texture,bool p_tile=false,const Color& p_modulate=Color(1,1,1),bool p_transpose=false); + virtual void canvas_item_add_texture_rect_region(RID p_item, const Rect2& p_rect, RID p_texture,const Rect2& p_src_rect,const Color& p_modulate=Color(1,1,1),bool p_transpose=false); virtual void canvas_item_add_style_box(RID p_item, const Rect2& p_rect, RID p_texture,const Vector2& p_topleft, const Vector2& p_bottomright, bool p_draw_center=true,const Color& p_modulate=Color(1,1,1)); virtual void canvas_item_add_primitive(RID p_item, const Vector& p_points, const Vector& p_colors,const Vector& p_uvs, RID p_texture,float p_width=1.0); virtual void canvas_item_add_polygon(RID p_item, const Vector& p_points, const Vector& p_colors,const Vector& p_uvs=Vector(), RID p_texture=RID()); diff --git a/servers/visual/visual_server_wrap_mt.h b/servers/visual/visual_server_wrap_mt.h index b59fdbc66a..4ba7b7143c 100644 --- a/servers/visual/visual_server_wrap_mt.h +++ b/servers/visual/visual_server_wrap_mt.h @@ -1116,9 +1116,8 @@ public: FUNC5(canvas_item_add_line,RID, const Point2& , const Point2& ,const Color& ,float ); FUNC3(canvas_item_add_rect,RID, const Rect2& , const Color& ); FUNC4(canvas_item_add_circle,RID, const Point2& , float ,const Color& ); - FUNC5(canvas_item_add_texture_rect,RID, const Rect2& , RID ,bool ,const Color& ); - FUNC5(canvas_item_add_texture_rect_region,RID, const Rect2& , RID ,const Rect2& ,const Color& ); - + FUNC6(canvas_item_add_texture_rect,RID, const Rect2& , RID ,bool ,const Color&,bool ); + FUNC6(canvas_item_add_texture_rect_region,RID, const Rect2& , RID ,const Rect2& ,const Color&,bool ); FUNC7(canvas_item_add_style_box,RID, const Rect2& , RID ,const Vector2& ,const Vector2&, bool ,const Color& ); FUNC6(canvas_item_add_primitive,RID, const Vector& , const Vector& ,const Vector& , RID ,float ); FUNC5(canvas_item_add_polygon,RID, const Vector& , const Vector& ,const Vector& , RID ); diff --git a/servers/visual_server.cpp b/servers/visual_server.cpp index e0238c8042..5ddfaf7967 100644 --- a/servers/visual_server.cpp +++ b/servers/visual_server.cpp @@ -28,6 +28,7 @@ /*************************************************************************/ #include "visual_server.h" #include "globals.h" +#include "method_bind_ext.inc" VisualServer *VisualServer::singleton=NULL; VisualServer* (*VisualServer::create_func)()=NULL; @@ -510,8 +511,9 @@ void VisualServer::_bind_methods() { ObjectTypeDB::bind_method(_MD("canvas_item_add_line"),&VisualServer::canvas_item_add_line, DEFVAL(1.0)); ObjectTypeDB::bind_method(_MD("canvas_item_add_rect"),&VisualServer::canvas_item_add_rect); - ObjectTypeDB::bind_method(_MD("canvas_item_add_texture_rect"),&VisualServer::canvas_item_add_texture_rect, DEFVAL(Color(1,1,1))); - ObjectTypeDB::bind_method(_MD("canvas_item_add_texture_rect_region"),&VisualServer::canvas_item_add_texture_rect_region, DEFVAL(Color(1,1,1))); + ObjectTypeDB::bind_method(_MD("canvas_item_add_texture_rect"),&VisualServer::canvas_item_add_texture_rect, DEFVAL(Color(1,1,1)), DEFVAL(false)); + ObjectTypeDB::bind_method(_MD("canvas_item_add_texture_rect_region"),&VisualServer::canvas_item_add_texture_rect_region, DEFVAL(Color(1,1,1)), DEFVAL(false)); + ObjectTypeDB::bind_method(_MD("canvas_item_add_style_box"),&VisualServer::_canvas_item_add_style_box, DEFVAL(Color(1,1,1))); // ObjectTypeDB::bind_method(_MD("canvas_item_add_primitive"),&VisualServer::canvas_item_add_primitive,DEFVAL(Vector()),DEFVAL(RID())); ObjectTypeDB::bind_method(_MD("canvas_item_add_circle"),&VisualServer::canvas_item_add_circle); diff --git a/servers/visual_server.h b/servers/visual_server.h index 5721e7acf0..979355d339 100644 --- a/servers/visual_server.h +++ b/servers/visual_server.h @@ -974,8 +974,8 @@ public: virtual void canvas_item_add_line(RID p_item, const Point2& p_from, const Point2& p_to,const Color& p_color,float p_width=1.0)=0; virtual void canvas_item_add_rect(RID p_item, const Rect2& p_rect, const Color& p_color)=0; virtual void canvas_item_add_circle(RID p_item, const Point2& p_pos, float p_radius,const Color& p_color)=0; - virtual void canvas_item_add_texture_rect(RID p_item, const Rect2& p_rect, RID p_texture,bool p_tile=false,const Color& p_modulate=Color(1,1,1))=0; - virtual void canvas_item_add_texture_rect_region(RID p_item, const Rect2& p_rect, RID p_texture,const Rect2& p_src_rect,const Color& p_modulate=Color(1,1,1))=0; + virtual void canvas_item_add_texture_rect(RID p_item, const Rect2& p_rect, RID p_texture,bool p_tile=false,const Color& p_modulate=Color(1,1,1),bool p_transpose=false)=0; + virtual void canvas_item_add_texture_rect_region(RID p_item, const Rect2& p_rect, RID p_texture,const Rect2& p_src_rect,const Color& p_modulate=Color(1,1,1),bool p_transpose=false)=0; virtual void canvas_item_add_style_box(RID p_item, const Rect2& p_rect, RID p_texture,const Vector2& p_topleft, const Vector2& p_bottomright, bool p_draw_center=true,const Color& p_modulate=Color(1,1,1))=0; virtual void canvas_item_add_primitive(RID p_item, const Vector& p_points, const Vector& p_colors,const Vector& p_uvs, RID p_texture,float p_width=1.0)=0; virtual void canvas_item_add_polygon(RID p_item, const Vector& p_points, const Vector& p_colors,const Vector& p_uvs=Vector(), RID p_texture=RID())=0; diff --git a/tools/editor/icons/icon_transpose.png b/tools/editor/icons/icon_transpose.png index fab253c504..f9b78bc0fd 100644 Binary files a/tools/editor/icons/icon_transpose.png and b/tools/editor/icons/icon_transpose.png differ diff --git a/tools/editor/plugins/tile_map_editor_plugin.cpp b/tools/editor/plugins/tile_map_editor_plugin.cpp index e387125b56..34270d5076 100644 --- a/tools/editor/plugins/tile_map_editor_plugin.cpp +++ b/tools/editor/plugins/tile_map_editor_plugin.cpp @@ -99,7 +99,7 @@ void TileMapEditor::_set_cell(const Point2i& p_pos,int p_value,bool p_flip_h, bo bool prev_transpose=node->is_cell_transposed(p_pos.x,p_pos.y); int prev_val=node->get_cell(p_pos.x,p_pos.y); - if (p_value==prev_val && p_flip_h==prev_flip_h && p_flip_v==prev_transpose && p_flip_v==prev_transpose) + if (p_value==prev_val && p_flip_h==prev_flip_h && p_flip_v==prev_flip_v && p_transpose==prev_transpose) return; //check that it's actually different @@ -127,7 +127,7 @@ void TileMapEditor::_update_palette() { TreeItem *root = palette->create_item(); - palette->set_hide_root(true); + //palette->set_hide_root(true); List tiles; tileset->get_tile_list(&tiles); @@ -211,6 +211,7 @@ bool TileMapEditor::forward_input_event(const InputEvent& p_event) { tcd.cell=node->get_cell(j,i); tcd.flip_h=node->is_cell_x_flipped(j,i); tcd.flip_v=node->is_cell_y_flipped(j,i); + tcd.transpose=node->is_cell_transposed(j,i); dupdata.push_back(tcd); @@ -638,15 +639,12 @@ void TileMapEditor::_canvas_draw() { sc.x*=-1.0; if (mirror_y->is_pressed()) sc.y*=-1.0; - if (transpose->is_pressed()) { - //TODO - } if (r==Rect2()) { - canvas_item_editor->draw_texture_rect(t,Rect2(from,t->get_size()*sc),false,Color(1,1,1,0.5)); + canvas_item_editor->draw_texture_rect(t,Rect2(from,t->get_size()*sc),false,Color(1,1,1,0.5),transpose->is_pressed()); } else { - canvas_item_editor->draw_texture_rect_region(t,Rect2(from,r.get_size()*sc),r,Color(1,1,1,0.5)); + canvas_item_editor->draw_texture_rect_region(t,Rect2(from,r.get_size()*sc),r,Color(1,1,1,0.5),transpose->is_pressed()); } } } @@ -713,6 +711,7 @@ void TileMapEditor::_bind_methods() { ObjectTypeDB::bind_method(_MD("_canvas_mouse_enter"),&TileMapEditor::_canvas_mouse_enter); ObjectTypeDB::bind_method(_MD("_canvas_mouse_exit"),&TileMapEditor::_canvas_mouse_exit); ObjectTypeDB::bind_method(_MD("_tileset_settings_changed"),&TileMapEditor::_tileset_settings_changed); + ObjectTypeDB::bind_method(_MD("_update_transform_buttons"),&TileMapEditor::_update_transform_buttons); } @@ -725,10 +724,19 @@ TileMapEditor::CellOp TileMapEditor::_get_op_from_cell(const Point2i& p_pos) op.xf=true; if (node->is_cell_y_flipped(p_pos.x,p_pos.y)) op.yf=true; + if (node->is_cell_transposed(p_pos.x,p_pos.y)) + op.tr=true; } return op; } +void TileMapEditor::_update_transform_buttons(Object *p_button) { + ERR_FAIL_NULL(p_button); + ToolButton *b=p_button->cast_to(); + ERR_FAIL_COND(!b); + +} + TileMapEditor::TileMapEditor(EditorNode *p_editor) { node=NULL; @@ -754,37 +762,44 @@ TileMapEditor::TileMapEditor(EditorNode *p_editor) { mirror_x->set_toggle_mode(true); mirror_x->set_tooltip("Mirror X (A)"); mirror_x->set_focus_mode(FOCUS_NONE); + mirror_x->connect("pressed", this, "_update_transform_buttons", make_binds(mirror_x)); canvas_item_editor_hb->add_child(mirror_x); mirror_y = memnew( ToolButton ); mirror_y->set_toggle_mode(true); mirror_y->set_tooltip("Mirror Y (S)"); mirror_y->set_focus_mode(FOCUS_NONE); + mirror_y->connect("pressed", this, "_update_transform_buttons", make_binds(mirror_y)); canvas_item_editor_hb->add_child(mirror_y); transpose = memnew( ToolButton ); transpose->set_toggle_mode(true); transpose->set_tooltip("Transpose"); transpose->set_focus_mode(FOCUS_NONE); + transpose->connect("pressed", this, "_update_transform_buttons", make_binds(transpose)); canvas_item_editor_hb->add_child(transpose); canvas_item_editor_hb->add_child(memnew(VSeparator)); rotate_0 = memnew( ToolButton ); rotate_0->set_toggle_mode(true); rotate_0->set_tooltip("Rotate 0 degrees"); rotate_0->set_focus_mode(FOCUS_NONE); + rotate_0->connect("pressed", this, "_update_transform_buttons", make_binds(rotate_0)); canvas_item_editor_hb->add_child(rotate_0); rotate_90 = memnew( ToolButton ); rotate_90->set_toggle_mode(true); rotate_90->set_tooltip("Rotate 90 degrees"); rotate_90->set_focus_mode(FOCUS_NONE); + rotate_90->connect("pressed", this, "_update_transform_buttons", make_binds(rotate_90)); canvas_item_editor_hb->add_child(rotate_90); rotate_180 = memnew( ToolButton ); rotate_180->set_toggle_mode(true); rotate_180->set_tooltip("Rotate 180 degrees"); rotate_180->set_focus_mode(FOCUS_NONE); + rotate_180->connect("pressed", this, "_update_transform_buttons", make_binds(rotate_180)); canvas_item_editor_hb->add_child(rotate_180); rotate_270 = memnew( ToolButton ); rotate_270->set_toggle_mode(true); rotate_270->set_tooltip("Rotate 270 degrees"); rotate_270->set_focus_mode(FOCUS_NONE); + rotate_270->connect("pressed", this, "_update_transform_buttons", make_binds(rotate_270)); canvas_item_editor_hb->add_child(rotate_270); canvas_item_editor_hb->hide(); diff --git a/tools/editor/plugins/tile_map_editor_plugin.h b/tools/editor/plugins/tile_map_editor_plugin.h index dd278be2c8..caa9b57c84 100644 --- a/tools/editor/plugins/tile_map_editor_plugin.h +++ b/tools/editor/plugins/tile_map_editor_plugin.h @@ -111,6 +111,7 @@ protected: void _node_removed(Node *p_node); static void _bind_methods(); CellOp _get_op_from_cell(const Point2i& p_pos); + void _update_transform_buttons(Object *p_button); public: HBoxContainer *get_canvas_item_editor_hb() const { return canvas_item_editor_hb; } -- cgit v1.2.3 From 52700563bc35f7dcfdae7650a40d6249252b64d8 Mon Sep 17 00:00:00 2001 From: Carl Olsson Date: Mon, 2 Feb 2015 22:28:10 +1000 Subject: Finish GUI for tile transform. --- tools/editor/plugins/tile_map_editor_plugin.cpp | 46 +++++++++++++++++++++++-- 1 file changed, 44 insertions(+), 2 deletions(-) diff --git a/tools/editor/plugins/tile_map_editor_plugin.cpp b/tools/editor/plugins/tile_map_editor_plugin.cpp index 34270d5076..ba23c018cc 100644 --- a/tools/editor/plugins/tile_map_editor_plugin.cpp +++ b/tools/editor/plugins/tile_map_editor_plugin.cpp @@ -734,7 +734,48 @@ void TileMapEditor::_update_transform_buttons(Object *p_button) { ERR_FAIL_NULL(p_button); ToolButton *b=p_button->cast_to(); ERR_FAIL_COND(!b); - + + mirror_x->set_block_signals(true); + mirror_y->set_block_signals(true); + transpose->set_block_signals(true); + rotate_0->set_block_signals(true); + rotate_90->set_block_signals(true); + rotate_180->set_block_signals(true); + rotate_270->set_block_signals(true); + + if (b == rotate_0) { + mirror_x->set_pressed(false); + mirror_y->set_pressed(false); + transpose->set_pressed(false); + } + else if (b == rotate_90) { + mirror_x->set_pressed(false); + mirror_y->set_pressed(true); + transpose->set_pressed(true); + } + else if (b == rotate_180) { + mirror_x->set_pressed(true); + mirror_y->set_pressed(true); + transpose->set_pressed(false); + } + else if (b == rotate_270) { + mirror_x->set_pressed(true); + mirror_y->set_pressed(false); + transpose->set_pressed(true); + } + + rotate_0->set_pressed(!mirror_x->is_pressed() && !mirror_y->is_pressed() && !transpose->is_pressed()); + rotate_90->set_pressed(!mirror_x->is_pressed() && mirror_y->is_pressed() && transpose->is_pressed()); + rotate_180->set_pressed(mirror_x->is_pressed() && mirror_y->is_pressed() && !transpose->is_pressed()); + rotate_270->set_pressed(mirror_x->is_pressed() && !mirror_y->is_pressed() && transpose->is_pressed()); + + mirror_x->set_block_signals(false); + mirror_y->set_block_signals(false); + transpose->set_block_signals(false); + rotate_0->set_block_signals(false); + rotate_90->set_block_signals(false); + rotate_180->set_block_signals(false); + rotate_270->set_block_signals(false); } TileMapEditor::TileMapEditor(EditorNode *p_editor) { @@ -802,7 +843,8 @@ TileMapEditor::TileMapEditor(EditorNode *p_editor) { rotate_270->connect("pressed", this, "_update_transform_buttons", make_binds(rotate_270)); canvas_item_editor_hb->add_child(rotate_270); canvas_item_editor_hb->hide(); - + + rotate_0->set_pressed(true); tool=TOOL_NONE; selection_active=false; mouse_over=false; -- cgit v1.2.3 From afa13bf868239191bf2ef95ff3b039729f4bd2e1 Mon Sep 17 00:00:00 2001 From: Carl Olsson Date: Tue, 3 Feb 2015 19:51:21 +1000 Subject: Forgot to update tile transform buttons when picking tiles. --- tools/editor/plugins/tile_map_editor_plugin.cpp | 8 +++++--- tools/editor/plugins/tile_map_editor_plugin.h | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/tools/editor/plugins/tile_map_editor_plugin.cpp b/tools/editor/plugins/tile_map_editor_plugin.cpp index ba23c018cc..7dbbda7135 100644 --- a/tools/editor/plugins/tile_map_editor_plugin.cpp +++ b/tools/editor/plugins/tile_map_editor_plugin.cpp @@ -127,7 +127,7 @@ void TileMapEditor::_update_palette() { TreeItem *root = palette->create_item(); - //palette->set_hide_root(true); + palette->set_hide_root(true); List tiles; tileset->get_tile_list(&tiles); @@ -250,6 +250,7 @@ bool TileMapEditor::forward_input_event(const InputEvent& p_event) { mirror_x->set_pressed(node->is_cell_x_flipped(over_tile.x, over_tile.y)); mirror_y->set_pressed(node->is_cell_y_flipped(over_tile.x, over_tile.y)); transpose->set_pressed(node->is_cell_transposed(over_tile.x, over_tile.y)); + _update_transform_buttons(); canvas_item_editor->update(); return true; } else { @@ -394,6 +395,7 @@ bool TileMapEditor::forward_input_event(const InputEvent& p_event) { mirror_x->set_pressed(node->is_cell_x_flipped(over_tile.x, over_tile.y)); mirror_y->set_pressed(node->is_cell_y_flipped(over_tile.x, over_tile.y)); transpose->set_pressed(node->is_cell_transposed(over_tile.x, over_tile.y)); + _update_transform_buttons(); canvas_item_editor->update(); return true; } @@ -731,9 +733,9 @@ TileMapEditor::CellOp TileMapEditor::_get_op_from_cell(const Point2i& p_pos) } void TileMapEditor::_update_transform_buttons(Object *p_button) { - ERR_FAIL_NULL(p_button); + //ERR_FAIL_NULL(p_button); ToolButton *b=p_button->cast_to(); - ERR_FAIL_COND(!b); + //ERR_FAIL_COND(!b); mirror_x->set_block_signals(true); mirror_y->set_block_signals(true); diff --git a/tools/editor/plugins/tile_map_editor_plugin.h b/tools/editor/plugins/tile_map_editor_plugin.h index caa9b57c84..eb3205a15c 100644 --- a/tools/editor/plugins/tile_map_editor_plugin.h +++ b/tools/editor/plugins/tile_map_editor_plugin.h @@ -111,7 +111,7 @@ protected: void _node_removed(Node *p_node); static void _bind_methods(); CellOp _get_op_from_cell(const Point2i& p_pos); - void _update_transform_buttons(Object *p_button); + void _update_transform_buttons(Object *p_button=0); public: HBoxContainer *get_canvas_item_editor_hb() const { return canvas_item_editor_hb; } -- cgit v1.2.3 From 9171f71ff55def0f661a3d76e4ebcfc945092ad3 Mon Sep 17 00:00:00 2001 From: Carl Olsson Date: Wed, 11 Feb 2015 21:11:14 +1000 Subject: Revert variant arg length to 5 and add 5 arg wrapper function for TileMap set_cell. --- core/object.h | 14 +++++++------- core/variant.h | 2 +- scene/2d/tile_map.cpp | 5 +++++ scene/2d/tile_map.h | 1 + tools/editor/plugins/tile_map_editor_plugin.cpp | 12 ++++++------ 5 files changed, 20 insertions(+), 14 deletions(-) diff --git a/core/object.h b/core/object.h index 3c493de157..97ca50cb1a 100644 --- a/core/object.h +++ b/core/object.h @@ -35,13 +35,13 @@ #include "map.h" #include "vmap.h" -#define VARIANT_ARG_LIST const Variant& p_arg1=Variant(),const Variant& p_arg2=Variant(),const Variant& p_arg3=Variant(),const Variant& p_arg4=Variant(),const Variant& p_arg5=Variant(),const Variant& p_arg6=Variant() -#define VARIANT_ARG_PASS p_arg1,p_arg2,p_arg3,p_arg4,p_arg5,p_arg6 -#define VARIANT_ARG_DECLARE const Variant& p_arg1,const Variant& p_arg2,const Variant& p_arg3,const Variant& p_arg4,const Variant& p_arg5,const Variant& p_arg6 -#define VARIANT_ARG_MAX 6 -#define VARIANT_ARGPTRS const Variant *argptr[6]={&p_arg1,&p_arg2,&p_arg3,&p_arg4,&p_arg5,&p_arg6}; -#define VARIANT_ARGPTRS_PASS *argptr[0],*argptr[1],*argptr[2],*argptr[3],*argptr[4],*argptr[5] -#define VARIANT_ARGS_FROM_ARRAY(m_arr) m_arr[0],m_arr[1],m_arr[2],m_arr[3],m_arr[4],m_arr[5] +#define VARIANT_ARG_LIST const Variant& p_arg1=Variant(),const Variant& p_arg2=Variant(),const Variant& p_arg3=Variant(),const Variant& p_arg4=Variant(),const Variant& p_arg5=Variant() +#define VARIANT_ARG_PASS p_arg1,p_arg2,p_arg3,p_arg4,p_arg5 +#define VARIANT_ARG_DECLARE const Variant& p_arg1,const Variant& p_arg2,const Variant& p_arg3,const Variant& p_arg4,const Variant& p_arg5 +#define VARIANT_ARG_MAX 5 +#define VARIANT_ARGPTRS const Variant *argptr[5]={&p_arg1,&p_arg2,&p_arg3,&p_arg4,&p_arg5}; +#define VARIANT_ARGPTRS_PASS *argptr[0],*argptr[1],*argptr[2],*argptr[3],*argptr[4] +#define VARIANT_ARGS_FROM_ARRAY(m_arr) m_arr[0],m_arr[1],m_arr[2],m_arr[3],m_arr[4] /** @author Juan Linietsky diff --git a/core/variant.h b/core/variant.h index a3efc34452..47fc3f43ac 100644 --- a/core/variant.h +++ b/core/variant.h @@ -387,7 +387,7 @@ public: }; Variant call(const StringName& p_method,const Variant** p_args,int p_argcount,CallError &r_error); - Variant call(const StringName& p_method,const Variant& p_arg1=Variant(),const Variant& p_arg2=Variant(),const Variant& p_arg3=Variant(),const Variant& p_arg4=Variant(),const Variant& p_arg5=Variant(),const Variant& p_arg6=Variant()); + Variant call(const StringName& p_method,const Variant& p_arg1=Variant(),const Variant& p_arg2=Variant(),const Variant& p_arg3=Variant(),const Variant& p_arg4=Variant(),const Variant& p_arg5=Variant()); static Variant construct(const Variant::Type,const Variant** p_args,int p_argcount,CallError &r_error); void get_method_list(List *p_list) const; diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp index 0b123bfa1c..77558bd7b4 100644 --- a/scene/2d/tile_map.cpp +++ b/scene/2d/tile_map.cpp @@ -439,6 +439,10 @@ void TileMap::set_cell(int p_x,int p_y,int p_tile,bool p_flip_x,bool p_flip_y,bo } +void TileMap::_set_cell(Point2 pos,int p_tile,bool p_flip_x,bool p_flip_y,bool p_transpose) { + set_cell(floor(pos.x), floor(pos.y), p_tile, p_flip_x, p_flip_y, p_transpose); +} + int TileMap::get_cell(int p_x,int p_y) const { PosKey pk(p_x,p_y); @@ -830,6 +834,7 @@ void TileMap::_bind_methods() { ObjectTypeDB::bind_method(_MD("get_collision_bounce"),&TileMap::get_collision_bounce); ObjectTypeDB::bind_method(_MD("set_cell","x","y","tile","flip_x","flip_y","transpose"),&TileMap::set_cell,DEFVAL(false),DEFVAL(false),DEFVAL(false)); + ObjectTypeDB::bind_method(_MD("_set_cell","pos","tile","flip_x","flip_y","transpose"),&TileMap::_set_cell,DEFVAL(false),DEFVAL(false),DEFVAL(false)); ObjectTypeDB::bind_method(_MD("get_cell","x","y"),&TileMap::get_cell); ObjectTypeDB::bind_method(_MD("is_cell_x_flipped","x","y"),&TileMap::is_cell_x_flipped); ObjectTypeDB::bind_method(_MD("is_cell_y_flipped","x","y"),&TileMap::is_cell_y_flipped); diff --git a/scene/2d/tile_map.h b/scene/2d/tile_map.h index 2809cdb378..fb366ab7e8 100644 --- a/scene/2d/tile_map.h +++ b/scene/2d/tile_map.h @@ -169,6 +169,7 @@ public: bool get_center_y() const; void set_cell(int p_x,int p_y,int p_tile,bool p_flip_x=false,bool p_flip_y=false,bool p_transpose=false); + void _set_cell(Point2 pos,int p_tile,bool p_flip_x=false,bool p_flip_y=false,bool p_transpose=false); int get_cell(int p_x,int p_y) const; bool is_cell_x_flipped(int p_x,int p_y) const; bool is_cell_y_flipped(int p_x,int p_y) const; diff --git a/tools/editor/plugins/tile_map_editor_plugin.cpp b/tools/editor/plugins/tile_map_editor_plugin.cpp index 7dbbda7135..7250f198d6 100644 --- a/tools/editor/plugins/tile_map_editor_plugin.cpp +++ b/tools/editor/plugins/tile_map_editor_plugin.cpp @@ -34,7 +34,7 @@ #include "os/file_access.h" #include "tools/editor/editor_settings.h" #include "os/input.h" - +#include "method_bind_ext.inc" void TileMapEditor::_notification(int p_what) { @@ -104,8 +104,8 @@ void TileMapEditor::_set_cell(const Point2i& p_pos,int p_value,bool p_flip_h, bo if (p_with_undo) { - undo_redo->add_do_method(node,"set_cell",p_pos.x,p_pos.y,p_value,p_flip_h,p_flip_v,p_transpose); - undo_redo->add_undo_method(node,"set_cell",p_pos.x,p_pos.y,prev_val,prev_flip_h,prev_flip_v,prev_transpose); + undo_redo->add_do_method(node,"_set_cell",Point2(p_pos),p_value,p_flip_h,p_flip_v,p_transpose); + undo_redo->add_undo_method(node,"_set_cell",Point2(p_pos),prev_val,prev_flip_h,prev_flip_v,prev_transpose); } else { node->set_cell(p_pos.x,p_pos.y,p_value,p_flip_h,p_flip_v,p_transpose); @@ -275,8 +275,8 @@ bool TileMapEditor::forward_input_event(const InputEvent& p_event) { for(Map::Element *E=paint_undo.front();E;E=E->next()) { Point2i p=E->key(); - undo_redo->add_do_method(node,"set_cell",p.x,p.y,node->get_cell(p.x,p.y),node->is_cell_x_flipped(p.x,p.y),node->is_cell_y_flipped(p.x,p.y),node->is_cell_transposed(p.x,p.y)); - undo_redo->add_undo_method(node,"set_cell",p.x,p.y,E->get().idx,E->get().xf,E->get().yf,E->get().tr); + undo_redo->add_do_method(node,"_set_cell",Point2(p),node->get_cell(p.x,p.y),node->is_cell_x_flipped(p.x,p.y),node->is_cell_y_flipped(p.x,p.y),node->is_cell_transposed(p.x,p.y)); + undo_redo->add_undo_method(node,"_set_cell",Point2(p),E->get().idx,E->get().xf,E->get().yf,E->get().tr); } undo_redo->commit_action(); @@ -316,7 +316,7 @@ bool TileMapEditor::forward_input_event(const InputEvent& p_event) { Point2i p=E->key(); //undo_redo->add_do_method(node,"set_cell",p.x,p.y,node->get_cell(p.x,p.y),node->is_cell_x_flipped(p.x,p.y),node->is_cell_y_flipped(p.x,p.y),node->is_cell_transposed(p.x,p.y)); _set_cell(p,TileMap::INVALID_CELL,false,false,false,true); - undo_redo->add_undo_method(node,"set_cell",p.x,p.y,E->get().idx,E->get().xf,E->get().yf,E->get().tr); + undo_redo->add_undo_method(node,"_set_cell",Point2(p),E->get().idx,E->get().xf,E->get().yf,E->get().tr); } undo_redo->commit_action(); -- cgit v1.2.3 From c613fb121b292d7abf601634b2db42c966f4a4ff Mon Sep 17 00:00:00 2001 From: Carl Olsson Date: Wed, 11 Feb 2015 21:40:50 +1000 Subject: Moved wrapper function to TileMapEditor. --- scene/2d/tile_map.cpp | 5 ----- scene/2d/tile_map.h | 1 - tools/editor/plugins/tile_map_editor_plugin.cpp | 16 +++++++++++----- tools/editor/plugins/tile_map_editor_plugin.h | 1 + 4 files changed, 12 insertions(+), 11 deletions(-) diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp index 77558bd7b4..0b123bfa1c 100644 --- a/scene/2d/tile_map.cpp +++ b/scene/2d/tile_map.cpp @@ -439,10 +439,6 @@ void TileMap::set_cell(int p_x,int p_y,int p_tile,bool p_flip_x,bool p_flip_y,bo } -void TileMap::_set_cell(Point2 pos,int p_tile,bool p_flip_x,bool p_flip_y,bool p_transpose) { - set_cell(floor(pos.x), floor(pos.y), p_tile, p_flip_x, p_flip_y, p_transpose); -} - int TileMap::get_cell(int p_x,int p_y) const { PosKey pk(p_x,p_y); @@ -834,7 +830,6 @@ void TileMap::_bind_methods() { ObjectTypeDB::bind_method(_MD("get_collision_bounce"),&TileMap::get_collision_bounce); ObjectTypeDB::bind_method(_MD("set_cell","x","y","tile","flip_x","flip_y","transpose"),&TileMap::set_cell,DEFVAL(false),DEFVAL(false),DEFVAL(false)); - ObjectTypeDB::bind_method(_MD("_set_cell","pos","tile","flip_x","flip_y","transpose"),&TileMap::_set_cell,DEFVAL(false),DEFVAL(false),DEFVAL(false)); ObjectTypeDB::bind_method(_MD("get_cell","x","y"),&TileMap::get_cell); ObjectTypeDB::bind_method(_MD("is_cell_x_flipped","x","y"),&TileMap::is_cell_x_flipped); ObjectTypeDB::bind_method(_MD("is_cell_y_flipped","x","y"),&TileMap::is_cell_y_flipped); diff --git a/scene/2d/tile_map.h b/scene/2d/tile_map.h index fb366ab7e8..2809cdb378 100644 --- a/scene/2d/tile_map.h +++ b/scene/2d/tile_map.h @@ -169,7 +169,6 @@ public: bool get_center_y() const; void set_cell(int p_x,int p_y,int p_tile,bool p_flip_x=false,bool p_flip_y=false,bool p_transpose=false); - void _set_cell(Point2 pos,int p_tile,bool p_flip_x=false,bool p_flip_y=false,bool p_transpose=false); int get_cell(int p_x,int p_y) const; bool is_cell_x_flipped(int p_x,int p_y) const; bool is_cell_y_flipped(int p_x,int p_y) const; diff --git a/tools/editor/plugins/tile_map_editor_plugin.cpp b/tools/editor/plugins/tile_map_editor_plugin.cpp index 7250f198d6..1dcf948505 100644 --- a/tools/editor/plugins/tile_map_editor_plugin.cpp +++ b/tools/editor/plugins/tile_map_editor_plugin.cpp @@ -90,6 +90,11 @@ void TileMapEditor::set_selected_tile(int p_tile) { } } +void TileMapEditor::_set_cell_shortened(const Point2& p_pos,int p_value,bool p_flip_h, bool p_flip_v, bool p_transpose) { + ERR_FAIL_COND(!node); + node->set_cell(floor(p_pos.x), floor(p_pos.y), p_value, p_flip_h, p_flip_v, p_transpose); +} + void TileMapEditor::_set_cell(const Point2i& p_pos,int p_value,bool p_flip_h, bool p_flip_v, bool p_transpose,bool p_with_undo) { ERR_FAIL_COND(!node); @@ -104,8 +109,8 @@ void TileMapEditor::_set_cell(const Point2i& p_pos,int p_value,bool p_flip_h, bo if (p_with_undo) { - undo_redo->add_do_method(node,"_set_cell",Point2(p_pos),p_value,p_flip_h,p_flip_v,p_transpose); - undo_redo->add_undo_method(node,"_set_cell",Point2(p_pos),prev_val,prev_flip_h,prev_flip_v,prev_transpose); + undo_redo->add_do_method(this,"_set_cell_shortened",Point2(p_pos),p_value,p_flip_h,p_flip_v,p_transpose); + undo_redo->add_undo_method(this,"_set_cell_shortened",Point2(p_pos),prev_val,prev_flip_h,prev_flip_v,prev_transpose); } else { node->set_cell(p_pos.x,p_pos.y,p_value,p_flip_h,p_flip_v,p_transpose); @@ -275,8 +280,8 @@ bool TileMapEditor::forward_input_event(const InputEvent& p_event) { for(Map::Element *E=paint_undo.front();E;E=E->next()) { Point2i p=E->key(); - undo_redo->add_do_method(node,"_set_cell",Point2(p),node->get_cell(p.x,p.y),node->is_cell_x_flipped(p.x,p.y),node->is_cell_y_flipped(p.x,p.y),node->is_cell_transposed(p.x,p.y)); - undo_redo->add_undo_method(node,"_set_cell",Point2(p),E->get().idx,E->get().xf,E->get().yf,E->get().tr); + undo_redo->add_do_method(this,"_set_cell_shortened",Point2(p),node->get_cell(p.x,p.y),node->is_cell_x_flipped(p.x,p.y),node->is_cell_y_flipped(p.x,p.y),node->is_cell_transposed(p.x,p.y)); + undo_redo->add_undo_method(this,"_set_cell_shortened",Point2(p),E->get().idx,E->get().xf,E->get().yf,E->get().tr); } undo_redo->commit_action(); @@ -316,7 +321,7 @@ bool TileMapEditor::forward_input_event(const InputEvent& p_event) { Point2i p=E->key(); //undo_redo->add_do_method(node,"set_cell",p.x,p.y,node->get_cell(p.x,p.y),node->is_cell_x_flipped(p.x,p.y),node->is_cell_y_flipped(p.x,p.y),node->is_cell_transposed(p.x,p.y)); _set_cell(p,TileMap::INVALID_CELL,false,false,false,true); - undo_redo->add_undo_method(node,"_set_cell",Point2(p),E->get().idx,E->get().xf,E->get().yf,E->get().tr); + undo_redo->add_undo_method(this,"_set_cell_shortened",Point2(p),E->get().idx,E->get().xf,E->get().yf,E->get().tr); } undo_redo->commit_action(); @@ -714,6 +719,7 @@ void TileMapEditor::_bind_methods() { ObjectTypeDB::bind_method(_MD("_canvas_mouse_exit"),&TileMapEditor::_canvas_mouse_exit); ObjectTypeDB::bind_method(_MD("_tileset_settings_changed"),&TileMapEditor::_tileset_settings_changed); ObjectTypeDB::bind_method(_MD("_update_transform_buttons"),&TileMapEditor::_update_transform_buttons); + ObjectTypeDB::bind_method(_MD("_set_cell_shortened","pos","tile","flip_x","flip_y","transpose"),&TileMapEditor::_set_cell_shortened,DEFVAL(false),DEFVAL(false),DEFVAL(false)); } diff --git a/tools/editor/plugins/tile_map_editor_plugin.h b/tools/editor/plugins/tile_map_editor_plugin.h index eb3205a15c..525315a8f1 100644 --- a/tools/editor/plugins/tile_map_editor_plugin.h +++ b/tools/editor/plugins/tile_map_editor_plugin.h @@ -100,6 +100,7 @@ class TileMapEditor : public VBoxContainer { void _menu_option(int p_option); void _set_cell(const Point2i& p_pos, int p_value, bool p_flip_h=false, bool p_flip_v=false, bool p_transpose=false, bool p_with_undo=false); + void _set_cell_shortened(const Point2& p_pos, int p_value, bool p_flip_h=false, bool p_flip_v=false, bool p_transpose=false); void _canvas_mouse_enter(); void _canvas_mouse_exit(); -- cgit v1.2.3 From 6a38ab1b43e4a107a28c52ba2036a4886794f625 Mon Sep 17 00:00:00 2001 From: Carl Olsson Date: Fri, 13 Feb 2015 10:56:53 +1000 Subject: Reorder tile transforms so transpose occurs before flips. Much more intuitive for flipping transposed tiles. --- drivers/gles2/rasterizer_gles2.cpp | 6 +++--- scene/2d/tile_map.cpp | 17 +++++++++------- tools/editor/plugins/tile_map_editor_plugin.cpp | 27 +++++++++++++------------ tools/editor/plugins/tile_map_editor_plugin.h | 2 +- 4 files changed, 28 insertions(+), 24 deletions(-) diff --git a/drivers/gles2/rasterizer_gles2.cpp b/drivers/gles2/rasterizer_gles2.cpp index 62fb271930..2b70cec3fa 100644 --- a/drivers/gles2/rasterizer_gles2.cpp +++ b/drivers/gles2/rasterizer_gles2.cpp @@ -8119,6 +8119,9 @@ void RasterizerGLES2::_draw_textured_quad(const Rect2& p_rect, const Rect2& p_sr (p_src_region.pos.y+p_src_region.size.height)/p_tex_size.height) }; + if (p_transpose) { + SWAP( texcoords[1], texcoords[3] ); + } if (p_h_flip) { SWAP( texcoords[0], texcoords[1] ); SWAP( texcoords[2], texcoords[3] ); @@ -8127,9 +8130,6 @@ void RasterizerGLES2::_draw_textured_quad(const Rect2& p_rect, const Rect2& p_sr SWAP( texcoords[1], texcoords[2] ); SWAP( texcoords[0], texcoords[3] ); } - if (p_transpose) { - SWAP( texcoords[1], texcoords[3] ); - } Vector2 coords[4]= { Vector2( p_rect.pos.x, p_rect.pos.y ), diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp index 0b123bfa1c..93005ed1e3 100644 --- a/scene/2d/tile_map.cpp +++ b/scene/2d/tile_map.cpp @@ -242,19 +242,22 @@ void TileMap::_update_dirty_quadrants() { Vector2 shape_ofs = tile_set->tile_get_shape_offset(c.id); Matrix32 xform; xform.set_origin(offset.floor()); + if (c.transpose) { + SWAP(xform.elements[0].x, xform.elements[0].y); + SWAP(xform.elements[1].x, xform.elements[1].y); + SWAP(shape_ofs.x, shape_ofs.y); + SWAP(s.x, s.y); + } if (c.flip_h) { - xform.elements[0]=-xform.elements[0]; + xform.elements[0].x=-xform.elements[0].x; + xform.elements[1].x=-xform.elements[1].x; shape_ofs.x=s.x-shape_ofs.x; } if (c.flip_v) { - xform.elements[1]=-xform.elements[1]; + xform.elements[0].y=-xform.elements[0].y; + xform.elements[1].y=-xform.elements[1].y; shape_ofs.y=s.y-shape_ofs.y; } - if (c.transpose) { - SWAP(xform.elements[0].x, xform.elements[0].y); - SWAP(xform.elements[1].x, xform.elements[1].y); - SWAP(shape_ofs.x, shape_ofs.y); - } xform.elements[2].x+=shape_ofs.x; xform.elements[2].y+=shape_ofs.y; diff --git a/tools/editor/plugins/tile_map_editor_plugin.cpp b/tools/editor/plugins/tile_map_editor_plugin.cpp index 1dcf948505..47727a00c2 100644 --- a/tools/editor/plugins/tile_map_editor_plugin.cpp +++ b/tools/editor/plugins/tile_map_editor_plugin.cpp @@ -42,9 +42,9 @@ void TileMapEditor::_notification(int p_what) { case NOTIFICATION_READY: { + transpose->set_icon( get_icon("Transpose","EditorIcons")); mirror_x->set_icon( get_icon("MirrorX","EditorIcons")); mirror_y->set_icon( get_icon("MirrorY","EditorIcons")); - transpose->set_icon( get_icon("Transpose","EditorIcons")); rotate_0->set_icon( get_icon("Rotate0","EditorIcons")); rotate_90->set_icon( get_icon("Rotate90","EditorIcons")); rotate_180->set_icon( get_icon("Rotate180","EditorIcons")); @@ -90,6 +90,7 @@ void TileMapEditor::set_selected_tile(int p_tile) { } } +// Wrapper to workaround five arg limit of undo/redo methods void TileMapEditor::_set_cell_shortened(const Point2& p_pos,int p_value,bool p_flip_h, bool p_flip_v, bool p_transpose) { ERR_FAIL_COND(!node); node->set_cell(floor(p_pos.x), floor(p_pos.y), p_value, p_flip_h, p_flip_v, p_transpose); @@ -757,8 +758,8 @@ void TileMapEditor::_update_transform_buttons(Object *p_button) { transpose->set_pressed(false); } else if (b == rotate_90) { - mirror_x->set_pressed(false); - mirror_y->set_pressed(true); + mirror_x->set_pressed(true); + mirror_y->set_pressed(false); transpose->set_pressed(true); } else if (b == rotate_180) { @@ -767,15 +768,15 @@ void TileMapEditor::_update_transform_buttons(Object *p_button) { transpose->set_pressed(false); } else if (b == rotate_270) { - mirror_x->set_pressed(true); - mirror_y->set_pressed(false); + mirror_x->set_pressed(false); + mirror_y->set_pressed(true); transpose->set_pressed(true); } rotate_0->set_pressed(!mirror_x->is_pressed() && !mirror_y->is_pressed() && !transpose->is_pressed()); - rotate_90->set_pressed(!mirror_x->is_pressed() && mirror_y->is_pressed() && transpose->is_pressed()); + rotate_90->set_pressed(mirror_x->is_pressed() && !mirror_y->is_pressed() && transpose->is_pressed()); rotate_180->set_pressed(mirror_x->is_pressed() && mirror_y->is_pressed() && !transpose->is_pressed()); - rotate_270->set_pressed(mirror_x->is_pressed() && !mirror_y->is_pressed() && transpose->is_pressed()); + rotate_270->set_pressed(!mirror_x->is_pressed() && mirror_y->is_pressed() && transpose->is_pressed()); mirror_x->set_block_signals(false); mirror_y->set_block_signals(false); @@ -807,6 +808,12 @@ TileMapEditor::TileMapEditor(EditorNode *p_editor) { canvas_item_editor_hb = memnew( HBoxContainer ); CanvasItemEditor::get_singleton()->add_control_to_menu_panel(canvas_item_editor_hb); canvas_item_editor_hb->add_child( memnew( VSeparator )); + transpose = memnew( ToolButton ); + transpose->set_toggle_mode(true); + transpose->set_tooltip("Transpose"); + transpose->set_focus_mode(FOCUS_NONE); + transpose->connect("pressed", this, "_update_transform_buttons", make_binds(transpose)); + canvas_item_editor_hb->add_child(transpose); mirror_x = memnew( ToolButton ); mirror_x->set_toggle_mode(true); mirror_x->set_tooltip("Mirror X (A)"); @@ -819,12 +826,6 @@ TileMapEditor::TileMapEditor(EditorNode *p_editor) { mirror_y->set_focus_mode(FOCUS_NONE); mirror_y->connect("pressed", this, "_update_transform_buttons", make_binds(mirror_y)); canvas_item_editor_hb->add_child(mirror_y); - transpose = memnew( ToolButton ); - transpose->set_toggle_mode(true); - transpose->set_tooltip("Transpose"); - transpose->set_focus_mode(FOCUS_NONE); - transpose->connect("pressed", this, "_update_transform_buttons", make_binds(transpose)); - canvas_item_editor_hb->add_child(transpose); canvas_item_editor_hb->add_child(memnew(VSeparator)); rotate_0 = memnew( ToolButton ); rotate_0->set_toggle_mode(true); diff --git a/tools/editor/plugins/tile_map_editor_plugin.h b/tools/editor/plugins/tile_map_editor_plugin.h index 525315a8f1..367e687d77 100644 --- a/tools/editor/plugins/tile_map_editor_plugin.h +++ b/tools/editor/plugins/tile_map_editor_plugin.h @@ -71,9 +71,9 @@ class TileMapEditor : public VBoxContainer { bool mouse_over; Label *mirror_label; + ToolButton *transpose; ToolButton *mirror_x; ToolButton *mirror_y; - ToolButton *transpose; ToolButton *rotate_0; ToolButton *rotate_90; ToolButton *rotate_180; -- cgit v1.2.3 From f4312a5076061862908c6df732157d452c2d37b8 Mon Sep 17 00:00:00 2001 From: romulox_x Date: Sat, 21 Feb 2015 01:35:06 -0800 Subject: added option to disable automatic clearing of viewport render buffer --- scene/main/viewport.cpp | 24 ++++++++++++++++++++++++ scene/main/viewport.h | 5 +++++ servers/visual/visual_server_raster.cpp | 31 ++++++++++++++++++++++++++++++- servers/visual/visual_server_raster.h | 7 ++++++- servers/visual/visual_server_wrap_mt.h | 4 ++++ servers/visual_server.h | 3 +++ 6 files changed, 72 insertions(+), 2 deletions(-) diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index fa163bf96d..02e009866f 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -972,6 +972,22 @@ bool Viewport::get_render_target_vflip() const{ return render_target_vflip; } +void Viewport::set_render_target_clear_on_new_frame(bool p_enable) { + + render_target_clear_on_new_frame=p_enable; + VisualServer::get_singleton()->viewport_set_render_target_clear_on_new_frame(viewport,p_enable); +} + +bool Viewport::get_render_target_clear_on_new_frame() const{ + + return render_target_clear_on_new_frame; +} + +void Viewport::render_target_clear() { + + //render_target_clear=true; + VisualServer::get_singleton()->viewport_render_target_clear(viewport); +} void Viewport::set_render_target_filter(bool p_enable) { @@ -1264,6 +1280,11 @@ void Viewport::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_render_target_vflip","enable"), &Viewport::set_render_target_vflip); ObjectTypeDB::bind_method(_MD("get_render_target_vflip"), &Viewport::get_render_target_vflip); + + ObjectTypeDB::bind_method(_MD("set_render_target_clear_on_new_frame","enable"), &Viewport::set_render_target_clear_on_new_frame); + ObjectTypeDB::bind_method(_MD("get_render_target_clear_on_new_frame"), &Viewport::get_render_target_clear_on_new_frame); + + ObjectTypeDB::bind_method(_MD("render_target_clear"), &Viewport::render_target_clear); ObjectTypeDB::bind_method(_MD("set_render_target_filter","enable"), &Viewport::set_render_target_filter); ObjectTypeDB::bind_method(_MD("get_render_target_filter"), &Viewport::get_render_target_filter); @@ -1306,6 +1327,7 @@ void Viewport::_bind_methods() { ADD_PROPERTY( PropertyInfo(Variant::BOOL,"transparent_bg"), _SCS("set_transparent_background"), _SCS("has_transparent_background") ); ADD_PROPERTY( PropertyInfo(Variant::BOOL,"render_target/enabled"), _SCS("set_as_render_target"), _SCS("is_set_as_render_target") ); ADD_PROPERTY( PropertyInfo(Variant::BOOL,"render_target/v_flip"), _SCS("set_render_target_vflip"), _SCS("get_render_target_vflip") ); + ADD_PROPERTY( PropertyInfo(Variant::BOOL,"render_target/clear_on_new_frame"), _SCS("set_render_target_clear_on_new_frame"), _SCS("get_render_target_clear_on_new_frame") ); ADD_PROPERTY( PropertyInfo(Variant::BOOL,"render_target/filter"), _SCS("set_render_target_filter"), _SCS("get_render_target_filter") ); ADD_PROPERTY( PropertyInfo(Variant::BOOL,"render_target/gen_mipmaps"), _SCS("set_render_target_gen_mipmaps"), _SCS("get_render_target_gen_mipmaps") ); ADD_PROPERTY( PropertyInfo(Variant::INT,"render_target/update_mode",PROPERTY_HINT_ENUM,"Disabled,Once,When Visible,Always"), _SCS("set_render_target_update_mode"), _SCS("get_render_target_update_mode") ); @@ -1344,6 +1366,8 @@ Viewport::Viewport() { render_target_gen_mipmaps=false; render_target=false; render_target_vflip=false; + render_target_clear_on_new_frame=true; + //render_target_clear=true; render_target_update_mode=RENDER_TARGET_UPDATE_WHEN_VISIBLE; render_target_texture = Ref( memnew( RenderTargetTexture(this) ) ); diff --git a/scene/main/viewport.h b/scene/main/viewport.h index 832a6b6107..d2a22401bd 100644 --- a/scene/main/viewport.h +++ b/scene/main/viewport.h @@ -114,6 +114,7 @@ friend class RenderTargetTexture; bool transparent_bg; bool render_target_vflip; + bool render_target_clear_on_new_frame; bool render_target_filter; bool render_target_gen_mipmaps; @@ -220,6 +221,10 @@ public: void set_render_target_vflip(bool p_enable); bool get_render_target_vflip() const; + void set_render_target_clear_on_new_frame(bool p_enable); + bool get_render_target_clear_on_new_frame() const; + void render_target_clear(); + void set_render_target_filter(bool p_enable); bool get_render_target_filter() const; diff --git a/servers/visual/visual_server_raster.cpp b/servers/visual/visual_server_raster.cpp index cef6fe567d..4c12ac9670 100644 --- a/servers/visual/visual_server_raster.cpp +++ b/servers/visual/visual_server_raster.cpp @@ -1576,6 +1576,15 @@ void VisualServerRaster::viewport_set_render_target_vflip(RID p_viewport,bool p_ } +void VisualServerRaster::viewport_set_render_target_clear_on_new_frame(RID p_viewport,bool p_enable) { + + Viewport *viewport = viewport_owner.get( p_viewport ); + ERR_FAIL_COND(!viewport); + + viewport->render_target_clear_on_new_frame=p_enable; + +} + void VisualServerRaster::viewport_set_render_target_to_screen_rect(RID p_viewport,const Rect2& p_rect) { Viewport *viewport = viewport_owner.get( p_viewport ); @@ -1594,6 +1603,23 @@ bool VisualServerRaster::viewport_get_render_target_vflip(RID p_viewport) const{ } +bool VisualServerRaster::viewport_get_render_target_clear_on_new_frame(RID p_viewport) const{ + + const Viewport *viewport = viewport_owner.get( p_viewport ); + ERR_FAIL_COND_V(!viewport,false); + + return viewport->render_target_clear_on_new_frame; + +} + +void VisualServerRaster::viewport_render_target_clear(RID p_viewport) { + + Viewport *viewport = viewport_owner.get( p_viewport ); + ERR_FAIL_COND(!viewport); + + viewport->render_target_clear=true; + +} void VisualServerRaster::viewport_queue_screen_capture(RID p_viewport) { @@ -6605,7 +6631,10 @@ void VisualServerRaster::_draw_viewport(Viewport *p_viewport,int p_ofs_x, int p_ } else if (true /*|| !p_viewport->canvas_list.empty()*/){ //clear the viewport black because of no camera? i seriously should.. - rasterizer->clear_viewport(clear_color); + if (p_viewport->render_target_clear_on_new_frame || p_viewport->render_target_clear) { + rasterizer->clear_viewport(clear_color); + p_viewport->render_target_clear=false; + } } if (!p_viewport->hide_canvas) { diff --git a/servers/visual/visual_server_raster.h b/servers/visual/visual_server_raster.h index eec677068e..78a4e77170 100644 --- a/servers/visual/visual_server_raster.h +++ b/servers/visual/visual_server_raster.h @@ -468,6 +468,8 @@ class VisualServerRaster : public VisualServer { bool transparent_bg; bool queue_capture; bool render_target_vflip; + bool render_target_clear_on_new_frame; + bool render_target_clear; Image capture; bool rendered_in_prev_frame; @@ -494,7 +496,7 @@ class VisualServerRaster : public VisualServer { SelfList update_list; - Viewport() : update_list(this) { transparent_bg=false; render_target_update_mode=RENDER_TARGET_UPDATE_WHEN_VISIBLE; queue_capture=false; rendered_in_prev_frame=false; render_target_vflip=false;} + Viewport() : update_list(this) { transparent_bg=false; render_target_update_mode=RENDER_TARGET_UPDATE_WHEN_VISIBLE; queue_capture=false; rendered_in_prev_frame=false; render_target_vflip=false; render_target_clear_on_new_frame=true; render_target_clear=true;} }; SelfList::List viewport_update_list; @@ -957,6 +959,9 @@ public: virtual RID viewport_get_render_target_texture(RID p_viewport) const; virtual void viewport_set_render_target_vflip(RID p_viewport,bool p_enable); virtual bool viewport_get_render_target_vflip(RID p_viewport) const; + virtual void viewport_set_render_target_clear_on_new_frame(RID p_viewport,bool p_enable); + virtual bool viewport_get_render_target_clear_on_new_frame(RID p_viewport) const; + virtual void viewport_render_target_clear(RID p_viewport); virtual void viewport_set_render_target_to_screen_rect(RID p_viewport,const Rect2& p_rect); virtual void viewport_queue_screen_capture(RID p_viewport); diff --git a/servers/visual/visual_server_wrap_mt.h b/servers/visual/visual_server_wrap_mt.h index c94425c586..cb69f79cbc 100644 --- a/servers/visual/visual_server_wrap_mt.h +++ b/servers/visual/visual_server_wrap_mt.h @@ -967,6 +967,10 @@ public: FUNC2(viewport_set_render_target_vflip,RID,bool); FUNC1RC(bool,viewport_get_render_target_vflip,RID); FUNC2(viewport_set_render_target_to_screen_rect,RID,const Rect2&); + + FUNC2(viewport_set_render_target_clear_on_new_frame,RID,bool); + FUNC1RC(bool,viewport_get_render_target_clear_on_new_frame,RID); + FUNC1(viewport_render_target_clear,RID); FUNC1(viewport_queue_screen_capture,RID); FUNC1RC(Image,viewport_get_screen_capture,RID); diff --git a/servers/visual_server.h b/servers/visual_server.h index e9bc97628f..cbffe74315 100644 --- a/servers/visual_server.h +++ b/servers/visual_server.h @@ -684,6 +684,9 @@ public: virtual RID viewport_get_render_target_texture(RID p_viewport) const=0; virtual void viewport_set_render_target_vflip(RID p_viewport,bool p_enable)=0; virtual bool viewport_get_render_target_vflip(RID p_viewport) const=0; + virtual void viewport_set_render_target_clear_on_new_frame(RID p_viewport,bool p_enable)=0; + virtual bool viewport_get_render_target_clear_on_new_frame(RID p_viewport) const=0; + virtual void viewport_render_target_clear(RID p_viewport)=0; virtual void viewport_queue_screen_capture(RID p_viewport)=0; virtual Image viewport_get_screen_capture(RID p_viewport) const=0; -- cgit v1.2.3 From 2ac767b1f52f2d5d9d6b2dc00e8c3d065b9fc9bb Mon Sep 17 00:00:00 2001 From: romulox_x Date: Sat, 21 Feb 2015 13:57:12 -0800 Subject: changed viewport clearing to use the alpha value of the clear color, and made the transparent bg option of viewport force a clear color of 0,0,0,0 --- drivers/gles2/rasterizer_gles2.cpp | 2 +- servers/visual/visual_server_raster.cpp | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/gles2/rasterizer_gles2.cpp b/drivers/gles2/rasterizer_gles2.cpp index fe42b67d23..b6a48652cb 100644 --- a/drivers/gles2/rasterizer_gles2.cpp +++ b/drivers/gles2/rasterizer_gles2.cpp @@ -4280,7 +4280,7 @@ void RasterizerGLES2::clear_viewport(const Color& p_color) { } glEnable(GL_SCISSOR_TEST); - glClearColor(p_color.r,p_color.g,p_color.b,1.0); + glClearColor(p_color.r,p_color.g,p_color.b,p_color.a); glClear(GL_COLOR_BUFFER_BIT); //should not clear if anything else cleared.. glDisable(GL_SCISSOR_TEST); }; diff --git a/servers/visual/visual_server_raster.cpp b/servers/visual/visual_server_raster.cpp index 764a969e77..feb14d8a9d 100644 --- a/servers/visual/visual_server_raster.cpp +++ b/servers/visual/visual_server_raster.cpp @@ -6641,7 +6641,12 @@ void VisualServerRaster::_draw_viewport(Viewport *p_viewport,int p_ofs_x, int p_ //clear the viewport black because of no camera? i seriously should.. if (p_viewport->render_target_clear_on_new_frame || p_viewport->render_target_clear) { - rasterizer->clear_viewport(clear_color); + if (p_viewport->transparent_bg) { + rasterizer->clear_viewport(Color(0,0,0,0)); + } + else { + rasterizer->clear_viewport(clear_color); + } p_viewport->render_target_clear=false; } } -- cgit v1.2.3 From 9229d9d1bbc3bb850839e022b8c8d37609839edd Mon Sep 17 00:00:00 2001 From: Hinsbart Date: Wed, 25 Feb 2015 16:33:08 +0100 Subject: fix get joystick name from registry on some systems --- platform/windows/os_windows.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp index 13f2c32e77..e392a56aa8 100644 --- a/platform/windows/os_windows.cpp +++ b/platform/windows/os_windows.cpp @@ -715,9 +715,14 @@ String OS_Windows::get_joystick_name(int id, JOYCAPS jcaps) return ""; _snprintf( buffer, sizeof(buffer), "%s\\%s", REGSTR_PATH_JOYOEM, OEM); - res = RegOpenKeyEx ( HKEY_LOCAL_MACHINE, buffer, 0, KEY_QUERY_VALUE, &hKey); - if (res != ERROR_SUCCESS) - return ""; + res = RegOpenKeyEx(HKEY_LOCAL_MACHINE, buffer, 0, KEY_QUERY_VALUE, &hKey); + if (res != ERROR_SUCCESS) + { + res = RegOpenKeyEx(HKEY_CURRENT_USER, buffer, 0, KEY_QUERY_VALUE, &hKey); + if (res != ERROR_SUCCESS) + return ""; + } + sz = sizeof(buffer); res = RegQueryValueEx(hKey, REGSTR_VAL_JOYOEMNAME, 0, 0, (LPBYTE) buffer, -- cgit v1.2.3 From 320700fc92f48c4c9d01c69f36cad1affc58b535 Mon Sep 17 00:00:00 2001 From: romulox_x Date: Sun, 1 Mar 2015 15:44:02 -0800 Subject: changed the blending function when using a transparent render target so that it blends properly --- drivers/gles2/rasterizer_gles2.cpp | 63 ++++++++++++++++++++++++++++++++------ 1 file changed, 54 insertions(+), 9 deletions(-) diff --git a/drivers/gles2/rasterizer_gles2.cpp b/drivers/gles2/rasterizer_gles2.cpp index b6a48652cb..aba0b5ca90 100644 --- a/drivers/gles2/rasterizer_gles2.cpp +++ b/drivers/gles2/rasterizer_gles2.cpp @@ -6398,7 +6398,12 @@ void RasterizerGLES2::_render_list_forward(RenderList *p_render_list,const Trans case VS::MATERIAL_BLEND_MODE_MIX: { glBlendEquation(GL_FUNC_ADD); - glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); + if (current_rt && current_rt_transparent) { + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + } + else { + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + } } break; case VS::MATERIAL_BLEND_MODE_ADD: { @@ -6414,7 +6419,12 @@ void RasterizerGLES2::_render_list_forward(RenderList *p_render_list,const Trans } break; case VS::MATERIAL_BLEND_MODE_MUL: { glBlendEquation(GL_FUNC_ADD); - glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); + if (current_rt && current_rt_transparent) { + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + } + else { + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + } } break; @@ -6681,7 +6691,12 @@ void RasterizerGLES2::_copy_to_texscreen() { #endif glDisable(GL_BLEND); glBlendEquation(GL_FUNC_ADD); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + if (current_rt && current_rt_transparent) { + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + } + else { + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + } //glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); glBindBuffer(GL_ARRAY_BUFFER,0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0); @@ -7155,7 +7170,12 @@ void RasterizerGLES2::end_scene() { current_depth_mask=true; texscreen_copied=false; glBlendEquation(GL_FUNC_ADD); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + if (current_rt && current_rt_transparent) { + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + } + else { + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + } glDisable(GL_BLEND); current_blend_mode=VS::MATERIAL_BLEND_MODE_MIX; @@ -7172,7 +7192,12 @@ void RasterizerGLES2::end_scene() { } glBlendEquation(GL_FUNC_ADD); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + if (current_rt && current_rt_transparent) { + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + } + else { + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + } glDisable(GL_BLEND); current_blend_mode=VS::MATERIAL_BLEND_MODE_MIX; material_shader.set_conditional(MaterialShaderGLES2::USE_GLOW,false); @@ -7809,7 +7834,12 @@ void RasterizerGLES2::canvas_begin() { #endif glEnable(GL_BLEND); glBlendEquation(GL_FUNC_ADD); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + if (current_rt && current_rt_transparent) { + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + } + else { + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + } //glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); glLineWidth(1.0); glBindBuffer(GL_ARRAY_BUFFER,0); @@ -7866,7 +7896,12 @@ void RasterizerGLES2::canvas_set_blend_mode(VS::MaterialBlendMode p_mode) { case VS::MATERIAL_BLEND_MODE_MIX: { glBlendEquation(GL_FUNC_ADD); - glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); + if (current_rt && current_rt_transparent) { + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + } + else { + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + } } break; case VS::MATERIAL_BLEND_MODE_ADD: { @@ -8675,7 +8710,12 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list,int p_z,const case VS::MATERIAL_BLEND_MODE_MIX: { glBlendEquation(GL_FUNC_ADD); - glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); + if (current_rt && current_rt_transparent) { + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + } + else { + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + } } break; case VS::MATERIAL_BLEND_MODE_ADD: { @@ -8805,7 +8845,12 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list,int p_z,const canvas_shader.set_uniform(CanvasShaderGLES2::MODULATE,canvas_modulate); glBlendEquation(GL_FUNC_ADD); - glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); + if (current_rt && current_rt_transparent) { + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + } + else { + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + } } -- cgit v1.2.3 From a1f715a4da71fbc2b7d6fad68624bf8b22c6da17 Mon Sep 17 00:00:00 2001 From: Juan Linietsky Date: Mon, 2 Mar 2015 00:54:10 -0300 Subject: support for 2D shadow casters Added support for 2D shadow casters. *DANGER* Shaders in CanvasItem CHANGED, if you are using shader in a CanvasItem and pull this, you will lose them. Shaders now work through a 2D material system similar to 3D. If you don't want to lose the 2D shader code, save the shader as a .shd, then create a material in CanvasItem and re-assign the shader. --- core/io/resource_format_binary.cpp | 10 + core/io/resource_format_xml.cpp | 5 + core/math/camera_matrix.cpp | 19 +- core/variant_op.cpp | 3 + demos/3d/kinematic_char/cubelib.res | Bin 11431 -> 11530 bytes demos/3d/kinematic_char/level.scn | Bin 15323 -> 15556 bytes drivers/SCsub | 1 - drivers/gles2/rasterizer_gles2.cpp | 598 ++++++++++++++++++++- drivers/gles2/rasterizer_gles2.h | 62 ++- drivers/gles2/shaders/SCsub | 1 + drivers/gles2/shaders/canvas.glsl | 123 ++++- drivers/gles2/shaders/canvas_shadow.glsl | 62 +++ drivers/windows/file_access_windows.cpp | 20 +- modules/gdscript/gd_script.cpp | 5 +- platform/android/audio_driver_opensl.cpp | 8 + platform/android/os_android.cpp | 2 +- platform/windows/detect.py | 4 +- scene/2d/canvas_item.cpp | 309 +++++++---- scene/2d/canvas_item.h | 59 +- scene/2d/light_2d.cpp | 49 +- scene/2d/light_2d.h | 8 + scene/2d/light_occluder_2d.cpp | 201 +++++++ scene/2d/light_occluder_2d.h | 73 +++ scene/3d/camera.cpp | 6 +- scene/3d/visual_instance.cpp | 15 + scene/3d/visual_instance.h | 4 + scene/register_scene_types.cpp | 4 + scene/scene_string_names.cpp | 1 + scene/scene_string_names.h | 1 + servers/visual/rasterizer.h | 67 ++- servers/visual/visual_server_raster.cpp | 377 +++++++++++-- servers/visual/visual_server_raster.h | 61 ++- servers/visual/visual_server_wrap_mt.h | 30 +- servers/visual_server.h | 33 +- tools/editor/editor_node.cpp | 2 + tools/editor/icons/icon_canvas_item_material.png | Bin 0 -> 835 bytes tools/editor/icons/icon_canvas_modulate.png | Bin 0 -> 441 bytes tools/editor/icons/icon_light_occluder_2d.png | Bin 0 -> 516 bytes tools/editor/icons/icon_occluder_polygon_2d.png | Bin 0 -> 581 bytes .../plugins/collision_polygon_2d_editor_plugin.cpp | 1 + .../plugins/light_occluder_2d_editor_plugin.cpp | 500 +++++++++++++++++ .../plugins/light_occluder_2d_editor_plugin.h | 87 +++ tools/editor/property_editor.cpp | 40 +- 43 files changed, 2583 insertions(+), 268 deletions(-) create mode 100644 drivers/gles2/shaders/canvas_shadow.glsl create mode 100644 scene/2d/light_occluder_2d.cpp create mode 100644 scene/2d/light_occluder_2d.h create mode 100644 tools/editor/icons/icon_canvas_item_material.png create mode 100644 tools/editor/icons/icon_canvas_modulate.png create mode 100644 tools/editor/icons/icon_light_occluder_2d.png create mode 100644 tools/editor/icons/icon_occluder_polygon_2d.png create mode 100644 tools/editor/plugins/light_occluder_2d_editor_plugin.cpp create mode 100644 tools/editor/plugins/light_occluder_2d_editor_plugin.h diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp index e2371fe24f..ead6984650 100644 --- a/core/io/resource_format_binary.cpp +++ b/core/io/resource_format_binary.cpp @@ -1778,6 +1778,11 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path,const RES& p_ f->store_32(VERSION_MINOR); f->store_32(FORMAT_VERSION); + if (f->get_error()!=OK && f->get_error()!=ERR_FILE_EOF) { + f->close(); + return ERR_CANT_CREATE; + } + //f->store_32(saved_resources.size()+external_resources.size()); // load steps -not needed save_unicode_string(p_resource->get_type()); uint64_t md_at = f->get_pos(); @@ -1910,6 +1915,11 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path,const RES& p_ f->store_buffer((const uint8_t*)"RSRC",4); //magic at end + if (f->get_error()!=OK && f->get_error()!=ERR_FILE_EOF) { + f->close(); + return ERR_CANT_CREATE; + } + f->close(); diff --git a/core/io/resource_format_xml.cpp b/core/io/resource_format_xml.cpp index 75384d4ab6..033b4d5e5a 100644 --- a/core/io/resource_format_xml.cpp +++ b/core/io/resource_format_xml.cpp @@ -2592,6 +2592,11 @@ Error ResourceFormatSaverXMLInstance::save(const String &p_path,const RES& p_res } exit_tag("resource_file"); + if (f->get_error()!=OK && f->get_error()!=ERR_FILE_EOF) { + f->close(); + return ERR_CANT_CREATE; + } + f->close(); //memdelete(f); diff --git a/core/math/camera_matrix.cpp b/core/math/camera_matrix.cpp index a60dea7379..fbe5f8c741 100644 --- a/core/math/camera_matrix.cpp +++ b/core/math/camera_matrix.cpp @@ -121,7 +121,7 @@ void CameraMatrix::set_orthogonal(float p_size, float p_aspect, float p_znear, f void CameraMatrix::set_frustum(float p_left, float p_right, float p_bottom, float p_top, float p_near, float p_far) { - +#if 0 ///@TODO, give a check to this. I'm not sure if it's working. set_identity(); @@ -133,10 +133,27 @@ void CameraMatrix::set_frustum(float p_left, float p_right, float p_bottom, floa matrix[2][3]=-(2*p_far*p_near) / (p_far-p_near); matrix[3][2]=-1; matrix[3][3]=0; +#else + float *te = &matrix[0][0]; + float x = 2 * p_near / ( p_right - p_left ); + float y = 2 * p_near / ( p_top - p_bottom ); + + float a = ( p_right + p_left ) / ( p_right - p_left ); + float b = ( p_top + p_bottom ) / ( p_top - p_bottom ); + float c = - ( p_far + p_near ) / ( p_far - p_near ); + float d = - 2 * p_far * p_near / ( p_far - p_near ); + + te[0] = x; te[4] = 0; te[8] = a; te[12] = 0; + te[1] = 0; te[5] = y; te[9] = b; te[13] = 0; + te[2] = 0; te[6] = 0; te[10] = c; te[14] = d; + te[3] = 0; te[7] = 0; te[11] = - 1; te[15] = 0; + +#endif } + float CameraMatrix::get_z_far() const { const float * matrix = (const float*)this->matrix; diff --git a/core/variant_op.cpp b/core/variant_op.cpp index 21bbc8c7ee..d6129e150c 100644 --- a/core/variant_op.cpp +++ b/core/variant_op.cpp @@ -552,6 +552,9 @@ void Variant::evaluate(const Operator& p_op, const Variant& p_a, const Variant& if (p_b.type==MATRIX32) { _RETURN( *p_a._data._matrix32 * *p_b._data._matrix32 ); }; + if (p_b.type==VECTOR2) { + _RETURN( p_a._data._matrix32->xform( *(const Vector2*)p_b._data._mem) ); + }; r_valid=false; return; } break; diff --git a/demos/3d/kinematic_char/cubelib.res b/demos/3d/kinematic_char/cubelib.res index 66b999d78d..27f2b9b3bd 100644 Binary files a/demos/3d/kinematic_char/cubelib.res and b/demos/3d/kinematic_char/cubelib.res differ diff --git a/demos/3d/kinematic_char/level.scn b/demos/3d/kinematic_char/level.scn index a276fe22e1..7ccb2430c1 100644 Binary files a/demos/3d/kinematic_char/level.scn and b/demos/3d/kinematic_char/level.scn differ diff --git a/drivers/SCsub b/drivers/SCsub index 46334468ba..a1a2191cbc 100644 --- a/drivers/SCsub +++ b/drivers/SCsub @@ -10,7 +10,6 @@ SConscript('alsa/SCsub'); SConscript('pulseaudio/SCsub'); SConscript('windows/SCsub'); SConscript('gles2/SCsub'); -SConscript('gles1/SCsub'); SConscript('gl_context/SCsub'); SConscript('openssl/SCsub'); diff --git a/drivers/gles2/rasterizer_gles2.cpp b/drivers/gles2/rasterizer_gles2.cpp index aba0b5ca90..aa7bad0b8f 100644 --- a/drivers/gles2/rasterizer_gles2.cpp +++ b/drivers/gles2/rasterizer_gles2.cpp @@ -971,7 +971,7 @@ void RasterizerGLES2::texture_set_data(RID p_texture,const Image& p_image,VS::Cu - if ((!texture->flags&VS::TEXTURE_FLAG_VIDEO_SURFACE) && img.detect_alpha()==Image::ALPHA_BLEND) { + if (!(texture->flags&VS::TEXTURE_FLAG_VIDEO_SURFACE) && img.detect_alpha()==Image::ALPHA_BLEND) { texture->has_alpha=true; } @@ -2525,7 +2525,7 @@ Error RasterizerGLES2::_surface_set_arrays(Surface *p_surface, uint8_t *p_mem,ui void RasterizerGLES2::mesh_add_custom_surface(RID p_mesh,const Variant& p_dat) { ERR_EXPLAIN("OpenGL Rasterizer does not support custom surfaces. Running on wrong platform?"); - ERR_FAIL_V(); + ERR_FAIL(); } Array RasterizerGLES2::mesh_get_surface_arrays(RID p_mesh,int p_surface) const { @@ -4116,6 +4116,10 @@ void RasterizerGLES2::begin_frame() { shadow_filter=ShadowFilterTechnique(int(Globals::get_singleton()->get("rasterizer/shadow_filter"))); #endif + canvas_shader.set_conditional(CanvasShaderGLES2::SHADOW_PCF5,shadow_filter==SHADOW_FILTER_PCF5); + canvas_shader.set_conditional(CanvasShaderGLES2::SHADOW_PCF13,shadow_filter==SHADOW_FILTER_PCF13); + canvas_shader.set_conditional(CanvasShaderGLES2::SHADOW_ESM,shadow_filter==SHADOW_FILTER_ESM); + window_size = Size2( OS::get_singleton()->get_video_mode().width, OS::get_singleton()->get_video_mode().height ); double time = (OS::get_singleton()->get_ticks_usec()/1000); // get msec @@ -7874,7 +7878,8 @@ void RasterizerGLES2::canvas_begin() { canvas_blend_mode=VS::MATERIAL_BLEND_MODE_MIX; canvas_texscreen_used=false; uses_texpixel_size=false; - canvas_last_shader=RID(); + + canvas_last_material=NULL; } @@ -8364,6 +8369,476 @@ void RasterizerGLES2::canvas_set_transform(const Matrix32& p_transform) { //canvas_transform = Variant(p_transform); } +RID RasterizerGLES2::canvas_light_occluder_create() { + + CanvasOccluder *co = memnew( CanvasOccluder ); + co->index_id=0; + co->vertex_id=0; + co->len=0; + + return canvas_occluder_owner.make_rid(co); +} + +void RasterizerGLES2::canvas_light_occluder_set_polylines(RID p_occluder, const DVector& p_lines) { + + CanvasOccluder *co = canvas_occluder_owner.get(p_occluder); + ERR_FAIL_COND(!co); + + co->lines=p_lines; + + if (p_lines.size()!=co->len) { + + if (co->index_id) + glDeleteBuffers(1,&co->index_id); + if (co->vertex_id) + glDeleteBuffers(1,&co->vertex_id); + + co->index_id=0; + co->vertex_id=0; + co->len=0; + + } + + if (p_lines.size()) { + + + + DVector geometry; + DVector indices; + int lc = p_lines.size(); + + geometry.resize(lc*6); + indices.resize(lc*3); + + DVector::Write vw=geometry.write(); + DVector::Write iw=indices.write(); + + + DVector::Read lr=p_lines.read(); + + const int POLY_HEIGHT = 16384; + + for(int i=0;ivertex_id) { + glGenBuffers(1,&co->vertex_id); + glBindBuffer(GL_ARRAY_BUFFER,co->vertex_id); + glBufferData(GL_ARRAY_BUFFER,lc*6*sizeof(real_t),vw.ptr(),GL_STATIC_DRAW); + } else { + + glBindBuffer(GL_ARRAY_BUFFER,co->vertex_id); + glBufferSubData(GL_ARRAY_BUFFER,0,lc*6*sizeof(real_t),vw.ptr()); + + } + + glBindBuffer(GL_ARRAY_BUFFER,0); //unbind + + if (!co->index_id) { + + glGenBuffers(1,&co->index_id); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,co->index_id); + glBufferData(GL_ELEMENT_ARRAY_BUFFER,lc*3*sizeof(uint16_t),iw.ptr(),GL_STATIC_DRAW); + } else { + + + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,co->index_id); + glBufferSubData(GL_ELEMENT_ARRAY_BUFFER,0,lc*3*sizeof(uint16_t),iw.ptr()); + } + + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0); //unbind + + co->len=lc; + + } + + + +} + +RID RasterizerGLES2::canvas_light_shadow_buffer_create(int p_width) { + + CanvasLightShadow *cls = memnew( CanvasLightShadow ); + if (p_width>max_texture_size) + p_width=max_texture_size; + + cls->size=p_width; + glActiveTexture(GL_TEXTURE0); + + glGenFramebuffers(1, &cls->fbo); + glBindFramebuffer(GL_FRAMEBUFFER, cls->fbo); + + // Create a render buffer + glGenRenderbuffers(1, &cls->rbo); + glBindRenderbuffer(GL_RENDERBUFFER, cls->rbo); + + // Create a texture for storing the depth + glGenTextures(1, &cls->depth); + glBindTexture(GL_TEXTURE_2D, cls->depth); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + // Remove artifact on the edges of the shadowmap + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + cls->height=16; + + //print_line("ERROR? "+itos(glGetError())); + if ( read_depth_supported ) { + + // We'll use a depth texture to store the depths in the shadow map + glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, cls->size, cls->height, 0, + GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL); + +#ifdef GLEW_ENABLED + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); +#endif + + // Attach the depth texture to FBO depth attachment point + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, + GL_TEXTURE_2D, cls->depth, 0); + +#ifdef GLEW_ENABLED + glDrawBuffer(GL_NONE); +#endif + } else { + // We'll use a RGBA texture into which we pack the depth info + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, cls->size, cls->height, 0, + GL_RGBA, GL_UNSIGNED_BYTE, NULL); + + // Attach the RGBA texture to FBO color attachment point + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, + GL_TEXTURE_2D, cls->depth, 0); + + // Allocate 16-bit depth buffer + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, cls->size, cls->height); + + // Attach the render buffer as depth buffer - will be ignored + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, + GL_RENDERBUFFER, cls->rbo); + + + } + + GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); + //printf("errnum: %x\n",status); +#ifdef GLEW_ENABLED + if (read_depth_supported) { + glDrawBuffer(GL_BACK); + } +#endif + glBindFramebuffer(GL_FRAMEBUFFER, base_framebuffer); + DEBUG_TEST_ERROR("2D Shadow Buffer Init"); + ERR_FAIL_COND_V( status != GL_FRAMEBUFFER_COMPLETE, RID() ); + +#ifdef GLEW_ENABLED + if (read_depth_supported) { + glDrawBuffer(GL_BACK); + } +#endif + + return canvas_light_shadow_owner.make_rid(cls); +} + +void RasterizerGLES2::canvas_light_shadow_buffer_update(RID p_buffer, const Matrix32& p_light_xform, int p_light_mask,float p_near, float p_far, CanvasLightOccluderInstance* p_occluders, CameraMatrix *p_xform_cache) { + + CanvasLightShadow *cls = canvas_light_shadow_owner.get(p_buffer); + ERR_FAIL_COND(!cls); + + + glDisable(GL_BLEND); + glDisable(GL_SCISSOR_TEST); + glDisable(GL_DITHER); + glDisable(GL_CULL_FACE); + glDepthFunc(GL_LEQUAL); + glEnable(GL_DEPTH_TEST); + glDepthMask(true); + + glBindFramebuffer(GL_FRAMEBUFFER, cls->fbo); + + if (!use_rgba_shadowmaps) + glColorMask(0, 0, 0, 0); + + glEnableVertexAttribArray(VS::ARRAY_VERTEX); + canvas_shadow_shader.bind(); + + const int vp_height = 10; + + glViewport(0, 0, cls->size,cls->height); + _glClearDepth(1.0f); + glClearColor(1,1,1,1); + glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); + + VS::CanvasOccluderPolygonCullMode cull=VS::CANVAS_OCCLUDER_POLYGON_CULL_DISABLED; + + + for(int i=0;i<4;i++) { + + //make sure it remains orthogonal, makes easy to read angle later + + Transform light; + light.origin[0]=p_light_xform[2][0]; + light.origin[1]=p_light_xform[2][1]; + light.basis[0][0]=p_light_xform[0][0]; + light.basis[0][1]=p_light_xform[1][0]; + light.basis[1][0]=p_light_xform[0][1]; + light.basis[1][1]=p_light_xform[1][1]; + + //light.basis.scale(Vector3(to_light.elements[0].length(),to_light.elements[1].length(),1)); + + /// p_near=1; + CameraMatrix projection; + { + real_t fov = 90; + real_t near = p_near; + real_t far = p_far; + real_t aspect = 1.0; + + real_t ymax = near * Math::tan( Math::deg2rad( fov * 0.5 ) ); + real_t ymin = - ymax; + real_t xmin = ymin * aspect; + real_t xmax = ymax * aspect; + + projection.set_frustum( xmin, xmax, ymin, ymax, near, far ); + } + + Vector3 cam_target=Matrix3(Vector3(0,0,Math_PI*2*(i/4.0))).xform(Vector3(0,1,0)); + projection = projection * CameraMatrix(Transform().looking_at(cam_target,Vector3(0,0,-1)).affine_inverse()); + + //print_line("near: "+rtos(p_near)); + //print_line("far: "+rtos(p_far)); + //projection.set_perspective(60,size/float(vp_height),p_near,p_far); + + // CameraMatrix light_mat = projection * CameraMatrix(camera); + + canvas_shadow_shader.set_uniform(CanvasShadowShaderGLES2::PROJECTION_MATRIX,projection); + canvas_shadow_shader.set_uniform(CanvasShadowShaderGLES2::LIGHT_MATRIX,light); + + if (i==0) + *p_xform_cache=projection; + + glViewport(0, (cls->height/4)*i, cls->size,cls->height/4); + + CanvasLightOccluderInstance *instance=p_occluders; + + while(instance) { + + CanvasOccluder *cc = canvas_occluder_owner.get(instance->polygon_buffer); + if (!cc || cc->len==0 || !(p_light_mask&instance->light_mask)) { + + instance=instance->next; + continue; + } + + canvas_shadow_shader.set_uniform(CanvasShadowShaderGLES2::WORLD_MATRIX,instance->xform_cache); + if (cull!=instance->cull_cache) { + + cull=instance->cull_cache; + switch(cull) { + case VS::CANVAS_OCCLUDER_POLYGON_CULL_DISABLED: { + + glDisable(GL_CULL_FACE); + + } break; + case VS::CANVAS_OCCLUDER_POLYGON_CULL_CLOCKWISE: { + + glEnable(GL_CULL_FACE); + glCullFace(GL_FRONT); + } break; + case VS::CANVAS_OCCLUDER_POLYGON_CULL_COUNTER_CLOCKWISE: { + + glEnable(GL_CULL_FACE); + glCullFace(GL_BACK); + + } break; + } + } +/* + if (i==0) { + for(int i=0;ilines.size();i++) { + Vector2 p = instance->xform_cache.xform(cc->lines.get(i)); + Plane pp(Vector3(p.x,p.y,0),1); + pp.normal = light.xform(pp.normal); + pp = projection.xform4(pp); + print_line(itos(i)+": "+pp.normal/pp.d); + //pp=light_mat.xform4(pp); + //print_line(itos(i)+": "+pp.normal/pp.d); + } + } +*/ + glBindBuffer(GL_ARRAY_BUFFER,cc->vertex_id); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,cc->index_id); + glVertexAttribPointer(VS::ARRAY_VERTEX, 3, GL_FLOAT, false, 0, 0); + glDrawElements(GL_TRIANGLES,cc->len*3,GL_UNSIGNED_SHORT,0); + + + instance=instance->next; + } + + + } + + glDisableVertexAttribArray(VS::ARRAY_VERTEX); + glBindBuffer(GL_ARRAY_BUFFER,0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0); + + if (shadow_filter==SHADOW_FILTER_ESM) { + //blur the buffer +#if 0 + //this is ignord, it did not make any difference.. + if (read_depth_supported) { + glDepthFunc(GL_ALWAYS); + } else { + glDisable(GL_DEPTH_TEST); + glDepthMask(false); + } + glDisable(GL_CULL_FACE); + glViewport(0, 0, cls->size,cls->height); + + int passes=1; + CanvasLightShadow *blur = canvas_light_shadow_owner.get(canvas_shadow_blur); + + copy_shader.set_conditional(CopyShaderGLES2::SHADOW_BLUR_H_PASS,true); + copy_shader.bind(); + copy_shader.set_uniform(CopyShaderGLES2::PIXEL_SCALE,1); + copy_shader.set_uniform(CopyShaderGLES2::BLUR_MAGNITUDE,1); + glUniform1i(copy_shader.get_uniform_location(CopyShaderGLES2::SOURCE),0); + + for(int i=0;ifbo); + glActiveTexture(GL_TEXTURE0); + + if (read_depth_supported) + glBindTexture(GL_TEXTURE_2D,cls->depth); + else + glBindTexture(GL_TEXTURE_2D,cls->rgba); + + + { + Vector2 src_sb_uv[4]={ + Vector2( 0, 1), + Vector2( 1, 1), + Vector2( 1, 0), + Vector2( 0, 0) + }; + static const Vector2 dst_pos[4]={ + Vector2(-1, 1), + Vector2( 1, 1), + Vector2( 1,-1), + Vector2(-1,-1) + }; + + + + copy_shader.set_uniform(CopyShaderGLES2::PIXEL_SIZE,Vector2(1.0,1.0)/cls->size); + _draw_gui_primitive(4,dst_pos,NULL,src_sb_uv); + } + + glActiveTexture(GL_TEXTURE0); + if (read_depth_supported) + glBindTexture(GL_TEXTURE_2D,blur->depth); + else + glBindTexture(GL_TEXTURE_2D,blur->rgba); + + glBindFramebuffer(GL_FRAMEBUFFER, cls->fbo); + + { + float hlimit = float(cls->size) / blur->size; + //hlimit*=2.0; + Vector2 src_sb_uv[4]={ + Vector2( 0, 1), + Vector2( hlimit, 1), + Vector2( hlimit, 0), + Vector2( 0, 0) + }; + static const Vector2 dst_pos[4]={ + Vector2(-1, 1), + Vector2( 1, 1), + Vector2( 1,-1), + Vector2(-1,-1) + }; + + + copy_shader.set_uniform(CopyShaderGLES2::PIXEL_SIZE,Vector2(1.0,1.0)/blur->size); + _draw_gui_primitive(4,dst_pos,NULL,src_sb_uv); + } + + } + copy_shader.set_conditional(CopyShaderGLES2::SHADOW_BLUR_H_PASS,false); + glDepthFunc(GL_LEQUAL); +#endif + } + + glBindFramebuffer(GL_FRAMEBUFFER, current_rt?current_rt->fbo:base_framebuffer); + glColorMask(1, 1, 1, 1); + + + +} + + +void RasterizerGLES2::canvas_debug_viewport_shadows(CanvasLight* p_lights_with_shadow) { + + CanvasLight* light=p_lights_with_shadow; + + canvas_begin(); //reset + + int h = 10; + int w = viewport.width; + int ofs = h; + while(light) { + + if (light->shadow_buffer.is_valid()) { + + CanvasLightShadow * sb = canvas_light_shadow_owner.get(light->shadow_buffer); + if (sb) { + glActiveTexture(GL_TEXTURE0); + if (read_depth_supported) + glBindTexture(GL_TEXTURE_2D,sb->depth); + else + glBindTexture(GL_TEXTURE_2D,sb->rgba); + _draw_textured_quad(Rect2(h,ofs,w-h*2,h),Rect2(0,0,sb->size,10),Size2(sb->size,10),false,false); + ofs+=h*2; + + } + } + + light=light->shadows_next_ptr; + } + +} + void RasterizerGLES2::_canvas_normal_set_flip(const Vector2& p_flip) { if (p_flip==normal_flip) @@ -8508,14 +8983,14 @@ void RasterizerGLES2::_canvas_item_render_commands(CanvasItem *p_item,CanvasItem } -void RasterizerGLES2::_canvas_item_setup_shader_params(CanvasItem *shader_owner,Shader* shader) { +void RasterizerGLES2::_canvas_item_setup_shader_params(CanvasItemMaterial *material,Shader* shader) { if (canvas_shader.bind()) rebind_texpixel_size=true; - if (shader_owner->shader_version!=shader->version) { + if (material->shader_version!=shader->version) { //todo optimize uniforms - shader_owner->shader_version=shader->version; + material->shader_version=shader->version; } if (shader->has_texscreen && framebuffer.active) { @@ -8558,14 +9033,14 @@ void RasterizerGLES2::_canvas_item_setup_shader_params(CanvasItem *shader_owner, } -void RasterizerGLES2::_canvas_item_setup_shader_uniforms(CanvasItem *shader_owner,Shader* shader) { +void RasterizerGLES2::_canvas_item_setup_shader_uniforms(CanvasItemMaterial *material,Shader* shader) { //this can be optimized.. int tex_id=1; int idx=0; for(Map::Element *E=shader->uniforms.front();E;E=E->next()) { - Map::Element *F=shader_owner->shader_param.find(E->key()); + Map::Element *F=material->shader_param.find(E->key()); if ((E->get().type==ShaderLanguage::TYPE_TEXTURE || E->get().type==ShaderLanguage::TYPE_CUBEMAP)) { @@ -8623,6 +9098,8 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list,int p_z,const canvas_modulate=p_modulate; canvas_shader.set_conditional(CanvasShaderGLES2::USE_MODULATE,canvas_use_modulate); + bool reset_modulate=false; + while(p_item_list) { CanvasItem *ci=p_item_list; @@ -8632,12 +9109,13 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list,int p_z,const draw_viewport_func(ci->vp_render->owner,ci->vp_render->udata,ci->vp_render->rect); } memdelete(ci->vp_render); - ci->vp_render=NULL; - canvas_last_shader=RID(); + ci->vp_render=NULL; + canvas_last_material=NULL; canvas_use_modulate=p_modulate!=Color(1,1,1,1); canvas_modulate=p_modulate; canvas_shader.set_conditional(CanvasShaderGLES2::USE_MODULATE,canvas_use_modulate); rebind_shader=true; + reset_modulate=true; } @@ -8660,13 +9138,14 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list,int p_z,const //begin rect - CanvasItem *shader_owner = ci->shader_owner?ci->shader_owner:ci; + CanvasItem *material_owner = ci->material_owner?ci->material_owner:ci; + CanvasItemMaterial *material = material_owner->material; - if (shader_owner->shader!=canvas_last_shader || rebind_shader) { + if (material!=canvas_last_material || rebind_shader) { Shader *shader = NULL; - if (shader_owner->shader.is_valid()) { - shader = this->shader_owner.get(shader_owner->shader); + if (material && material->shader.is_valid()) { + shader = shader_owner.get(material->shader); if (shader && !shader->valid) { shader=NULL; } @@ -8676,7 +9155,7 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list,int p_z,const if (shader) { canvas_shader.set_custom_shader(shader->custom_code_id); - _canvas_item_setup_shader_params(shader_owner,shader); + _canvas_item_setup_shader_params(material,shader); } else { shader_cache=NULL; canvas_shader.set_custom_shader(0); @@ -8688,16 +9167,26 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list,int p_z,const canvas_shader.set_uniform(CanvasShaderGLES2::PROJECTION_MATRIX,canvas_transform); if (canvas_use_modulate) - canvas_shader.set_uniform(CanvasShaderGLES2::MODULATE,canvas_modulate); - canvas_last_shader=shader_owner->shader; + reset_modulate=true; + canvas_last_material=material; rebind_shader=false; } - if (shader_cache) { + if (material && shader_cache) { + + _canvas_item_setup_shader_uniforms(material,shader_cache); + } - _canvas_item_setup_shader_uniforms(shader_owner,shader_cache); + if (material && material->unshaded) { + canvas_shader.set_uniform(CanvasShaderGLES2::MODULATE,Color(1,1,1,1)); + reset_modulate=true; + } else if (reset_modulate) { + canvas_shader.set_uniform(CanvasShaderGLES2::MODULATE,canvas_modulate); + reset_modulate=false; } + + canvas_shader.set_uniform(CanvasShaderGLES2::MODELVIEW_MATRIX,ci->final_transform); canvas_shader.set_uniform(CanvasShaderGLES2::EXTRA_MATRIX,Matrix32()); @@ -8747,7 +9236,7 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list,int p_z,const _canvas_item_render_commands(ci,current_clip,reclip); - if (canvas_blend_mode==VS::MATERIAL_BLEND_MODE_MIX && p_light) { + if (canvas_blend_mode==VS::MATERIAL_BLEND_MODE_MIX && p_light && (!material || !material->unshaded)) { CanvasLight *light = p_light; bool light_used=false; @@ -8785,13 +9274,15 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list,int p_z,const normal_flip=Vector2(1,1); } + canvas_shader.set_conditional(CanvasShaderGLES2::USE_SHADOWS,light->shadow_buffer.is_valid()); + bool light_rebind = canvas_shader.bind(); if (light_rebind) { - if (shader_owner && shader_cache) { - _canvas_item_setup_shader_params(shader_owner,shader_cache); - _canvas_item_setup_shader_uniforms(shader_owner,shader_cache); + if (material && shader_cache) { + _canvas_item_setup_shader_params(material,shader_cache); + _canvas_item_setup_shader_uniforms(material,shader_cache); } canvas_shader.set_uniform(CanvasShaderGLES2::MODELVIEW_MATRIX,ci->final_transform); @@ -8800,6 +9291,7 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list,int p_z,const if (canvas_use_modulate) canvas_shader.set_uniform(CanvasShaderGLES2::MODULATE,canvas_modulate); canvas_shader.set_uniform(CanvasShaderGLES2::NORMAL_FLIP,Vector2(1,1)); + canvas_shader.set_uniform(CanvasShaderGLES2::SHADOWPIXEL_SIZE,1.0/light->shadow_buffer_size); } @@ -8808,6 +9300,23 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list,int p_z,const canvas_shader.set_uniform(CanvasShaderGLES2::LIGHT_POS,light->light_shader_pos); canvas_shader.set_uniform(CanvasShaderGLES2::LIGHT_COLOR,light->color); canvas_shader.set_uniform(CanvasShaderGLES2::LIGHT_HEIGHT,light->height); + if (light->shadow_buffer.is_valid()) { + + CanvasLightShadow *cls = canvas_light_shadow_owner.get(light->shadow_buffer); + glActiveTexture(GL_TEXTURE0+max_texture_units-3); + if (read_depth_supported) + glBindTexture(GL_TEXTURE_2D,cls->depth); + else + glBindTexture(GL_TEXTURE_2D,cls->rgba); + + canvas_shader.set_uniform(CanvasShaderGLES2::SHADOW_TEXTURE,max_texture_units-3); + canvas_shader.set_uniform(CanvasShaderGLES2::SHADOW_MATRIX,light->shadow_matrix_cache); + canvas_shader.set_uniform(CanvasShaderGLES2::LIGHT_LOCAL_MATRIX,light->xform_cache.affine_inverse()); + canvas_shader.set_uniform(CanvasShaderGLES2::SHADOW_ESM_MULTIPLIER,light->shadow_esm_mult); + + } + + glActiveTexture(GL_TEXTURE0+max_texture_units-2); canvas_shader.set_uniform(CanvasShaderGLES2::LIGHT_TEXTURE,max_texture_units-2); Texture *t = texture_owner.get(light->texture); @@ -8831,12 +9340,13 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list,int p_z,const canvas_shader.set_conditional(CanvasShaderGLES2::USE_LIGHTING,false); canvas_shader.set_conditional(CanvasShaderGLES2::USE_MODULATE,canvas_use_modulate); + canvas_shader.set_conditional(CanvasShaderGLES2::USE_SHADOWS,false); canvas_shader.bind(); - if (shader_owner && shader_cache) { - _canvas_item_setup_shader_params(shader_owner,shader_cache); - _canvas_item_setup_shader_uniforms(shader_owner,shader_cache); + if (material && shader_cache) { + _canvas_item_setup_shader_params(material,shader_cache); + _canvas_item_setup_shader_uniforms(material,shader_cache); } canvas_shader.set_uniform(CanvasShaderGLES2::MODELVIEW_MATRIX,ci->final_transform); @@ -9067,6 +9577,11 @@ bool RasterizerGLES2::is_environment(const RID& p_rid) const { } bool RasterizerGLES2::is_shader(const RID& p_rid) const { + return shader_owner.owns(p_rid); +} + +bool RasterizerGLES2::is_canvas_light_occluder(const RID& p_rid) const { + return false; } @@ -9244,7 +9759,30 @@ void RasterizerGLES2::free(const RID& p_rid) { glDeleteTextures(1,&sampled_light->texture); sampled_light_owner.free(p_rid); memdelete( sampled_light ); + } else if (canvas_occluder_owner.owns(p_rid)) { + + CanvasOccluder *co = canvas_occluder_owner.get(p_rid); + if (co->index_id) + glDeleteBuffers(1,&co->index_id); + if (co->vertex_id) + glDeleteBuffers(1,&co->vertex_id); + + canvas_occluder_owner.free(p_rid); + memdelete(co); + + } else if (canvas_light_shadow_owner.owns(p_rid)) { + + CanvasLightShadow *cls = canvas_light_shadow_owner.get(p_rid); + glDeleteFramebuffers(1,&cls->fbo); + glDeleteRenderbuffers(1,&cls->rbo); + glDeleteTextures(1,&cls->depth); + if (!read_depth_supported) { + glDeleteTextures(1,&cls->rgba); + } + + canvas_light_shadow_owner.free(p_rid); + memdelete(cls); }; } @@ -9779,10 +10317,12 @@ void RasterizerGLES2::init() { material_shader.init(); canvas_shader.init(); copy_shader.init(); + canvas_shadow_shader.init(); #ifdef GLEW_ENABLED material_shader.set_conditional(MaterialShaderGLES2::USE_GLES_OVER_GL,true); canvas_shader.set_conditional(CanvasShaderGLES2::USE_GLES_OVER_GL,true); + canvas_shadow_shader.set_conditional(CanvasShadowShaderGLES2::USE_GLES_OVER_GL,true); copy_shader.set_conditional(CopyShaderGLES2::USE_GLES_OVER_GL,true); #endif @@ -9923,8 +10463,11 @@ void RasterizerGLES2::init() { glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &max_texture_units); + glGetIntegerv(GL_MAX_TEXTURE_SIZE,&max_texture_size); //read_depth_supported=false; + canvas_shadow_blur = canvas_light_shadow_buffer_create(max_texture_size); + { //shadowmaps OS::VideoMode vm=OS::get_singleton()->get_video_mode(); @@ -9946,6 +10489,7 @@ void RasterizerGLES2::init() { //material_shader material_shader.set_conditional(MaterialShaderGLES2::USE_DEPTH_SHADOWS,!use_rgba_shadowmaps); + canvas_shadow_shader.set_conditional(CanvasShadowShaderGLES2::USE_DEPTH_SHADOWS,!use_rgba_shadowmaps); } @@ -9978,7 +10522,7 @@ void RasterizerGLES2::init() { void RasterizerGLES2::finish() { - + free(canvas_shadow_blur); } int RasterizerGLES2::get_render_info(VS::RenderInfo p_info) { diff --git a/drivers/gles2/rasterizer_gles2.h b/drivers/gles2/rasterizer_gles2.h index 173ca14180..f09714f50c 100644 --- a/drivers/gles2/rasterizer_gles2.h +++ b/drivers/gles2/rasterizer_gles2.h @@ -51,6 +51,7 @@ #include "drivers/gles2/shaders/material.glsl.h" #include "drivers/gles2/shaders/canvas.glsl.h" +#include "drivers/gles2/shaders/canvas_shadow.glsl.h" #include "drivers/gles2/shaders/blur.glsl.h" #include "drivers/gles2/shaders/copy.glsl.h" #include "drivers/gles2/shader_compiler_gles2.h" @@ -816,6 +817,7 @@ class RasterizerGLES2 : public Rasterizer { bool current_depth_mask; VS::MaterialBlendMode current_blend_mode; bool use_fast_texture_filter; + int max_texture_size; bool fragment_lighting; RID shadow_material; @@ -1160,6 +1162,7 @@ class RasterizerGLES2 : public Rasterizer { void _process_glow_and_bloom(); //void _update_blur_buffer(); + /*********/ /* FRAME */ /*********/ @@ -1178,6 +1181,45 @@ class RasterizerGLES2 : public Rasterizer { } _rinfo; + /*******************/ + /* CANVAS OCCLUDER */ + /*******************/ + + + struct CanvasOccluder { + + GLuint vertex_id; // 0 means, unconfigured + GLuint index_id; // 0 means, unconfigured + DVector lines; + int len; + }; + + RID_Owner canvas_occluder_owner; + + /***********************/ + /* CANVAS LIGHT SHADOW */ + /***********************/ + + + struct CanvasLightShadow { + + int size; + int height; + GLuint fbo; + GLuint rbo; + GLuint depth; + GLuint rgba; //for older devices + + GLuint blur; + + }; + + RID_Owner canvas_light_shadow_owner; + + RID canvas_shadow_blur; + + /* ETC */ + RenderTarget *current_rt; bool current_rt_transparent; bool current_rt_vflip; @@ -1192,7 +1234,7 @@ class RasterizerGLES2 : public Rasterizer { bool uses_texpixel_size; bool rebind_texpixel_size; Transform canvas_transform; - RID canvas_last_shader; + CanvasItemMaterial *canvas_last_material; bool canvas_texscreen_used; Vector2 normal_flip; _FORCE_INLINE_ void _canvas_normal_set_flip(const Vector2& p_flip); @@ -1227,10 +1269,12 @@ class RasterizerGLES2 : public Rasterizer { VS::ScenarioDebugMode current_debug; RID overdraw_material; + mutable MaterialShaderGLES2 material_shader; mutable CanvasShaderGLES2 canvas_shader; BlurShaderGLES2 blur_shader; CopyShaderGLES2 copy_shader; + mutable CanvasShadowShaderGLES2 canvas_shadow_shader; mutable ShaderCompilerGLES2 shader_precompiler; @@ -1254,8 +1298,8 @@ class RasterizerGLES2 : public Rasterizer { template _FORCE_INLINE_ void _canvas_item_render_commands(CanvasItem *p_item,CanvasItem *current_clip,bool &reclip); - _FORCE_INLINE_ void _canvas_item_setup_shader_params(CanvasItem *shader_owner,Shader* p_shader); - _FORCE_INLINE_ void _canvas_item_setup_shader_uniforms(CanvasItem *shader_owner,Shader* p_shader); + _FORCE_INLINE_ void _canvas_item_setup_shader_params(CanvasItemMaterial *material,Shader* p_shader); + _FORCE_INLINE_ void _canvas_item_setup_shader_uniforms(CanvasItemMaterial *material,Shader* p_shader); public: /* TEXTURE API */ @@ -1572,7 +1616,17 @@ public: virtual void canvas_set_transform(const Matrix32& p_transform); virtual void canvas_render_items(CanvasItem *p_item_list,int p_z,const Color& p_modulate,CanvasLight *p_light); + virtual void canvas_debug_viewport_shadows(CanvasLight* p_lights_with_shadow); + /* CANVAS LIGHT SHADOW */ + + //buffer + virtual RID canvas_light_shadow_buffer_create(int p_width); + virtual void canvas_light_shadow_buffer_update(RID p_buffer, const Matrix32& p_light_xform, int p_light_mask,float p_near, float p_far, CanvasLightOccluderInstance* p_occluders, CameraMatrix *p_xform_cache); + + //occluder + virtual RID canvas_light_occluder_create(); + virtual void canvas_light_occluder_set_polylines(RID p_occluder, const DVector& p_lines); /* ENVIRONMENT */ @@ -1611,6 +1665,8 @@ public: virtual bool is_environment(const RID& p_rid) const; virtual bool is_shader(const RID& p_rid) const; + virtual bool is_canvas_light_occluder(const RID& p_rid) const; + virtual void free(const RID& p_rid); virtual void init(); diff --git a/drivers/gles2/shaders/SCsub b/drivers/gles2/shaders/SCsub index c665cf9036..9679223b16 100644 --- a/drivers/gles2/shaders/SCsub +++ b/drivers/gles2/shaders/SCsub @@ -3,6 +3,7 @@ Import('env') if env['BUILDERS'].has_key('GLSL120GLES'): env.GLSL120GLES('material.glsl'); env.GLSL120GLES('canvas.glsl'); + env.GLSL120GLES('canvas_shadow.glsl'); env.GLSL120GLES('blur.glsl'); env.GLSL120GLES('copy.glsl'); diff --git a/drivers/gles2/shaders/canvas.glsl b/drivers/gles2/shaders/canvas.glsl index 227a8b7bdd..9022f30d7f 100644 --- a/drivers/gles2/shaders/canvas.glsl +++ b/drivers/gles2/shaders/canvas.glsl @@ -34,6 +34,10 @@ varying vec4 local_rot; uniform vec2 normal_flip; #endif +#ifdef USE_SHADOWS +highp varying vec2 pos; +#endif + #endif #if defined(ENABLE_VAR1_INTERP) @@ -63,6 +67,8 @@ VERTEX_SHADER_CODE outvec = modelview_matrix * outvec; #endif + + #ifdef USE_PIXEL_SNAP outvec.xy=floor(outvec.xy+0.5); @@ -75,6 +81,9 @@ VERTEX_SHADER_CODE light_uv_interp.xy = (light_matrix * outvec).xy; light_uv_interp.zw = outvec.xy-light_pos; +#ifdef USE_SHADOWS + pos=outvec.xy; +#endif #if defined(NORMAL_USED) local_rot.xy=normalize( (modelview_matrix * ( extra_matrix * vec4(1.0,0.0,0.0,0.0) )).xy )*normal_flip.x; @@ -154,6 +163,15 @@ varying vec4 local_rot; uniform sampler2D shadow_texture; uniform float shadow_attenuation; +uniform highp mat4 shadow_matrix; +uniform highp mat4 light_local_matrix; +highp varying vec2 pos; +uniform float shadowpixel_size; + +#ifdef SHADOW_ESM +uniform float shadow_esm_multiplier; +#endif + #endif #endif @@ -173,10 +191,6 @@ void main() { vec3 normal = vec3(0,0,1); #endif -#ifdef USE_MODULATE - - color*=modulate; -#endif color *= texture2D( texture, uv_interp ); #if defined(ENABLE_SCREEN_UV) @@ -191,6 +205,12 @@ FRAGMENT_SHADER_CODE color = vec4(vec3(enc32),1.0); #endif +#ifdef USE_MODULATE + + color*=modulate; +#endif + + #ifdef USE_LIGHTING #if defined(NORMAL_USED) @@ -201,13 +221,96 @@ FRAGMENT_SHADER_CODE vec4 light = texture2D(light_texture,light_uv_interp.xy) * light_color; #ifdef USE_SHADOWS - //this might not be that great on mobile? - float light_dist = length(light_texture.zw); - float light_angle = atan2(light_texture.x,light_texture.z) + 1.0 * 0.5; - float shadow_dist = texture2D(shadow_texture,vec2(light_angle,0)); - if (light_dist>shadow_dist) { - light*=shadow_attenuation; + + + vec2 lpos = (light_local_matrix * vec4(pos,0.0,1.0)).xy; + float angle_to_light = -atan(lpos.x,lpos.y); + float PI = 3.14159265358979323846264; + /*int i = int(mod(floor((angle_to_light+7.0*PI/6.0)/(4.0*PI/6.0))+1.0, 3.0)); // +1 pq os indices estao em ordem 2,0,1 nos arrays + float ang*/ + + float su,sz; + + float abs_angle = abs(angle_to_light); + vec2 point; + float sh; + if (abs_angle<45.0*PI/180.0) { + point = lpos; + sh=0+(1.0/8.0); + } else if (abs_angle>135.0*PI/180.0) { + point = -lpos; + sh = 0.5+(1.0/8.0); + } else if (angle_to_light>0) { + + point = vec2(lpos.y,-lpos.x); + sh = 0.25+(1.0/8.0); + } else { + + point = vec2(-lpos.y,lpos.x); + sh = 0.75+(1.0/8.0); + + } + + + vec4 s = shadow_matrix * vec4(point,0.0,1.0); + s.xyz/=s.w; + su=s.x*0.5+0.5; + sz=s.z*0.5+0.5; + + float shadow_attenuation; + +#ifdef SHADOW_PCF5 + + shadow_attenuation=0.0; + shadow_attenuation += texture2D(shadow_texture,vec2(su,sh)).z +#include "Shlwapi.h" #include "file_access_windows.h" + #include #include #include #include #include "print_string.h" + #ifdef _MSC_VER #define S_ISREG(m) ((m)&_S_IFREG) #endif @@ -111,10 +115,20 @@ void FileAccessWindows::close() { //unlink(save_path.utf8().get_data()); //print_line("renaming.."); - _wunlink(save_path.c_str()); //unlink if exists - int rename_error = _wrename((save_path+".tmp").c_str(),save_path.c_str()); + //_wunlink(save_path.c_str()); //unlink if exists + //int rename_error = _wrename((save_path+".tmp").c_str(),save_path.c_str()); + + + bool rename_error; + if (!PathFileExistsW(save_path.c_str())) { + //creating new file + rename_error = _wrename((save_path+".tmp").c_str(),save_path.c_str())!=0; + } else { + //atomic replace for existing file + rename_error = !ReplaceFileW(save_path.c_str(), (save_path+".tmp").c_str(), NULL, 2|4, NULL, NULL); + } save_path=""; - ERR_FAIL_COND( rename_error != 0); + ERR_FAIL_COND( rename_error ); } diff --git a/modules/gdscript/gd_script.cpp b/modules/gdscript/gd_script.cpp index 0aa115ffbc..d3a9abf4b7 100644 --- a/modules/gdscript/gd_script.cpp +++ b/modules/gdscript/gd_script.cpp @@ -2696,7 +2696,10 @@ Error ResourceFormatSaverGDScript::save(const String &p_path,const RES& p_resour } file->store_string(source); - + if (file->get_error()!=OK && file->get_error()!=ERR_FILE_EOF) { + memdelete(file); + return ERR_CANT_CREATE; + } file->close(); memdelete(file); return OK; diff --git a/platform/android/audio_driver_opensl.cpp b/platform/android/audio_driver_opensl.cpp index 857d1a4a54..4c0c095e10 100644 --- a/platform/android/audio_driver_opensl.cpp +++ b/platform/android/audio_driver_opensl.cpp @@ -396,6 +396,14 @@ void AudioDriverOpenSL::finish(){ void AudioDriverOpenSL::set_pause(bool p_pause) { pause=p_pause; + + if (active) { + if (pause) { + (*playItf)->SetPlayState(playItf, SL_PLAYSTATE_PAUSED); + } else { + (*playItf)->SetPlayState(playItf, SL_PLAYSTATE_PLAYING); + } + } } diff --git a/platform/android/os_android.cpp b/platform/android/os_android.cpp index 6f1c03b593..6b91c01dfc 100644 --- a/platform/android/os_android.cpp +++ b/platform/android/os_android.cpp @@ -151,7 +151,7 @@ void OS_Android::initialize(const VideoMode& p_desired,int p_video_driver,int p_ sample_manager = memnew( SampleManagerMallocSW ); audio_server = memnew( AudioServerSW(sample_manager) ); - audio_server->set_mixer_params(AudioMixerSW::INTERPOLATION_LINEAR,false); + audio_server->set_mixer_params(AudioMixerSW::INTERPOLATION_LINEAR,true); audio_server->init(); spatial_sound_server = memnew( SpatialSoundServerSW ); diff --git a/platform/windows/detect.py b/platform/windows/detect.py index 16dd695c59..62bab00f7b 100644 --- a/platform/windows/detect.py +++ b/platform/windows/detect.py @@ -115,7 +115,7 @@ def configure(env): env.Append(CCFLAGS=['/DGLES2_ENABLED']) env.Append(CCFLAGS=['/DGLEW_ENABLED']) - LIBS=['winmm','opengl32','dsound','kernel32','ole32','user32','gdi32', 'IPHLPAPI', 'wsock32', 'shell32','advapi32'] + LIBS=['winmm','opengl32','dsound','kernel32','ole32','user32','gdi32', 'IPHLPAPI','Shlwapi', 'wsock32', 'shell32','advapi32'] env.Append(LINKFLAGS=[p+env["LIBSUFFIX"] for p in LIBS]) env.Append(LIBPATH=[os.getenv("WindowsSdkDir")+"/Lib"]) @@ -229,7 +229,7 @@ def configure(env): env.Append(CCFLAGS=['-DWINDOWS_ENABLED','-mwindows']) env.Append(CPPFLAGS=['-DRTAUDIO_ENABLED']) env.Append(CCFLAGS=['-DGLES2_ENABLED','-DGLEW_ENABLED']) - env.Append(LIBS=['mingw32','opengl32', 'dsound', 'ole32', 'd3d9','winmm','gdi32','iphlpapi','wsock32','kernel32']) + env.Append(LIBS=['mingw32','opengl32', 'dsound', 'ole32', 'd3d9','winmm','gdi32','iphlpapi','shlwapi','wsock32','kernel32']) if (env["bits"]=="32" and env["mingw64_for_32"]!="yes"): # env.Append(LIBS=['gcc_s']) diff --git a/scene/2d/canvas_item.cpp b/scene/2d/canvas_item.cpp index 223adaf9bb..4a1842100a 100644 --- a/scene/2d/canvas_item.cpp +++ b/scene/2d/canvas_item.cpp @@ -36,6 +36,192 @@ #include "scene/resources/texture.h" #include "scene/resources/style_box.h" + +bool CanvasItemMaterial::_set(const StringName& p_name, const Variant& p_value) { + + if (p_name==SceneStringNames::get_singleton()->shader_shader) { + set_shader(p_value); + return true; + } else if (p_name==SceneStringNames::get_singleton()->shader_unshaded) { + set_unshaded(p_value); + print_line("set unshaded"); + return true; + } else { + + if (shader.is_valid()) { + + + StringName pr = shader->remap_param(p_name); + if (!pr) { + String n = p_name; + if (n.find("param/")==0) { //backwards compatibility + pr = n.substr(6,n.length()); + } + } + if (pr) { + VisualServer::get_singleton()->canvas_item_material_set_shader_param(material,pr,p_value); + return true; + } + } + } + + return false; +} + +bool CanvasItemMaterial::_get(const StringName& p_name,Variant &r_ret) const { + + + if (p_name==SceneStringNames::get_singleton()->shader_shader) { + + r_ret=get_shader(); + return true; + } else if (p_name==SceneStringNames::get_singleton()->shader_unshaded) { + + + r_ret=unshaded; + return true; + } else { + + if (shader.is_valid()) { + + StringName pr = shader->remap_param(p_name); + if (pr) { + r_ret=VisualServer::get_singleton()->canvas_item_material_get_shader_param(material,pr); + return true; + } + } + + } + + + return false; +} + + +void CanvasItemMaterial::_get_property_list( List *p_list) const { + + p_list->push_back( PropertyInfo( Variant::OBJECT, "shader/shader", PROPERTY_HINT_RESOURCE_TYPE,"CanvasItemShader,CanvasItemShaderGraph" ) ); + p_list->push_back( PropertyInfo( Variant::BOOL, "shader/unshaded") ); + + if (!shader.is_null()) { + + shader->get_param_list(p_list); + } + +} + +void CanvasItemMaterial::set_shader(const Ref& p_shader) { + + ERR_FAIL_COND(p_shader.is_valid() && p_shader->get_mode()!=Shader::MODE_CANVAS_ITEM); +#ifdef TOOLS_ENABLED + + if (shader.is_valid()) { + shader->disconnect("changed",this,"_shader_changed"); + } +#endif + shader=p_shader; + +#ifdef TOOLS_ENABLED + + if (shader.is_valid()) { + shader->connect("changed",this,"_shader_changed"); + } +#endif + + RID rid; + if (shader.is_valid()) + rid=shader->get_rid(); + + VS::get_singleton()->canvas_item_material_set_shader(material,rid); + _change_notify(); //properties for shader exposed + emit_changed(); +} + +Ref CanvasItemMaterial::get_shader() const{ + + return shader; +} + +void CanvasItemMaterial::set_shader_param(const StringName& p_param,const Variant& p_value){ + + VS::get_singleton()->canvas_item_material_set_shader_param(material,p_param,p_value); +} + +Variant CanvasItemMaterial::get_shader_param(const StringName& p_param) const{ + + return VS::get_singleton()->canvas_item_material_get_shader_param(material,p_param); +} + +void CanvasItemMaterial::_shader_changed() { + + +} + +RID CanvasItemMaterial::get_rid() const { + + return material; +} + +void CanvasItemMaterial::set_unshaded(bool p_unshaded) { + + unshaded=p_unshaded; + VS::get_singleton()->canvas_item_material_set_unshaded(material,p_unshaded); +} + +bool CanvasItemMaterial::is_unshaded() const{ + + return unshaded; +} + +void CanvasItemMaterial::_bind_methods() { + + ObjectTypeDB::bind_method(_MD("set_shader","shader:Shader"),&CanvasItemMaterial::set_shader); + ObjectTypeDB::bind_method(_MD("get_shader:Shader"),&CanvasItemMaterial::get_shader); + ObjectTypeDB::bind_method(_MD("set_shader_param","param","value"),&CanvasItemMaterial::set_shader_param); + ObjectTypeDB::bind_method(_MD("get_shader_param","param"),&CanvasItemMaterial::get_shader_param); + ObjectTypeDB::bind_method(_MD("set_unshaded","unshaded"),&CanvasItemMaterial::set_unshaded); + ObjectTypeDB::bind_method(_MD("is_unshaded"),&CanvasItemMaterial::is_unshaded); + +} + +void CanvasItemMaterial::get_argument_options(const StringName& p_function,int p_idx,List*r_options) const { + + String f = p_function.operator String(); + if ((f=="get_shader_param" || f=="set_shader_param") && p_idx==0) { + + if (shader.is_valid()) { + List pl; + shader->get_param_list(&pl); + for (List::Element *E=pl.front();E;E=E->next()) { + r_options->push_back("\""+E->get().name.replace_first("shader_param/","")+"\""); + } + } + } + Resource::get_argument_options(p_function,p_idx,r_options); +} + +CanvasItemMaterial::CanvasItemMaterial() { + + material=VS::get_singleton()->canvas_item_material_create(); + unshaded=false; +} + +CanvasItemMaterial::~CanvasItemMaterial(){ + + VS::get_singleton()->free(material); +} + + + + + + + + +/////////////////////////////////////////////////////////////////// + + + bool CanvasItem::is_visible() const { if (!is_inside_tree()) @@ -730,111 +916,35 @@ bool CanvasItem::is_draw_behind_parent_enabled() const{ return behind; } -void CanvasItem::set_shader(const Ref& p_shader) { - - ERR_FAIL_COND(p_shader.is_valid() && p_shader->get_mode()!=Shader::MODE_CANVAS_ITEM); - -#ifdef TOOLS_ENABLED - - if (shader.is_valid()) { - shader->disconnect("changed",this,"_shader_changed"); - } -#endif - shader=p_shader; - -#ifdef TOOLS_ENABLED +void CanvasItem::set_material(const Ref& p_material) { - if (shader.is_valid()) { - shader->connect("changed",this,"_shader_changed"); - } -#endif + material=p_material; RID rid; - if (shader.is_valid()) - rid=shader->get_rid(); - VS::get_singleton()->canvas_item_set_shader(canvas_item,rid); - _change_notify(); //properties for shader exposed -} - -void CanvasItem::set_use_parent_shader(bool p_use_parent_shader) { - - use_parent_shader=p_use_parent_shader; - VS::get_singleton()->canvas_item_set_use_parent_shader(canvas_item,p_use_parent_shader); + if (material.is_valid()) + rid=material->get_rid(); + VS::get_singleton()->canvas_item_set_material(canvas_item,rid); + _change_notify(); //properties for material exposed } -bool CanvasItem::get_use_parent_shader() const{ +void CanvasItem::set_use_parent_material(bool p_use_parent_material) { - return use_parent_shader; + use_parent_material=p_use_parent_material; + VS::get_singleton()->canvas_item_set_use_parent_material(canvas_item,p_use_parent_material); } -Ref CanvasItem::get_shader() const{ +bool CanvasItem::get_use_parent_material() const{ - return shader; + return use_parent_material; } -void CanvasItem::set_shader_param(const StringName& p_param,const Variant& p_value) { +Ref CanvasItem::get_material() const{ - VS::get_singleton()->canvas_item_set_shader_param(canvas_item,p_param,p_value); + return material; } -Variant CanvasItem::get_shader_param(const StringName& p_param) const { - - return VS::get_singleton()->canvas_item_get_shader_param(canvas_item,p_param); -} - -bool CanvasItem::_set(const StringName& p_name, const Variant& p_value) { - - if (shader.is_valid()) { - StringName pr = shader->remap_param(p_name); - if (pr) { - set_shader_param(pr,p_value); - return true; - } - } - return false; -} -bool CanvasItem::_get(const StringName& p_name,Variant &r_ret) const{ - if (shader.is_valid()) { - StringName pr = shader->remap_param(p_name); - if (pr) { - r_ret=get_shader_param(pr); - return true; - } - } - return false; - -} -void CanvasItem::_get_property_list( List *p_list) const{ - - if (shader.is_valid()) { - shader->get_param_list(p_list); - } -} - -#ifdef TOOLS_ENABLED -void CanvasItem::_shader_changed() { - - _change_notify(); -} -#endif - -void CanvasItem::get_argument_options(const StringName& p_function,int p_idx,List*r_options) const { - - if (p_idx==0 && shader.is_valid() && (p_function.operator String()=="get_shader_param" || p_function.operator String()=="set_shader_param")) { - - List pl; - shader->get_param_list(&pl); - for(List::Element *E=pl.front();E;E=E->next()) { - r_options->push_back("\""+E->get().name.replace_first("shader_param/","")+"\""); - } - - return; - } - - Node::get_argument_options(p_function,p_idx,r_options); -} void CanvasItem::_bind_methods() { @@ -880,9 +990,6 @@ void CanvasItem::_bind_methods() { ObjectTypeDB::bind_method(_MD("_set_on_top","on_top"),&CanvasItem::_set_on_top); ObjectTypeDB::bind_method(_MD("_is_on_top"),&CanvasItem::_is_on_top); -#ifdef TOOLS_ENABLED - ObjectTypeDB::bind_method(_MD("_shader_changed"),&CanvasItem::_shader_changed); -#endif //ObjectTypeDB::bind_method(_MD("get_transform"),&CanvasItem::get_transform); ObjectTypeDB::bind_method(_MD("draw_line","from","to","color","width"),&CanvasItem::draw_line,DEFVAL(1.0)); @@ -901,20 +1008,18 @@ void CanvasItem::_bind_methods() { ObjectTypeDB::bind_method(_MD("draw_set_transform","pos","rot","scale"),&CanvasItem::draw_set_transform); ObjectTypeDB::bind_method(_MD("get_transform"),&CanvasItem::get_transform); ObjectTypeDB::bind_method(_MD("get_global_transform"),&CanvasItem::get_global_transform); + ObjectTypeDB::bind_method(_MD("get_global_transform_with_canvas"),&CanvasItem::get_global_transform_with_canvas); ObjectTypeDB::bind_method(_MD("get_viewport_transform"),&CanvasItem::get_viewport_transform); ObjectTypeDB::bind_method(_MD("get_viewport_rect"),&CanvasItem::get_viewport_rect); ObjectTypeDB::bind_method(_MD("get_canvas"),&CanvasItem::get_canvas); ObjectTypeDB::bind_method(_MD("get_world_2d"),&CanvasItem::get_world_2d); //ObjectTypeDB::bind_method(_MD("get_viewport"),&CanvasItem::get_viewport); - ObjectTypeDB::bind_method(_MD("set_shader","shader"),&CanvasItem::set_shader); - ObjectTypeDB::bind_method(_MD("get_shader"),&CanvasItem::get_shader); - ObjectTypeDB::bind_method(_MD("set_use_parent_shader","enable"),&CanvasItem::set_use_parent_shader); - ObjectTypeDB::bind_method(_MD("get_use_parent_shader"),&CanvasItem::get_use_parent_shader); - - ObjectTypeDB::bind_method(_MD("set_shader_param","param","value"),&CanvasItem::set_shader_param); - ObjectTypeDB::bind_method(_MD("get_shader_param","param"),&CanvasItem::get_shader_param); + ObjectTypeDB::bind_method(_MD("set_material","material:CanvasItemMaterial"),&CanvasItem::set_material); + ObjectTypeDB::bind_method(_MD("get_material:CanvasItemMaterial"),&CanvasItem::get_material); + ObjectTypeDB::bind_method(_MD("set_use_parent_material","enable"),&CanvasItem::set_use_parent_material); + ObjectTypeDB::bind_method(_MD("get_use_parent_material"),&CanvasItem::get_use_parent_material); BIND_VMETHOD(MethodInfo("_draw")); @@ -926,8 +1031,8 @@ void CanvasItem::_bind_methods() { ADD_PROPERTYNZ( PropertyInfo(Variant::INT,"visibility/blend_mode",PROPERTY_HINT_ENUM, "Mix,Add,Sub,Mul,PMAlpha"), _SCS("set_blend_mode"),_SCS("get_blend_mode") ); ADD_PROPERTYNZ( PropertyInfo(Variant::INT,"visibility/light_mask",PROPERTY_HINT_ALL_FLAGS), _SCS("set_light_mask"),_SCS("get_light_mask") ); - ADD_PROPERTYNZ( PropertyInfo(Variant::OBJECT,"shader/shader",PROPERTY_HINT_RESOURCE_TYPE, "CanvasItemShader,CanvasItemShaderGraph"), _SCS("set_shader"),_SCS("get_shader") ); - ADD_PROPERTYNZ( PropertyInfo(Variant::BOOL,"shader/use_parent"), _SCS("set_use_parent_shader"),_SCS("get_use_parent_shader") ); + ADD_PROPERTYNZ( PropertyInfo(Variant::OBJECT,"material/material",PROPERTY_HINT_RESOURCE_TYPE, "CanvasItemMaterial"), _SCS("set_material"),_SCS("get_material") ); + ADD_PROPERTYNZ( PropertyInfo(Variant::BOOL,"material/use_parent"), _SCS("set_use_parent_material"),_SCS("get_use_parent_material") ); //exporting these two things doesn't really make much sense i think //ADD_PROPERTY( PropertyInfo(Variant::BOOL,"transform/toplevel"), _SCS("set_as_toplevel"),_SCS("is_set_as_toplevel") ); //ADD_PROPERTY(PropertyInfo(Variant::BOOL,"transform/notify"),_SCS("set_transform_notify"),_SCS("is_transform_notify_enabled")); @@ -1004,7 +1109,7 @@ CanvasItem::CanvasItem() : xform_change(this) { block_transform_notify=false; // viewport=NULL; canvas_layer=NULL; - use_parent_shader=false; + use_parent_material=false; global_invalid=true; light_mask=1; diff --git a/scene/2d/canvas_item.h b/scene/2d/canvas_item.h index 2441d205ce..0c7be261ab 100644 --- a/scene/2d/canvas_item.h +++ b/scene/2d/canvas_item.h @@ -40,6 +40,41 @@ class Font; class StyleBox; +class CanvasItemMaterial : public Resource{ + + OBJ_TYPE(CanvasItemMaterial,Resource); + RID material; + Ref shader; + bool unshaded; + +protected: + + bool _set(const StringName& p_name, const Variant& p_value); + bool _get(const StringName& p_name,Variant &r_ret) const; + void _get_property_list( List *p_list) const; + + void _shader_changed(); + static void _bind_methods(); + + void get_argument_options(const StringName& p_function,int p_idx,List*r_options) const; + +public: + + void set_shader(const Ref& p_shader); + Ref get_shader() const; + + void set_shader_param(const StringName& p_param,const Variant& p_value); + Variant get_shader_param(const StringName& p_param) const; + + void set_unshaded(bool p_unshaded); + bool is_unshaded() const; + + virtual RID get_rid() const; + CanvasItemMaterial(); + ~CanvasItemMaterial(); +}; + + class CanvasItem : public Node { OBJ_TYPE( CanvasItem, Node ); @@ -81,9 +116,9 @@ private: bool drawing; bool block_transform_notify; bool behind; - bool use_parent_shader; + bool use_parent_material; - Ref shader; + Ref material; mutable Matrix32 global_transform; mutable bool global_invalid; @@ -104,9 +139,6 @@ private: void _queue_sort_children(); void _sort_children(); -#ifdef TOOLS_ENABLED - void _shader_changed(); -#endif void _notify_transform(CanvasItem *p_node); void _set_on_top(bool p_on_top) { set_draw_behind_parent(!p_on_top); } @@ -114,11 +146,6 @@ private: protected: - bool _set(const StringName& p_name, const Variant& p_value); - bool _get(const StringName& p_name,Variant &r_ret) const; - void _get_property_list( List *p_list) const; - - _FORCE_INLINE_ void _notify_transform() { if (!is_inside_tree()) return; _notify_transform(this); if (!block_transform_notify) notification(NOTIFICATION_LOCAL_TRANSFORM_CHANGED); } void item_rect_changed(); @@ -216,16 +243,12 @@ public: RID get_canvas() const; Ref get_world_2d() const; - void set_shader(const Ref& p_shader); - Ref get_shader() const; + void set_material(const Ref& p_material); + Ref get_material() const; - void set_use_parent_shader(bool p_use_parent_shader); - bool get_use_parent_shader() const; + void set_use_parent_material(bool p_use_parent_material); + bool get_use_parent_material() const; - void set_shader_param(const StringName& p_param,const Variant& p_value); - Variant get_shader_param(const StringName& p_param) const; - - void get_argument_options(const StringName& p_function,int p_idx,List*r_options) const; CanvasItem(); ~CanvasItem(); diff --git a/scene/2d/light_2d.cpp b/scene/2d/light_2d.cpp index cea8c06d3f..93be0c397f 100644 --- a/scene/2d/light_2d.cpp +++ b/scene/2d/light_2d.cpp @@ -170,6 +170,29 @@ bool Light2D::is_shadow_enabled() const { return shadow; } +void Light2D::set_shadow_buffer_size( int p_size ) { + + shadow_buffer_size=p_size; + VS::get_singleton()->canvas_light_set_shadow_buffer_size(canvas_light,shadow_buffer_size); +} + +int Light2D::get_shadow_buffer_size() const { + + return shadow_buffer_size; +} + +void Light2D::set_shadow_esm_multiplier( float p_multiplier) { + + shadow_esm_multiplier=p_multiplier; + VS::get_singleton()->canvas_light_set_shadow_esm_multiplier(canvas_light,p_multiplier); +} + +float Light2D::get_shadow_esm_multiplier() const{ + + return shadow_esm_multiplier; +} + + void Light2D::_notification(int p_what) { if (p_what==NOTIFICATION_ENTER_TREE) { @@ -229,18 +252,26 @@ void Light2D::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_shadow_enabled","enabled"),&Light2D::set_shadow_enabled); ObjectTypeDB::bind_method(_MD("is_shadow_enabled"),&Light2D::is_shadow_enabled); + ObjectTypeDB::bind_method(_MD("set_shadow_buffer_size","size"),&Light2D::set_shadow_buffer_size); + ObjectTypeDB::bind_method(_MD("get_shadow_buffer_size"),&Light2D::get_shadow_buffer_size); + + ObjectTypeDB::bind_method(_MD("set_shadow_esm_multiplier","multiplier"),&Light2D::set_shadow_esm_multiplier); + ObjectTypeDB::bind_method(_MD("get_shadow_esm_multiplier"),&Light2D::get_shadow_esm_multiplier); + ADD_PROPERTY( PropertyInfo(Variant::BOOL,"enabled"),_SCS("set_enabled"),_SCS("is_enabled")); ADD_PROPERTY( PropertyInfo(Variant::OBJECT,"texture",PROPERTY_HINT_RESOURCE_TYPE,"Texture"),_SCS("set_texture"),_SCS("get_texture")); - ADD_PROPERTY( PropertyInfo(Variant::VECTOR2,"texture_offset"),_SCS("set_texture_offset"),_SCS("get_texture_offset")); + ADD_PROPERTY( PropertyInfo(Variant::VECTOR2,"offset"),_SCS("set_texture_offset"),_SCS("get_texture_offset")); ADD_PROPERTY( PropertyInfo(Variant::COLOR,"color"),_SCS("set_color"),_SCS("get_color")); - ADD_PROPERTY( PropertyInfo(Variant::REAL,"height"),_SCS("set_height"),_SCS("get_height")); - ADD_PROPERTY( PropertyInfo(Variant::INT,"z_range_min",PROPERTY_HINT_RANGE,itos(VS::CANVAS_ITEM_Z_MIN)+","+itos(VS::CANVAS_ITEM_Z_MAX)+",1"),_SCS("set_z_range_min"),_SCS("get_z_range_min")); - ADD_PROPERTY( PropertyInfo(Variant::INT,"z_range_max",PROPERTY_HINT_RANGE,itos(VS::CANVAS_ITEM_Z_MIN)+","+itos(VS::CANVAS_ITEM_Z_MAX)+",1"),_SCS("set_z_range_max"),_SCS("get_z_range_max")); - ADD_PROPERTY( PropertyInfo(Variant::INT,"layer_range_min",PROPERTY_HINT_RANGE,"-512,512,1"),_SCS("set_layer_range_min"),_SCS("get_layer_range_min")); - ADD_PROPERTY( PropertyInfo(Variant::INT,"layer_range_max",PROPERTY_HINT_RANGE,"-512,512,1"),_SCS("set_layer_range_max"),_SCS("get_layer_range_max")); - ADD_PROPERTY( PropertyInfo(Variant::INT,"item_mask",PROPERTY_HINT_ALL_FLAGS),_SCS("set_item_mask"),_SCS("get_item_mask")); ADD_PROPERTY( PropertyInfo(Variant::BOOL,"subtract"),_SCS("set_subtract_mode"),_SCS("get_subtract_mode")); - ADD_PROPERTY( PropertyInfo(Variant::BOOL,"shadow_enabled"),_SCS("set_shadow_enabled"),_SCS("is_shadow_enabled")); + ADD_PROPERTY( PropertyInfo(Variant::REAL,"range/height"),_SCS("set_height"),_SCS("get_height")); + ADD_PROPERTY( PropertyInfo(Variant::INT,"range/z_min",PROPERTY_HINT_RANGE,itos(VS::CANVAS_ITEM_Z_MIN)+","+itos(VS::CANVAS_ITEM_Z_MAX)+",1"),_SCS("set_z_range_min"),_SCS("get_z_range_min")); + ADD_PROPERTY( PropertyInfo(Variant::INT,"range/z_max",PROPERTY_HINT_RANGE,itos(VS::CANVAS_ITEM_Z_MIN)+","+itos(VS::CANVAS_ITEM_Z_MAX)+",1"),_SCS("set_z_range_max"),_SCS("get_z_range_max")); + ADD_PROPERTY( PropertyInfo(Variant::INT,"range/layer_min",PROPERTY_HINT_RANGE,"-512,512,1"),_SCS("set_layer_range_min"),_SCS("get_layer_range_min")); + ADD_PROPERTY( PropertyInfo(Variant::INT,"range/layer_max",PROPERTY_HINT_RANGE,"-512,512,1"),_SCS("set_layer_range_max"),_SCS("get_layer_range_max")); + ADD_PROPERTY( PropertyInfo(Variant::INT,"range/item_mask",PROPERTY_HINT_ALL_FLAGS),_SCS("set_item_mask"),_SCS("get_item_mask")); + ADD_PROPERTY( PropertyInfo(Variant::BOOL,"shadow/enabled"),_SCS("set_shadow_enabled"),_SCS("is_shadow_enabled")); + ADD_PROPERTY( PropertyInfo(Variant::INT,"shadow/buffer_size",PROPERTY_HINT_RANGE,"32,16384,1"),_SCS("set_shadow_buffer_size"),_SCS("get_shadow_buffer_size")); + ADD_PROPERTY( PropertyInfo(Variant::REAL,"shadow/esm_multiplier",PROPERTY_HINT_RANGE,"1,4096,0.1"),_SCS("set_shadow_esm_multiplier"),_SCS("get_shadow_esm_multiplier")); } @@ -258,6 +289,8 @@ Light2D::Light2D() { layer_max=0; item_mask=1; subtract_mode=false; + shadow_buffer_size=2048; + shadow_esm_multiplier=80; } diff --git a/scene/2d/light_2d.h b/scene/2d/light_2d.h index dbfd233d39..89f351c3cd 100644 --- a/scene/2d/light_2d.h +++ b/scene/2d/light_2d.h @@ -17,6 +17,8 @@ private: int layer_min; int layer_max; int item_mask; + int shadow_buffer_size; + float shadow_esm_multiplier; bool subtract_mode; Ref texture; Vector2 texture_offset; @@ -68,6 +70,12 @@ public: void set_shadow_enabled( bool p_enabled); bool is_shadow_enabled() const; + void set_shadow_buffer_size( int p_size ); + int get_shadow_buffer_size() const; + + void set_shadow_esm_multiplier( float p_multiplier); + float get_shadow_esm_multiplier() const; + virtual Rect2 get_item_rect() const; Light2D(); diff --git a/scene/2d/light_occluder_2d.cpp b/scene/2d/light_occluder_2d.cpp new file mode 100644 index 0000000000..186ea2e248 --- /dev/null +++ b/scene/2d/light_occluder_2d.cpp @@ -0,0 +1,201 @@ +#include "light_occluder_2d.h" + + +void OccluderPolygon2D::set_polygon(const DVector& p_polygon) { + + polygon=p_polygon; + VS::get_singleton()->canvas_occluder_polygon_set_shape(occ_polygon,p_polygon,closed); + emit_changed(); +} + +DVector OccluderPolygon2D::get_polygon() const{ + + return polygon; +} + +void OccluderPolygon2D::set_closed(bool p_closed) { + + if (closed==p_closed) + return; + closed=p_closed; + VS::get_singleton()->canvas_occluder_polygon_set_shape(occ_polygon,polygon,closed); + emit_changed(); +} + +bool OccluderPolygon2D::is_closed() const{ + + return closed; +} + +void OccluderPolygon2D::set_cull_mode(CullMode p_mode){ + + cull=p_mode; + VS::get_singleton()->canvas_occluder_polygon_set_cull_mode(occ_polygon,VS::CanvasOccluderPolygonCullMode(p_mode)); +} + +OccluderPolygon2D::CullMode OccluderPolygon2D::get_cull_mode() const{ + + return cull; +} + + +RID OccluderPolygon2D::get_rid() const { + + return occ_polygon; +} + +void OccluderPolygon2D::_bind_methods() { + + + ObjectTypeDB::bind_method(_MD("set_closed","closed"),&OccluderPolygon2D::set_closed); + ObjectTypeDB::bind_method(_MD("is_closed"),&OccluderPolygon2D::is_closed); + + ObjectTypeDB::bind_method(_MD("set_cull_mode","cull_mode"),&OccluderPolygon2D::set_cull_mode); + ObjectTypeDB::bind_method(_MD("get_cull_mode"),&OccluderPolygon2D::get_cull_mode); + + ObjectTypeDB::bind_method(_MD("set_polygon","polygon"),&OccluderPolygon2D::set_polygon); + ObjectTypeDB::bind_method(_MD("get_polygon"),&OccluderPolygon2D::get_polygon); + + ADD_PROPERTY( PropertyInfo(Variant::VECTOR2_ARRAY,"polygon"),_SCS("set_polygon"),_SCS("get_polygon")); + ADD_PROPERTY( PropertyInfo(Variant::BOOL,"closed"),_SCS("set_closed"),_SCS("is_closed")); + ADD_PROPERTY( PropertyInfo(Variant::INT,"cull_mode",PROPERTY_HINT_ENUM,"Disabled,ClockWise,CounterClockWise"),_SCS("set_cull_mode"),_SCS("get_cull_mode")); + + BIND_CONSTANT(CULL_DISABLED); + BIND_CONSTANT(CULL_CLOCKWISE); + BIND_CONSTANT(CULL_COUNTER_CLOCKWISE); +} + + +OccluderPolygon2D::OccluderPolygon2D() { + + occ_polygon=VS::get_singleton()->canvas_occluder_polygon_create(); + closed=true; + cull=CULL_DISABLED; +} + +OccluderPolygon2D::~OccluderPolygon2D() { + + VS::get_singleton()->free(occ_polygon); +} + +#ifdef DEBUG_ENABLED +void LightOccluder2D::_poly_changed() { + + update(); +} +#endif + + +void LightOccluder2D::_notification(int p_what) { + + if (p_what==NOTIFICATION_ENTER_CANVAS) { + + VS::get_singleton()->canvas_light_occluder_attach_to_canvas(occluder,get_canvas()); + VS::get_singleton()->canvas_light_occluder_set_transform(occluder,get_global_transform()); + + } + if (p_what==NOTIFICATION_TRANSFORM_CHANGED) { + + VS::get_singleton()->canvas_light_occluder_set_transform(occluder,get_global_transform()); + } + + if (p_what==NOTIFICATION_DRAW) { + + if (get_tree()->is_editor_hint()) { + + if (occluder_polygon.is_valid()) { + + DVector poly = occluder_polygon->get_polygon(); + + if (poly.size()) { + if (occluder_polygon->is_closed()) { + Vector color; + color.push_back(Color(0,0,0,0.6)); + draw_polygon(Variant(poly),color); + } else { + + int ps=poly.size(); + DVector::Read r = poly.read(); + for(int i=0;icanvas_light_occluder_attach_to_canvas(occluder,RID()); + } + + +} + +void LightOccluder2D::set_occluder_polygon(const Ref& p_polygon) { + +#ifdef DEBUG_ENABLED + if (occluder_polygon.is_valid()) + occluder_polygon->disconnect("changed",this,"_poly_changed"); +#endif + occluder_polygon=p_polygon; + + if (occluder_polygon.is_valid()) + VS::get_singleton()->canvas_light_occluder_set_polygon(occluder,occluder_polygon->get_rid()); + else + VS::get_singleton()->canvas_light_occluder_set_polygon(occluder,RID()); + +#ifdef DEBUG_ENABLED + if (occluder_polygon.is_valid()) + occluder_polygon->connect("changed",this,"_poly_changed"); + update(); +#endif + +} + +Ref LightOccluder2D::get_occluder_polygon() const { + + return occluder_polygon; +} + +void LightOccluder2D::set_occluder_light_mask(int p_mask) { + + mask=p_mask; + VS::get_singleton()->canvas_light_occluder_set_light_mask(occluder,mask); +} + +int LightOccluder2D::get_occluder_light_mask() const{ + + return mask; +} + +void LightOccluder2D::_bind_methods() { + + ObjectTypeDB::bind_method(_MD("set_occluder_polygon","polygon:OccluderPolygon2D"),&LightOccluder2D::set_occluder_polygon); + ObjectTypeDB::bind_method(_MD("get_occluder_polygon:OccluderPolygon2D"),&LightOccluder2D::get_occluder_polygon); + + ObjectTypeDB::bind_method(_MD("set_occluder_light_mask","mask"),&LightOccluder2D::set_occluder_light_mask); + ObjectTypeDB::bind_method(_MD("get_occluder_light_mask"),&LightOccluder2D::get_occluder_light_mask); + +#ifdef DEBUG_ENABLED + ObjectTypeDB::bind_method("_poly_changed",&LightOccluder2D::_poly_changed); +#endif + + ADD_PROPERTY( PropertyInfo(Variant::OBJECT,"occluder",PROPERTY_HINT_RESOURCE_TYPE,"OccluderPolygon2D"),_SCS("set_occluder_polygon"),_SCS("get_occluder_polygon")); + ADD_PROPERTY( PropertyInfo(Variant::INT,"light_mask",PROPERTY_HINT_ALL_FLAGS),_SCS("set_occluder_light_mask"),_SCS("get_occluder_light_mask")); +} + +LightOccluder2D::LightOccluder2D() { + + occluder=VS::get_singleton()->canvas_light_occluder_create(); + mask=1; +} + +LightOccluder2D::~LightOccluder2D() { + + VS::get_singleton()->free(occluder); +} + diff --git a/scene/2d/light_occluder_2d.h b/scene/2d/light_occluder_2d.h new file mode 100644 index 0000000000..0343e3697e --- /dev/null +++ b/scene/2d/light_occluder_2d.h @@ -0,0 +1,73 @@ +#ifndef LIGHTOCCLUDER2D_H +#define LIGHTOCCLUDER2D_H + +#include "scene/2d/node_2d.h" + +class OccluderPolygon2D : public Resource { + + OBJ_TYPE(OccluderPolygon2D,Resource); +public: + + enum CullMode { + CULL_DISABLED, + CULL_CLOCKWISE, + CULL_COUNTER_CLOCKWISE + }; +private: + + + RID occ_polygon; + DVector polygon; + bool closed; + CullMode cull; + +protected: + + static void _bind_methods(); +public: + + void set_polygon(const DVector& p_polygon); + DVector get_polygon() const; + + void set_closed(bool p_closed); + bool is_closed() const; + + void set_cull_mode(CullMode p_mode); + CullMode get_cull_mode() const; + + virtual RID get_rid() const; + OccluderPolygon2D(); + ~OccluderPolygon2D(); + +}; + +VARIANT_ENUM_CAST(OccluderPolygon2D::CullMode); + +class LightOccluder2D : public Node2D { + OBJ_TYPE(LightOccluder2D,Node2D); + + RID occluder; + bool enabled; + int mask; + Ref occluder_polygon; + +#ifdef DEBUG_ENABLED + void _poly_changed(); +#endif + +protected: + void _notification(int p_what); + static void _bind_methods(); +public: + + void set_occluder_polygon(const Ref& p_polygon); + Ref get_occluder_polygon() const; + + void set_occluder_light_mask(int p_mask); + int get_occluder_light_mask() const; + + LightOccluder2D(); + ~LightOccluder2D(); +}; + +#endif // LIGHTOCCLUDER2D_H diff --git a/scene/3d/camera.cpp b/scene/3d/camera.cpp index 95eafa0df4..1109139180 100644 --- a/scene/3d/camera.cpp +++ b/scene/3d/camera.cpp @@ -152,11 +152,11 @@ void Camera::_get_property_list( List *p_list) const { case PROJECTION_PERSPECTIVE: { - p_list->push_back( PropertyInfo( Variant::REAL, "fov" , PROPERTY_HINT_RANGE, "1,89,0.1",PROPERTY_USAGE_NOEDITOR) ); + p_list->push_back( PropertyInfo( Variant::REAL, "fov" , PROPERTY_HINT_RANGE, "1,179,0.1",PROPERTY_USAGE_NOEDITOR) ); if (keep_aspect==KEEP_WIDTH) - p_list->push_back( PropertyInfo( Variant::REAL, "fovx" , PROPERTY_HINT_RANGE, "1,89,0.1",PROPERTY_USAGE_EDITOR) ); + p_list->push_back( PropertyInfo( Variant::REAL, "fovx" , PROPERTY_HINT_RANGE, "1,179,0.1",PROPERTY_USAGE_EDITOR) ); else - p_list->push_back( PropertyInfo( Variant::REAL, "fovy" , PROPERTY_HINT_RANGE, "1,89,0.1",PROPERTY_USAGE_EDITOR) ); + p_list->push_back( PropertyInfo( Variant::REAL, "fovy" , PROPERTY_HINT_RANGE, "1,179,0.1",PROPERTY_USAGE_EDITOR) ); } break; diff --git a/scene/3d/visual_instance.cpp b/scene/3d/visual_instance.cpp index a82c69e67f..45c7fa912c 100644 --- a/scene/3d/visual_instance.cpp +++ b/scene/3d/visual_instance.cpp @@ -310,6 +310,17 @@ int GeometryInstance::get_baked_light_texture_id() const{ return baked_light_texture_id; } +void GeometryInstance::set_extra_cull_margin(float p_margin) { + + ERR_FAIL_COND(p_margin<0); + extra_cull_margin=p_margin; + VS::get_singleton()->instance_set_extra_visibility_margin(get_instance(),extra_cull_margin); +} + +float GeometryInstance::get_extra_cull_margin() const{ + + return extra_cull_margin; +} void GeometryInstance::_bind_methods() { @@ -328,6 +339,9 @@ void GeometryInstance::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_baked_light_texture_id","id"), &GeometryInstance::set_baked_light_texture_id); ObjectTypeDB::bind_method(_MD("get_baked_light_texture_id"), &GeometryInstance::get_baked_light_texture_id); + ObjectTypeDB::bind_method(_MD("set_extra_cull_margin","margin"), &GeometryInstance::set_extra_cull_margin); + ObjectTypeDB::bind_method(_MD("get_extra_cull_margin"), &GeometryInstance::get_extra_cull_margin); + ObjectTypeDB::bind_method(_MD("_baked_light_changed"), &GeometryInstance::_baked_light_changed); ADD_PROPERTYI( PropertyInfo( Variant::BOOL, "geometry/visible"), _SCS("set_flag"), _SCS("get_flag"),FLAG_VISIBLE); @@ -336,6 +350,7 @@ void GeometryInstance::_bind_methods() { ADD_PROPERTYI( PropertyInfo( Variant::BOOL, "geometry/receive_shadows"), _SCS("set_flag"), _SCS("get_flag"),FLAG_RECEIVE_SHADOWS); ADD_PROPERTY( PropertyInfo( Variant::INT, "geometry/range_begin",PROPERTY_HINT_RANGE,"0,32768,0.01"), _SCS("set_draw_range_begin"), _SCS("get_draw_range_begin")); ADD_PROPERTY( PropertyInfo( Variant::INT, "geometry/range_end",PROPERTY_HINT_RANGE,"0,32768,0.01"), _SCS("set_draw_range_end"), _SCS("get_draw_range_end")); + ADD_PROPERTY( PropertyInfo( Variant::REAL, "geometry/extra_cull_margin",PROPERTY_HINT_RANGE,"0,16384,0"), _SCS("set_extra_cull_margin"), _SCS("get_extra_cull_margin")); ADD_PROPERTYI( PropertyInfo( Variant::BOOL, "geometry/billboard"), _SCS("set_flag"), _SCS("get_flag"),FLAG_BILLBOARD); ADD_PROPERTYI( PropertyInfo( Variant::BOOL, "geometry/billboard_y"), _SCS("set_flag"), _SCS("get_flag"),FLAG_BILLBOARD_FIX_Y); ADD_PROPERTYI( PropertyInfo( Variant::BOOL, "geometry/depth_scale"), _SCS("set_flag"), _SCS("get_flag"),FLAG_DEPH_SCALE); diff --git a/scene/3d/visual_instance.h b/scene/3d/visual_instance.h index e9fefe1ba0..e08acbe9a2 100644 --- a/scene/3d/visual_instance.h +++ b/scene/3d/visual_instance.h @@ -108,6 +108,7 @@ private: void _find_baked_light(); BakedLightInstance *baked_light_instance; int baked_light_texture_id; + float extra_cull_margin; void _baked_light_changed(); void _update_visibility(); @@ -132,6 +133,9 @@ public: void set_baked_light_texture_id(int p_id); int get_baked_light_texture_id() const; + void set_extra_cull_margin(float p_margin); + float get_extra_cull_margin() const; + GeometryInstance(); }; diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp index ff525203bf..f90db42614 100644 --- a/scene/register_scene_types.cpp +++ b/scene/register_scene_types.cpp @@ -80,6 +80,7 @@ #include "scene/2d/particles_2d.h" #include "scene/2d/path_2d.h" #include "scene/2d/light_2d.h" +#include "scene/2d/light_occluder_2d.h" #include "scene/2d/canvas_item.h" #include "scene/2d/sprite.h" @@ -454,6 +455,7 @@ void register_scene_types() { //ObjectTypeDB::set_type_enabled("BodyVolumeCylinder",false); //ObjectTypeDB::set_type_enabled("BodyVolumeConvexPolygon",false); + ObjectTypeDB::register_type(); ObjectTypeDB::register_virtual_type(); ObjectTypeDB::register_type(); ObjectTypeDB::register_type(); @@ -476,6 +478,8 @@ void register_scene_types() { ObjectTypeDB::register_type(); ObjectTypeDB::register_type(); ObjectTypeDB::register_type(); + ObjectTypeDB::register_type(); + ObjectTypeDB::register_type(); ObjectTypeDB::register_type(); ObjectTypeDB::set_type_enabled("CollisionShape2D",false); diff --git a/scene/scene_string_names.cpp b/scene/scene_string_names.cpp index af5e6d4165..c30ff0044e 100644 --- a/scene/scene_string_names.cpp +++ b/scene/scene_string_names.cpp @@ -41,6 +41,7 @@ SceneStringNames::SceneStringNames() { visibility_changed=StaticCString::create("visibility_changed"); input_event=StaticCString::create("input_event"); shader_shader=StaticCString::create("shader/shader"); + shader_unshaded=StaticCString::create("shader/unshaded"); enter_tree=StaticCString::create("enter_tree"); exit_tree=StaticCString::create("exit_tree"); item_rect_changed=StaticCString::create("item_rect_changed"); diff --git a/scene/scene_string_names.h b/scene/scene_string_names.h index 14e5e83b8d..184cbe347b 100644 --- a/scene/scene_string_names.h +++ b/scene/scene_string_names.h @@ -56,6 +56,7 @@ public: StringName _input_event; StringName item_rect_changed; StringName shader_shader; + StringName shader_unshaded; StringName enter_tree; StringName exit_tree; StringName size_flags_changed; diff --git a/servers/visual/rasterizer.h b/servers/visual/rasterizer.h index 4c9d0491b1..62ab8b3c56 100644 --- a/servers/visual/rasterizer.h +++ b/servers/visual/rasterizer.h @@ -572,8 +572,8 @@ public: struct CanvasLight { + bool enabled; - bool shadow; Color color; Matrix32 xform; float height; @@ -586,21 +586,26 @@ public: RID texture; Vector2 texture_offset; RID canvas; + RID shadow_buffer; + int shadow_buffer_size; + float shadow_esm_mult; void *texture_cache; // implementation dependent Rect2 rect_cache; Matrix32 xform_cache; + float radius_cache; //used for shadow far plane + CameraMatrix shadow_matrix_cache; Matrix32 light_shader_xform; Vector2 light_shader_pos; + CanvasLight *shadows_next_ptr; CanvasLight *filter_next_ptr; CanvasLight *next_ptr; CanvasLight() { - enabled=true; - shadow=false; + enabled=true; color=Color(1,1,1); height=0; z_min=-1024; @@ -612,9 +617,24 @@ public: texture_cache=NULL; next_ptr=NULL; filter_next_ptr=NULL; + shadow_buffer_size=2048; + shadow_esm_mult=80; + } }; + struct CanvasItem; + + struct CanvasItemMaterial { + + RID shader; + Map shader_param; + uint32_t shader_version; + Set owners; + bool unshaded; + + CanvasItemMaterial() {unshaded=false; shader_version=0; } + }; struct CanvasItem { @@ -744,16 +764,14 @@ public: mutable bool rect_dirty; mutable Rect2 rect; CanvasItem*next; - RID shader; - Map shader_param; - uint32_t shader_version; + CanvasItemMaterial* material; float final_opacity; Matrix32 final_transform; Rect2 final_clip_rect; CanvasItem* final_clip_owner; - CanvasItem* shader_owner; + CanvasItem* material_owner; ViewportRender *vp_render; Rect2 global_rect_cache; @@ -881,8 +899,8 @@ public: return rect; } - void clear() { for (int i=0;i& p_lines)=0; + + + virtual RID canvas_light_shadow_buffer_create(int p_width)=0; + struct CanvasLightOccluderInstance { + + + bool enabled; + RID canvas; + RID polygon; + RID polygon_buffer; + Rect2 aabb_cache; + Matrix32 xform; + Matrix32 xform_cache; + int light_mask; + VS::CanvasOccluderPolygonCullMode cull_cache; + + CanvasLightOccluderInstance *next; + + CanvasLightOccluderInstance() { enabled=true; next=NULL; light_mask=1; cull_cache=VS::CANVAS_OCCLUDER_POLYGON_CULL_DISABLED; } + }; + + + + virtual void canvas_light_shadow_buffer_update(RID p_buffer, const Matrix32& p_light_xform, int p_light_mask,float p_near, float p_far, CanvasLightOccluderInstance* p_occluders, CameraMatrix *p_xform_cache)=0; /* ENVIRONMENT */ @@ -945,6 +992,8 @@ public: virtual bool is_environment(const RID& p_rid) const=0; virtual bool is_shader(const RID& p_rid) const=0; + virtual bool is_canvas_light_occluder(const RID& p_rid) const=0; + virtual void free(const RID& p_rid)=0; virtual void init()=0; diff --git a/servers/visual/visual_server_raster.cpp b/servers/visual/visual_server_raster.cpp index feb14d8a9d..3bcf0b8a3e 100644 --- a/servers/visual/visual_server_raster.cpp +++ b/servers/visual/visual_server_raster.cpp @@ -3765,55 +3765,32 @@ void VisualServerRaster::canvas_item_set_z_as_relative_to_parent(RID p_item, boo } -void VisualServerRaster::canvas_item_set_use_parent_shader(RID p_item, bool p_enable) { +void VisualServerRaster::canvas_item_set_use_parent_material(RID p_item, bool p_enable) { VS_CHANGED; CanvasItem *canvas_item = canvas_item_owner.get( p_item ); ERR_FAIL_COND(!canvas_item); - canvas_item->use_parent_shader=p_enable; + canvas_item->use_parent_material=p_enable; } -void VisualServerRaster::canvas_item_set_shader(RID p_item, RID p_shader) { +void VisualServerRaster::canvas_item_set_material(RID p_item, RID p_material) { VS_CHANGED; CanvasItem *canvas_item = canvas_item_owner.get( p_item ); ERR_FAIL_COND(!canvas_item); - canvas_item->shader=p_shader; -} - -RID VisualServerRaster::canvas_item_get_shader(RID p_item) const{ - - CanvasItem *canvas_item = canvas_item_owner.get( p_item ); - ERR_FAIL_COND_V(!canvas_item,RID()); - return canvas_item->shader; -} + if (canvas_item->material) + canvas_item->material->owners.erase(canvas_item); -void VisualServerRaster::canvas_item_set_shader_param(RID p_canvas_item, const StringName& p_param, const Variant& p_value){ + canvas_item->material=NULL; - VS_CHANGED; - CanvasItem *canvas_item = canvas_item_owner.get( p_canvas_item ); - ERR_FAIL_COND(!canvas_item); - if (p_value.get_type()==Variant::NIL) - canvas_item->shader_param.erase(p_param); - else - canvas_item->shader_param[p_param]=p_value; - -} -Variant VisualServerRaster::canvas_item_get_shader_param(RID p_canvas_item, const StringName& p_param) const{ - - CanvasItem *canvas_item = canvas_item_owner.get( p_canvas_item ); - ERR_FAIL_COND_V(!canvas_item,Variant()); - if (!canvas_item->shader_param.has(p_param)) { - ERR_FAIL_COND_V(!canvas_item->shader.is_valid(),Variant()); - return rasterizer->shader_get_default_param(canvas_item->shader,p_param); + if (canvas_item_material_owner.owns(p_material)) { + canvas_item->material=canvas_item_material_owner.get(p_material); + canvas_item->material->owners.insert(canvas_item); } - - return canvas_item->shader_param[p_param]; } - void VisualServerRaster::canvas_item_set_sort_children_by_y(RID p_item, bool p_enable) { VS_CHANGED; @@ -3989,19 +3966,41 @@ void VisualServerRaster::canvas_light_set_shadow_enabled(RID p_light, bool p_ena Rasterizer::CanvasLight *clight = canvas_light_owner.get(p_light); ERR_FAIL_COND(!clight); - clight->shadow=p_enabled; + + if (clight->shadow_buffer.is_valid()==p_enabled) + return; + if (p_enabled) { + clight->shadow_buffer=rasterizer->canvas_light_shadow_buffer_create(clight->shadow_buffer_size); + } else { + rasterizer->free(clight->shadow_buffer); + clight->shadow_buffer=RID(); + + } } + void VisualServerRaster::canvas_light_set_shadow_buffer_size(RID p_light, int p_size){ Rasterizer::CanvasLight *clight = canvas_light_owner.get(p_light); ERR_FAIL_COND(!clight); + ERR_FAIL_COND(p_size<32 || p_size>16384); + + clight->shadow_buffer_size=nearest_power_of_2(p_size); + + + if (clight->shadow_buffer.is_valid()) { + rasterizer->free(clight->shadow_buffer); + clight->shadow_buffer=rasterizer->canvas_light_shadow_buffer_create(clight->shadow_buffer_size); + } + } -void VisualServerRaster::canvas_light_set_shadow_filter(RID p_light, int p_size){ + +void VisualServerRaster::canvas_light_set_shadow_esm_multiplier(RID p_light, float p_multiplier) { Rasterizer::CanvasLight *clight = canvas_light_owner.get(p_light); ERR_FAIL_COND(!clight); + clight->shadow_esm_mult=p_multiplier; } @@ -4009,26 +4008,217 @@ void VisualServerRaster::canvas_light_set_shadow_filter(RID p_light, int p_size) RID VisualServerRaster::canvas_light_occluder_create() { - return RID(); + Rasterizer::CanvasLightOccluderInstance *occluder = memnew( Rasterizer::CanvasLightOccluderInstance ); + + return canvas_light_occluder_owner.make_rid( occluder ); + } void VisualServerRaster::canvas_light_occluder_attach_to_canvas(RID p_occluder,RID p_canvas) { + Rasterizer::CanvasLightOccluderInstance *occluder = canvas_light_occluder_owner.get(p_occluder); + ERR_FAIL_COND(!occluder); + + if (occluder->canvas.is_valid()) { + + Canvas *canvas = canvas_owner.get(occluder->canvas); + canvas->occluders.erase(occluder); + } + + if (!canvas_owner.owns(p_canvas)) + p_canvas=RID(); + + occluder->canvas=p_canvas; + if (occluder->canvas.is_valid()) { + + Canvas *canvas = canvas_owner.get(occluder->canvas); + canvas->occluders.insert(occluder); + } } void VisualServerRaster::canvas_light_occluder_set_enabled(RID p_occluder,bool p_enabled){ + Rasterizer::CanvasLightOccluderInstance *occluder = canvas_light_occluder_owner.get(p_occluder); + ERR_FAIL_COND(!occluder); + + occluder->enabled=p_enabled; } -void VisualServerRaster::canvas_light_occluder_set_shape(RID p_occluder,const DVector& p_shape){ +void VisualServerRaster::canvas_light_occluder_set_polygon(RID p_occluder,RID p_polygon) { + + Rasterizer::CanvasLightOccluderInstance *occluder = canvas_light_occluder_owner.get(p_occluder); + ERR_FAIL_COND(!occluder); + + if (occluder->polygon.is_valid()) { + CanvasLightOccluderPolygon *occluder_poly = canvas_light_occluder_polygon_owner.get(p_polygon); + if (occluder_poly) { + occluder_poly->owners.erase(occluder); + } + } + occluder->polygon=p_polygon; + occluder->polygon_buffer=RID(); + + if (occluder->polygon.is_valid()) { + CanvasLightOccluderPolygon *occluder_poly = canvas_light_occluder_polygon_owner.get(p_polygon); + if (!occluder_poly) + occluder->polygon=RID(); + ERR_FAIL_COND(!occluder_poly); + occluder_poly->owners.insert(occluder); + occluder->polygon_buffer=occluder_poly->occluder; + occluder->aabb_cache=occluder_poly->aabb; + occluder->cull_cache=occluder_poly->cull_mode; + } } + +void VisualServerRaster::canvas_light_occluder_set_transform(RID p_occluder,const Matrix32& p_xform) { + + Rasterizer::CanvasLightOccluderInstance *occluder = canvas_light_occluder_owner.get(p_occluder); + ERR_FAIL_COND(!occluder); + + occluder->xform=p_xform; + +} + +void VisualServerRaster::canvas_light_occluder_set_light_mask(RID p_occluder,int p_mask) { + + Rasterizer::CanvasLightOccluderInstance *occluder = canvas_light_occluder_owner.get(p_occluder); + ERR_FAIL_COND(!occluder); + + occluder->light_mask=p_mask; + +} + + +RID VisualServerRaster::canvas_occluder_polygon_create() { + + CanvasLightOccluderPolygon * occluder_poly = memnew( CanvasLightOccluderPolygon ); + occluder_poly->occluder=rasterizer->canvas_light_occluder_create(); + return canvas_light_occluder_polygon_owner.make_rid(occluder_poly); + +} + +void VisualServerRaster::canvas_occluder_polygon_set_shape(RID p_occluder_polygon, const DVector& p_shape, bool p_close){ + + if (p_shape.size()<3) { + canvas_occluder_polygon_set_shape_as_lines(p_occluder_polygon,p_shape); + return; + } + + DVector lines; + int lc = p_shape.size()*2; + + lines.resize(lc-(p_close?0:2)); + { + DVector::Write w = lines.write(); + DVector::Read r = p_shape.read(); + + int max=lc/2; + if (!p_close) { + max--; + } + for(int i=0;i& p_shape) { + + CanvasLightOccluderPolygon * occluder_poly = canvas_light_occluder_polygon_owner.get(p_occluder_polygon); + ERR_FAIL_COND(!occluder_poly); + ERR_FAIL_COND(p_shape.size()&1); + + int lc = p_shape.size(); + occluder_poly->aabb=Rect2(); + { + DVector::Read r = p_shape.read(); + for(int i=0;iaabb.pos=r[i]; + else + occluder_poly->aabb.expand_to(r[i]); + } + } + + rasterizer->canvas_light_occluder_set_polylines(occluder_poly->occluder,p_shape); + for( Set::Element *E=occluder_poly->owners.front();E;E=E->next()) { + E->get()->aabb_cache=occluder_poly->aabb; + } +} + +void VisualServerRaster::canvas_occluder_polygon_set_cull_mode(RID p_occluder_polygon,CanvasOccluderPolygonCullMode p_mode) { + + CanvasLightOccluderPolygon * occluder_poly = canvas_light_occluder_polygon_owner.get(p_occluder_polygon); + ERR_FAIL_COND(!occluder_poly); + occluder_poly->cull_mode=p_mode; + for( Set::Element *E=occluder_poly->owners.front();E;E=E->next()) { + E->get()->cull_cache=p_mode; + } + +} + +RID VisualServerRaster::canvas_item_material_create() { + + Rasterizer::CanvasItemMaterial *material = memnew( Rasterizer::CanvasItemMaterial ); + return canvas_item_material_owner.make_rid(material); + +} + +void VisualServerRaster::canvas_item_material_set_shader(RID p_material, RID p_shader){ + + VS_CHANGED; + Rasterizer::CanvasItemMaterial *material = canvas_item_material_owner.get( p_material ); + ERR_FAIL_COND(!material); + material->shader=p_shader; + +} +void VisualServerRaster::canvas_item_material_set_shader_param(RID p_material, const StringName& p_param, const Variant& p_value){ + + VS_CHANGED; + Rasterizer::CanvasItemMaterial *material = canvas_item_material_owner.get( p_material ); + ERR_FAIL_COND(!material); + if (p_value.get_type()==Variant::NIL) + material->shader_param.erase(p_param); + else + material->shader_param[p_param]=p_value; + + +} +Variant VisualServerRaster::canvas_item_material_get_shader_param(RID p_material, const StringName& p_param) const{ + Rasterizer::CanvasItemMaterial *material = canvas_item_material_owner.get( p_material ); + ERR_FAIL_COND_V(!material,Variant()); + if (!material->shader_param.has(p_param)) { + ERR_FAIL_COND_V(!material->shader.is_valid(),Variant()); + return rasterizer->shader_get_default_param(material->shader,p_param); + } + + return material->shader_param[p_param]; +} + +void VisualServerRaster::canvas_item_material_set_unshaded(RID p_material, bool p_unshaded){ + + VS_CHANGED; + Rasterizer::CanvasItemMaterial *material = canvas_item_material_owner.get( p_material ); + ERR_FAIL_COND(!material); + material->unshaded=p_unshaded; + +} + + /******** CANVAS *********/ @@ -4285,6 +4475,10 @@ void VisualServerRaster::free( RID p_rid ) { E->get()->canvas=RID(); } + for (Set::Element *E=canvas->occluders.front();E;E=E->next()) { + + E->get()->canvas=RID(); + } canvas_owner.free( p_rid ); @@ -4314,10 +4508,26 @@ void VisualServerRaster::free( RID p_rid ) { canvas_item->child_items[i]->parent=RID(); } + if (canvas_item->material) { + canvas_item->material->owners.erase(canvas_item); + } + canvas_item_owner.free( p_rid ); memdelete( canvas_item ); + } else if (canvas_item_material_owner.owns(p_rid)) { + + Rasterizer::CanvasItemMaterial *material = canvas_item_material_owner.get(p_rid); + ERR_FAIL_COND(!material); + for(Set::Element *E=material->owners.front();E;E=E->next()) { + + E->get()->material=NULL; + } + + canvas_item_material_owner.free(p_rid); + memdelete(material); + } else if (canvas_light_owner.owns(p_rid)) { Rasterizer::CanvasLight *canvas_light = canvas_light_owner.get(p_rid); @@ -4329,9 +4539,44 @@ void VisualServerRaster::free( RID p_rid ) { canvas->lights.erase(canvas_light); } + if (canvas_light->shadow_buffer.is_valid()) + rasterizer->free(canvas_light->shadow_buffer); + canvas_light_owner.free( p_rid ); memdelete( canvas_light ); + } else if (canvas_light_occluder_owner.owns(p_rid)) { + + Rasterizer::CanvasLightOccluderInstance *occluder = canvas_light_occluder_owner.get(p_rid); + ERR_FAIL_COND(!occluder); + + if (occluder->polygon.is_valid()) { + + CanvasLightOccluderPolygon *occluder_poly = canvas_light_occluder_polygon_owner.get(occluder->polygon); + if (occluder_poly) { + occluder_poly->owners.erase(occluder); + } + + } + + canvas_light_occluder_owner.free( p_rid ); + memdelete(occluder); + + } else if (canvas_light_occluder_polygon_owner.owns(p_rid)) { + + CanvasLightOccluderPolygon *occluder_poly = canvas_light_occluder_polygon_owner.get(p_rid); + ERR_FAIL_COND(!occluder_poly); + rasterizer->free(occluder_poly->occluder); + + while(occluder_poly->owners.size()) { + + occluder_poly->owners.front()->get()->polygon=RID(); + occluder_poly->owners.erase( occluder_poly->owners.front() ); + } + + canvas_light_occluder_polygon_owner.free( p_rid ); + memdelete(occluder_poly); + } else if (scenario_owner.owns(p_rid)) { Scenario *scenario=scenario_owner.get(p_rid); @@ -6410,7 +6655,7 @@ void VisualServerRaster::_render_canvas_item_viewport(VisualServer* p_self,void } -void VisualServerRaster::_render_canvas_item(CanvasItem *p_canvas_item,const Matrix32& p_transform,const Rect2& p_clip_rect, float p_opacity,int p_z,Rasterizer::CanvasItem **z_list,Rasterizer::CanvasItem **z_last_list,CanvasItem *p_canvas_clip,CanvasItem *p_shader_owner) { +void VisualServerRaster::_render_canvas_item(CanvasItem *p_canvas_item,const Matrix32& p_transform,const Rect2& p_clip_rect, float p_opacity,int p_z,Rasterizer::CanvasItem **z_list,Rasterizer::CanvasItem **z_last_list,CanvasItem *p_canvas_clip,CanvasItem *p_material_owner) { CanvasItem *ci = p_canvas_item; @@ -6455,11 +6700,11 @@ void VisualServerRaster::_render_canvas_item(CanvasItem *p_canvas_item,const Mat ci->vp_render=NULL; } - if (ci->use_parent_shader && p_shader_owner) - ci->shader_owner=p_shader_owner; + if (ci->use_parent_material && p_material_owner) + ci->material_owner=p_material_owner; else { - p_shader_owner=ci; - ci->shader_owner=NULL; + p_material_owner=ci; + ci->material_owner=NULL; } @@ -6493,7 +6738,7 @@ void VisualServerRaster::_render_canvas_item(CanvasItem *p_canvas_item,const Mat if (child_items[i]->ontop) continue; - _render_canvas_item(child_items[i],xform,p_clip_rect,opacity,p_z,z_list,z_last_list,(CanvasItem*)ci->final_clip_owner,p_shader_owner); + _render_canvas_item(child_items[i],xform,p_clip_rect,opacity,p_z,z_list,z_last_list,(CanvasItem*)ci->final_clip_owner,p_material_owner); } @@ -6524,7 +6769,7 @@ void VisualServerRaster::_render_canvas_item(CanvasItem *p_canvas_item,const Mat if (!child_items[i]->ontop) continue; - _render_canvas_item(child_items[i],xform,p_clip_rect,opacity,p_z,z_list,z_last_list,(CanvasItem*)ci->final_clip_owner,p_shader_owner); + _render_canvas_item(child_items[i],xform,p_clip_rect,opacity,p_z,z_list,z_last_list,(CanvasItem*)ci->final_clip_owner,p_material_owner); } } @@ -6658,6 +6903,8 @@ void VisualServerRaster::_draw_viewport(Viewport *p_viewport,int p_ofs_x, int p_ Rect2 clip_rect(0,0,viewport_rect.width,viewport_rect.height); Rasterizer::CanvasLight *lights=NULL; + Rasterizer::CanvasLight *lights_with_shadow=NULL; + Rect2 shadow_rect; for (Map::Element *E=p_viewport->canvas_map.front();E;E=E->next()) { @@ -6676,6 +6923,7 @@ void VisualServerRaster::_draw_viewport(Viewport *p_viewport,int p_ofs_x, int p_ cl->rect_cache=Rect2(-offset+cl->texture_offset,tsize); cl->xform_cache=xf * cl->xform; + if (clip_rect.intersects_transformed(cl->xform_cache,cl->rect_cache)) { cl->filter_next_ptr=lights; lights=cl; @@ -6685,16 +6933,55 @@ void VisualServerRaster::_draw_viewport(Viewport *p_viewport,int p_ofs_x, int p_ scale.elements[2]=cl->rect_cache.pos; cl->light_shader_xform = (cl->xform_cache * scale).affine_inverse(); cl->light_shader_pos=cl->xform_cache[2]; + if (cl->shadow_buffer.is_valid()) { + cl->shadows_next_ptr=lights_with_shadow; + if (lights_with_shadow==NULL) { + shadow_rect = cl->xform_cache.xform(cl->rect_cache); + } else { + shadow_rect=shadow_rect.merge( cl->xform_cache.xform(cl->rect_cache) ); + } + lights_with_shadow=cl; + cl->radius_cache=cl->rect_cache.size.length(); + + } } + } + } + + canvas_map[ Viewport::CanvasKey( E->key(), E->get().layer) ]=&E->get(); + } + + if (lights_with_shadow) { + //update shadows if any + + Rasterizer::CanvasLightOccluderInstance * occluders=NULL; + + //make list of occluders + for (Map::Element *E=p_viewport->canvas_map.front();E;E=E->next()) { + + Matrix32 xf = p_viewport->global_transform * E->get().transform; + for(Set::Element *F=E->get().canvas->occluders.front();F;F=F->next()) { + F->get()->xform_cache = xf * F->get()->xform; + if (shadow_rect.intersects_transformed(F->get()->xform_cache,F->get()->aabb_cache)) { + F->get()->next=occluders; + occluders=F->get(); + + } } } + //update the light shadowmaps with them + Rasterizer::CanvasLight *light=lights_with_shadow; + while(light) { - canvas_map[ Viewport::CanvasKey( E->key(), E->get().layer) ]=&E->get(); + rasterizer->canvas_light_shadow_buffer_update(light->shadow_buffer,light->xform_cache.affine_inverse(),light->item_mask,light->radius_cache/1000.0,light->radius_cache*1.1,occluders,&light->shadow_matrix_cache); + light=light->shadows_next_ptr; + } + rasterizer->set_viewport(viewport_rect); //must reset viewport afterwards } for (Map::Element *E=canvas_map.front();E;E=E->next()) { @@ -6719,6 +7006,8 @@ void VisualServerRaster::_draw_viewport(Viewport *p_viewport,int p_ofs_x, int p_ i++; } + + rasterizer->canvas_debug_viewport_shadows(lights_with_shadow); } //capture diff --git a/servers/visual/visual_server_raster.h b/servers/visual/visual_server_raster.h index 9b2b0c9c1a..b9a3f83364 100644 --- a/servers/visual/visual_server_raster.h +++ b/servers/visual/visual_server_raster.h @@ -371,7 +371,7 @@ class VisualServerRaster : public VisualServer { - + mutable RID_Owner canvas_item_material_owner; struct CanvasItem : public Rasterizer::CanvasItem { @@ -384,7 +384,7 @@ class VisualServerRaster : public VisualServer { bool sort_y; float opacity; float self_opacity; - bool use_parent_shader; + bool use_parent_material; Vector child_items; @@ -396,7 +396,7 @@ class VisualServerRaster : public VisualServer { opacity=1; self_opacity=1; sort_y=false; - use_parent_shader=false; + use_parent_material=false; z_relative=true; } }; @@ -410,6 +410,24 @@ class VisualServerRaster : public VisualServer { } }; + struct CanvasLightOccluder; + + struct CanvasLightOccluderPolygon { + + bool active; + Rect2 aabb; + CanvasOccluderPolygonCullMode cull_mode; + RID occluder; + Set owners; + + CanvasLightOccluderPolygon() { active=false; cull_mode=CANVAS_OCCLUDER_POLYGON_CULL_DISABLED; } + }; + + + RID_Owner canvas_light_occluder_polygon_owner; + + RID_Owner canvas_light_occluder_owner; + struct CanvasLight; struct Canvas { @@ -422,6 +440,7 @@ class VisualServerRaster : public VisualServer { }; Set lights; + Set occluders; Vector child_items; Color modulate; @@ -610,7 +629,7 @@ class VisualServerRaster : public VisualServer { void _render_camera(Viewport *p_viewport,Camera *p_camera, Scenario *p_scenario); static void _render_canvas_item_viewport(VisualServer* p_self,void *p_vp,const Rect2& p_rect); void _render_canvas_item_tree(CanvasItem *p_canvas_item, const Matrix32& p_transform, const Rect2& p_clip_rect, const Color &p_modulate, Rasterizer::CanvasLight *p_lights); - void _render_canvas_item(CanvasItem *p_canvas_item,const Matrix32& p_transform,const Rect2& p_clip_rect, float p_opacity,int p_z,Rasterizer::CanvasItem **z_list,Rasterizer::CanvasItem **z_last_list,CanvasItem *p_canvas_clip,CanvasItem *p_shader_owner); + void _render_canvas_item(CanvasItem *p_canvas_item, const Matrix32& p_transform, const Rect2& p_clip_rect, float p_opacity, int p_z, Rasterizer::CanvasItem **z_list, Rasterizer::CanvasItem **z_last_list, CanvasItem *p_canvas_clip, CanvasItem *p_material_owner); void _render_canvas(Canvas *p_canvas, const Matrix32 &p_transform, Rasterizer::CanvasLight *p_lights); Vector _camera_generate_endpoints(Instance *p_light,Camera *p_camera,float p_range_min, float p_range_max); Vector _camera_generate_orthogonal_planes(Instance *p_light,Camera *p_camera,float p_range_min, float p_range_max); @@ -1131,15 +1150,8 @@ public: virtual void canvas_item_set_z(RID p_item, int p_z); virtual void canvas_item_set_z_as_relative_to_parent(RID p_item, bool p_enable); - virtual void canvas_item_set_shader(RID p_item, RID p_shader); - virtual RID canvas_item_get_shader(RID p_item) const; - - virtual void canvas_item_set_use_parent_shader(RID p_item, bool p_enable); - - - - virtual void canvas_item_set_shader_param(RID p_canvas_item, const StringName& p_param, const Variant& p_value); - virtual Variant canvas_item_get_shader_param(RID p_canvas_item, const StringName& p_param) const; + virtual void canvas_item_set_material(RID p_item, RID p_material); + virtual void canvas_item_set_use_parent_material(RID p_item, bool p_enable); virtual RID canvas_light_create(); virtual void canvas_light_attach_to_canvas(RID p_light,RID p_canvas); @@ -1156,17 +1168,36 @@ public: virtual void canvas_light_set_subtract_mode(RID p_light, bool p_enable); virtual void canvas_light_set_shadow_enabled(RID p_light, bool p_enabled); virtual void canvas_light_set_shadow_buffer_size(RID p_light, int p_size); - virtual void canvas_light_set_shadow_filter(RID p_light, int p_size); + virtual void canvas_light_set_shadow_esm_multiplier(RID p_light, float p_multiplier); virtual RID canvas_light_occluder_create(); virtual void canvas_light_occluder_attach_to_canvas(RID p_occluder,RID p_canvas); virtual void canvas_light_occluder_set_enabled(RID p_occluder,bool p_enabled); - virtual void canvas_light_occluder_set_shape(RID p_occluder,const DVector& p_shape); + virtual void canvas_light_occluder_set_polygon(RID p_occluder,RID p_polygon); + virtual void canvas_light_occluder_set_transform(RID p_occluder,const Matrix32& p_xform); + virtual void canvas_light_occluder_set_light_mask(RID p_occluder,int p_mask); + + + virtual RID canvas_occluder_polygon_create(); + virtual void canvas_occluder_polygon_set_shape(RID p_occluder_polygon,const DVector& p_shape,bool p_close); + virtual void canvas_occluder_polygon_set_shape_as_lines(RID p_occluder_polygon,const DVector& p_shape); + virtual void canvas_occluder_polygon_set_cull_mode(RID p_occluder_polygon,CanvasOccluderPolygonCullMode p_mode); + + virtual void canvas_item_clear(RID p_item); virtual void canvas_item_raise(RID p_item); + /* CANVAS ITEM MATERIAL */ + + virtual RID canvas_item_material_create(); + virtual void canvas_item_material_set_shader(RID p_material, RID p_shader); + virtual void canvas_item_material_set_shader_param(RID p_material, const StringName& p_param, const Variant& p_value); + virtual Variant canvas_item_material_get_shader_param(RID p_material, const StringName& p_param) const; + virtual void canvas_item_material_set_unshaded(RID p_material, bool p_unshaded); + + /* CURSOR */ virtual void cursor_set_rotation(float p_rotation, int p_cursor = 0); // radians virtual void cursor_set_texture(RID p_texture, const Point2 &p_center_offset, int p_cursor=0); diff --git a/servers/visual/visual_server_wrap_mt.h b/servers/visual/visual_server_wrap_mt.h index 6c95b6ed58..1890f7b760 100644 --- a/servers/visual/visual_server_wrap_mt.h +++ b/servers/visual/visual_server_wrap_mt.h @@ -1139,14 +1139,9 @@ public: FUNC2(canvas_item_set_z,RID,int); FUNC2(canvas_item_set_z_as_relative_to_parent,RID,bool); - FUNC2(canvas_item_set_shader,RID, RID ); - FUNC1RC(RID,canvas_item_get_shader,RID ); + FUNC2(canvas_item_set_material,RID, RID ); - FUNC2(canvas_item_set_use_parent_shader,RID, bool ); - - - FUNC3(canvas_item_set_shader_param,RID,const StringName&,const Variant&); - FUNC2RC(Variant,canvas_item_get_shader_param,RID,const StringName&); + FUNC2(canvas_item_set_use_parent_material,RID, bool ); FUNC1(canvas_item_clear,RID); FUNC1(canvas_item_raise,RID); @@ -1167,14 +1162,31 @@ public: FUNC2(canvas_light_set_subtract_mode,RID,bool); FUNC2(canvas_light_set_shadow_enabled,RID,bool); FUNC2(canvas_light_set_shadow_buffer_size,RID,int); - FUNC2(canvas_light_set_shadow_filter,RID,int); + FUNC2(canvas_light_set_shadow_esm_multiplier,RID,float); + /* CANVAS OCCLUDER */ FUNC0R(RID,canvas_light_occluder_create); FUNC2(canvas_light_occluder_attach_to_canvas,RID,RID); FUNC2(canvas_light_occluder_set_enabled,RID,bool); - FUNC2(canvas_light_occluder_set_shape,RID,const DVector&); + FUNC2(canvas_light_occluder_set_polygon,RID,RID); + FUNC2(canvas_light_occluder_set_transform,RID,const Matrix32&); + FUNC2(canvas_light_occluder_set_light_mask,RID,int); + + + FUNC0R(RID,canvas_occluder_polygon_create); + FUNC3(canvas_occluder_polygon_set_shape,RID,const DVector&,bool); + FUNC2(canvas_occluder_polygon_set_shape_as_lines,RID,const DVector&); + FUNC2(canvas_occluder_polygon_set_cull_mode,RID,CanvasOccluderPolygonCullMode); + + /* CANVAS MATERIAL */ + + FUNC0R(RID,canvas_item_material_create); + FUNC2(canvas_item_material_set_shader,RID,RID); + FUNC3(canvas_item_material_set_shader_param,RID,const StringName&,const Variant&); + FUNC2RC(Variant,canvas_item_material_get_shader_param,RID,const StringName&); + FUNC2(canvas_item_material_set_unshaded,RID,bool); /* CURSOR */ FUNC2(cursor_set_rotation,float , int ); // radians diff --git a/servers/visual_server.h b/servers/visual_server.h index 37368e32f4..ccf6978ae3 100644 --- a/servers/visual_server.h +++ b/servers/visual_server.h @@ -998,13 +998,9 @@ public: virtual void canvas_item_clear(RID p_item)=0; virtual void canvas_item_raise(RID p_item)=0; - virtual void canvas_item_set_shader(RID p_item, RID p_shader)=0; - virtual RID canvas_item_get_shader(RID p_item) const=0; + virtual void canvas_item_set_material(RID p_item, RID p_material)=0; - virtual void canvas_item_set_use_parent_shader(RID p_item, bool p_enable)=0; - - virtual void canvas_item_set_shader_param(RID p_canvas_item, const StringName& p_param, const Variant& p_value)=0; - virtual Variant canvas_item_get_shader_param(RID p_canvas_item, const StringName& p_param) const=0; + virtual void canvas_item_set_use_parent_material(RID p_item, bool p_enable)=0; virtual RID canvas_light_create()=0; virtual void canvas_light_attach_to_canvas(RID p_light,RID p_canvas)=0; @@ -1021,13 +1017,34 @@ public: virtual void canvas_light_set_subtract_mode(RID p_light, bool p_enable)=0; virtual void canvas_light_set_shadow_enabled(RID p_light, bool p_enabled)=0; virtual void canvas_light_set_shadow_buffer_size(RID p_light, int p_size)=0; - virtual void canvas_light_set_shadow_filter(RID p_light, int p_size)=0; + virtual void canvas_light_set_shadow_esm_multiplier(RID p_light, float p_multiplier)=0; + virtual RID canvas_light_occluder_create()=0; virtual void canvas_light_occluder_attach_to_canvas(RID p_occluder,RID p_canvas)=0; virtual void canvas_light_occluder_set_enabled(RID p_occluder,bool p_enabled)=0; - virtual void canvas_light_occluder_set_shape(RID p_occluder,const DVector& p_shape)=0; + virtual void canvas_light_occluder_set_polygon(RID p_occluder,RID p_polygon)=0; + virtual void canvas_light_occluder_set_transform(RID p_occluder,const Matrix32& p_xform)=0; + virtual void canvas_light_occluder_set_light_mask(RID p_occluder,int p_mask)=0; + + virtual RID canvas_occluder_polygon_create()=0; + virtual void canvas_occluder_polygon_set_shape(RID p_occluder_polygon,const DVector& p_shape,bool p_closed)=0; + virtual void canvas_occluder_polygon_set_shape_as_lines(RID p_occluder_polygon,const DVector& p_shape)=0; + enum CanvasOccluderPolygonCullMode { + CANVAS_OCCLUDER_POLYGON_CULL_DISABLED, + CANVAS_OCCLUDER_POLYGON_CULL_CLOCKWISE, + CANVAS_OCCLUDER_POLYGON_CULL_COUNTER_CLOCKWISE, + }; + virtual void canvas_occluder_polygon_set_cull_mode(RID p_occluder_polygon,CanvasOccluderPolygonCullMode p_mode)=0; + + /* CANVAS ITEM MATERIAL */ + + virtual RID canvas_item_material_create()=0; + virtual void canvas_item_material_set_shader(RID p_material, RID p_shader)=0; + virtual void canvas_item_material_set_shader_param(RID p_material, const StringName& p_param, const Variant& p_value)=0; + virtual Variant canvas_item_material_get_shader_param(RID p_material, const StringName& p_param) const=0; + virtual void canvas_item_material_set_unshaded(RID p_material, bool p_unshaded)=0; /* CURSOR */ virtual void cursor_set_rotation(float p_rotation, int p_cursor = 0)=0; // radians diff --git a/tools/editor/editor_node.cpp b/tools/editor/editor_node.cpp index cc1a05f7d3..3d42867d9a 100644 --- a/tools/editor/editor_node.cpp +++ b/tools/editor/editor_node.cpp @@ -90,6 +90,7 @@ #include "plugins/baked_light_editor_plugin.h" #include "plugins/polygon_2d_editor_plugin.h" #include "plugins/navigation_polygon_editor_plugin.h" +#include "plugins/light_occluder_2d_editor_plugin.h" // end #include "tools/editor/io_plugins/editor_texture_import_plugin.h" #include "tools/editor/io_plugins/editor_scene_import_plugin.h" @@ -4115,6 +4116,7 @@ EditorNode::EditorNode() { add_editor_plugin( memnew( PathEditorPlugin(this) ) ); add_editor_plugin( memnew( BakedLightEditorPlugin(this) ) ); add_editor_plugin( memnew( Polygon2DEditorPlugin(this) ) ); + add_editor_plugin( memnew( LightOccluder2DEditorPlugin(this) ) ); add_editor_plugin( memnew( NavigationPolygonEditorPlugin(this) ) ); for(int i=0;iset_icon( get_icon("Edit","EditorIcons")); + button_edit->set_icon( get_icon("MovePoint","EditorIcons")); + button_edit->set_pressed(true); + get_tree()->connect("node_removed",this,"_node_removed"); + create_poly->connect("confirmed",this,"_create_poly"); + + } break; + case NOTIFICATION_FIXED_PROCESS: { + + + } break; + } + +} +void LightOccluder2DEditor::_node_removed(Node *p_node) { + + if(p_node==node) { + node=NULL; + hide(); + canvas_item_editor->get_viewport_control()->update(); + } + +} + + +Vector2 LightOccluder2DEditor::snap_point(const Vector2& p_point) const { + + if (canvas_item_editor->is_snap_active()) { + + return p_point.snapped(Vector2(1,1)*canvas_item_editor->get_snap()); + + } else { + return p_point; + } +} + +void LightOccluder2DEditor::_menu_option(int p_option) { + + switch(p_option) { + + case MODE_CREATE: { + + mode=MODE_CREATE; + button_create->set_pressed(true); + button_edit->set_pressed(false); + } break; + case MODE_EDIT: { + + mode=MODE_EDIT; + button_create->set_pressed(false); + button_edit->set_pressed(true); + } break; + + } +} + +void LightOccluder2DEditor::_wip_close(bool p_closed) { + + undo_redo->create_action("Create Poly"); + undo_redo->add_undo_method(node->get_occluder_polygon().ptr(),"set_polygon",node->get_occluder_polygon()->get_polygon()); + undo_redo->add_do_method(node->get_occluder_polygon().ptr(),"set_polygon",wip); + undo_redo->add_undo_method(node->get_occluder_polygon().ptr(),"set_closed",node->get_occluder_polygon()->is_closed()); + undo_redo->add_do_method(node->get_occluder_polygon().ptr(),"set_closed",p_closed); + + undo_redo->add_do_method(canvas_item_editor->get_viewport_control(),"update"); + undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(),"update"); + undo_redo->commit_action(); + wip.clear(); + wip_active=false; + mode=MODE_EDIT; + button_edit->set_pressed(true); + button_create->set_pressed(false); + edited_point=-1; +} + +bool LightOccluder2DEditor::forward_input_event(const InputEvent& p_event) { + + + if (!node) + return false; + + if (node->get_occluder_polygon().is_null()) { + if (p_event.type==InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index==1 && p_event.mouse_button.pressed) { + create_poly->set_text("No OccluderPolygon2D resource on this node.\nCreate and assign one?"); + create_poly->popup_centered_minsize(); + } + return false; + } + switch(p_event.type) { + + case InputEvent::MOUSE_BUTTON: { + + const InputEventMouseButton &mb=p_event.mouse_button; + + Matrix32 xform = canvas_item_editor->get_canvas_transform() * node->get_global_transform(); + + + Vector2 gpoint = Point2(mb.x,mb.y); + Vector2 cpoint = canvas_item_editor->get_canvas_transform().affine_inverse().xform(gpoint); + cpoint=snap_point(cpoint); + cpoint = node->get_global_transform().affine_inverse().xform(cpoint); + + Vector poly = Variant(node->get_occluder_polygon()->get_polygon()); + + //first check if a point is to be added (segment split) + real_t grab_treshold=EDITOR_DEF("poly_editor/point_grab_radius",8); + + switch(mode) { + + + case MODE_CREATE: { + + if (mb.button_index==BUTTON_LEFT && mb.pressed) { + + + if (!wip_active) { + + wip.clear(); + wip.push_back( cpoint ); + wip_active=true; + edited_point_pos=cpoint; + canvas_item_editor->get_viewport_control()->update(); + edited_point=1; + return true; + } else { + + + if (wip.size()>1 && xform.xform(wip[0]).distance_to(gpoint)1 && xform.xform(wip[wip.size()-1]).distance_to(gpoint)get_viewport_control()->update(); + return true; + + //add wip point + } + } + } else if (mb.button_index==BUTTON_RIGHT && mb.pressed && wip_active) { + _wip_close(true); + } + + + + } break; + + case MODE_EDIT: { + + if (mb.button_index==BUTTON_LEFT) { + if (mb.pressed) { + + if (mb.mod.control) { + + + if (poly.size() < 3) { + + undo_redo->create_action("Edit Poly"); + undo_redo->add_undo_method(node->get_occluder_polygon().ptr(),"set_polygon",poly); + poly.push_back(cpoint); + undo_redo->add_do_method(node->get_occluder_polygon().ptr(),"set_polygon",poly); + undo_redo->add_do_method(canvas_item_editor->get_viewport_control(),"update"); + undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(),"update"); + undo_redo->commit_action(); + return true; + } + + //search edges + int closest_idx=-1; + Vector2 closest_pos; + real_t closest_dist=1e10; + for(int i=0;i=0) { + + pre_move_edit=poly; + poly.insert(closest_idx+1,xform.affine_inverse().xform(closest_pos)); + edited_point=closest_idx+1; + edited_point_pos=xform.affine_inverse().xform(closest_pos); + node->get_occluder_polygon()->set_polygon(Variant(poly)); + canvas_item_editor->get_viewport_control()->update(); + return true; + } + } else { + + //look for points to move + + int closest_idx=-1; + Vector2 closest_pos; + real_t closest_dist=1e10; + for(int i=0;i=0) { + + pre_move_edit=poly; + edited_point=closest_idx; + edited_point_pos=xform.affine_inverse().xform(closest_pos); + canvas_item_editor->get_viewport_control()->update(); + return true; + } + } + } else { + + if (edited_point!=-1) { + + //apply + + ERR_FAIL_INDEX_V(edited_point,poly.size(),false); + poly[edited_point]=edited_point_pos; + undo_redo->create_action("Edit Poly"); + undo_redo->add_do_method(node->get_occluder_polygon().ptr(),"set_polygon",poly); + undo_redo->add_undo_method(node->get_occluder_polygon().ptr(),"set_polygon",pre_move_edit); + undo_redo->add_do_method(canvas_item_editor->get_viewport_control(),"update"); + undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(),"update"); + undo_redo->commit_action(); + + edited_point=-1; + return true; + } + } + } if (mb.button_index==BUTTON_RIGHT && mb.pressed && edited_point==-1) { + + + + int closest_idx=-1; + Vector2 closest_pos; + real_t closest_dist=1e10; + for(int i=0;i=0) { + + + undo_redo->create_action("Edit Poly (Remove Point)"); + undo_redo->add_undo_method(node->get_occluder_polygon().ptr(),"set_polygon",poly); + poly.remove(closest_idx); + undo_redo->add_do_method(node->get_occluder_polygon().ptr(),"set_polygon",poly); + undo_redo->add_do_method(canvas_item_editor->get_viewport_control(),"update"); + undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(),"update"); + undo_redo->commit_action(); + return true; + } + + } + + + + } break; + } + + + + } break; + case InputEvent::MOUSE_MOTION: { + + const InputEventMouseMotion &mm=p_event.mouse_motion; + + if (edited_point!=-1 && (wip_active || mm.button_mask&BUTTON_MASK_LEFT)) { + + Vector2 gpoint = Point2(mm.x,mm.y); + Vector2 cpoint = canvas_item_editor->get_canvas_transform().affine_inverse().xform(gpoint); + cpoint=snap_point(cpoint); + edited_point_pos = node->get_global_transform().affine_inverse().xform(cpoint); + + canvas_item_editor->get_viewport_control()->update(); + + } + + } break; + } + + return false; +} +void LightOccluder2DEditor::_canvas_draw() { + + if (!node || !node->get_occluder_polygon().is_valid()) + return; + + Control *vpc = canvas_item_editor->get_viewport_control(); + + Vector poly; + + if (wip_active) + poly=wip; + else + poly=Variant(node->get_occluder_polygon()->get_polygon()); + + + Matrix32 xform = canvas_item_editor->get_canvas_transform() * node->get_global_transform(); + Ref handle= get_icon("EditorHandle","EditorIcons"); + + int len = poly.size(); + + for(int i=0;iget_occluder_polygon()->is_closed() || wip_active)) { + + } else { + vpc->draw_line(point,next_point,col,2); + } + vpc->draw_texture(handle,point-handle->get_size()*0.5); + } +} + + + +void LightOccluder2DEditor::edit(Node *p_collision_polygon) { + + if (!canvas_item_editor) { + canvas_item_editor=CanvasItemEditor::get_singleton(); + } + + if (p_collision_polygon) { + + node=p_collision_polygon->cast_to(); + if (!canvas_item_editor->get_viewport_control()->is_connected("draw",this,"_canvas_draw")) + canvas_item_editor->get_viewport_control()->connect("draw",this,"_canvas_draw"); + wip.clear(); + wip_active=false; + edited_point=-1; + + } else { + node=NULL; + + if (canvas_item_editor->get_viewport_control()->is_connected("draw",this,"_canvas_draw")) + canvas_item_editor->get_viewport_control()->disconnect("draw",this,"_canvas_draw"); + + } + +} + +void LightOccluder2DEditor::_create_poly() { + + undo_redo->create_action("Create Occluder Polygon"); + undo_redo->add_do_method(node,"set_occluder_polygon",Ref(memnew( OccluderPolygon2D))); + undo_redo->add_undo_method(node,"set_occluder_polygon",Variant(REF())); + undo_redo->commit_action(); +} + +void LightOccluder2DEditor::_bind_methods() { + + ObjectTypeDB::bind_method(_MD("_menu_option"),&LightOccluder2DEditor::_menu_option); + ObjectTypeDB::bind_method(_MD("_canvas_draw"),&LightOccluder2DEditor::_canvas_draw); + ObjectTypeDB::bind_method(_MD("_node_removed"),&LightOccluder2DEditor::_node_removed); + ObjectTypeDB::bind_method(_MD("_create_poly"),&LightOccluder2DEditor::_create_poly); + +} + + +LightOccluder2DEditor::LightOccluder2DEditor(EditorNode *p_editor) { + + canvas_item_editor=NULL; + editor=p_editor; + undo_redo = editor->get_undo_redo(); + + add_child( memnew( VSeparator )); + button_create = memnew( ToolButton ); + add_child(button_create); + button_create->connect("pressed",this,"_menu_option",varray(MODE_CREATE)); + button_create->set_toggle_mode(true); + button_create->set_tooltip("Create a new polygon from scratch"); + + button_edit = memnew( ToolButton ); + add_child(button_edit); + button_edit->connect("pressed",this,"_menu_option",varray(MODE_EDIT)); + button_edit->set_toggle_mode(true); + button_edit->set_tooltip("Edit existing polygon:\nLMB: Move Point.\nCtrl+LMB: Split Segment.\nRMB: Erase Point."); + + create_poly = memnew( ConfirmationDialog ); + add_child(create_poly); + create_poly->get_ok()->set_text("Create"); + + + //add_constant_override("separation",0); + +#if 0 + options = memnew( MenuButton ); + add_child(options); + options->set_area_as_parent_rect(); + options->set_text("Polygon"); + //options->get_popup()->add_item("Parse BBCODE",PARSE_BBCODE); + options->get_popup()->connect("item_pressed", this,"_menu_option"); +#endif + + mode = MODE_EDIT; + wip_active=false; + +} + + +void LightOccluder2DEditorPlugin::edit(Object *p_object) { + + collision_polygon_editor->edit(p_object->cast_to()); +} + +bool LightOccluder2DEditorPlugin::handles(Object *p_object) const { + + return p_object->is_type("LightOccluder2D"); +} + +void LightOccluder2DEditorPlugin::make_visible(bool p_visible) { + + if (p_visible) { + collision_polygon_editor->show(); + } else { + + collision_polygon_editor->hide(); + collision_polygon_editor->edit(NULL); + } + +} + +LightOccluder2DEditorPlugin::LightOccluder2DEditorPlugin(EditorNode *p_node) { + + editor=p_node; + collision_polygon_editor = memnew( LightOccluder2DEditor(p_node) ); + CanvasItemEditor::get_singleton()->add_control_to_menu_panel(collision_polygon_editor); + + collision_polygon_editor->hide(); + + + +} + + +LightOccluder2DEditorPlugin::~LightOccluder2DEditorPlugin() +{ +} + diff --git a/tools/editor/plugins/light_occluder_2d_editor_plugin.h b/tools/editor/plugins/light_occluder_2d_editor_plugin.h new file mode 100644 index 0000000000..5fb5631d05 --- /dev/null +++ b/tools/editor/plugins/light_occluder_2d_editor_plugin.h @@ -0,0 +1,87 @@ +#ifndef LIGHT_OCCLUDER_2D_EDITOR_PLUGIN_H +#define LIGHT_OCCLUDER_2D_EDITOR_PLUGIN_H + + + +#include "tools/editor/editor_plugin.h" +#include "tools/editor/editor_node.h" +#include "scene/2d/light_occluder_2d.h" +#include "scene/gui/tool_button.h" +#include "scene/gui/button_group.h" + +/** + @author Juan Linietsky +*/ +class CanvasItemEditor; + +class LightOccluder2DEditor : public HBoxContainer { + + OBJ_TYPE(LightOccluder2DEditor, HBoxContainer ); + + UndoRedo *undo_redo; + enum Mode { + + MODE_CREATE, + MODE_EDIT, + + }; + + Mode mode; + + ToolButton *button_create; + ToolButton *button_edit; + + CanvasItemEditor *canvas_item_editor; + EditorNode *editor; + Panel *panel; + LightOccluder2D *node; + MenuButton *options; + + int edited_point; + Vector2 edited_point_pos; + Vector pre_move_edit; + Vector wip; + bool wip_active; + + ConfirmationDialog *create_poly; + + void _wip_close(bool p_closed); + void _canvas_draw(); + void _menu_option(int p_option); + void _create_poly(); + +protected: + void _notification(int p_what); + void _node_removed(Node *p_node); + static void _bind_methods(); +public: + + Vector2 snap_point(const Vector2& p_point) const; + bool forward_input_event(const InputEvent& p_event); + void edit(Node *p_collision_polygon); + LightOccluder2DEditor(EditorNode *p_editor); +}; + +class LightOccluder2DEditorPlugin : public EditorPlugin { + + OBJ_TYPE( LightOccluder2DEditorPlugin, EditorPlugin ); + + LightOccluder2DEditor *collision_polygon_editor; + EditorNode *editor; + +public: + + virtual bool forward_input_event(const InputEvent& p_event) { return collision_polygon_editor->forward_input_event(p_event); } + + virtual String get_name() const { return "LightOccluder2D"; } + bool has_main_screen() const { return false; } + virtual void edit(Object *p_node); + virtual bool handles(Object *p_node) const; + virtual void make_visible(bool p_visible); + + LightOccluder2DEditorPlugin(EditorNode *p_node); + ~LightOccluder2DEditorPlugin(); + +}; + +#endif // LIGHT_OCCLUDER_2D_EDITOR_PLUGIN_H diff --git a/tools/editor/property_editor.cpp b/tools/editor/property_editor.cpp index a600683097..25c39b3173 100644 --- a/tools/editor/property_editor.cpp +++ b/tools/editor/property_editor.cpp @@ -1857,8 +1857,33 @@ void PropertyEditor::set_item_text(TreeItem *p_item, int p_type, const String& p } else { p_item->set_text(1,"<"+res->get_type()+">"); }; + + if (has_icon(res->get_type(),"EditorIcons")) { + + p_item->set_icon(1,get_icon(res->get_type(),"EditorIcons")); + } else { + + Dictionary d = p_item->get_metadata(0); + int hint=d.has("hint")?d["hint"].operator int():-1; + String hint_text=d.has("hint_text")?d["hint_text"]:""; + if (hint==PROPERTY_HINT_RESOURCE_TYPE) { + + if (has_icon(hint_text,"EditorIcons")) { + + p_item->set_icon(1,get_icon(hint_text,"EditorIcons")); + + } else { + p_item->set_icon(1,get_icon("Object","EditorIcons")); + + } + } + } + + + } + } break; default: {}; } @@ -2529,7 +2554,10 @@ void PropertyEditor::update_tree() { item->set_editable( 1, !read_only ); item->add_button(1,get_icon("EditResource","EditorIcons")); String type; + if (p.hint==PROPERTY_HINT_RESOURCE_TYPE) + type=p.hint_string; bool notnil=false; + if (obj->get( p.name ).get_type() == Variant::NIL || obj->get( p.name ).operator RefPtr().is_null()) { item->set_text(1,""); @@ -2553,12 +2581,18 @@ void PropertyEditor::update_tree() { }; notnil=true; + if (has_icon(res->get_type(),"EditorIcons")) { + type=res->get_type(); + } } - if (p.hint==PROPERTY_HINT_RESOURCE_TYPE) { + + if (type!=String()) { + if (type.find(",")!=-1) + type=type.get_slice(",",0); //printf("prop %s , type %s\n",p.name.ascii().get_data(),p.hint_string.ascii().get_data()); - if (has_icon(p.hint_string,"EditorIcons")) - item->set_icon( 0, get_icon(p.hint_string,"EditorIcons") ); + if (has_icon(type,"EditorIcons")) + item->set_icon( 0, get_icon(type,"EditorIcons") ); else item->set_icon( 0, get_icon("Object","EditorIcons") ); } -- cgit v1.2.3 From a0ee5cc3531786a652ee43d3a57cb69dff34bd70 Mon Sep 17 00:00:00 2001 From: Juan Linietsky Date: Mon, 2 Mar 2015 19:21:19 -0300 Subject: time was not being set properly with the rest of the uniforms. --- drivers/gles2/rasterizer_gles2.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/gles2/rasterizer_gles2.cpp b/drivers/gles2/rasterizer_gles2.cpp index aa7bad0b8f..e167b647e7 100644 --- a/drivers/gles2/rasterizer_gles2.cpp +++ b/drivers/gles2/rasterizer_gles2.cpp @@ -9023,11 +9023,6 @@ void RasterizerGLES2::_canvas_item_setup_shader_params(CanvasItemMaterial *mater canvas_shader.set_uniform(CanvasShaderGLES2::SCREEN_UV_MULT,Vector2(1.0/viewport.width,1.0/viewport.height)); } - if (shader->uses_time) { - canvas_shader.set_uniform(CanvasShaderGLES2::TIME,Math::fmod(last_time,300.0)); - draw_next_frame=true; - } - //if uses TIME - draw_next_frame=true uses_texpixel_size=shader->uses_texpixel_size; @@ -9083,6 +9078,13 @@ void RasterizerGLES2::_canvas_item_setup_shader_uniforms(CanvasItemMaterial *mat glActiveTexture(GL_TEXTURE0); } + if (shader->uses_time) { + canvas_shader.set_uniform(CanvasShaderGLES2::TIME,Math::fmod(last_time,300.0)); + draw_next_frame=true; + } + //if uses TIME - draw_next_frame=true + + } void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list,int p_z,const Color& p_modulate,CanvasLight *p_light) { -- cgit v1.2.3 From 4d2198110b4af7f203eeef95697255569e49bce7 Mon Sep 17 00:00:00 2001 From: Juan Linietsky Date: Tue, 3 Mar 2015 14:39:13 -0300 Subject: merges from okam repo --- SConstruct | 4 + core/object.cpp | 8 + core/object.h | 1 + doc/base/classes.xml | 3 +- drivers/gles2/rasterizer_gles2.cpp | 24 ++- methods.py | 8 + modules/gdscript/gd_tokenizer.cpp | 4 +- modules/gridmap/grid_map.cpp | 3 +- platform/android/AndroidManifest.xml.template | 3 +- platform/android/SCsub | 2 + platform/android/java_glue.cpp | 113 ++++++++++--- platform/bb10/SCsub | 10 +- platform/bb10/bar/bar-descriptor.xml | 30 ++-- platform/bb10/detect.py | 2 - platform/bb10/export/export.cpp | 79 ++++----- platform/bb10/os_bb10.cpp | 2 +- platform/iphone/gl_view.h | 2 + platform/iphone/gl_view.mm | 52 ++++++ scene/2d/camera_2d.cpp | 11 ++ scene/2d/camera_2d.h | 189 +++++++++++----------- scene/resources/shader_graph.h | 2 + servers/visual/shader_language.cpp | 4 +- tools/collada/collada.cpp | 2 +- tools/collada/collada.h | 18 +++ tools/editor/editor_import_export.cpp | 30 +++- tools/editor/editor_import_export.h | 3 +- tools/editor/io_plugins/editor_import_collada.cpp | 11 +- tools/export/blender25/io_scene_dae/export_dae.py | 71 ++++++-- 28 files changed, 458 insertions(+), 233 deletions(-) diff --git a/SConstruct b/SConstruct index c68ca3989f..2dc9fa1e70 100644 --- a/SConstruct +++ b/SConstruct @@ -67,12 +67,16 @@ env_base.android_source_modules=[] env_base.android_source_files=[] env_base.android_module_libraries=[] env_base.android_manifest_chunk="" +env_base.android_permission_chunk="" +env_base.android_appattributes_chunk="" env_base.disabled_modules=[] env_base.__class__.android_module_source = methods.android_module_source env_base.__class__.android_module_library = methods.android_module_library env_base.__class__.android_module_file = methods.android_module_file env_base.__class__.android_module_manifest = methods.android_module_manifest +env_base.__class__.android_module_permission = methods.android_module_permission +env_base.__class__.android_module_attribute = methods.android_module_attribute env_base.__class__.disable_module = methods.disable_module env_base.__class__.add_source_files = methods.add_source_files diff --git a/core/object.cpp b/core/object.cpp index 82144ab4be..2b83f728d1 100644 --- a/core/object.cpp +++ b/core/object.cpp @@ -1033,6 +1033,13 @@ void Object::add_user_signal(const MethodInfo& p_signal) { signal_map[p_signal.name]=s; } +bool Object::_has_user_signal(const StringName& p_name) const { + + if (!signal_map.has(p_name)) + return false; + return signal_map[p_name].user.name.length()>0; +} + struct _ObjectSignalDisconnectData { StringName signal; @@ -1431,6 +1438,7 @@ void Object::_bind_methods() { // ObjectTypeDB::bind_method(_MD("call_deferred","method","arg1","arg2","arg3","arg4"),&Object::_call_deferred_bind,DEFVAL(Variant()),DEFVAL(Variant()),DEFVAL(Variant()),DEFVAL(Variant())); ObjectTypeDB::bind_method(_MD("add_user_signal","signal","arguments"),&Object::_add_user_signal,DEFVAL(Array())); + ObjectTypeDB::bind_method(_MD("has_user_signal","signal"),&Object::_has_user_signal); // ObjectTypeDB::bind_method(_MD("emit_signal","signal","arguments"),&Object::_emit_signal,DEFVAL(Array())); diff --git a/core/object.h b/core/object.h index 97ca50cb1a..eb885f5d20 100644 --- a/core/object.h +++ b/core/object.h @@ -386,6 +386,7 @@ friend void postinitialize_handler(Object*); Dictionary metadata; void _add_user_signal(const String& p_name, const Array& p_pargs=Array()); + bool _has_user_signal(const StringName& p_name) const; Variant _emit_signal(const Variant** p_args, int p_argcount, Variant::CallError& r_error); Array _get_signal_list() const; Array _get_signal_connection_list(const String& p_signal) const; diff --git a/doc/base/classes.xml b/doc/base/classes.xml index 35de0106b5..e5bdcfbc6a 100644 --- a/doc/base/classes.xml +++ b/doc/base/classes.xml @@ -18902,7 +18902,8 @@ collider_id: collider id of the object agaisnt which the ray was stopped[br] collider: collider object agaisnt which the ray was stopped[br] rid: [RID] of the object agaisnt which the ray was stopped[br] - If the ray did not intersect anything, then null is returned instead of a [Dictionary]. + If the ray did not intersect anything, then an empty + dictionary (dir.empty()==true) is returned instead. diff --git a/drivers/gles2/rasterizer_gles2.cpp b/drivers/gles2/rasterizer_gles2.cpp index 9375532f07..9cee702c05 100644 --- a/drivers/gles2/rasterizer_gles2.cpp +++ b/drivers/gles2/rasterizer_gles2.cpp @@ -4954,12 +4954,26 @@ _FORCE_INLINE_ void RasterizerGLES2::_update_material_shader_params(Material *p_ Material::UniformData ud; bool keep=true; //keep material value - bool has_old = old_mparams.has(E->key()); + + Map::Element *OLD=old_mparams.find(E->key()); + bool has_old = OLD; bool old_inuse=has_old && old_mparams[E->key()].inuse; - if (!has_old || !old_inuse) + ud.istexture=(E->get().type==ShaderLanguage::TYPE_TEXTURE || E->get().type==ShaderLanguage::TYPE_CUBEMAP); + + if (!has_old || !old_inuse) { keep=false; - else if (old_mparams[E->key()].value.get_type()!=E->value().default_value.get_type()) { + } + else if (OLD->get().value.get_type()!=E->value().default_value.get_type()) { + + if (OLD->get().value.get_type()==Variant::INT && E->get().type==ShaderLanguage::TYPE_FLOAT) { + //handle common mistake using shaders (feeding ints instead of float) + OLD->get().value=float(OLD->get().value); + keep=true; + } else if (!ud.istexture && E->value().default_value.get_type()!=Variant::NIL) { + + keep=false; + } //type changed between old and new /* if (old_mparams[E->key()].value.get_type()==Variant::OBJECT) { if (E->value().default_value.get_type()!=Variant::_RID) //hackfor textures @@ -4968,11 +4982,9 @@ _FORCE_INLINE_ void RasterizerGLES2::_update_material_shader_params(Material *p_ keep=false;*/ //value is invalid because type differs and default is not null - if (E->value().default_value.get_type()!=Variant::NIL) - keep=false; + ; } - ud.istexture=(E->get().type==ShaderLanguage::TYPE_TEXTURE || E->get().type==ShaderLanguage::TYPE_CUBEMAP); if (keep) { ud.value=old_mparams[E->key()].value; diff --git a/methods.py b/methods.py index da1491e3f9..9608b1b61d 100755 --- a/methods.py +++ b/methods.py @@ -1291,6 +1291,14 @@ def android_module_manifest(self,file): base_path = self.Dir(".").abspath+"/modules/"+self.current_module+"/"+file f = open(base_path,"rb") self.android_manifest_chunk+=f.read() +def android_module_permission(self,file): + base_path = self.Dir(".").abspath+"/modules/"+self.current_module+"/"+file + f = open(base_path,"rb") + self.android_permission_chunk+=f.read() +def android_module_attribute(self,file): + base_path = self.Dir(".").abspath+"/modules/"+self.current_module+"/"+file + f = open(base_path,"rb") + self.android_appattributes_chunk+=f.read() def disable_module(self): self.disabled_modules.append(self.current_module) diff --git a/modules/gdscript/gd_tokenizer.cpp b/modules/gdscript/gd_tokenizer.cpp index 6f968f2080..71dbf81fbf 100644 --- a/modules/gdscript/gd_tokenizer.cpp +++ b/modules/gdscript/gd_tokenizer.cpp @@ -538,9 +538,11 @@ void GDTokenizerText::_advance() { is_node_path=true; case '\'': - string_mode=STRING_SINGLE_QUOTE; case '"': { + if (GETCHAR(0)=='\'') + string_mode=STRING_SINGLE_QUOTE; + int i=1; if (string_mode==STRING_DOUBLE_QUOTE && GETCHAR(i)=='"' && GETCHAR(i+1)=='"') { i+=2; diff --git a/modules/gridmap/grid_map.cpp b/modules/gridmap/grid_map.cpp index 7c344e1e90..441b274e33 100644 --- a/modules/gridmap/grid_map.cpp +++ b/modules/gridmap/grid_map.cpp @@ -122,7 +122,7 @@ bool GridMap::_set(const StringName& p_name, const Variant& p_value) { Octant &g = *octant_map[ok]; g.baked=b; - g.bake_instance=VS::get_singleton()->instance_create();; + g.bake_instance=VS::get_singleton()->instance_create();; VS::get_singleton()->instance_set_base(g.bake_instance,g.baked->get_rid()); VS::get_singleton()->instance_geometry_set_baked_light(g.bake_instance,baked_light_instance?baked_light_instance->get_baked_light_instance():RID()); } @@ -418,6 +418,7 @@ void GridMap::set_cell_item(int p_x,int p_y,int p_z, int p_item,int p_rot){ Octant *g = memnew( Octant ); g->dirty=true; g->static_body = PhysicsServer::get_singleton()->body_create(PhysicsServer::BODY_MODE_STATIC); + PhysicsServer::get_singleton()->body_attach_object_instance_ID(g->static_body,get_instance_ID()); if (is_inside_world()) PhysicsServer::get_singleton()->body_set_space(g->static_body,get_world()->get_space()); diff --git a/platform/android/AndroidManifest.xml.template b/platform/android/AndroidManifest.xml.template index 60861db603..d31bdbfa53 100644 --- a/platform/android/AndroidManifest.xml.template +++ b/platform/android/AndroidManifest.xml.template @@ -10,7 +10,7 @@ android:largeScreens="true" android:xlargeScreens="true"/> - + +$$ADD_PERMISSION_CHUNKS$$ diff --git a/platform/android/SCsub b/platform/android/SCsub index cffec5ae95..6feeb8b365 100644 --- a/platform/android/SCsub +++ b/platform/android/SCsub @@ -56,6 +56,8 @@ pp_basein = open(abspath+"/AndroidManifest.xml.template","rb") pp_baseout = open(abspath+"/java/AndroidManifest.xml","wb") manifest = pp_basein.read() manifest = manifest.replace("$$ADD_APPLICATION_CHUNKS$$",env.android_manifest_chunk) +manifest = manifest.replace("$$ADD_PERMISSION_CHUNKS$$",env.android_permission_chunk) +manifest = manifest.replace("$$ADD_APPATTRIBUTE_CHUNKS$$",env.android_appattributes_chunk) pp_baseout.write( manifest ) diff --git a/platform/android/java_glue.cpp b/platform/android/java_glue.cpp index 0312d13644..349db08e36 100644 --- a/platform/android/java_glue.cpp +++ b/platform/android/java_glue.cpp @@ -45,9 +45,18 @@ static JavaClassWrapper *java_class_wrapper=NULL; static OS_Android *os_android=NULL; -jvalue _variant_to_jvalue(JNIEnv *env, Variant::Type p_type, const Variant* p_arg, bool force_jobject = false) { +struct jvalret { - jvalue v; + jobject obj; + jvalue val; + jvalret() { obj=NULL; } + + +}; + +jvalret _variant_to_jvalue(JNIEnv *env, Variant::Type p_type, const Variant* p_arg, bool force_jobject = false) { + + jvalret v; switch(p_type) { @@ -59,9 +68,12 @@ jvalue _variant_to_jvalue(JNIEnv *env, Variant::Type p_type, const Variant* p_ar jvalue val; val.z = (bool)(*p_arg); jobject obj = env->NewObjectA(bclass, ctor, &val); - v.l = obj; + v.val.l = obj; + v.obj=obj; + env->DeleteLocalRef(bclass); } else { - v.z=*p_arg; + v.val.z=*p_arg; + }; } break; case Variant::INT: { @@ -73,10 +85,13 @@ jvalue _variant_to_jvalue(JNIEnv *env, Variant::Type p_type, const Variant* p_ar jvalue val; val.i = (int)(*p_arg); jobject obj = env->NewObjectA(bclass, ctor, &val); - v.l = obj; + v.val.l = obj; + v.obj=obj; + env->DeleteLocalRef(bclass); } else { - v.i=*p_arg; + v.val.i=*p_arg; + }; } break; case Variant::REAL: { @@ -88,17 +103,20 @@ jvalue _variant_to_jvalue(JNIEnv *env, Variant::Type p_type, const Variant* p_ar jvalue val; val.d = (double)(*p_arg); jobject obj = env->NewObjectA(bclass, ctor, &val); - v.l = obj; + v.val.l = obj; + v.obj=obj; + env->DeleteLocalRef(bclass); } else { - v.f=*p_arg; + v.val.f=*p_arg; }; } break; case Variant::STRING: { String s = *p_arg; jstring jStr = env->NewStringUTF(s.utf8().get_data()); - v.l=jStr; + v.val.l=jStr; + v.obj=jStr; } break; case Variant::STRING_ARRAY: { @@ -107,9 +125,12 @@ jvalue _variant_to_jvalue(JNIEnv *env, Variant::Type p_type, const Variant* p_ar for(int j=0;jSetObjectArrayElement(arr,j,env->NewStringUTF( sarray[j].utf8().get_data() )); + jstring str = env->NewStringUTF( sarray[j].utf8().get_data() ); + env->SetObjectArrayElement(arr,j,str); + env->DeleteLocalRef(str); } - v.l=arr; + v.val.l=arr; + v.obj=arr; } break; @@ -124,27 +145,36 @@ jvalue _variant_to_jvalue(JNIEnv *env, Variant::Type p_type, const Variant* p_ar jobjectArray jkeys = env->NewObjectArray(keys.size(), env->FindClass("java/lang/String"), env->NewStringUTF("")); for (int j=0; jSetObjectArrayElement(jkeys, j, env->NewStringUTF(String(keys[j]).utf8().get_data())); + jstring str = env->NewStringUTF(String(keys[j]).utf8().get_data()); + env->SetObjectArrayElement(jkeys, j, str); + env->DeleteLocalRef(str); }; jmethodID set_keys = env->GetMethodID(dclass, "set_keys", "([Ljava/lang/String;)V"); jvalue val; val.l = jkeys; env->CallVoidMethodA(jdict, set_keys, &val); + env->DeleteLocalRef(jkeys); jobjectArray jvalues = env->NewObjectArray(keys.size(), env->FindClass("java/lang/Object"), NULL); for (int j=0; jSetObjectArrayElement(jvalues, j, val.l); + jvalret v = _variant_to_jvalue(env, var.get_type(), &var, true); + env->SetObjectArrayElement(jvalues, j, v.val.l); + if (v.obj) { + env->DeleteLocalRef(v.obj); + } }; jmethodID set_values = env->GetMethodID(dclass, "set_values", "([Ljava/lang/Object;)V"); val.l = jvalues; env->CallVoidMethodA(jdict, set_values, &val); + env->DeleteLocalRef(jvalues); + env->DeleteLocalRef(dclass); - v.l = jdict; + v.val.l = jdict; + v.obj=jdict; } break; case Variant::INT_ARRAY: { @@ -153,7 +183,8 @@ jvalue _variant_to_jvalue(JNIEnv *env, Variant::Type p_type, const Variant* p_ar jintArray arr = env->NewIntArray(array.size()); DVector::Read r = array.read(); env->SetIntArrayRegion(arr,0,array.size(),r.ptr()); - v.l=arr; + v.val.l=arr; + v.obj=arr; } break; case Variant::RAW_ARRAY: { @@ -161,7 +192,8 @@ jvalue _variant_to_jvalue(JNIEnv *env, Variant::Type p_type, const Variant* p_ar jbyteArray arr = env->NewByteArray(array.size()); DVector::Read r = array.read(); env->SetByteArrayRegion(arr,0,array.size(),reinterpret_cast(r.ptr())); - v.l=arr; + v.val.l=arr; + v.obj=arr; } break; case Variant::REAL_ARRAY: { @@ -170,12 +202,13 @@ jvalue _variant_to_jvalue(JNIEnv *env, Variant::Type p_type, const Variant* p_ar jfloatArray arr = env->NewFloatArray(array.size()); DVector::Read r = array.read(); env->SetFloatArrayRegion(arr,0,array.size(),r.ptr()); - v.l=arr; + v.val.l=arr; + v.obj=arr; } break; default: { - v.i = 0; + v.val.i = 0; } break; } @@ -193,8 +226,11 @@ String _get_class_name(JNIEnv * env, jclass cls, bool* array) { jboolean isarr = env->CallBooleanMethod(cls, isArray); (*array) = isarr ? true : false; } + String name = env->GetStringUTFChars( clsName, NULL ); + env->DeleteLocalRef(clsName); + + return name; - return env->GetStringUTFChars( clsName, NULL ); }; @@ -223,6 +259,8 @@ Variant _jobject_to_variant(JNIEnv * env, jobject obj) { jstring string = (jstring) env->GetObjectArrayElement(arr, i); const char *rawString = env->GetStringUTFChars(string, 0); sarr.push_back(String(rawString)); + env->DeleteLocalRef(string); + } return sarr; @@ -321,30 +359,34 @@ Variant _jobject_to_variant(JNIEnv * env, jobject obj) { jobjectArray arr = (jobjectArray)obj; int objCount = env->GetArrayLength(arr); - Array varr; + Array varr(true); for (int i=0; iGetObjectArrayElement(arr, i); Variant v = _jobject_to_variant(env, jobj); varr.push_back(v); + env->DeleteLocalRef(jobj); + } return varr; }; - if (name == "com.android.godot.Dictionary") { + if (name == "java.util.HashMap" || name == "com.android.godot.Dictionary") { - Dictionary ret; + Dictionary ret(true); jclass oclass = c; jmethodID get_keys = env->GetMethodID(oclass, "get_keys", "()[Ljava/lang/String;"); jobjectArray arr = (jobjectArray)env->CallObjectMethod(obj, get_keys); StringArray keys = _jobject_to_variant(env, arr); + env->DeleteLocalRef(arr); jmethodID get_values = env->GetMethodID(oclass, "get_values", "()[Ljava/lang/Object;"); arr = (jobjectArray)env->CallObjectMethod(obj, get_values); Array vals = _jobject_to_variant(env, arr); + env->DeleteLocalRef(arr); //print_line("adding " + String::num(keys.size()) + " to Dictionary!"); for (int i=0; iDeleteLocalRef(c); + return Variant(); }; @@ -432,9 +477,13 @@ public: JNIEnv *env = ThreadAndroid::get_env(); //print_line("argcount "+String::num(p_argcount)); + List to_erase; for(int i=0;iget().argtypes[i], p_args[i]); + jvalret vr = _variant_to_jvalue(env, E->get().argtypes[i], p_args[i]); + v[i] = vr.val; + if (vr.obj) + to_erase.push_back(vr.obj); } //print_line("calling method!!"); @@ -468,6 +517,7 @@ public: jobject o = env->CallObjectMethodA(instance,E->get().method,v); String str = env->GetStringUTFChars((jstring)o, NULL ); ret=str; + env->DeleteLocalRef(o); } break; case Variant::STRING_ARRAY: { @@ -475,6 +525,7 @@ public: ret = _jobject_to_variant(env, arr); + env->DeleteLocalRef(arr); } break; case Variant::INT_ARRAY: { @@ -488,6 +539,7 @@ public: env->GetIntArrayRegion(arr,0,fCount,w.ptr()); w = DVector::Write(); ret=sarr; + env->DeleteLocalRef(arr); } break; case Variant::REAL_ARRAY: { @@ -501,6 +553,7 @@ public: env->GetFloatArrayRegion(arr,0,fCount,w.ptr()); w = DVector::Write(); ret=sarr; + env->DeleteLocalRef(arr); } break; case Variant::DICTIONARY: { @@ -508,6 +561,7 @@ public: //print_line("call dictionary"); jobject obj = env->CallObjectMethodA(instance, E->get().method, v); ret = _jobject_to_variant(env, obj); + env->DeleteLocalRef(obj); } break; default: { @@ -518,6 +572,10 @@ public: } break; } + while (to_erase.size()) { + env->DeleteLocalRef(to_erase.front()->get()); + to_erase.pop_front(); + } //print_line("success"); return ret; @@ -872,6 +930,7 @@ static void _initialize_java_modules() { String modules = Globals::get_singleton()->get("android/modules"); Vector mods = modules.split(",",false); + print_line("ANDROID MODULES : " + modules); __android_log_print(ANDROID_LOG_INFO,"godot","mod count: %i",mods.size()); if (mods.size()) { @@ -1571,6 +1630,8 @@ JNIEXPORT void JNICALL Java_com_android_godot_GodotLib_callobject(JNIEnv * env, memnew_placement(&vlist[i], Variant); vlist[i] = v; vptr[i] = &vlist[i]; + env->DeleteLocalRef(obj); + }; Variant::CallError err; @@ -1588,13 +1649,15 @@ JNIEXPORT void JNICALL Java_com_android_godot_GodotLib_calldeferred(JNIEnv * env int count = env->GetArrayLength(params); Variant args[VARIANT_ARG_MAX]; -// print_line("Java->GD call: "+obj->get_type()+"::"+str_method+" argc "+itos(count)); + //print_line("Java->GD call: "+obj->get_type()+"::"+str_method+" argc "+itos(count)); for (int i=0; iGetObjectArrayElement(params, i); if (obj) args[i] = _jobject_to_variant(env, obj); + env->DeleteLocalRef(obj); + // print_line("\targ"+itos(i)+": "+Variant::get_type_name(args[i].get_type())); }; diff --git a/platform/bb10/SCsub b/platform/bb10/SCsub index 2e8ef47005..24f2b5d242 100644 --- a/platform/bb10/SCsub +++ b/platform/bb10/SCsub @@ -18,13 +18,5 @@ if env['bb10_lgles_override'] == "yes": prog = None -if env["target"]=="release": - prog = env_bps.Program('#platform/bb10/godot_bb10_opt', bb10_lib) -else: - prog = env_bps.Program('#platform/bb10/godot_bb10', bb10_lib) - -import os -fname = os.path.basename(str(prog[0])) - -env.Command('#bin/'+fname, prog, Copy('bin/'+fname, prog[0])) +prog = env_bps.Program('#bin/godot', bb10_lib) diff --git a/platform/bb10/bar/bar-descriptor.xml b/platform/bb10/bar/bar-descriptor.xml index df5d34e077..0ba70b7180 100644 --- a/platform/bb10/bar/bar-descriptor.xml +++ b/platform/bb10/bar/bar-descriptor.xml @@ -1,65 +1,53 @@ - + - - - com.godot.game - Godot Game - 0.0.1 - 0 - Game made with Godot Engine - You Name or Company authorIDherePlease - - landscape false none false - core.games read_device_identifying_information access_internet - assets + data.pck - armle-v7 - godot_bb10.qnx.armle + armle-v7 + godot.bb10.debug.qnx.armle - armle-v7 - godot_bb10_opt.qnx.armle + armle-v7 + godot.bb10.opt.qnx.armle - icon.png + icon.png - - - + diff --git a/platform/bb10/detect.py b/platform/bb10/detect.py index 3ddb7a4450..f134a9df19 100644 --- a/platform/bb10/detect.py +++ b/platform/bb10/detect.py @@ -81,8 +81,6 @@ def configure(env): if (env["target"]=="release"): env.Append(CCFLAGS=['-O3','-DRELEASE_BUILD']) - env['OBJSUFFIX'] = "_opt"+env['OBJSUFFIX'] - env['LIBSUFFIX'] = "_opt"+env['LIBSUFFIX'] elif (env["target"]=="debug"): diff --git a/platform/bb10/export/export.cpp b/platform/bb10/export/export.cpp index d40cb82cdf..7862ecd493 100644 --- a/platform/bb10/export/export.cpp +++ b/platform/bb10/export/export.cpp @@ -321,12 +321,29 @@ Error EditorExportPlatformBB10::export_project(const String& p_path, bool p_debu //BE SUPER CAREFUL WITH THIS PLEASE!!! //BLACKBERRY THIS IS YOUR FAULT FOR NOT MAKING A BETTER WAY!! - if (bar_dir.ends_with("bb10_export")) { - Error err = da->erase_contents_recursive(); - if (err!=OK) { + bool berr = bar_dir.ends_with("bb10_export"); + if (berr) { + if (da->list_dir_begin()) { EditorNode::add_io_error("Can't ensure that dir is empty:\n"+bar_dir); - ERR_FAIL_COND_V(err!=OK,err); - } + ERR_FAIL_COND_V(berr,FAILED); + }; + + String f = da->get_next(); + while (f != "") { + + if (f == "." || f == "..") { + f = da->get_next(); + continue; + }; + Error err = da->remove(bar_dir + "/" + f); + if (err != OK) { + EditorNode::add_io_error("Can't ensure that dir is empty:\n"+bar_dir); + ERR_FAIL_COND_V(err!=OK,err); + }; + f = da->get_next(); + }; + + da->list_dir_end(); } else { print_line("ARE YOU CRAZY??? THIS IS A SERIOUS BUG HERE!!!"); @@ -405,52 +422,23 @@ Error EditorExportPlatformBB10::export_project(const String& p_path, bool p_debu ret = unzGoToNextFile(pkg); } - ep.step("Finding Files..",1); - - Vector files=get_dependencies(false); - ep.step("Adding Files..",2); - da->change_dir(bar_dir); - da->make_dir("assets"); - Error err = da->change_dir("assets"); - ERR_FAIL_COND_V(err,err); - - String asset_dir=da->get_current_dir(); - if (!asset_dir.ends_with("/")) - asset_dir+="/"; - - for(int i=0;i data = get_exported_file(fname); - /* - FileAccess *f=FileAccess::open(files[i],FileAccess::READ); - if (!f) { - EditorNode::add_io_error("Couldn't read: "+String(files[i])); - } - ERR_CONTINUE(!f); - data.resize(f->get_len()); - f->get_buffer(data.ptr(),data.size()); -*/ - String dst_path=fname; - dst_path=dst_path.replace_first("res://",asset_dir); - - da->make_dir_recursive(dst_path.get_base_dir()); - - ep.step("Adding File: "+String(files[i]).get_file(),3+i*100/files.size()); - - FileAccessRef fr = FileAccess::open(dst_path,FileAccess::WRITE); - fr->store_buffer(data.ptr(),data.size()); + FileAccess* dst = FileAccess::open(bar_dir+"/data.pck", FileAccess::WRITE); + if (!dst) { + EditorNode::add_io_error("Can't copy executable file to:\n "+p_path); + return ERR_FILE_CANT_WRITE; } - + save_pack(dst, false, 1024); + dst->close(); + memdelete(dst); ep.step("Creating BAR Package..",104); String bb_packager=EditorSettings::get_singleton()->get("blackberry/host_tools"); bb_packager=bb_packager.plus_file("blackberry-nativepackager"); if (OS::get_singleton()->get_name()=="Windows") - bb_packager+=".exe"; + bb_packager+=".bat"; if (!FileAccess::exists(bb_packager)) { @@ -482,7 +470,7 @@ Error EditorExportPlatformBB10::export_project(const String& p_path, bool p_debu int ec; - err = OS::get_singleton()->execute(bb_packager,args,true,NULL,NULL,&ec); + Error err = OS::get_singleton()->execute(bb_packager,args,true,NULL,NULL,&ec); if (err!=OK) return err; @@ -493,7 +481,6 @@ Error EditorExportPlatformBB10::export_project(const String& p_path, bool p_debu } - bool EditorExportPlatformBB10::poll_devices() { bool dc=devices_changed; @@ -537,7 +524,7 @@ void EditorExportPlatformBB10::_device_poll_thread(void *ud) { bb_deploy=bb_deploy.plus_file("blackberry-deploy"); bool windows = OS::get_singleton()->get_name()=="Windows"; if (windows) - bb_deploy+=".exe"; + bb_deploy+=".bat"; if (!FileAccess::exists(bb_deploy)) { OS::get_singleton()->delay_usec(3000000); @@ -639,7 +626,7 @@ Error EditorExportPlatformBB10::run(int p_device, bool p_dumb) { String bb_deploy=EditorSettings::get_singleton()->get("blackberry/host_tools"); bb_deploy=bb_deploy.plus_file("blackberry-deploy"); if (OS::get_singleton()->get_name()=="Windows") - bb_deploy+=".exe"; + bb_deploy+=".bat"; if (!FileAccess::exists(bb_deploy)) { EditorNode::add_io_error("Blackberry Deploy not found:\n"+bb_deploy); diff --git a/platform/bb10/os_bb10.cpp b/platform/bb10/os_bb10.cpp index ff43a68b1d..d89033b1df 100644 --- a/platform/bb10/os_bb10.cpp +++ b/platform/bb10/os_bb10.cpp @@ -619,7 +619,7 @@ OSBB10::OSBB10() { printf("godot bb10!\n"); getcwd(launch_dir, sizeof(launch_dir)); printf("launch dir %s\n", launch_dir); - chdir("app/native/assets"); + chdir("app/native"); launch_dir_ptr = launch_dir; } diff --git a/platform/iphone/gl_view.h b/platform/iphone/gl_view.h index 8ae7c2f87d..8eb96e7e98 100755 --- a/platform/iphone/gl_view.h +++ b/platform/iphone/gl_view.h @@ -93,6 +93,8 @@ - (BOOL)createFramebuffer; - (void)destroyFramebuffer; +- (void)audioRouteChangeListenerCallback:(NSNotification*)notification; + @property NSTimeInterval animationInterval; @end diff --git a/platform/iphone/gl_view.mm b/platform/iphone/gl_view.mm index bee01d3c72..7d33c11315 100755 --- a/platform/iphone/gl_view.mm +++ b/platform/iphone/gl_view.mm @@ -119,6 +119,8 @@ bool _play_video(String p_path, float p_volume, String p_audio_track, String p_s name:AVPlayerItemDidPlayToEndTimeNotification object:[_instance.avPlayer currentItem]]; + [_instance.avPlayer addObserver:_instance forKeyPath:@"rate" options:NSKeyValueObservingOptionNew context:0]; + [_instance.avPlayerLayer setFrame:_instance.bounds]; [_instance.layer addSublayer:_instance.avPlayerLayer]; [_instance.avPlayer play]; @@ -578,6 +580,39 @@ static void clear_touches() { printf("inserting text with character %i\n", character[0]); }; +- (void)audioRouteChangeListenerCallback:(NSNotification*)notification +{ + printf("*********** route changed!%i\n"); + NSDictionary *interuptionDict = notification.userInfo; + + NSInteger routeChangeReason = [[interuptionDict valueForKey:AVAudioSessionRouteChangeReasonKey] integerValue]; + + switch (routeChangeReason) { + + case AVAudioSessionRouteChangeReasonNewDeviceAvailable: + NSLog(@"AVAudioSessionRouteChangeReasonNewDeviceAvailable"); + NSLog(@"Headphone/Line plugged in"); + break; + + case AVAudioSessionRouteChangeReasonOldDeviceUnavailable: + NSLog(@"AVAudioSessionRouteChangeReasonOldDeviceUnavailable"); + NSLog(@"Headphone/Line was pulled. Resuming video play...."); + if (_is_video_playing) { + + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.5f * NSEC_PER_SEC), dispatch_get_main_queue(), ^{ + [_instance.avPlayer play]; // NOTE: change this line according your current player implementation + NSLog(@"resumed play"); + }); + }; + break; + + case AVAudioSessionRouteChangeReasonCategoryChange: + // called at start - also when other audio wants to play + NSLog(@"AVAudioSessionRouteChangeReasonCategoryChange"); + break; + } +} + // When created via code however, we get initWithFrame -(id)initWithFrame:(CGRect)frame @@ -593,6 +628,11 @@ static void clear_touches() { init_touches(); self. multipleTouchEnabled = YES; + printf("******** adding observer for sound routing changes\n"); + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(audioRouteChangeListenerCallback:) + name:AVAudioSessionRouteChangeNotification + object:nil]; + //self.autoresizesSubviews = YES; //[self setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleWidth]; @@ -642,6 +682,18 @@ static void clear_touches() { video_current_time = kCMTimeZero; } } + + if (object == _instance.avPlayer && [keyPath isEqualToString:@"rate"]) { + NSLog(@"Player playback rate changed: %.5f", _instance.avPlayer.rate); + if (_is_video_playing() && _instance.avPlayer.rate == 0.0 && !_instance.avPlayer.error) { + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.5f * NSEC_PER_SEC), dispatch_get_main_queue(), ^{ + [_instance.avPlayer play]; // NOTE: change this line according your current player implementation + NSLog(@"resumed play"); + }); + + NSLog(@" . . . PAUSED (or just started)"); + } + } } - (void)playerItemDidReachEnd:(NSNotification *)notification { diff --git a/scene/2d/camera_2d.cpp b/scene/2d/camera_2d.cpp index b3897010bf..b2d74b4ad5 100644 --- a/scene/2d/camera_2d.cpp +++ b/scene/2d/camera_2d.cpp @@ -323,6 +323,16 @@ void Camera2D::make_current() { } } +void Camera2D::clear_current() { + + current=false; + if (is_inside_tree()) { + get_tree()->call_group(SceneTree::GROUP_CALL_REALTIME,group_name,"_make_current",(Object*)(NULL)); + } + +} + + void Camera2D::set_limit(Margin p_margin,int p_limit) { ERR_FAIL_INDEX(p_margin,4); @@ -435,6 +445,7 @@ void Camera2D::_bind_methods() { ObjectTypeDB::bind_method(_MD("is_rotating"),&Camera2D::is_rotating); ObjectTypeDB::bind_method(_MD("make_current"),&Camera2D::make_current); + ObjectTypeDB::bind_method(_MD("clear_current"),&Camera2D::clear_current); ObjectTypeDB::bind_method(_MD("_make_current"),&Camera2D::_make_current); ObjectTypeDB::bind_method(_MD("_update_scroll"),&Camera2D::_update_scroll); diff --git a/scene/2d/camera_2d.h b/scene/2d/camera_2d.h index 116169cac1..515f9711bf 100644 --- a/scene/2d/camera_2d.h +++ b/scene/2d/camera_2d.h @@ -26,97 +26,98 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef CAMERA_2D_H -#define CAMERA_2D_H - -#include "scene/2d/node_2d.h" -#include "scene/main/viewport.h" - - -class Camera2D : public Node2D { - - OBJ_TYPE( Camera2D, Node2D ); - -protected: - Point2 camera_pos; - Point2 smoothed_camera_pos; - bool first; - - Viewport *viewport; - - StringName group_name; - StringName canvas_group_name; - RID canvas; - Vector2 offset; - Vector2 zoom; - bool centered; - bool rotating; - bool current; - float smoothing; - int limit[4]; - float drag_margin[4]; - - bool h_drag_enabled; - bool v_drag_enabled; - float h_ofs; - float v_ofs; - - - Point2 camera_screen_center; - void _update_scroll(); - - void _make_current(Object *p_which); - void _set_current(bool p_current); -protected: - - virtual Matrix32 get_camera_transform(); - void _notification(int p_what); - static void _bind_methods(); -public: - - void set_offset(const Vector2& p_offset); - Vector2 get_offset() const; - - void set_centered(bool p_centered); - bool is_centered() const; - - void set_rotating(bool p_rotating); - bool is_rotating() const; - - void set_limit(Margin p_margin,int p_limit); - int get_limit(Margin p_margin) const; - - - void set_h_drag_enabled(bool p_enabled); - bool is_h_drag_enabled() const; - - void set_v_drag_enabled(bool p_enabled); - bool is_v_drag_enabled() const; - - void set_drag_margin(Margin p_margin,float p_drag_margin); - float get_drag_margin(Margin p_margin) const; - - void set_v_offset(float p_offset); - float get_v_offset() const; - - void set_h_offset(float p_offset); - float get_h_offset() const; - - void set_follow_smoothing(float p_speed); - float get_follow_smoothing() const; - - void make_current(); - bool is_current() const; - - void set_zoom(const Vector2& p_zoom); - Vector2 get_zoom() const; - - Point2 get_camera_screen_center() const; - - Vector2 get_camera_pos() const; - void force_update_scroll(); - - Camera2D(); -}; - -#endif // CAMERA_2D_H +#ifndef CAMERA_2D_H +#define CAMERA_2D_H + +#include "scene/2d/node_2d.h" +#include "scene/main/viewport.h" + + +class Camera2D : public Node2D { + + OBJ_TYPE( Camera2D, Node2D ); + +protected: + Point2 camera_pos; + Point2 smoothed_camera_pos; + bool first; + + Viewport *viewport; + + StringName group_name; + StringName canvas_group_name; + RID canvas; + Vector2 offset; + Vector2 zoom; + bool centered; + bool rotating; + bool current; + float smoothing; + int limit[4]; + float drag_margin[4]; + + bool h_drag_enabled; + bool v_drag_enabled; + float h_ofs; + float v_ofs; + + + Point2 camera_screen_center; + void _update_scroll(); + + void _make_current(Object *p_which); + void _set_current(bool p_current); +protected: + + virtual Matrix32 get_camera_transform(); + void _notification(int p_what); + static void _bind_methods(); +public: + + void set_offset(const Vector2& p_offset); + Vector2 get_offset() const; + + void set_centered(bool p_centered); + bool is_centered() const; + + void set_rotating(bool p_rotating); + bool is_rotating() const; + + void set_limit(Margin p_margin,int p_limit); + int get_limit(Margin p_margin) const; + + + void set_h_drag_enabled(bool p_enabled); + bool is_h_drag_enabled() const; + + void set_v_drag_enabled(bool p_enabled); + bool is_v_drag_enabled() const; + + void set_drag_margin(Margin p_margin,float p_drag_margin); + float get_drag_margin(Margin p_margin) const; + + void set_v_offset(float p_offset); + float get_v_offset() const; + + void set_h_offset(float p_offset); + float get_h_offset() const; + + void set_follow_smoothing(float p_speed); + float get_follow_smoothing() const; + + void make_current(); + void clear_current(); + bool is_current() const; + + void set_zoom(const Vector2& p_zoom); + Vector2 get_zoom() const; + + Point2 get_camera_screen_center() const; + + Vector2 get_camera_pos() const; + void force_update_scroll(); + + Camera2D(); +}; + +#endif // CAMERA_2D_H diff --git a/scene/resources/shader_graph.h b/scene/resources/shader_graph.h index 55d09b4c38..c515f6e101 100644 --- a/scene/resources/shader_graph.h +++ b/scene/resources/shader_graph.h @@ -66,6 +66,8 @@ public: NODE_VEC_TO_XFORM, // 3 vec input, 1 xform output NODE_SCALAR_INTERP, // scalar interpolation (with optional curve) NODE_VEC_INTERP, // vec3 interpolation (with optional curve) + /*NODE_SCALAR_CURVE_REMAP, + NODE_VEC_CURVE_REMAP,*/ NODE_SCALAR_INPUT, // scalar uniform (assignable in material) NODE_VEC_INPUT, // vec3 uniform (assignable in material) NODE_RGB_INPUT, // color uniform (assignable in material) diff --git a/servers/visual/shader_language.cpp b/servers/visual/shader_language.cpp index 9a76a009a9..30499ca210 100644 --- a/servers/visual/shader_language.cpp +++ b/servers/visual/shader_language.cpp @@ -2058,7 +2058,9 @@ Error ShaderLanguage::parse_expression(Parser& parser,Node *p_parent,Node **r_ex at+=get_datatype_name(compute_node_type(op->arguments[i])); } - parser.set_error("Invalid arguments to operator "+String(token_names[op->op])+": "+at); + static const char *op_names[OP_MAX]={"=","+","-","*","/","+=","-=","*=","/=","-","!","==","!=","<=",">=","<",">","||","&&","call","()"}; + + parser.set_error("Invalid arguments to operator "+String(op_names[op->op])+": "+at); return ERR_PARSE_ERROR; } expression.remove(next_op); diff --git a/tools/collada/collada.cpp b/tools/collada/collada.cpp index 97e9f5c36d..b55edde801 100644 --- a/tools/collada/collada.cpp +++ b/tools/collada/collada.cpp @@ -817,7 +817,7 @@ void Collada::_parse_camera(XMLParser& parser) { if (name=="perspective") { camera.mode=CameraData::MODE_PERSPECTIVE; - } else if (name=="orthogonal") { + } else if (name=="orthographic") { camera.mode=CameraData::MODE_ORTHOGONAL; } else if (name=="xfov") { diff --git a/tools/collada/collada.h b/tools/collada/collada.h index f523d24e02..7691d90c0a 100644 --- a/tools/collada/collada.h +++ b/tools/collada/collada.h @@ -337,6 +337,24 @@ public: if(normal==p_vert.normal) { if(uv==p_vert.uv) { if(uv2==p_vert.uv2) { + + if (!weights.empty() || !p_vert.weights.empty()) { + + if (weights.size()==p_vert.weights.size()) { + + for(int i=0;i 0) { + pad = p_alignment - rest; + }; + + return pad; +}; Error EditorExportPlatform::save_pack_file(void *p_userdata,const String& p_path, const Vector& p_data,int p_file,int p_total) { @@ -930,11 +940,19 @@ Error EditorExportPlatform::save_pack_file(void *p_userdata,const String& p_path pd->ep->step("Storing File: "+p_path,2+p_file*100/p_total); pd->count++; pd->ftmp->store_buffer(p_data.ptr(),p_data.size()); + if (pd->alignment > 1) { + + int pad = _get_pad(pd->alignment, pd->ftmp->get_pos()); + for (int i=0; iftmp->store_8(0); + }; + }; return OK; } -Error EditorExportPlatform::save_pack(FileAccess *dst,bool p_make_bundles) { +Error EditorExportPlatform::save_pack(FileAccess *dst,bool p_make_bundles, int p_alignment) { EditorProgress ep("savepack","Packing",102); @@ -952,7 +970,6 @@ Error EditorExportPlatform::save_pack(FileAccess *dst,bool p_make_bundles) { dst->store_32(0); } - size_t fcountpos = dst->get_pos(); dst->store_32(0); @@ -961,11 +978,20 @@ Error EditorExportPlatform::save_pack(FileAccess *dst,bool p_make_bundles) { pd.f=dst; pd.ftmp=tmp; pd.count=0; + pd.alignment = p_alignment; Error err = export_project_files(save_pack_file,&pd,p_make_bundles); memdelete(tmp); if (err) return err; + if (p_alignment > 1) { + int pad = _get_pad(p_alignment, dst->get_pos()); + for (int i=0; istore_8(0); + }; + }; + size_t ofsplus = dst->get_pos(); //append file diff --git a/tools/editor/editor_import_export.h b/tools/editor/editor_import_export.h index 8305e3c88c..b97dde12f2 100644 --- a/tools/editor/editor_import_export.h +++ b/tools/editor/editor_import_export.h @@ -100,6 +100,7 @@ protected: Vector file_ofs; EditorProgress *ep; int count; + int alignment; }; @@ -121,7 +122,7 @@ public: Error export_project_files(EditorExportSaveFunction p_func, void* p_udata,bool p_make_bundles); - Error save_pack(FileAccess *p_where, bool p_make_bundles=false); + Error save_pack(FileAccess *p_where, bool p_make_bundles=false, int p_alignment = 1); virtual String get_name() const =0; virtual ImageCompression get_image_compression() const=0; virtual Ref get_logo() const =0; diff --git a/tools/editor/io_plugins/editor_import_collada.cpp b/tools/editor/io_plugins/editor_import_collada.cpp index 529ed3374b..6dd46843cc 100644 --- a/tools/editor/io_plugins/editor_import_collada.cpp +++ b/tools/editor/io_plugins/editor_import_collada.cpp @@ -285,13 +285,16 @@ Error ColladaImport::_create_scene(Collada::Node *p_node, Spatial *p_parent) { case Collada::CameraData::MODE_ORTHOGONAL: { - if (cd.orthogonal.x_mag) { + if (cd.orthogonal.y_mag) { - camera->set_orthogonal(cd.orthogonal.x_mag,cd.z_near,cd.z_far); + camera->set_keep_aspect_mode(Camera::KEEP_HEIGHT); + camera->set_orthogonal(cd.orthogonal.y_mag*2.0 ,cd.z_near,cd.z_far); - } else if (!cd.orthogonal.x_mag && cd.orthogonal.y_mag) { + } else if (!cd.orthogonal.y_mag && cd.orthogonal.x_mag) { - camera->set_orthogonal(cd.orthogonal.y_mag * cd.aspect,cd.z_near,cd.z_far); + + camera->set_keep_aspect_mode(Camera::KEEP_WIDTH); + camera->set_orthogonal(cd.orthogonal.x_mag*2.0,cd.z_near,cd.z_far); } } break; diff --git a/tools/export/blender25/io_scene_dae/export_dae.py b/tools/export/blender25/io_scene_dae/export_dae.py index 8161f05bf8..5e5febfb1f 100644 --- a/tools/export/blender25/io_scene_dae/export_dae.py +++ b/tools/export/blender25/io_scene_dae/export_dae.py @@ -94,8 +94,6 @@ def strarr(arr): s+=" " return s - - class DaeExporter: def validate_id(self,d): @@ -132,10 +130,10 @@ class DaeExporter: tup = tup + (self.tangent.x,self.tangent.y,self.tangent.z) if (self.bitangent!=None): tup = tup + (self.bitangent.x,self.bitangent.y,self.bitangent.z) - #for t in self.bones: - # tup = tup + (t) - #for t in self.weights: - # tup = tup + (t) + for t in self.bones: + tup = tup + (float(t),) + for t in self.weights: + tup = tup + (float(t),) return tup @@ -212,8 +210,8 @@ class DaeExporter: imgid = self.new_id("image") if (not os.path.isfile(imgpath)): - if img_tmp_path.endswith((".bmp",".rgb",".png",".jpeg",".jpg",".jp2",".tga",".cin",".dpx",".exr",".hdr",".tif")): - imgpath="images/"+os.path.basename(img_tmp_path) + if imgpath.endswith((".bmp",".rgb",".png",".jpeg",".jpg",".jp2",".tga",".cin",".dpx",".exr",".hdr",".tif")): + imgpath="images/"+os.path.basename(imgpath) else: imgpath="images/"+image.name+".png" @@ -512,12 +510,12 @@ class DaeExporter: mat_assign=[] uv_layer_count=len(mesh.uv_textures) - if (len(mesh.uv_textures)): + if (has_tangents and len(mesh.uv_textures)): try: mesh.calc_tangents() except: - print("Warning, blender API is fucked up, not exporting UVs for this object.") - uv_layer_count=0 + self.operator.report({'WARNING'},'CalcTangets failed for mesh "'+mesh.name+'", no tangets will be exported.') + #uv_layer_count=0 mesh.calc_normals_split() has_tangents=False @@ -591,16 +589,30 @@ class DaeExporter: if (armature!=None): wsum=0.0 + zero_bones=[] + for vg in mv.groups: if vg.group >= len(node.vertex_groups): continue; name = node.vertex_groups[vg.group].name + if (name in si["bone_index"]): #could still put the weight as 0.0001 maybe if (vg.weight>0.001): #blender has a lot of zero weight stuff v.bones.append(si["bone_index"][name]) v.weights.append(vg.weight) wsum+=vg.weight + if (wsum==0.0): + if not self.wrongvtx_report: + self.operator.report({'WARNING'},'Mesh for object "'+node.name+'" has unassigned weights. This may look wrong in exported model.') + self.wrongvtx_report=True + + #blender can have bones assigned that weight zero so they remain local + #this is the best it can be done? + v.bones.append(0) + v.weights.append(1) + + tup = v.get_tup() @@ -889,6 +901,15 @@ class DaeExporter: if (node.parent!=None): if (node.parent.type=="ARMATURE"): armature=node.parent + armcount=0 + for n in node.modifiers: + if (n.type=="ARMATURE"): + armcount+=1 + if (armcount>1): + self.operator.report({'WARNING'},'Object "'+node.name+'" refers to more than one armature! This is unsopported.') + + + if (node.data.shape_keys!=None): sk = node.data.shape_keys @@ -940,6 +961,12 @@ class DaeExporter: boneidx = si["bone_count"] si["bone_count"]+=1 bonesid = si["id"]+"-"+str(boneidx) + if (bone.name in self.used_bones): + if (self.config["use_anim_action_all"]): + self.operator.report({'WARNING'},'Bone name "'+bone.name+'" used in more than one skeleton. Actions might export wrong.') + else: + self.used_bones.append(bone.name) + si["bone_index"][bone.name]=boneidx si["bone_ids"][bone]=boneid si["bone_names"].append(bonesid) @@ -1002,12 +1029,12 @@ class DaeExporter: self.writel(S_CAMS,5,' '+str(camera.clip_end)+' ') self.writel(S_CAMS,4,'') else: - self.writel(S_CAMS,4,'') - self.writel(S_CAMS,5,' '+str(camera.ortho_scale)+' ') # I think? + self.writel(S_CAMS,4,'') + self.writel(S_CAMS,5,' '+str(camera.ortho_scale*0.5)+' ') # I think? self.writel(S_CAMS,5,' '+str(self.scene.render.resolution_x / self.scene.render.resolution_y)+' ') self.writel(S_CAMS,5,' '+str(camera.clip_start)+' ') self.writel(S_CAMS,5,' '+str(camera.clip_end)+' ') - self.writel(S_CAMS,4,'') + self.writel(S_CAMS,4,'') self.writel(S_CAMS,3,'') self.writel(S_CAMS,2,'') @@ -1534,10 +1561,14 @@ class DaeExporter: for z in tcn: self.writel(S_ANIM_CLIPS,2,'') self.writel(S_ANIM_CLIPS,1,'') + if (len(tcn)==0): + self.operator.report({'WARNING'},'Animation clip "'+x.name+'" contains no tracks.') + self.writel(S_ANIM_CLIPS,0,'') + for i,s in enumerate(self.skeletons): if (s.animation_data==None): continue @@ -1547,6 +1578,7 @@ class DaeExporter: s.animation_data.action = None for j,bone in enumerate(s.pose.bones): bone.matrix_basis = tmp_mat[i][1][j] + else: self.export_animation(self.scene.frame_start,self.scene.frame_end) @@ -1617,7 +1649,8 @@ class DaeExporter: f.write(bytes('\n',"UTF-8")) return True - def __init__(self,path,kwargs): + def __init__(self,path,kwargs,operator): + self.operator=operator self.scene=bpy.context.scene self.last_id=0 self.scene_name=self.new_id("scene") @@ -1631,6 +1664,10 @@ class DaeExporter: self.config=kwargs self.valid_nodes=[] self.armature_for_morph={} + self.used_bones=[] + self.wrongvtx_report=False + + @@ -1642,9 +1679,11 @@ def save(operator, context, **kwargs ): - exp = DaeExporter(filepath,kwargs) + exp = DaeExporter(filepath,kwargs,operator) exp.export() + + return {'FINISHED'} # so the script wont run after we have batch exported. -- cgit v1.2.3 From 09489e3a78de39bb4d8690f3c65f8a5e7a56a95e Mon Sep 17 00:00:00 2001 From: Juan Linietsky Date: Mon, 9 Mar 2015 02:34:56 -0300 Subject: lot of work on 2D lighting and isometric maps added a new demo, isometric_light that does full isometric sorting, lights, shadows, etc. --- LICENSE.md | 4 + demos/2d/isometric_light/character_shder.res | Bin 0 -> 1150 bytes demos/2d/isometric_light/column.scn | Bin 0 -> 1909 bytes demos/2d/isometric_light/cubio.gd | 96 +++++++ demos/2d/isometric_light/cubio.scn | Bin 0 -> 6878 bytes demos/2d/isometric_light/cubio/idle0001.png | Bin 0 -> 7163 bytes demos/2d/isometric_light/cubio/idle0002.png | Bin 0 -> 7182 bytes demos/2d/isometric_light/cubio/idle0003.png | Bin 0 -> 7173 bytes demos/2d/isometric_light/cubio/idle0004.png | Bin 0 -> 7174 bytes demos/2d/isometric_light/cubio/idle0005.png | Bin 0 -> 7207 bytes demos/2d/isometric_light/cubio/idle0006.png | Bin 0 -> 7302 bytes demos/2d/isometric_light/cubio/idle0007.png | Bin 0 -> 7296 bytes demos/2d/isometric_light/cubio/idle0008.png | Bin 0 -> 7332 bytes demos/2d/isometric_light/cubio/idle0009.png | Bin 0 -> 7320 bytes demos/2d/isometric_light/cubio/idle0010.png | Bin 0 -> 7311 bytes demos/2d/isometric_light/cubio/idle0011.png | Bin 0 -> 7359 bytes demos/2d/isometric_light/cubio/idle0012.png | Bin 0 -> 7392 bytes demos/2d/isometric_light/cubio/idle0013.png | Bin 0 -> 7398 bytes demos/2d/isometric_light/cubio/idle0014.png | Bin 0 -> 7399 bytes demos/2d/isometric_light/cubio/idle0015.png | Bin 0 -> 7340 bytes demos/2d/isometric_light/cubio/idle0016.png | Bin 0 -> 7278 bytes demos/2d/isometric_light/cubio/idle0017.png | Bin 0 -> 7342 bytes demos/2d/isometric_light/cubio/idle0018.png | Bin 0 -> 7370 bytes demos/2d/isometric_light/cubio/idle0019.png | Bin 0 -> 7379 bytes demos/2d/isometric_light/cubio/idle0020.png | Bin 0 -> 7432 bytes demos/2d/isometric_light/cubio/idle0021.png | Bin 0 -> 7391 bytes demos/2d/isometric_light/cubio/idle0022.png | Bin 0 -> 7381 bytes demos/2d/isometric_light/cubio/idle0023.png | Bin 0 -> 7330 bytes demos/2d/isometric_light/cubio/idle0024.png | Bin 0 -> 7363 bytes demos/2d/isometric_light/cubio/idle0025.png | Bin 0 -> 7368 bytes demos/2d/isometric_light/cubio/idle0026.png | Bin 0 -> 7356 bytes demos/2d/isometric_light/cubio/idle0027.png | Bin 0 -> 7358 bytes demos/2d/isometric_light/cubio/idle0028.png | Bin 0 -> 7294 bytes demos/2d/isometric_light/cubio/idle0029.png | Bin 0 -> 7342 bytes demos/2d/isometric_light/cubio/idle0030.png | Bin 0 -> 7402 bytes demos/2d/isometric_light/cubio/idle0031.png | Bin 0 -> 7442 bytes demos/2d/isometric_light/cubio/idle0032.png | Bin 0 -> 7409 bytes demos/2d/isometric_light/cubio/idle0033.png | Bin 0 -> 7407 bytes demos/2d/isometric_light/cubio/idle0034.png | Bin 0 -> 7389 bytes demos/2d/isometric_light/cubio/idle0035.png | Bin 0 -> 7351 bytes demos/2d/isometric_light/cubio/idle0036.png | Bin 0 -> 7348 bytes demos/2d/isometric_light/cubio/idle0037.png | Bin 0 -> 7356 bytes demos/2d/isometric_light/cubio/idle0038.png | Bin 0 -> 7318 bytes demos/2d/isometric_light/cubio/idle0039.png | Bin 0 -> 7366 bytes demos/2d/isometric_light/cubio/idle0040.png | Bin 0 -> 7385 bytes demos/2d/isometric_light/cubio/idle0041.png | Bin 0 -> 7400 bytes demos/2d/isometric_light/cubio/idle0042.png | Bin 0 -> 7397 bytes demos/2d/isometric_light/cubio/idle0043.png | Bin 0 -> 7363 bytes demos/2d/isometric_light/cubio/idle0044.png | Bin 0 -> 7377 bytes demos/2d/isometric_light/cubio/idle0045.png | Bin 0 -> 7368 bytes demos/2d/isometric_light/cubio/idle0046.png | Bin 0 -> 7346 bytes demos/2d/isometric_light/cubio/idle0047.png | Bin 0 -> 7333 bytes demos/2d/isometric_light/cubio/idle0048.png | Bin 0 -> 7305 bytes demos/2d/isometric_light/cubio/idle0049.png | Bin 0 -> 7328 bytes demos/2d/isometric_light/cubio/idle0050.png | Bin 0 -> 7319 bytes demos/2d/isometric_light/cubio/idle0051.png | Bin 0 -> 7256 bytes demos/2d/isometric_light/cubio/idle0052.png | Bin 0 -> 7287 bytes demos/2d/isometric_light/cubio/idle0053.png | Bin 0 -> 7236 bytes demos/2d/isometric_light/cubio/idle0054.png | Bin 0 -> 7182 bytes demos/2d/isometric_light/cubio/idle0055.png | Bin 0 -> 7169 bytes demos/2d/isometric_light/cubio/idle0056.png | Bin 0 -> 7166 bytes demos/2d/isometric_light/cubio/idle0057.png | Bin 0 -> 7146 bytes demos/2d/isometric_light/cubio/idle0058.png | Bin 0 -> 7174 bytes demos/2d/isometric_light/cubio/idle0059.png | Bin 0 -> 7163 bytes demos/2d/isometric_light/cubio/idle0060.png | Bin 0 -> 7163 bytes demos/2d/isometric_light/cubio/norm-b-0001.png | Bin 0 -> 7027 bytes demos/2d/isometric_light/cubio/norm-b-0002.png | Bin 0 -> 7234 bytes demos/2d/isometric_light/cubio/norm-b-0003.png | Bin 0 -> 7658 bytes demos/2d/isometric_light/cubio/norm-b-0004.png | Bin 0 -> 7999 bytes demos/2d/isometric_light/cubio/norm-b-0005.png | Bin 0 -> 8086 bytes demos/2d/isometric_light/cubio/norm-b-0006.png | Bin 0 -> 8004 bytes demos/2d/isometric_light/cubio/norm-b-0007.png | Bin 0 -> 7759 bytes demos/2d/isometric_light/cubio/norm-b-0008.png | Bin 0 -> 7485 bytes demos/2d/isometric_light/cubio/norm-b-0009.png | Bin 0 -> 7066 bytes demos/2d/isometric_light/cubio/norm-b-0010.png | Bin 0 -> 6925 bytes demos/2d/isometric_light/cubio/norm-b-0011.png | Bin 0 -> 7003 bytes demos/2d/isometric_light/cubio/norm-b-0012.png | Bin 0 -> 7316 bytes demos/2d/isometric_light/cubio/norm-b-0013.png | Bin 0 -> 7607 bytes demos/2d/isometric_light/cubio/norm-b-0014.png | Bin 0 -> 7924 bytes demos/2d/isometric_light/cubio/norm-b-0015.png | Bin 0 -> 8000 bytes demos/2d/isometric_light/cubio/norm-b-0016.png | Bin 0 -> 8025 bytes demos/2d/isometric_light/cubio/norm-b-0017.png | Bin 0 -> 7918 bytes demos/2d/isometric_light/cubio/norm-b-0018.png | Bin 0 -> 7532 bytes demos/2d/isometric_light/cubio/norm-b-0019.png | Bin 0 -> 7247 bytes demos/2d/isometric_light/cubio/norm-b-0020.png | Bin 0 -> 7035 bytes demos/2d/isometric_light/cubio/norm-bl-0001.png | Bin 0 -> 7097 bytes demos/2d/isometric_light/cubio/norm-bl-0002.png | Bin 0 -> 7074 bytes demos/2d/isometric_light/cubio/norm-bl-0003.png | Bin 0 -> 7273 bytes demos/2d/isometric_light/cubio/norm-bl-0004.png | Bin 0 -> 7778 bytes demos/2d/isometric_light/cubio/norm-bl-0005.png | Bin 0 -> 7717 bytes demos/2d/isometric_light/cubio/norm-bl-0006.png | Bin 0 -> 8142 bytes demos/2d/isometric_light/cubio/norm-bl-0007.png | Bin 0 -> 8300 bytes demos/2d/isometric_light/cubio/norm-bl-0008.png | Bin 0 -> 8653 bytes demos/2d/isometric_light/cubio/norm-bl-0009.png | Bin 0 -> 8846 bytes demos/2d/isometric_light/cubio/norm-bl-0010.png | Bin 0 -> 8824 bytes demos/2d/isometric_light/cubio/norm-bl-0011.png | Bin 0 -> 8848 bytes demos/2d/isometric_light/cubio/norm-bl-0012.png | Bin 0 -> 8649 bytes demos/2d/isometric_light/cubio/norm-bl-0013.png | Bin 0 -> 8695 bytes demos/2d/isometric_light/cubio/norm-bl-0014.png | Bin 0 -> 8435 bytes demos/2d/isometric_light/cubio/norm-bl-0015.png | Bin 0 -> 8226 bytes demos/2d/isometric_light/cubio/norm-bl-0016.png | Bin 0 -> 7895 bytes demos/2d/isometric_light/cubio/norm-bl-0017.png | Bin 0 -> 7712 bytes demos/2d/isometric_light/cubio/norm-bl-0018.png | Bin 0 -> 7103 bytes demos/2d/isometric_light/cubio/norm-bl-0019.png | Bin 0 -> 7094 bytes demos/2d/isometric_light/cubio/norm-bl-0020.png | Bin 0 -> 7051 bytes demos/2d/isometric_light/cubio/norm-l-0001.png | Bin 0 -> 8257 bytes demos/2d/isometric_light/cubio/norm-l-0002.png | Bin 0 -> 7883 bytes demos/2d/isometric_light/cubio/norm-l-0003.png | Bin 0 -> 6680 bytes demos/2d/isometric_light/cubio/norm-l-0004.png | Bin 0 -> 6278 bytes demos/2d/isometric_light/cubio/norm-l-0005.png | Bin 0 -> 6348 bytes demos/2d/isometric_light/cubio/norm-l-0006.png | Bin 0 -> 5629 bytes demos/2d/isometric_light/cubio/norm-l-0007.png | Bin 0 -> 6754 bytes demos/2d/isometric_light/cubio/norm-l-0008.png | Bin 0 -> 7612 bytes demos/2d/isometric_light/cubio/norm-l-0009.png | Bin 0 -> 8044 bytes demos/2d/isometric_light/cubio/norm-l-0010.png | Bin 0 -> 8013 bytes demos/2d/isometric_light/cubio/norm-l-0011.png | Bin 0 -> 7917 bytes demos/2d/isometric_light/cubio/norm-l-0012.png | Bin 0 -> 7692 bytes demos/2d/isometric_light/cubio/norm-l-0013.png | Bin 0 -> 6778 bytes demos/2d/isometric_light/cubio/norm-l-0014.png | Bin 0 -> 6176 bytes demos/2d/isometric_light/cubio/norm-l-0015.png | Bin 0 -> 6263 bytes demos/2d/isometric_light/cubio/norm-l-0016.png | Bin 0 -> 6004 bytes demos/2d/isometric_light/cubio/norm-l-0017.png | Bin 0 -> 6483 bytes demos/2d/isometric_light/cubio/norm-l-0018.png | Bin 0 -> 7276 bytes demos/2d/isometric_light/cubio/norm-l-0019.png | Bin 0 -> 7899 bytes demos/2d/isometric_light/cubio/norm-l-0020.png | Bin 0 -> 8119 bytes demos/2d/isometric_light/cubio/norm-u-0001.png | Bin 0 -> 7095 bytes demos/2d/isometric_light/cubio/norm-u-0002.png | Bin 0 -> 7064 bytes demos/2d/isometric_light/cubio/norm-u-0003.png | Bin 0 -> 6854 bytes demos/2d/isometric_light/cubio/norm-u-0004.png | Bin 0 -> 6801 bytes demos/2d/isometric_light/cubio/norm-u-0005.png | Bin 0 -> 6900 bytes demos/2d/isometric_light/cubio/norm-u-0006.png | Bin 0 -> 7017 bytes demos/2d/isometric_light/cubio/norm-u-0007.png | Bin 0 -> 7128 bytes demos/2d/isometric_light/cubio/norm-u-0008.png | Bin 0 -> 7065 bytes demos/2d/isometric_light/cubio/norm-u-0009.png | Bin 0 -> 7000 bytes demos/2d/isometric_light/cubio/norm-u-0010.png | Bin 0 -> 6980 bytes demos/2d/isometric_light/cubio/norm-u-0011.png | Bin 0 -> 6978 bytes demos/2d/isometric_light/cubio/norm-u-0012.png | Bin 0 -> 7139 bytes demos/2d/isometric_light/cubio/norm-u-0013.png | Bin 0 -> 7191 bytes demos/2d/isometric_light/cubio/norm-u-0014.png | Bin 0 -> 7119 bytes demos/2d/isometric_light/cubio/norm-u-0015.png | Bin 0 -> 7051 bytes demos/2d/isometric_light/cubio/norm-u-0016.png | Bin 0 -> 6995 bytes demos/2d/isometric_light/cubio/norm-u-0017.png | Bin 0 -> 6832 bytes demos/2d/isometric_light/cubio/norm-u-0018.png | Bin 0 -> 6962 bytes demos/2d/isometric_light/cubio/norm-u-0019.png | Bin 0 -> 7049 bytes demos/2d/isometric_light/cubio/norm-u-0020.png | Bin 0 -> 7067 bytes demos/2d/isometric_light/cubio/norm-ul-0001.png | Bin 0 -> 8202 bytes demos/2d/isometric_light/cubio/norm-ul-0002.png | Bin 0 -> 8074 bytes demos/2d/isometric_light/cubio/norm-ul-0003.png | Bin 0 -> 7716 bytes demos/2d/isometric_light/cubio/norm-ul-0004.png | Bin 0 -> 7587 bytes demos/2d/isometric_light/cubio/norm-ul-0005.png | Bin 0 -> 7383 bytes demos/2d/isometric_light/cubio/norm-ul-0006.png | Bin 0 -> 7107 bytes demos/2d/isometric_light/cubio/norm-ul-0007.png | Bin 0 -> 6671 bytes demos/2d/isometric_light/cubio/norm-ul-0008.png | Bin 0 -> 6847 bytes demos/2d/isometric_light/cubio/norm-ul-0009.png | Bin 0 -> 6892 bytes demos/2d/isometric_light/cubio/norm-ul-0010.png | Bin 0 -> 6858 bytes demos/2d/isometric_light/cubio/norm-ul-0011.png | Bin 0 -> 7067 bytes demos/2d/isometric_light/cubio/norm-ul-0012.png | Bin 0 -> 6985 bytes demos/2d/isometric_light/cubio/norm-ul-0013.png | Bin 0 -> 6600 bytes demos/2d/isometric_light/cubio/norm-ul-0014.png | Bin 0 -> 7104 bytes demos/2d/isometric_light/cubio/norm-ul-0015.png | Bin 0 -> 7320 bytes demos/2d/isometric_light/cubio/norm-ul-0016.png | Bin 0 -> 7478 bytes demos/2d/isometric_light/cubio/norm-ul-0017.png | Bin 0 -> 7736 bytes demos/2d/isometric_light/cubio/norm-ul-0018.png | Bin 0 -> 7960 bytes demos/2d/isometric_light/cubio/norm-ul-0019.png | Bin 0 -> 7982 bytes demos/2d/isometric_light/cubio/norm-ul-0020.png | Bin 0 -> 8137 bytes demos/2d/isometric_light/energy.png | Bin 0 -> 6968 bytes demos/2d/isometric_light/engine.cfg | 14 + demos/2d/isometric_light/faceColor.png | Bin 0 -> 45476 bytes demos/2d/isometric_light/faceMask.png | Bin 0 -> 3106 bytes demos/2d/isometric_light/faceNormal.png | Bin 0 -> 131067 bytes demos/2d/isometric_light/fire.png | Bin 0 -> 8116 bytes demos/2d/isometric_light/floor_shader.res | Bin 0 -> 972 bytes demos/2d/isometric_light/light2.png | Bin 0 -> 60871 bytes demos/2d/isometric_light/map.gd | 18 ++ demos/2d/isometric_light/map.scn | Bin 0 -> 8520 bytes demos/2d/isometric_light/shadow_blob.png | Bin 0 -> 884 bytes demos/2d/isometric_light/shoot.gd | 27 ++ demos/2d/isometric_light/shoot.scn | Bin 0 -> 4561 bytes demos/2d/isometric_light/shoot_halo.png | Bin 0 -> 91312 bytes demos/2d/isometric_light/tileset.res | Bin 0 -> 2775 bytes demos/2d/isometric_light/tileset_scene.scn | Bin 0 -> 4813 bytes demos/2d/isometric_light/torch.scn | Bin 0 -> 4232 bytes demos/2d/isometric_light/torch_light.png | Bin 0 -> 28516 bytes demos/2d/isometric_light/torch_shader.res | Bin 0 -> 741 bytes demos/2d/isometric_light/wall_shader.res | Bin 0 -> 1628 bytes drivers/gles2/rasterizer_gles2.cpp | 10 +- drivers/gles2/shader_compiler_gles2.cpp | 17 +- drivers/gles2/shaders/canvas.glsl | 180 ++++++------ scene/2d/canvas_item.cpp | 1 + scene/2d/light_2d.cpp | 17 ++ scene/2d/light_2d.h | 4 + scene/2d/light_occluder_2d.cpp | 5 +- scene/2d/tile_map.cpp | 308 ++++++++++++++++++--- scene/2d/tile_map.h | 41 ++- scene/2d/visibility_notifier_2d.cpp | 22 ++ scene/2d/visibility_notifier_2d.h | 1 + scene/gui/control.cpp | 84 +++--- scene/resources/tile_set.cpp | 106 ++++++- scene/resources/tile_set.h | 22 ++ servers/visual/rasterizer.h | 2 + servers/visual/shader_language.cpp | 16 +- servers/visual/visual_server_raster.cpp | 23 +- servers/visual/visual_server_raster.h | 1 + servers/visual/visual_server_wrap_mt.h | 1 + servers/visual_server.h | 1 + tools/editor/plugins/canvas_item_editor_plugin.cpp | 101 ++++++- tools/editor/plugins/canvas_item_editor_plugin.h | 11 +- .../plugins/collision_polygon_2d_editor_plugin.cpp | 1 + .../plugins/light_occluder_2d_editor_plugin.cpp | 6 +- .../plugins/navigation_polygon_editor_plugin.cpp | 6 +- tools/editor/plugins/tile_map_editor_plugin.cpp | 40 ++- tools/editor/plugins/tile_set_editor_plugin.cpp | 170 +++++++----- tools/editor/plugins/tile_set_editor_plugin.h | 2 +- tools/editor/property_editor.cpp | 6 +- 214 files changed, 1074 insertions(+), 290 deletions(-) create mode 100644 demos/2d/isometric_light/character_shder.res create mode 100644 demos/2d/isometric_light/column.scn create mode 100644 demos/2d/isometric_light/cubio.gd create mode 100644 demos/2d/isometric_light/cubio.scn create mode 100644 demos/2d/isometric_light/cubio/idle0001.png create mode 100644 demos/2d/isometric_light/cubio/idle0002.png create mode 100644 demos/2d/isometric_light/cubio/idle0003.png create mode 100644 demos/2d/isometric_light/cubio/idle0004.png create mode 100644 demos/2d/isometric_light/cubio/idle0005.png create mode 100644 demos/2d/isometric_light/cubio/idle0006.png create mode 100644 demos/2d/isometric_light/cubio/idle0007.png create mode 100644 demos/2d/isometric_light/cubio/idle0008.png create mode 100644 demos/2d/isometric_light/cubio/idle0009.png create mode 100644 demos/2d/isometric_light/cubio/idle0010.png create mode 100644 demos/2d/isometric_light/cubio/idle0011.png create mode 100644 demos/2d/isometric_light/cubio/idle0012.png create mode 100644 demos/2d/isometric_light/cubio/idle0013.png create mode 100644 demos/2d/isometric_light/cubio/idle0014.png create mode 100644 demos/2d/isometric_light/cubio/idle0015.png create mode 100644 demos/2d/isometric_light/cubio/idle0016.png create mode 100644 demos/2d/isometric_light/cubio/idle0017.png create mode 100644 demos/2d/isometric_light/cubio/idle0018.png create mode 100644 demos/2d/isometric_light/cubio/idle0019.png create mode 100644 demos/2d/isometric_light/cubio/idle0020.png create mode 100644 demos/2d/isometric_light/cubio/idle0021.png create mode 100644 demos/2d/isometric_light/cubio/idle0022.png create mode 100644 demos/2d/isometric_light/cubio/idle0023.png create mode 100644 demos/2d/isometric_light/cubio/idle0024.png create mode 100644 demos/2d/isometric_light/cubio/idle0025.png create mode 100644 demos/2d/isometric_light/cubio/idle0026.png create mode 100644 demos/2d/isometric_light/cubio/idle0027.png create mode 100644 demos/2d/isometric_light/cubio/idle0028.png create mode 100644 demos/2d/isometric_light/cubio/idle0029.png create mode 100644 demos/2d/isometric_light/cubio/idle0030.png create mode 100644 demos/2d/isometric_light/cubio/idle0031.png create mode 100644 demos/2d/isometric_light/cubio/idle0032.png create mode 100644 demos/2d/isometric_light/cubio/idle0033.png create mode 100644 demos/2d/isometric_light/cubio/idle0034.png create mode 100644 demos/2d/isometric_light/cubio/idle0035.png create mode 100644 demos/2d/isometric_light/cubio/idle0036.png create mode 100644 demos/2d/isometric_light/cubio/idle0037.png create mode 100644 demos/2d/isometric_light/cubio/idle0038.png create mode 100644 demos/2d/isometric_light/cubio/idle0039.png create mode 100644 demos/2d/isometric_light/cubio/idle0040.png create mode 100644 demos/2d/isometric_light/cubio/idle0041.png create mode 100644 demos/2d/isometric_light/cubio/idle0042.png create mode 100644 demos/2d/isometric_light/cubio/idle0043.png create mode 100644 demos/2d/isometric_light/cubio/idle0044.png create mode 100644 demos/2d/isometric_light/cubio/idle0045.png create mode 100644 demos/2d/isometric_light/cubio/idle0046.png create mode 100644 demos/2d/isometric_light/cubio/idle0047.png create mode 100644 demos/2d/isometric_light/cubio/idle0048.png create mode 100644 demos/2d/isometric_light/cubio/idle0049.png create mode 100644 demos/2d/isometric_light/cubio/idle0050.png create mode 100644 demos/2d/isometric_light/cubio/idle0051.png create mode 100644 demos/2d/isometric_light/cubio/idle0052.png create mode 100644 demos/2d/isometric_light/cubio/idle0053.png create mode 100644 demos/2d/isometric_light/cubio/idle0054.png create mode 100644 demos/2d/isometric_light/cubio/idle0055.png create mode 100644 demos/2d/isometric_light/cubio/idle0056.png create mode 100644 demos/2d/isometric_light/cubio/idle0057.png create mode 100644 demos/2d/isometric_light/cubio/idle0058.png create mode 100644 demos/2d/isometric_light/cubio/idle0059.png create mode 100644 demos/2d/isometric_light/cubio/idle0060.png create mode 100644 demos/2d/isometric_light/cubio/norm-b-0001.png create mode 100644 demos/2d/isometric_light/cubio/norm-b-0002.png create mode 100644 demos/2d/isometric_light/cubio/norm-b-0003.png create mode 100644 demos/2d/isometric_light/cubio/norm-b-0004.png create mode 100644 demos/2d/isometric_light/cubio/norm-b-0005.png create mode 100644 demos/2d/isometric_light/cubio/norm-b-0006.png create mode 100644 demos/2d/isometric_light/cubio/norm-b-0007.png create mode 100644 demos/2d/isometric_light/cubio/norm-b-0008.png create mode 100644 demos/2d/isometric_light/cubio/norm-b-0009.png create mode 100644 demos/2d/isometric_light/cubio/norm-b-0010.png create mode 100644 demos/2d/isometric_light/cubio/norm-b-0011.png create mode 100644 demos/2d/isometric_light/cubio/norm-b-0012.png create mode 100644 demos/2d/isometric_light/cubio/norm-b-0013.png create mode 100644 demos/2d/isometric_light/cubio/norm-b-0014.png create mode 100644 demos/2d/isometric_light/cubio/norm-b-0015.png create mode 100644 demos/2d/isometric_light/cubio/norm-b-0016.png create mode 100644 demos/2d/isometric_light/cubio/norm-b-0017.png create mode 100644 demos/2d/isometric_light/cubio/norm-b-0018.png create mode 100644 demos/2d/isometric_light/cubio/norm-b-0019.png create mode 100644 demos/2d/isometric_light/cubio/norm-b-0020.png create mode 100644 demos/2d/isometric_light/cubio/norm-bl-0001.png create mode 100644 demos/2d/isometric_light/cubio/norm-bl-0002.png create mode 100644 demos/2d/isometric_light/cubio/norm-bl-0003.png create mode 100644 demos/2d/isometric_light/cubio/norm-bl-0004.png create mode 100644 demos/2d/isometric_light/cubio/norm-bl-0005.png create mode 100644 demos/2d/isometric_light/cubio/norm-bl-0006.png create mode 100644 demos/2d/isometric_light/cubio/norm-bl-0007.png create mode 100644 demos/2d/isometric_light/cubio/norm-bl-0008.png create mode 100644 demos/2d/isometric_light/cubio/norm-bl-0009.png create mode 100644 demos/2d/isometric_light/cubio/norm-bl-0010.png create mode 100644 demos/2d/isometric_light/cubio/norm-bl-0011.png create mode 100644 demos/2d/isometric_light/cubio/norm-bl-0012.png create mode 100644 demos/2d/isometric_light/cubio/norm-bl-0013.png create mode 100644 demos/2d/isometric_light/cubio/norm-bl-0014.png create mode 100644 demos/2d/isometric_light/cubio/norm-bl-0015.png create mode 100644 demos/2d/isometric_light/cubio/norm-bl-0016.png create mode 100644 demos/2d/isometric_light/cubio/norm-bl-0017.png create mode 100644 demos/2d/isometric_light/cubio/norm-bl-0018.png create mode 100644 demos/2d/isometric_light/cubio/norm-bl-0019.png create mode 100644 demos/2d/isometric_light/cubio/norm-bl-0020.png create mode 100644 demos/2d/isometric_light/cubio/norm-l-0001.png create mode 100644 demos/2d/isometric_light/cubio/norm-l-0002.png create mode 100644 demos/2d/isometric_light/cubio/norm-l-0003.png create mode 100644 demos/2d/isometric_light/cubio/norm-l-0004.png create mode 100644 demos/2d/isometric_light/cubio/norm-l-0005.png create mode 100644 demos/2d/isometric_light/cubio/norm-l-0006.png create mode 100644 demos/2d/isometric_light/cubio/norm-l-0007.png create mode 100644 demos/2d/isometric_light/cubio/norm-l-0008.png create mode 100644 demos/2d/isometric_light/cubio/norm-l-0009.png create mode 100644 demos/2d/isometric_light/cubio/norm-l-0010.png create mode 100644 demos/2d/isometric_light/cubio/norm-l-0011.png create mode 100644 demos/2d/isometric_light/cubio/norm-l-0012.png create mode 100644 demos/2d/isometric_light/cubio/norm-l-0013.png create mode 100644 demos/2d/isometric_light/cubio/norm-l-0014.png create mode 100644 demos/2d/isometric_light/cubio/norm-l-0015.png create mode 100644 demos/2d/isometric_light/cubio/norm-l-0016.png create mode 100644 demos/2d/isometric_light/cubio/norm-l-0017.png create mode 100644 demos/2d/isometric_light/cubio/norm-l-0018.png create mode 100644 demos/2d/isometric_light/cubio/norm-l-0019.png create mode 100644 demos/2d/isometric_light/cubio/norm-l-0020.png create mode 100644 demos/2d/isometric_light/cubio/norm-u-0001.png create mode 100644 demos/2d/isometric_light/cubio/norm-u-0002.png create mode 100644 demos/2d/isometric_light/cubio/norm-u-0003.png create mode 100644 demos/2d/isometric_light/cubio/norm-u-0004.png create mode 100644 demos/2d/isometric_light/cubio/norm-u-0005.png create mode 100644 demos/2d/isometric_light/cubio/norm-u-0006.png create mode 100644 demos/2d/isometric_light/cubio/norm-u-0007.png create mode 100644 demos/2d/isometric_light/cubio/norm-u-0008.png create mode 100644 demos/2d/isometric_light/cubio/norm-u-0009.png create mode 100644 demos/2d/isometric_light/cubio/norm-u-0010.png create mode 100644 demos/2d/isometric_light/cubio/norm-u-0011.png create mode 100644 demos/2d/isometric_light/cubio/norm-u-0012.png create mode 100644 demos/2d/isometric_light/cubio/norm-u-0013.png create mode 100644 demos/2d/isometric_light/cubio/norm-u-0014.png create mode 100644 demos/2d/isometric_light/cubio/norm-u-0015.png create mode 100644 demos/2d/isometric_light/cubio/norm-u-0016.png create mode 100644 demos/2d/isometric_light/cubio/norm-u-0017.png create mode 100644 demos/2d/isometric_light/cubio/norm-u-0018.png create mode 100644 demos/2d/isometric_light/cubio/norm-u-0019.png create mode 100644 demos/2d/isometric_light/cubio/norm-u-0020.png create mode 100644 demos/2d/isometric_light/cubio/norm-ul-0001.png create mode 100644 demos/2d/isometric_light/cubio/norm-ul-0002.png create mode 100644 demos/2d/isometric_light/cubio/norm-ul-0003.png create mode 100644 demos/2d/isometric_light/cubio/norm-ul-0004.png create mode 100644 demos/2d/isometric_light/cubio/norm-ul-0005.png create mode 100644 demos/2d/isometric_light/cubio/norm-ul-0006.png create mode 100644 demos/2d/isometric_light/cubio/norm-ul-0007.png create mode 100644 demos/2d/isometric_light/cubio/norm-ul-0008.png create mode 100644 demos/2d/isometric_light/cubio/norm-ul-0009.png create mode 100644 demos/2d/isometric_light/cubio/norm-ul-0010.png create mode 100644 demos/2d/isometric_light/cubio/norm-ul-0011.png create mode 100644 demos/2d/isometric_light/cubio/norm-ul-0012.png create mode 100644 demos/2d/isometric_light/cubio/norm-ul-0013.png create mode 100644 demos/2d/isometric_light/cubio/norm-ul-0014.png create mode 100644 demos/2d/isometric_light/cubio/norm-ul-0015.png create mode 100644 demos/2d/isometric_light/cubio/norm-ul-0016.png create mode 100644 demos/2d/isometric_light/cubio/norm-ul-0017.png create mode 100644 demos/2d/isometric_light/cubio/norm-ul-0018.png create mode 100644 demos/2d/isometric_light/cubio/norm-ul-0019.png create mode 100644 demos/2d/isometric_light/cubio/norm-ul-0020.png create mode 100644 demos/2d/isometric_light/energy.png create mode 100644 demos/2d/isometric_light/engine.cfg create mode 100644 demos/2d/isometric_light/faceColor.png create mode 100644 demos/2d/isometric_light/faceMask.png create mode 100644 demos/2d/isometric_light/faceNormal.png create mode 100644 demos/2d/isometric_light/fire.png create mode 100644 demos/2d/isometric_light/floor_shader.res create mode 100644 demos/2d/isometric_light/light2.png create mode 100644 demos/2d/isometric_light/map.gd create mode 100644 demos/2d/isometric_light/map.scn create mode 100644 demos/2d/isometric_light/shadow_blob.png create mode 100644 demos/2d/isometric_light/shoot.gd create mode 100644 demos/2d/isometric_light/shoot.scn create mode 100644 demos/2d/isometric_light/shoot_halo.png create mode 100644 demos/2d/isometric_light/tileset.res create mode 100644 demos/2d/isometric_light/tileset_scene.scn create mode 100644 demos/2d/isometric_light/torch.scn create mode 100644 demos/2d/isometric_light/torch_light.png create mode 100644 demos/2d/isometric_light/torch_shader.res create mode 100644 demos/2d/isometric_light/wall_shader.res diff --git a/LICENSE.md b/LICENSE.md index 122736f5f1..ca0a9702f7 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -21,3 +21,7 @@ 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. + + +********************************************************************** + diff --git a/demos/2d/isometric_light/character_shder.res b/demos/2d/isometric_light/character_shder.res new file mode 100644 index 0000000000..ca221f766c Binary files /dev/null and b/demos/2d/isometric_light/character_shder.res differ diff --git a/demos/2d/isometric_light/column.scn b/demos/2d/isometric_light/column.scn new file mode 100644 index 0000000000..f0b7683885 Binary files /dev/null and b/demos/2d/isometric_light/column.scn differ diff --git a/demos/2d/isometric_light/cubio.gd b/demos/2d/isometric_light/cubio.gd new file mode 100644 index 0000000000..30c766936c --- /dev/null +++ b/demos/2d/isometric_light/cubio.gd @@ -0,0 +1,96 @@ + +extends KinematicBody2D + +# member variables here, example: +# var a=2 +# var b="textvar" + +const MAX_SPEED = 300.0 +const IDLE_SPEED = 10.0 +const ACCEL=5.0 +const VSCALE=0.5 +const SHOOT_INTERVAL=0.3 + +var speed=Vector2() +var current_anim="" +var current_mirror=false + +var shoot_countdown=0 + +func _input(ev): + if (ev.type==InputEvent.MOUSE_BUTTON and ev.button_index==1 and ev.pressed and shoot_countdown<=0): + var pos = get_canvas_transform().affine_inverse() * ev.pos + var dir = (pos-get_global_pos()).normalized() + var bullet = preload("res://shoot.scn").instance() + bullet.advance_dir=dir + bullet.set_pos( get_global_pos() + dir * 60 ) + get_parent().add_child(bullet) + shoot_countdown=SHOOT_INTERVAL + + + + +func _fixed_process(delta): + + shoot_countdown-=delta + var dir = Vector2() + if (Input.is_action_pressed("up")): + dir+=Vector2(0,-1) + if (Input.is_action_pressed("down")): + dir+=Vector2(0,1) + if (Input.is_action_pressed("left")): + dir+=Vector2(-1,0) + if (Input.is_action_pressed("right")): + dir+=Vector2(1,0) + + if (dir!=Vector2()): + dir=dir.normalized() + speed = speed.linear_interpolate(dir*MAX_SPEED,delta*ACCEL) + var motion = speed * delta + motion.y*=VSCALE + motion=move(motion) + + if (is_colliding()): + var n = get_collision_normal() + motion=n.slide(motion) + move(motion) + + var next_anim="" + var next_mirror=false + + if (dir==Vector2() and speed.length()IDLE_SPEED*0.1): + var angle = atan2(abs(speed.x),speed.y) + + next_mirror = speed.x>0 + if (angleshadow_buffer.is_valid()); + + bool has_shadow = light->shadow_buffer.is_valid() && ci->light_mask&light->item_shadow_mask; + + canvas_shader.set_conditional(CanvasShaderGLES2::USE_SHADOWS,has_shadow); bool light_rebind = canvas_shader.bind(); @@ -9302,7 +9305,9 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list,int p_z,const canvas_shader.set_uniform(CanvasShaderGLES2::LIGHT_POS,light->light_shader_pos); canvas_shader.set_uniform(CanvasShaderGLES2::LIGHT_COLOR,light->color); canvas_shader.set_uniform(CanvasShaderGLES2::LIGHT_HEIGHT,light->height); - if (light->shadow_buffer.is_valid()) { + canvas_shader.set_uniform(CanvasShaderGLES2::LIGHT_LOCAL_MATRIX,light->xform_cache.affine_inverse()); + + if (has_shadow) { CanvasLightShadow *cls = canvas_light_shadow_owner.get(light->shadow_buffer); glActiveTexture(GL_TEXTURE0+max_texture_units-3); @@ -9313,7 +9318,6 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list,int p_z,const canvas_shader.set_uniform(CanvasShaderGLES2::SHADOW_TEXTURE,max_texture_units-3); canvas_shader.set_uniform(CanvasShaderGLES2::SHADOW_MATRIX,light->shadow_matrix_cache); - canvas_shader.set_uniform(CanvasShaderGLES2::LIGHT_LOCAL_MATRIX,light->xform_cache.affine_inverse()); canvas_shader.set_uniform(CanvasShaderGLES2::SHADOW_ESM_MULTIPLIER,light->shadow_esm_mult); } diff --git a/drivers/gles2/shader_compiler_gles2.cpp b/drivers/gles2/shader_compiler_gles2.cpp index b2052c7cbb..be40043573 100644 --- a/drivers/gles2/shader_compiler_gles2.cpp +++ b/drivers/gles2/shader_compiler_gles2.cpp @@ -808,12 +808,19 @@ ShaderCompilerGLES2::ShaderCompilerGLES2() { mode_replace_table[4]["POINT_COORD"]="gl_PointCoord"; mode_replace_table[4]["TIME"]="time"; - mode_replace_table[5]["SRC_COLOR"]="color"; - mode_replace_table[5]["COLOR"]="color"; + mode_replace_table[5]["POSITION"]="gl_Position"; mode_replace_table[5]["NORMAL"]="normal"; - mode_replace_table[5]["LIGHT_DIR"]="light_dir"; - mode_replace_table[5]["LIGHT_DISTANCE"]="light_distance"; - mode_replace_table[5]["LIGHT"]="light"; + mode_replace_table[5]["UV"]="uv_interp"; + mode_replace_table[5]["COLOR"]="color"; + mode_replace_table[5]["TEXTURE"]="texture"; + mode_replace_table[5]["TEXTURE_PIXEL_SIZE"]="texpixel_size"; + mode_replace_table[5]["VAR1"]="var1_interp"; + mode_replace_table[5]["VAR2"]="var2_interp"; + mode_replace_table[5]["LIGHT_VEC"]="light_vec"; + mode_replace_table[5]["LIGHT_HEIGHT"]="light_height"; + mode_replace_table[5]["LIGHT_COLOR"]="light"; + mode_replace_table[5]["LIGHT"]="light_out"; + mode_replace_table[5]["SCREEN_UV"]="screen_uv"; mode_replace_table[5]["POINT_COORD"]="gl_PointCoord"; mode_replace_table[5]["TIME"]="time"; diff --git a/drivers/gles2/shaders/canvas.glsl b/drivers/gles2/shaders/canvas.glsl index 9022f30d7f..0e19736fd5 100644 --- a/drivers/gles2/shaders/canvas.glsl +++ b/drivers/gles2/shaders/canvas.glsl @@ -26,6 +26,7 @@ uniform float time; #ifdef USE_LIGHTING uniform highp mat4 light_matrix; +uniform highp mat4 light_local_matrix; uniform vec2 light_pos; varying vec4 light_uv_interp; @@ -80,7 +81,7 @@ VERTEX_SHADER_CODE #ifdef USE_LIGHTING light_uv_interp.xy = (light_matrix * outvec).xy; - light_uv_interp.zw = outvec.xy-light_pos; + light_uv_interp.zw =(light_local_matrix * outvec).xy; #ifdef USE_SHADOWS pos=outvec.xy; #endif @@ -164,7 +165,6 @@ uniform sampler2D shadow_texture; uniform float shadow_attenuation; uniform highp mat4 shadow_matrix; -uniform highp mat4 light_local_matrix; highp varying vec2 pos; uniform float shadowpixel_size; @@ -188,7 +188,7 @@ void main() { vec4 color = color_interp; #if defined(NORMAL_USED) - vec3 normal = vec3(0,0,1); + vec3 normal = vec3(0.0,0.0,1.0); #endif @@ -197,6 +197,7 @@ void main() { vec2 screen_uv = gl_FragCoord.xy*screen_uv_mult; #endif + { FRAGMENT_SHADER_CODE } @@ -213,79 +214,110 @@ FRAGMENT_SHADER_CODE #ifdef USE_LIGHTING + vec2 light_vec = light_uv_interp.zw;; //for shadow and normal mapping + #if defined(NORMAL_USED) normal.xy = mat2(local_rot.xy,local_rot.zw) * normal.xy; #endif float att=1.0; - vec4 light = texture2D(light_texture,light_uv_interp.xy) * light_color; -#ifdef USE_SHADOWS + vec4 light = texture2D(light_texture,light_uv_interp.xy) * light_color; + +#if defined(USE_LIGHT_SHADER_CODE) +//light is written by the light shader +{ + vec4 light_out=vec4(0.0,0.0,0.0,0.0); +LIGHT_SHADER_CODE + color=light_out; +} +#else - vec2 lpos = (light_local_matrix * vec4(pos,0.0,1.0)).xy; - float angle_to_light = -atan(lpos.x,lpos.y); - float PI = 3.14159265358979323846264; - /*int i = int(mod(floor((angle_to_light+7.0*PI/6.0)/(4.0*PI/6.0))+1.0, 3.0)); // +1 pq os indices estao em ordem 2,0,1 nos arrays - float ang*/ +#if defined(NORMAL_USED) + vec3 light_normal = normalize(vec3(light_vec,-light_height)); + light*=max(dot(-light_normal,normal),0.0); +#endif - float su,sz; + color*=light; +/* +#ifdef USE_NORMAL + color.xy=local_rot.xy;//normal.xy; + color.zw=vec2(0.0,1.0); +#endif +*/ - float abs_angle = abs(angle_to_light); - vec2 point; - float sh; - if (abs_angle<45.0*PI/180.0) { - point = lpos; - sh=0+(1.0/8.0); - } else if (abs_angle>135.0*PI/180.0) { - point = -lpos; - sh = 0.5+(1.0/8.0); - } else if (angle_to_light>0) { +//light shader code +#endif - point = vec2(lpos.y,-lpos.x); - sh = 0.25+(1.0/8.0); + if (any(lessThan(light_uv_interp.xy,vec2(0.0,0.0))) || any(greaterThanEqual(light_uv_interp.xy,vec2(1.0,1.0)))) { + color.a=0.0; //invisible } else { - point = vec2(-lpos.y,lpos.x); - sh = 0.75+(1.0/8.0); +#ifdef USE_SHADOWS - } + float angle_to_light = -atan(light_vec.x,light_vec.y); + float PI = 3.14159265358979323846264; + /*int i = int(mod(floor((angle_to_light+7.0*PI/6.0)/(4.0*PI/6.0))+1.0, 3.0)); // +1 pq os indices estao em ordem 2,0,1 nos arrays + float ang*/ + + float su,sz; + float abs_angle = abs(angle_to_light); + vec2 point; + float sh; + if (abs_angle<45.0*PI/180.0) { + point = light_vec; + sh=0.0+(1.0/8.0); + } else if (abs_angle>135.0*PI/180.0) { + point = -light_vec; + sh = 0.5+(1.0/8.0); + } else if (angle_to_light>0.0) { - vec4 s = shadow_matrix * vec4(point,0.0,1.0); - s.xyz/=s.w; - su=s.x*0.5+0.5; - sz=s.z*0.5+0.5; + point = vec2(light_vec.y,-light_vec.x); + sh = 0.25+(1.0/8.0); + } else { - float shadow_attenuation; + point = vec2(-light_vec.y,light_vec.x); + sh = 0.75+(1.0/8.0); + + } + + + vec4 s = shadow_matrix * vec4(point,0.0,1.0); + s.xyz/=s.w; + su=s.x*0.5+0.5; + sz=s.z*0.5+0.5; + + float shadow_attenuation; #ifdef SHADOW_PCF5 - shadow_attenuation=0.0; - shadow_attenuation += texture2D(shadow_texture,vec2(su,sh)).zcanvas_light_set_item_shadow_mask(canvas_light,item_shadow_mask); + +} + +int Light2D::get_item_shadow_mask() const { + + return item_shadow_mask; +} + void Light2D::set_subtract_mode( bool p_enable ) { subtract_mode=p_enable; @@ -246,6 +258,9 @@ void Light2D::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_item_mask","item_mask"),&Light2D::set_item_mask); ObjectTypeDB::bind_method(_MD("get_item_mask"),&Light2D::get_item_mask); + ObjectTypeDB::bind_method(_MD("set_item_shadow_mask","item_shadow_mask"),&Light2D::set_item_shadow_mask); + ObjectTypeDB::bind_method(_MD("get_item_shadow_mask"),&Light2D::get_item_shadow_mask); + ObjectTypeDB::bind_method(_MD("set_subtract_mode","enable"),&Light2D::set_subtract_mode); ObjectTypeDB::bind_method(_MD("get_subtract_mode"),&Light2D::get_subtract_mode); @@ -272,6 +287,7 @@ void Light2D::_bind_methods() { ADD_PROPERTY( PropertyInfo(Variant::BOOL,"shadow/enabled"),_SCS("set_shadow_enabled"),_SCS("is_shadow_enabled")); ADD_PROPERTY( PropertyInfo(Variant::INT,"shadow/buffer_size",PROPERTY_HINT_RANGE,"32,16384,1"),_SCS("set_shadow_buffer_size"),_SCS("get_shadow_buffer_size")); ADD_PROPERTY( PropertyInfo(Variant::REAL,"shadow/esm_multiplier",PROPERTY_HINT_RANGE,"1,4096,0.1"),_SCS("set_shadow_esm_multiplier"),_SCS("get_shadow_esm_multiplier")); + ADD_PROPERTY( PropertyInfo(Variant::INT,"shadow/item_mask",PROPERTY_HINT_ALL_FLAGS),_SCS("set_item_shadow_mask"),_SCS("get_item_shadow_mask")); } @@ -288,6 +304,7 @@ Light2D::Light2D() { layer_min=0; layer_max=0; item_mask=1; + item_shadow_mask=1; subtract_mode=false; shadow_buffer_size=2048; shadow_esm_multiplier=80; diff --git a/scene/2d/light_2d.h b/scene/2d/light_2d.h index 89f351c3cd..26dc1f4d44 100644 --- a/scene/2d/light_2d.h +++ b/scene/2d/light_2d.h @@ -17,6 +17,7 @@ private: int layer_min; int layer_max; int item_mask; + int item_shadow_mask; int shadow_buffer_size; float shadow_esm_multiplier; bool subtract_mode; @@ -64,6 +65,9 @@ public: void set_item_mask( int p_mask); int get_item_mask() const; + void set_item_shadow_mask( int p_mask); + int get_item_shadow_mask() const; + void set_subtract_mode( bool p_enable ); bool get_subtract_mode() const; diff --git a/scene/2d/light_occluder_2d.cpp b/scene/2d/light_occluder_2d.cpp index 186ea2e248..6ebd499f71 100644 --- a/scene/2d/light_occluder_2d.cpp +++ b/scene/2d/light_occluder_2d.cpp @@ -18,7 +18,8 @@ void OccluderPolygon2D::set_closed(bool p_closed) { if (closed==p_closed) return; closed=p_closed; - VS::get_singleton()->canvas_occluder_polygon_set_shape(occ_polygon,polygon,closed); + if (polygon.size()) + VS::get_singleton()->canvas_occluder_polygon_set_shape(occ_polygon,polygon,closed); emit_changed(); } @@ -56,9 +57,9 @@ void OccluderPolygon2D::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_polygon","polygon"),&OccluderPolygon2D::set_polygon); ObjectTypeDB::bind_method(_MD("get_polygon"),&OccluderPolygon2D::get_polygon); - ADD_PROPERTY( PropertyInfo(Variant::VECTOR2_ARRAY,"polygon"),_SCS("set_polygon"),_SCS("get_polygon")); ADD_PROPERTY( PropertyInfo(Variant::BOOL,"closed"),_SCS("set_closed"),_SCS("is_closed")); ADD_PROPERTY( PropertyInfo(Variant::INT,"cull_mode",PROPERTY_HINT_ENUM,"Disabled,ClockWise,CounterClockWise"),_SCS("set_cull_mode"),_SCS("get_cull_mode")); + ADD_PROPERTY( PropertyInfo(Variant::VECTOR2_ARRAY,"polygon"),_SCS("set_polygon"),_SCS("get_polygon")); BIND_CONSTANT(CULL_DISABLED); BIND_CONSTANT(CULL_CLOCKWISE); diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp index 75e7957cb8..b9d87c1224 100644 --- a/scene/2d/tile_map.cpp +++ b/scene/2d/tile_map.cpp @@ -30,12 +30,32 @@ #include "io/marshalls.h" #include "servers/physics_2d_server.h" #include "method_bind_ext.inc" + +int TileMap::_get_quadrant_size() const { + + if (y_sort_mode) + return 1; + else + return quadrant_size; +} + void TileMap::_notification(int p_what) { switch(p_what) { case NOTIFICATION_ENTER_TREE: { + Node2D *c=this; + while(c) { + + navigation=c->cast_to(); + if (navigation) { + break; + } + + c=c->get_parent()->cast_to(); + } + pending_update=true; _update_dirty_quadrants(); RID space = get_world_2d()->get_space(); @@ -47,6 +67,25 @@ void TileMap::_notification(int p_what) { case NOTIFICATION_EXIT_TREE: { _update_quadrant_space(RID()); + for (Map::Element *E=quadrant_map.front();E;E=E->next()) { + + Quadrant &q=E->get(); + if (navigation) { + for(Map::Element *E=q.navpoly_ids.front();E;E=E->next()) { + + navigation->navpoly_remove(E->get().id); + } + q.navpoly_ids.clear(); + } + + for(Map::Element *E=q.occluder_instances.front();E;E=E->next()) { + VS::get_singleton()->free(E->get().id); + } + q.occluder_instances.clear(); + } + + navigation=NULL; + } break; case NOTIFICATION_TRANSFORM_CHANGED: { @@ -74,6 +113,10 @@ void TileMap::_update_quadrant_transform() { Matrix32 global_transform = get_global_transform(); + Matrix32 nav_rel; + if (navigation) + nav_rel = get_relative_transform(navigation); + for (Map::Element *E=quadrant_map.front();E;E=E->next()) { Quadrant &q=E->get(); @@ -81,6 +124,17 @@ void TileMap::_update_quadrant_transform() { xform.set_origin( q.pos ); xform = global_transform * xform; Physics2DServer::get_singleton()->body_set_state(q.body,Physics2DServer::BODY_STATE_TRANSFORM,xform); + + if (navigation) { + for(Map::Element *E=q.navpoly_ids.front();E;E=E->next()) { + + navigation->navpoly_set_transform(E->get().id,nav_rel * E->get().xform); + } + } + + for(Map::Element *E=q.occluder_instances.front();E;E=E->next()) { + VS::get_singleton()->canvas_light_occluder_set_transform(E->get().id,global_transform * E->get().xform); + } } } @@ -161,6 +215,33 @@ bool TileMap::get_center_y() const { return center_y; } +void TileMap::_fix_cell_transform(Matrix32& xform,const Cell& c,Vector2& offset,const Size2 &sc) { + + Size2 s=sc; + + if (c.transpose) { + SWAP(xform.elements[0].x, xform.elements[0].y); + SWAP(xform.elements[1].x, xform.elements[1].y); + SWAP(offset.x, offset.y); + SWAP(s.x, s.y); + } + if (c.flip_h) { + xform.elements[0].x=-xform.elements[0].x; + xform.elements[1].x=-xform.elements[1].x; + if (tile_origin==TILE_ORIGIN_TOP_LEFT) + offset.x=s.x-offset.x; + } + if (c.flip_v) { + xform.elements[0].y=-xform.elements[0].y; + xform.elements[1].y=-xform.elements[1].y; + if (tile_origin==TILE_ORIGIN_TOP_LEFT) + offset.y=s.y-offset.y; + } + xform.elements[2].x+=offset.x; + xform.elements[2].y+=offset.y; + +} + void TileMap::_update_dirty_quadrants() { if (!pending_update) @@ -173,15 +254,42 @@ void TileMap::_update_dirty_quadrants() { VisualServer *vs = VisualServer::get_singleton(); Physics2DServer *ps = Physics2DServer::get_singleton(); Vector2 tofs = get_cell_draw_offset(); + Vector2 tcenter = cell_size/2; + Matrix32 nav_rel; + if (navigation) + nav_rel = get_relative_transform(navigation); + + Vector2 qofs; while (dirty_quadrant_list.first()) { Quadrant &q = *dirty_quadrant_list.first()->self(); - vs->canvas_item_clear(q.canvas_item); + for (List::Element *E=q.canvas_items.front();E;E=E->next()) { + + vs->free(E->get()); + } + + q.canvas_items.clear(); + ps->body_clear_shapes(q.body); int shape_idx=0; + if (navigation) { + for(Map::Element *E=q.navpoly_ids.front();E;E=E->next()) { + + navigation->navpoly_remove(E->get().id); + } + q.navpoly_ids.clear(); + } + + for(Map::Element *E=q.occluder_instances.front();E;E=E->next()) { + VS::get_singleton()->free(E->get().id); + } + q.occluder_instances.clear(); + Ref prev_material; + RID prev_canvas_item; + for(int i=0;i::Element *E=tile_map.find( q.cells[i] ); @@ -192,11 +300,35 @@ void TileMap::_update_dirty_quadrants() { Ref tex = tile_set->tile_get_texture(c.id); Vector2 tile_ofs = tile_set->tile_get_texture_offset(c.id); - Vector2 offset = _map_to_world(E->key().x, E->key().y) - q.pos + tofs; + Vector2 wofs = _map_to_world(E->key().x, E->key().y); + Vector2 offset = wofs - q.pos + tofs; if (!tex.is_valid()) continue; + Ref mat = tile_set->tile_get_material(c.id); + + RID canvas_item; + + if (prev_canvas_item==RID() || prev_material!=mat) { + + canvas_item=vs->canvas_item_create(); + if (mat.is_valid()) + vs->canvas_item_set_material(canvas_item,mat->get_rid()); + vs->canvas_item_set_parent( canvas_item, get_canvas_item() ); + Matrix32 xform; + xform.set_origin( q.pos ); + vs->canvas_item_set_transform( canvas_item, xform ); + q.canvas_items.push_back(canvas_item); + + prev_canvas_item=canvas_item; + prev_material=mat; + + } else { + canvas_item=prev_canvas_item; + } + + Rect2 r = tile_set->tile_get_region(c.id); Size2 s = tex->get_size(); @@ -223,12 +355,32 @@ void TileMap::_update_dirty_quadrants() { if (c.flip_v) rect.size.y=-rect.size.y; + Vector2 center_ofs; + + if (tile_origin==TILE_ORIGIN_TOP_LEFT) { + rect.pos+=tile_ofs; + } else if (tile_origin==TILE_ORIGIN_CENTER) { + rect.pos+=tcenter; + + Vector2 center = (s/2) - tile_ofs; + center_ofs=tcenter-(s/2); + + if (c.flip_h) + rect.pos.x-=s.x-center.x; + else + rect.pos.x-=center.x; + + if (c.flip_v) + rect.pos.y-=s.y-center.y; + else + rect.pos.y-=center.y; + } + - rect.pos+=tile_ofs; if (r==Rect2()) { - tex->draw_rect(q.canvas_item,rect,false,Color(1,1,1),c.transpose); + tex->draw_rect(canvas_item,rect,false,Color(1,1,1),c.transpose); } else { - tex->draw_rect_region(q.canvas_item,rect,r,Color(1,1,1),c.transpose); + tex->draw_rect_region(canvas_item,rect,r,Color(1,1,1),c.transpose); } Vector< Ref > shapes = tile_set->tile_get_shapes(c.id); @@ -242,32 +394,48 @@ void TileMap::_update_dirty_quadrants() { Vector2 shape_ofs = tile_set->tile_get_shape_offset(c.id); Matrix32 xform; xform.set_origin(offset.floor()); - if (c.transpose) { - SWAP(xform.elements[0].x, xform.elements[0].y); - SWAP(xform.elements[1].x, xform.elements[1].y); - SWAP(shape_ofs.x, shape_ofs.y); - SWAP(s.x, s.y); - } - if (c.flip_h) { - xform.elements[0].x=-xform.elements[0].x; - xform.elements[1].x=-xform.elements[1].x; - shape_ofs.x=s.x-shape_ofs.x; - } - if (c.flip_v) { - xform.elements[0].y=-xform.elements[0].y; - xform.elements[1].y=-xform.elements[1].y; - shape_ofs.y=s.y-shape_ofs.y; - } - xform.elements[2].x+=shape_ofs.x; - xform.elements[2].y+=shape_ofs.y; - + _fix_cell_transform(xform,c,shape_ofs+center_ofs,s); ps->body_add_shape(q.body,shape->get_rid(),xform); ps->body_set_shape_metadata(q.body,shape_idx++,Vector2(E->key().x,E->key().y)); } } + + if (navigation) { + Ref navpoly = tile_set->tile_get_navigation_polygon(c.id); + Vector2 npoly_ofs = tile_set->tile_get_navigation_polygon_offset(c.id); + Matrix32 xform; + xform.set_origin(offset.floor()+q.pos); + _fix_cell_transform(xform,c,npoly_ofs+center_ofs,s); + + int pid = navigation->navpoly_create(navpoly,nav_rel * xform); + + Quadrant::NavPoly np; + np.id=pid; + np.xform=xform; + q.navpoly_ids[E->key()]=np; + } + + + Ref occluder=tile_set->tile_get_light_occluder(c.id); + if (occluder.is_valid()) { + + Vector2 occluder_ofs = tile_set->tile_get_occluder_offset(c.id); + Matrix32 xform; + xform.set_origin(offset.floor()+q.pos); + _fix_cell_transform(xform,c,occluder_ofs+center_ofs,s); + + RID orid = VS::get_singleton()->canvas_light_occluder_create(); + VS::get_singleton()->canvas_light_occluder_set_transform(orid,get_global_transform() * xform); + VS::get_singleton()->canvas_light_occluder_set_polygon(orid,occluder->get_rid()); + VS::get_singleton()->canvas_light_occluder_attach_to_canvas(orid,get_canvas()); + Quadrant::Occluder oc; + oc.xform=xform; + oc.id=orid; + q.occluder_instances[E->key()]=oc; + } } dirty_quadrant_list.remove( dirty_quadrant_list.first() ); @@ -282,10 +450,10 @@ void TileMap::_update_dirty_quadrants() { for (Map::Element *E=quadrant_map.front();E;E=E->next()) { Quadrant &q=E->get(); - if (q.canvas_item.is_valid()) { - VS::get_singleton()->canvas_item_raise(q.canvas_item); - } + for (List::Element *E=q.canvas_items.front();E;E=E->next()) { + VS::get_singleton()->canvas_item_raise(E->get()); + } } quadrant_order_dirty=false; @@ -308,10 +476,10 @@ void TileMap::_recompute_rect_cache() { Rect2 r; - r.pos=_map_to_world(E->key().x*quadrant_size, E->key().y*quadrant_size); - r.expand_to( _map_to_world(E->key().x*quadrant_size+quadrant_size, E->key().y*quadrant_size) ); - r.expand_to( _map_to_world(E->key().x*quadrant_size+quadrant_size, E->key().y*quadrant_size+quadrant_size) ); - r.expand_to( _map_to_world(E->key().x*quadrant_size, E->key().y*quadrant_size+quadrant_size) ); + r.pos=_map_to_world(E->key().x*_get_quadrant_size(), E->key().y*_get_quadrant_size()); + r.expand_to( _map_to_world(E->key().x*_get_quadrant_size()+_get_quadrant_size(), E->key().y*_get_quadrant_size()) ); + r.expand_to( _map_to_world(E->key().x*_get_quadrant_size()+_get_quadrant_size(), E->key().y*_get_quadrant_size()+_get_quadrant_size()) ); + r.expand_to( _map_to_world(E->key().x*_get_quadrant_size(), E->key().y*_get_quadrant_size()+_get_quadrant_size()) ); if (E==quadrant_map.front()) r_total=r; else @@ -322,7 +490,7 @@ void TileMap::_recompute_rect_cache() { if (r_total==Rect2()) { rect_cache=Rect2(-10,-10,20,20); } else { - rect_cache=r_total.grow(MAX(cell_size.x,cell_size.y)*quadrant_size); + rect_cache=r_total.grow(MAX(cell_size.x,cell_size.y)*_get_quadrant_size()); } item_rect_changed(); @@ -338,11 +506,13 @@ Map::Element *TileMap::_create_quadrant(const Matrix32 xform; //xform.set_origin(Point2(p_qk.x,p_qk.y)*cell_size*quadrant_size); Quadrant q; - q.pos = _map_to_world(p_qk.x*quadrant_size,p_qk.y*quadrant_size); + q.pos = _map_to_world(p_qk.x*_get_quadrant_size(),p_qk.y*_get_quadrant_size()); + q.pos+=get_cell_draw_offset(); + if (tile_origin==TILE_ORIGIN_CENTER) + q.pos+=cell_size/2; + xform.set_origin( q.pos ); - q.canvas_item = VisualServer::get_singleton()->canvas_item_create(); - VisualServer::get_singleton()->canvas_item_set_parent( q.canvas_item, get_canvas_item() ); - VisualServer::get_singleton()->canvas_item_set_transform( q.canvas_item, xform ); +// q.canvas_item = VisualServer::get_singleton()->canvas_item_create(); q.body=Physics2DServer::get_singleton()->body_create(use_kinematic?Physics2DServer::BODY_MODE_KINEMATIC:Physics2DServer::BODY_MODE_STATIC); Physics2DServer::get_singleton()->body_attach_object_instance_ID(q.body,get_instance_ID()); Physics2DServer::get_singleton()->body_set_layer_mask(q.body,collision_layer); @@ -366,10 +536,27 @@ void TileMap::_erase_quadrant(Map::Element *Q) { Quadrant &q=Q->get(); Physics2DServer::get_singleton()->free(q.body); - VisualServer::get_singleton()->free(q.canvas_item); + for (List::Element *E=q.canvas_items.front();E;E=E->next()) { + + VisualServer::get_singleton()->free(E->get()); + } + q.canvas_items.clear(); if (q.dirty_list.in_list()) dirty_quadrant_list.remove(&q.dirty_list); + if (navigation) { + for(Map::Element *E=q.navpoly_ids.front();E;E=E->next()) { + + navigation->navpoly_remove(E->get().id); + } + q.navpoly_ids.clear(); + } + + for(Map::Element *E=q.occluder_instances.front();E;E=E->next()) { + VS::get_singleton()->free(E->get().id); + } + q.occluder_instances.clear(); + quadrant_map.erase(Q); rect_cache_dirty=true; } @@ -397,7 +584,7 @@ void TileMap::set_cell(int p_x,int p_y,int p_tile,bool p_flip_x,bool p_flip_y,bo if (!E && p_tile==INVALID_CELL) return; //nothing to do - PosKey qk(p_x/quadrant_size,p_y/quadrant_size); + PosKey qk(p_x/_get_quadrant_size(),p_y/_get_quadrant_size()); if (p_tile==INVALID_CELL) { //erase existing tile_map.erase(pk); @@ -495,7 +682,7 @@ void TileMap::_recreate_quadrants() { for (Map::Element *E=tile_map.front();E;E=E->next()) { - PosKey qk(E->key().x/quadrant_size,E->key().y/quadrant_size); + PosKey qk(E->key().x/_get_quadrant_size(),E->key().y/_get_quadrant_size()); Map::Element *Q=quadrant_map.find(qk); if (!Q) { @@ -511,6 +698,7 @@ void TileMap::_recreate_quadrants() { } + void TileMap::_clear_quadrants() { while (quadrant_map.size()) { @@ -678,6 +866,20 @@ void TileMap::set_half_offset(HalfOffset p_half_offset) { emit_signal("settings_changed"); } +void TileMap::set_tile_origin(TileOrigin p_tile_origin) { + + _clear_quadrants(); + tile_origin=p_tile_origin; + _recreate_quadrants(); + emit_signal("settings_changed"); +} + +TileMap::TileOrigin TileMap::get_tile_origin() const{ + + return tile_origin; +} + + Vector2 TileMap::get_cell_draw_offset() const { switch(mode) { @@ -804,6 +1006,21 @@ Vector2 TileMap::world_to_map(const Vector2& p_pos) const{ return ret.floor(); } +void TileMap::set_y_sort_mode(bool p_enable) { + + _clear_quadrants(); + y_sort_mode=p_enable; + VS::get_singleton()->canvas_item_set_sort_children_by_y(get_canvas_item(),y_sort_mode); + _recreate_quadrants(); + emit_signal("settings_changed"); + +} + +bool TileMap::is_y_sort_mode_enabled() const { + + return y_sort_mode; +} + void TileMap::_bind_methods() { @@ -829,12 +1046,18 @@ void TileMap::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_quadrant_size","size"),&TileMap::set_quadrant_size); ObjectTypeDB::bind_method(_MD("get_quadrant_size"),&TileMap::get_quadrant_size); + ObjectTypeDB::bind_method(_MD("set_tile_origin","origin"),&TileMap::set_tile_origin); + ObjectTypeDB::bind_method(_MD("get_tile_origin"),&TileMap::get_tile_origin); + ObjectTypeDB::bind_method(_MD("set_center_x","enable"),&TileMap::set_center_x); ObjectTypeDB::bind_method(_MD("get_center_x"),&TileMap::get_center_x); ObjectTypeDB::bind_method(_MD("set_center_y","enable"),&TileMap::set_center_y); ObjectTypeDB::bind_method(_MD("get_center_y"),&TileMap::get_center_y); + ObjectTypeDB::bind_method(_MD("set_y_sort_mode","enable"),&TileMap::set_y_sort_mode); + ObjectTypeDB::bind_method(_MD("is_y_sort_mode_enabled"),&TileMap::is_y_sort_mode_enabled); + ObjectTypeDB::bind_method(_MD("set_collision_use_kinematic","use_kinematic"),&TileMap::set_collision_use_kinematic); ObjectTypeDB::bind_method(_MD("get_collision_use_kinematic"),&TileMap::get_collision_use_kinematic); @@ -871,6 +1094,8 @@ void TileMap::_bind_methods() { ADD_PROPERTY( PropertyInfo(Variant::INT,"cell/quadrant_size",PROPERTY_HINT_RANGE,"1,128,1"),_SCS("set_quadrant_size"),_SCS("get_quadrant_size")); ADD_PROPERTY( PropertyInfo(Variant::MATRIX32,"cell/custom_transform"),_SCS("set_custom_transform"),_SCS("get_custom_transform")); ADD_PROPERTY( PropertyInfo(Variant::INT,"cell/half_offset",PROPERTY_HINT_ENUM,"Offset X,Offset Y,Disabled"),_SCS("set_half_offset"),_SCS("get_half_offset")); + ADD_PROPERTY( PropertyInfo(Variant::INT,"cell/tile_origin",PROPERTY_HINT_ENUM,"Top Left,Center"),_SCS("set_tile_origin"),_SCS("get_tile_origin")); + ADD_PROPERTY( PropertyInfo(Variant::BOOL,"cell/y_sort"),_SCS("set_y_sort_mode"),_SCS("is_y_sort_mode_enabled")); ADD_PROPERTY( PropertyInfo(Variant::BOOL,"collision/use_kinematic",PROPERTY_HINT_NONE,""),_SCS("set_collision_use_kinematic"),_SCS("get_collision_use_kinematic")); ADD_PROPERTY( PropertyInfo(Variant::REAL,"collision/friction",PROPERTY_HINT_RANGE,"0,1,0.01"),_SCS("set_collision_friction"),_SCS("get_collision_friction")); ADD_PROPERTY( PropertyInfo(Variant::REAL,"collision/bounce",PROPERTY_HINT_RANGE,"0,1,0.01"),_SCS("set_collision_bounce"),_SCS("get_collision_bounce")); @@ -886,6 +1111,8 @@ void TileMap::_bind_methods() { BIND_CONSTANT( HALF_OFFSET_X ); BIND_CONSTANT( HALF_OFFSET_Y ); BIND_CONSTANT( HALF_OFFSET_DISABLED ); + BIND_CONSTANT( TILE_ORIGIN_TOP_LEFT ); + BIND_CONSTANT( TILE_ORIGIN_CENTER ); } @@ -906,9 +1133,12 @@ TileMap::TileMap() { mode=MODE_SQUARE; half_offset=HALF_OFFSET_DISABLED; use_kinematic=false; + navigation=NULL; + y_sort_mode=false; fp_adjust=0.01; fp_adjust=0.01; + tile_origin=TILE_ORIGIN_TOP_LEFT; } TileMap::~TileMap() { diff --git a/scene/2d/tile_map.h b/scene/2d/tile_map.h index fe1067fc1d..3facc9e8b7 100644 --- a/scene/2d/tile_map.h +++ b/scene/2d/tile_map.h @@ -30,6 +30,7 @@ #define TILE_MAP_H #include "scene/2d/node_2d.h" +#include "scene/2d/navigation2d.h" #include "scene/resources/tile_set.h" #include "self_list.h" #include "vset.h" @@ -51,6 +52,12 @@ public: HALF_OFFSET_DISABLED, }; + enum TileOrigin { + TILE_ORIGIN_TOP_LEFT, + TILE_ORIGIN_CENTER + }; + + private: Ref tile_set; @@ -61,6 +68,7 @@ private: Matrix32 custom_transform; HalfOffset half_offset; bool use_kinematic; + Navigation2D *navigation; union PosKey { @@ -98,15 +106,29 @@ private: struct Quadrant { Vector2 pos; - RID canvas_item; + List canvas_items; RID body; SelfList dirty_list; + struct NavPoly { + int id; + Matrix32 xform; + }; + + struct Occluder { + RID id; + Matrix32 xform; + }; + + + Map navpoly_ids; + Map occluder_instances; + VSet cells; - void operator=(const Quadrant& q) { pos=q.pos; canvas_item=q.canvas_item; body=q.body; cells=q.cells; } - Quadrant(const Quadrant& q) : dirty_list(this) { pos=q.pos; canvas_item=q.canvas_item; body=q.body; cells=q.cells;} + void operator=(const Quadrant& q) { pos=q.pos; canvas_items=q.canvas_items; body=q.body; cells=q.cells; navpoly_ids=q.navpoly_ids; occluder_instances=q.occluder_instances; } + Quadrant(const Quadrant& q) : dirty_list(this) { pos=q.pos; canvas_items=q.canvas_items; body=q.body; cells=q.cells; occluder_instances=q.occluder_instances; navpoly_ids=q.navpoly_ids;} Quadrant() : dirty_list(this) {} }; @@ -119,11 +141,14 @@ private: Rect2 rect_cache; bool rect_cache_dirty; bool quadrant_order_dirty; + bool y_sort_mode; float fp_adjust; float friction; float bounce; uint32_t collision_layer; + TileOrigin tile_origin; + void _fix_cell_transform(Matrix32& xform, const Cell& c, Vector2 &offset, const Size2 &s); Map::Element *_create_quadrant(const PosKey& p_qk); void _erase_quadrant(Map::Element *Q); @@ -135,6 +160,9 @@ private: void _update_quadrant_transform(); void _recompute_rect_cache(); + _FORCE_INLINE_ int _get_quadrant_size() const; + + void _set_tile_data(const DVector& p_data); DVector _get_tile_data() const; @@ -195,6 +223,9 @@ public: void set_half_offset(HalfOffset p_half_offset); HalfOffset get_half_offset() const; + void set_tile_origin(TileOrigin p_tile_origin); + TileOrigin get_tile_origin() const; + void set_custom_transform(const Matrix32& p_xform); Matrix32 get_custom_transform() const; @@ -204,6 +235,9 @@ public: Vector2 map_to_world(const Vector2& p_pos, bool p_ignore_ofs=false) const; Vector2 world_to_map(const Vector2& p_pos) const; + void set_y_sort_mode(bool p_enable); + bool is_y_sort_mode_enabled() const; + void clear(); TileMap(); @@ -212,5 +246,6 @@ public: VARIANT_ENUM_CAST(TileMap::Mode); VARIANT_ENUM_CAST(TileMap::HalfOffset); +VARIANT_ENUM_CAST(TileMap::TileOrigin); #endif // TILE_MAP_H diff --git a/scene/2d/visibility_notifier_2d.cpp b/scene/2d/visibility_notifier_2d.cpp index 22534eeb0e..cd3c788b65 100644 --- a/scene/2d/visibility_notifier_2d.cpp +++ b/scene/2d/visibility_notifier_2d.cpp @@ -32,6 +32,7 @@ #include "scene/2d/physics_body_2d.h" #include "scene/animation/animation_player.h" #include "scene/scene_string_names.h" +#include "particles_2d.h" void VisibilityNotifier2D::_enter_viewport(Viewport* p_viewport) { @@ -188,6 +189,15 @@ void VisibilityEnabler2D::_find_nodes(Node* p_node) { } + if (enabler[ENABLER_PAUSE_PARTICLES]) { + + Particles2D *ps = p_node->cast_to(); + if (ps) { + add=true; + } + + } + if (add) { p_node->connect(SceneStringNames::get_singleton()->exit_tree,this,"_node_removed",varray(p_node),CONNECT_ONESHOT); @@ -271,6 +281,15 @@ void VisibilityEnabler2D::_change_node_state(Node* p_node,bool p_enabled) { } } + { + Particles2D *ps=p_node->cast_to(); + + if (ps) { + + ps->set_emitting(p_enabled); + } + } + } @@ -292,9 +311,11 @@ void VisibilityEnabler2D::_bind_methods(){ ADD_PROPERTYI( PropertyInfo(Variant::BOOL,"enabler/pause_animations"),_SCS("set_enabler"),_SCS("is_enabler_enabled"), ENABLER_PAUSE_ANIMATIONS ); ADD_PROPERTYI( PropertyInfo(Variant::BOOL,"enabler/freeze_bodies"),_SCS("set_enabler"),_SCS("is_enabler_enabled"), ENABLER_FREEZE_BODIES); + ADD_PROPERTYI( PropertyInfo(Variant::BOOL,"enabler/pause_particles"),_SCS("set_enabler"),_SCS("is_enabler_enabled"), ENABLER_PAUSE_PARTICLES); BIND_CONSTANT( ENABLER_FREEZE_BODIES ); BIND_CONSTANT( ENABLER_PAUSE_ANIMATIONS ); + BIND_CONSTANT( ENABLER_PAUSE_PARTICLES ); BIND_CONSTANT( ENABLER_MAX); } @@ -320,3 +341,4 @@ VisibilityEnabler2D::VisibilityEnabler2D() { } + diff --git a/scene/2d/visibility_notifier_2d.h b/scene/2d/visibility_notifier_2d.h index cdf52ecb27..621c470d5d 100644 --- a/scene/2d/visibility_notifier_2d.h +++ b/scene/2d/visibility_notifier_2d.h @@ -73,6 +73,7 @@ public: enum Enabler { ENABLER_PAUSE_ANIMATIONS, ENABLER_FREEZE_BODIES, + ENABLER_PAUSE_PARTICLES, ENABLER_MAX }; diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp index a8070be91d..86f442fd8c 100644 --- a/scene/gui/control.cpp +++ b/scene/gui/control.cpp @@ -940,67 +940,67 @@ void Control::_window_input_event(InputEvent p_event) { case InputEvent::MOUSE_BUTTON: { - window->key_event_accepted=false; + window->key_event_accepted=false; - Point2 mpos =(get_canvas_transform()).affine_inverse().xform(Point2(p_event.mouse_button.x,p_event.mouse_button.y)); - if (p_event.mouse_button.pressed) { + Point2 mpos =(get_canvas_transform()).affine_inverse().xform(Point2(p_event.mouse_button.x,p_event.mouse_button.y)); + if (p_event.mouse_button.pressed) { - Size2 pos = mpos; - if (window->mouse_focus && p_event.mouse_button.button_index!=window->mouse_focus_button) { + Size2 pos = mpos; + if (window->mouse_focus && p_event.mouse_button.button_index!=window->mouse_focus_button) { - //do not steal mouse focus and stuff + //do not steal mouse focus and stuff - } else { + } else { - _window_sort_modal_stack(); - while (!window->modal_stack.empty()) { + _window_sort_modal_stack(); + while (!window->modal_stack.empty()) { - Control *top = window->modal_stack.back()->get(); - if (!top->has_point(top->get_global_transform().affine_inverse().xform(pos))) { + Control *top = window->modal_stack.back()->get(); + if (!top->has_point(top->get_global_transform().affine_inverse().xform(pos))) { - if (top->data.modal_exclusive) { - //cancel event, sorry, modal exclusive EATS UP ALL - get_tree()->call_group(SceneTree::GROUP_CALL_REALTIME,"windows","_cancel_input_ID",p_event.ID); - get_tree()->set_input_as_handled(); - return; // no one gets the event if exclusive NO ONE - } + if (top->data.modal_exclusive) { + //cancel event, sorry, modal exclusive EATS UP ALL + get_tree()->call_group(SceneTree::GROUP_CALL_REALTIME,"windows","_cancel_input_ID",p_event.ID); + get_tree()->set_input_as_handled(); + return; // no one gets the event if exclusive NO ONE + } - top->notification(NOTIFICATION_MODAL_CLOSE); - top->_modal_stack_remove(); - top->hide(); - } else { - break; + top->notification(NOTIFICATION_MODAL_CLOSE); + top->_modal_stack_remove(); + top->hide(); + } else { + break; + } } - } - Matrix32 parent_xform; + Matrix32 parent_xform; - if (data.parent_canvas_item) - parent_xform=data.parent_canvas_item->get_global_transform(); + if (data.parent_canvas_item) + parent_xform=data.parent_canvas_item->get_global_transform(); - window->mouse_focus = _find_control_at_pos(this,pos,parent_xform,window->focus_inv_xform); - //print_line("has mf "+itos(window->mouse_focus!=NULL)); - window->mouse_focus_button=p_event.mouse_button.button_index; + window->mouse_focus = _find_control_at_pos(this,pos,parent_xform,window->focus_inv_xform); + //print_line("has mf "+itos(window->mouse_focus!=NULL)); + window->mouse_focus_button=p_event.mouse_button.button_index; - if (!window->mouse_focus) { - break; - } + if (!window->mouse_focus) { + break; + } - if (p_event.mouse_button.button_index==BUTTON_LEFT) { - window->drag_accum=Vector2(); - window->drag_attempted=false; - window->drag_data=Variant(); - } + if (p_event.mouse_button.button_index==BUTTON_LEFT) { + window->drag_accum=Vector2(); + window->drag_attempted=false; + window->drag_data=Variant(); + } - } + } p_event.mouse_button.global_x = pos.x; p_event.mouse_button.global_y = pos.y; @@ -1020,8 +1020,8 @@ void Control::_window_input_event(InputEvent p_event) { /*if (bool(GLOBAL_DEF("debug/print_clicked_control",false))) { - print_line(String(window->mouse_focus->get_path())+" - "+pos); - }*/ + print_line(String(window->mouse_focus->get_path())+" - "+pos); + }*/ #endif if (window->mouse_focus->get_focus_mode()!=FOCUS_NONE && window->mouse_focus!=window->key_focus && p_event.mouse_button.button_index==BUTTON_LEFT) { @@ -1033,10 +1033,12 @@ void Control::_window_input_event(InputEvent p_event) { if (window->mouse_focus->can_process()) { _window_call_input(window->mouse_focus,p_event); } - + get_tree()->call_group(SceneTree::GROUP_CALL_REALTIME,"windows","_cancel_input_ID",p_event.ID); get_tree()->set_input_as_handled(); + window->tooltip_popup->hide(); + } else { if (window->drag_preview && p_event.mouse_button.button_index==BUTTON_LEFT) { diff --git a/scene/resources/tile_set.cpp b/scene/resources/tile_set.cpp index 208ba5bb66..338804e0e1 100644 --- a/scene/resources/tile_set.cpp +++ b/scene/resources/tile_set.cpp @@ -46,6 +46,8 @@ bool TileSet::_set(const StringName& p_name, const Variant& p_value) { tile_set_texture(id,p_value); else if (what=="tex_offset") tile_set_texture_offset(id,p_value); + else if (what=="material") + tile_set_material(id,p_value); else if (what=="shape_offset") tile_set_shape_offset(id,p_value); else if (what=="region") @@ -54,6 +56,14 @@ bool TileSet::_set(const StringName& p_name, const Variant& p_value) { tile_set_shape(id,p_value); else if (what=="shapes") _tile_set_shapes(id,p_value); + else if (what=="occluder") + tile_set_light_occluder(id,p_value); + else if (what=="occluder_offset") + tile_set_occluder_offset(id,p_value); + else if (what=="navigation") + tile_set_navigation_polygon(id,p_value); + else if (what=="navigation_offset") + tile_set_navigation_polygon_offset(id,p_value); else return false; @@ -79,6 +89,8 @@ bool TileSet::_get(const StringName& p_name,Variant &r_ret) const{ r_ret=tile_get_texture(id); else if (what=="tex_offset") r_ret=tile_get_texture_offset(id); + else if (what=="material") + r_ret=tile_get_material(id); else if (what=="shape_offset") r_ret=tile_get_shape_offset(id); else if (what=="region") @@ -87,6 +99,14 @@ bool TileSet::_get(const StringName& p_name,Variant &r_ret) const{ r_ret=tile_get_shape(id); else if (what=="shapes") r_ret=_tile_get_shapes(id); + else if (what=="occluder") + r_ret=tile_get_light_occluder(id); + else if (what=="occluder_offset") + r_ret=tile_get_occluder_offset(id); + else if (what=="navigation") + r_ret=tile_get_navigation_polygon(id); + else if (what=="navigation_offset") + r_ret=tile_get_navigation_polygon_offset(id); else return false; @@ -103,8 +123,13 @@ void TileSet::_get_property_list( List *p_list) const{ p_list->push_back(PropertyInfo(Variant::STRING,pre+"name")); p_list->push_back(PropertyInfo(Variant::OBJECT,pre+"texture",PROPERTY_HINT_RESOURCE_TYPE,"Texture")); p_list->push_back(PropertyInfo(Variant::VECTOR2,pre+"tex_offset")); - p_list->push_back(PropertyInfo(Variant::VECTOR2,pre+"shape_offset")); + p_list->push_back(PropertyInfo(Variant::OBJECT,pre+"material",PROPERTY_HINT_RESOURCE_TYPE,"CanvasItemMaterial")); p_list->push_back(PropertyInfo(Variant::RECT2,pre+"region")); + p_list->push_back(PropertyInfo(Variant::VECTOR2,pre+"occluder_offset")); + p_list->push_back(PropertyInfo(Variant::OBJECT,pre+"occluder",PROPERTY_HINT_RESOURCE_TYPE,"OccluderPolygon2D")); + p_list->push_back(PropertyInfo(Variant::VECTOR2,pre+"navigation_offset")); + p_list->push_back(PropertyInfo(Variant::OBJECT,pre+"navigation",PROPERTY_HINT_RESOURCE_TYPE,"NavigationPolygon")); + p_list->push_back(PropertyInfo(Variant::VECTOR2,pre+"shape_offset")); p_list->push_back(PropertyInfo(Variant::OBJECT,pre+"shape",PROPERTY_HINT_RESOURCE_TYPE,"Shape2D",PROPERTY_USAGE_EDITOR)); p_list->push_back(PropertyInfo(Variant::ARRAY,pre+"shapes",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR)); } @@ -134,6 +159,22 @@ Ref TileSet::tile_get_texture(int p_id) const { } + +void TileSet::tile_set_material(int p_id,const Ref &p_material) { + + ERR_FAIL_COND(!tile_map.has(p_id)); + tile_map[p_id].material=p_material; + emit_changed(); + +} + +Ref TileSet::tile_get_material(int p_id) const{ + + ERR_FAIL_COND_V(!tile_map.has(p_id),Ref()); + return tile_map[p_id].material; +} + + void TileSet::tile_set_texture_offset(int p_id,const Vector2 &p_offset) { ERR_FAIL_COND(!tile_map.has(p_id)); @@ -210,6 +251,58 @@ Ref TileSet::tile_get_shape(int p_id) const { } +void TileSet::tile_set_light_occluder(int p_id,const Ref &p_light_occluder) { + + ERR_FAIL_COND(!tile_map.has(p_id)); + tile_map[p_id].occluder=p_light_occluder; + +} + +Ref TileSet::tile_get_light_occluder(int p_id) const{ + + ERR_FAIL_COND_V(!tile_map.has(p_id),Ref()); + return tile_map[p_id].occluder; + +} + +void TileSet::tile_set_navigation_polygon_offset(int p_id,const Vector2& p_offset) { + + ERR_FAIL_COND(!tile_map.has(p_id)); + tile_map[p_id].navigation_polygon_offset=p_offset; + +} + +Vector2 TileSet::tile_get_navigation_polygon_offset(int p_id) const{ + ERR_FAIL_COND_V(!tile_map.has(p_id),Vector2()); + return tile_map[p_id].navigation_polygon_offset; +} + +void TileSet::tile_set_navigation_polygon(int p_id,const Ref &p_navigation_polygon) { + + ERR_FAIL_COND(!tile_map.has(p_id)); + tile_map[p_id].navigation_polygon=p_navigation_polygon; + +} + +Ref TileSet::tile_get_navigation_polygon(int p_id) const { + + ERR_FAIL_COND_V(!tile_map.has(p_id),Ref()); + return tile_map[p_id].navigation_polygon; + +} + +void TileSet::tile_set_occluder_offset(int p_id,const Vector2& p_offset) { + + ERR_FAIL_COND(!tile_map.has(p_id)); + tile_map[p_id].occluder_offset=p_offset; + +} + +Vector2 TileSet::tile_get_occluder_offset(int p_id) const{ + ERR_FAIL_COND_V(!tile_map.has(p_id),Vector2()); + return tile_map[p_id].occluder_offset; +} + void TileSet::tile_set_shapes(int p_id,const Vector > &p_shapes) { ERR_FAIL_COND(!tile_map.has(p_id)); @@ -319,6 +412,8 @@ void TileSet::_bind_methods() { ObjectTypeDB::bind_method(_MD("tile_get_name","id"),&TileSet::tile_get_name); ObjectTypeDB::bind_method(_MD("tile_set_texture","id","texture:Texture"),&TileSet::tile_set_texture); ObjectTypeDB::bind_method(_MD("tile_get_texture:Texture","id"),&TileSet::tile_get_texture); + ObjectTypeDB::bind_method(_MD("tile_set_material","id","material:CanvasItemMaterial"),&TileSet::tile_set_material); + ObjectTypeDB::bind_method(_MD("tile_get_material:CanvasItemMaterial","id"),&TileSet::tile_get_material); ObjectTypeDB::bind_method(_MD("tile_set_texture_offset","id","texture_offset"),&TileSet::tile_set_texture_offset); ObjectTypeDB::bind_method(_MD("tile_get_texture_offset","id"),&TileSet::tile_get_texture_offset); ObjectTypeDB::bind_method(_MD("tile_set_shape_offset","id","shape_offset"),&TileSet::tile_set_shape_offset); @@ -329,6 +424,15 @@ void TileSet::_bind_methods() { ObjectTypeDB::bind_method(_MD("tile_get_shape:Shape2D","id"),&TileSet::tile_get_shape); ObjectTypeDB::bind_method(_MD("tile_set_shapes","id","shapes"),&TileSet::_tile_set_shapes); ObjectTypeDB::bind_method(_MD("tile_get_shapes","id"),&TileSet::_tile_get_shapes); + ObjectTypeDB::bind_method(_MD("tile_set_navigation_polygon","id","navigation_polygon:NavigationPolygon"),&TileSet::tile_set_navigation_polygon); + ObjectTypeDB::bind_method(_MD("tile_get_navigation_polygon:NavigationPolygon","id"),&TileSet::tile_get_navigation_polygon); + ObjectTypeDB::bind_method(_MD("tile_set_navigation_polygon_offset","id","navigation_polygon_offset"),&TileSet::tile_set_navigation_polygon_offset); + ObjectTypeDB::bind_method(_MD("tile_get_navigation_polygon_offset","id"),&TileSet::tile_get_navigation_polygon_offset); + ObjectTypeDB::bind_method(_MD("tile_set_light_occluder","id","light_occluder:OccluderPolygon2D"),&TileSet::tile_set_light_occluder); + ObjectTypeDB::bind_method(_MD("tile_get_light_occluder:OccluderPolygon2D","id"),&TileSet::tile_get_light_occluder); + ObjectTypeDB::bind_method(_MD("tile_set_occluder_offset","id","occluder_offset"),&TileSet::tile_set_occluder_offset); + ObjectTypeDB::bind_method(_MD("tile_get_occluder_offset","id"),&TileSet::tile_get_occluder_offset); + ObjectTypeDB::bind_method(_MD("remove_tile","id"),&TileSet::remove_tile); ObjectTypeDB::bind_method(_MD("clear"),&TileSet::clear); ObjectTypeDB::bind_method(_MD("get_last_unused_tile_id"),&TileSet::get_last_unused_tile_id); diff --git a/scene/resources/tile_set.h b/scene/resources/tile_set.h index ddbb1b59a6..0234755a53 100644 --- a/scene/resources/tile_set.h +++ b/scene/resources/tile_set.h @@ -32,6 +32,8 @@ #include "resource.h" #include "scene/resources/shape_2d.h" #include "scene/resources/texture.h" +#include "scene/2d/light_occluder_2d.h" +#include "scene/2d/navigation_polygon.h" class TileSet : public Resource { @@ -45,6 +47,11 @@ class TileSet : public Resource { Vector2 shape_offset; Rect2i region; Vector > shapes; + Vector2 occluder_offset; + Ref occluder; + Vector2 navigation_polygon_offset; + Ref navigation_polygon; + Ref material; }; Map tile_map; @@ -84,6 +91,21 @@ public: void tile_set_shape(int p_id,const Ref &p_shape); Ref tile_get_shape(int p_id) const; + void tile_set_material(int p_id,const Ref &p_material); + Ref tile_get_material(int p_id) const; + + void tile_set_occluder_offset(int p_id,const Vector2& p_offset); + Vector2 tile_get_occluder_offset(int p_id) const; + + void tile_set_light_occluder(int p_id,const Ref &p_light_occluder); + Ref tile_get_light_occluder(int p_id) const; + + void tile_set_navigation_polygon_offset(int p_id,const Vector2& p_offset); + Vector2 tile_get_navigation_polygon_offset(int p_id) const; + + void tile_set_navigation_polygon(int p_id,const Ref &p_navigation_polygon); + Ref tile_get_navigation_polygon(int p_id) const; + void tile_set_shapes(int p_id,const Vector > &p_shapes); Vector > tile_get_shapes(int p_id) const; diff --git a/servers/visual/rasterizer.h b/servers/visual/rasterizer.h index 62ab8b3c56..d2a1c48c46 100644 --- a/servers/visual/rasterizer.h +++ b/servers/visual/rasterizer.h @@ -582,6 +582,7 @@ public: int layer_min; int layer_max; int item_mask; + int item_shadow_mask; bool subtract; RID texture; Vector2 texture_offset; @@ -613,6 +614,7 @@ public: layer_min=0; layer_max=0; item_mask=1; + item_shadow_mask=-1; subtract=false; texture_cache=NULL; next_ptr=NULL; diff --git a/servers/visual/shader_language.cpp b/servers/visual/shader_language.cpp index f178c27ed0..e53fe8f82d 100644 --- a/servers/visual/shader_language.cpp +++ b/servers/visual/shader_language.cpp @@ -1149,11 +1149,19 @@ const ShaderLanguage::BuiltinsDef ShaderLanguage::ci_fragment_builtins_defs[]={ const ShaderLanguage::BuiltinsDef ShaderLanguage::ci_light_builtins_defs[]={ - { "COLOR", TYPE_VEC4}, + { "POSITION", TYPE_VEC4}, { "NORMAL", TYPE_VEC3}, - { "LIGHT_DIR", TYPE_VEC2}, - { "LIGHT_DISTANCE", TYPE_FLOAT}, - { "LIGHT", TYPE_VEC3}, + { "UV", TYPE_VEC2}, + { "COLOR", TYPE_VEC4}, + { "TEXTURE", TYPE_TEXTURE}, + { "TEXTURE_PIXEL_SIZE", TYPE_VEC2}, + { "VAR1", TYPE_VEC4}, + { "VAR2", TYPE_VEC4}, + { "SCREEN_UV", TYPE_VEC2}, + { "LIGHT_VEC", TYPE_VEC2}, + { "LIGHT_HEIGHT", TYPE_FLOAT}, + { "LIGHT_COLOR", TYPE_VEC4}, + { "LIGHT", TYPE_VEC4}, { "POINT_COORD", TYPE_VEC2}, // { "SCREEN_POS", TYPE_VEC2}, // { "SCREEN_TEXEL_SIZE", TYPE_VEC2}, diff --git a/servers/visual/visual_server_raster.cpp b/servers/visual/visual_server_raster.cpp index 3bcf0b8a3e..1c16f51e89 100644 --- a/servers/visual/visual_server_raster.cpp +++ b/servers/visual/visual_server_raster.cpp @@ -3954,6 +3954,15 @@ void VisualServerRaster::canvas_light_set_item_mask(RID p_light, int p_mask){ } +void VisualServerRaster::canvas_light_set_item_shadow_mask(RID p_light, int p_mask){ + + Rasterizer::CanvasLight *clight = canvas_light_owner.get(p_light); + ERR_FAIL_COND(!clight); + clight->item_shadow_mask=p_mask; + +} + + void VisualServerRaster::canvas_light_set_subtract_mode(RID p_light, bool p_enable) { @@ -4559,6 +4568,13 @@ void VisualServerRaster::free( RID p_rid ) { } + if (occluder->canvas.is_valid() && canvas_owner.owns(occluder->canvas)) { + + Canvas *canvas = canvas_owner.get(occluder->canvas); + canvas->occluders.erase(occluder); + + } + canvas_light_occluder_owner.free( p_rid ); memdelete(occluder); @@ -6906,6 +6922,8 @@ void VisualServerRaster::_draw_viewport(Viewport *p_viewport,int p_ofs_x, int p_ Rasterizer::CanvasLight *lights_with_shadow=NULL; Rect2 shadow_rect; + int light_count=0; + for (Map::Element *E=p_viewport->canvas_map.front();E;E=E->next()) { Matrix32 xf = p_viewport->global_transform * E->get().transform; @@ -6944,10 +6962,13 @@ void VisualServerRaster::_draw_viewport(Viewport *p_viewport,int p_ofs_x, int p_ cl->radius_cache=cl->rect_cache.size.length(); } + + light_count++; } } } + //print_line("lights: "+itos(light_count)); canvas_map[ Viewport::CanvasKey( E->key(), E->get().layer) ]=&E->get(); } @@ -7007,7 +7028,7 @@ void VisualServerRaster::_draw_viewport(Viewport *p_viewport,int p_ofs_x, int p_ } - rasterizer->canvas_debug_viewport_shadows(lights_with_shadow); + //rasterizer->canvas_debug_viewport_shadows(lights_with_shadow); } //capture diff --git a/servers/visual/visual_server_raster.h b/servers/visual/visual_server_raster.h index b9a3f83364..7d7bbe1d71 100644 --- a/servers/visual/visual_server_raster.h +++ b/servers/visual/visual_server_raster.h @@ -1164,6 +1164,7 @@ public: virtual void canvas_light_set_z_range(RID p_light, int p_min_z,int p_max_z); virtual void canvas_light_set_layer_range(RID p_light, int p_min_layer,int p_max_layer); virtual void canvas_light_set_item_mask(RID p_light, int p_mask); + virtual void canvas_light_set_item_shadow_mask(RID p_light, int p_mask); virtual void canvas_light_set_subtract_mode(RID p_light, bool p_enable); virtual void canvas_light_set_shadow_enabled(RID p_light, bool p_enabled); diff --git a/servers/visual/visual_server_wrap_mt.h b/servers/visual/visual_server_wrap_mt.h index 1890f7b760..bccb096e1b 100644 --- a/servers/visual/visual_server_wrap_mt.h +++ b/servers/visual/visual_server_wrap_mt.h @@ -1158,6 +1158,7 @@ public: FUNC3(canvas_light_set_layer_range,RID,int,int); FUNC3(canvas_light_set_z_range,RID,int,int); FUNC2(canvas_light_set_item_mask,RID,int); + FUNC2(canvas_light_set_item_shadow_mask,RID,int); FUNC2(canvas_light_set_subtract_mode,RID,bool); FUNC2(canvas_light_set_shadow_enabled,RID,bool); diff --git a/servers/visual_server.h b/servers/visual_server.h index ccf6978ae3..9404ea040c 100644 --- a/servers/visual_server.h +++ b/servers/visual_server.h @@ -1013,6 +1013,7 @@ public: virtual void canvas_light_set_z_range(RID p_light, int p_min_z,int p_max_z)=0; virtual void canvas_light_set_layer_range(RID p_light, int p_min_layer,int p_max_layer)=0; virtual void canvas_light_set_item_mask(RID p_light, int p_mask)=0; + virtual void canvas_light_set_item_shadow_mask(RID p_light, int p_mask)=0; virtual void canvas_light_set_subtract_mode(RID p_light, bool p_enable)=0; virtual void canvas_light_set_shadow_enabled(RID p_light, bool p_enabled)=0; diff --git a/tools/editor/plugins/canvas_item_editor_plugin.cpp b/tools/editor/plugins/canvas_item_editor_plugin.cpp index 514f4b6525..fdec72332e 100644 --- a/tools/editor/plugins/canvas_item_editor_plugin.cpp +++ b/tools/editor/plugins/canvas_item_editor_plugin.cpp @@ -87,7 +87,7 @@ Dictionary CanvasItemEditor::get_state() const { state["ofs"]=Point2(h_scroll->get_val(),v_scroll->get_val()); // state["ofs"]=-transform.get_origin(); state["use_snap"]=is_snap_active(); - state["snap"]=snap; + state["snap_vec"]=Vector2(get_snap()); state["pixel_snap"]=pixel_snap; return state; } @@ -111,7 +111,15 @@ void CanvasItemEditor::set_state(const Dictionary& p_state){ } if (state.has("snap")) { - snap=state["snap"]; + snap_x->set_val(state["snap"]); + snap_y->set_val(state["snap"]); + } + + if (state.has("snap_vec")) { + Vector2 sv = state["snap_vec"]; + snap_x->set_val(sv.x); + snap_y->set_val(sv.y); + viewport->update(); } if (state.has("pixel_snap")) { @@ -300,7 +308,7 @@ void CanvasItemEditor::_key_move(const Vector2& p_dir, bool p_snap, KeyMoveMODE Vector2 drag = p_dir; if (p_snap) - drag*=snap; + drag*=get_snap(); undo_redo->add_undo_method(canvas_item,"edit_set_state",canvas_item->edit_get_state()); @@ -554,6 +562,13 @@ void CanvasItemEditor::_append_canvas_item(CanvasItem *c) { } +void CanvasItemEditor::_snap_changed(double) { + + viewport->update(); +} + + + void CanvasItemEditor::_dialog_value_changed(double) { if (updating_value_dialog) @@ -563,7 +578,7 @@ void CanvasItemEditor::_dialog_value_changed(double) { case SNAP_CONFIGURE: { - snap=dialog_val->get_val(); + // snap=dialog_val->get_val(); viewport->update(); } break; case ZOOM_SET: { @@ -1165,7 +1180,7 @@ void CanvasItemEditor::_viewport_input_event(const InputEvent& p_event) { continue; } - if (pixel_snap || (is_snap_active() && snap>0)) { + if (pixel_snap || (is_snap_active() && get_snap().x>0 && get_snap().y>0)) { if (drag!=DRAG_ALL) { dfrom=drag_point_from; @@ -1174,14 +1189,14 @@ void CanvasItemEditor::_viewport_input_event(const InputEvent& p_event) { Vector2 newpos = drag_point_from + (dto-dfrom); Vector2 disp; - if (!is_snap_active() || snap<1) { + if (!is_snap_active() || get_snap().x<1 || get_snap().y<1) { disp.x = Math::fposmod(newpos.x,1); disp.y = Math::fposmod(newpos.y,1); } else { - disp.x = Math::fposmod(newpos.x,snap); - disp.y = Math::fposmod(newpos.y,snap); + disp.x = Math::fposmod(newpos.x,get_snap().x); + disp.y = Math::fposmod(newpos.y,get_snap().y); } dto-=disp; } @@ -1477,7 +1492,7 @@ void CanvasItemEditor::_viewport_draw() { _update_scrollbars(); RID ci=viewport->get_canvas_item(); - if (snap>0 && is_snap_active() && true ) { + if (get_snap().x>0 && get_snap().y>0 && is_snap_active() && true ) { Size2 s = viewport->get_size(); @@ -1485,7 +1500,7 @@ void CanvasItemEditor::_viewport_draw() { Matrix32 xform = transform.affine_inverse(); for(int i=0;iset_icon(get_icon("Group","EditorIcons")); ungroup_button->set_icon(get_icon("Ungroup","EditorIcons")); key_insert_button->set_icon(get_icon("Key","EditorIcons")); + snap_x->connect("value_changed",this,"_snap_changed"); + snap_y->connect("value_changed",this,"_snap_changed"); } @@ -2002,7 +2019,7 @@ Point2 CanvasItemEditor::snapify(const Point2& p_pos) const { Vector2 pos = p_pos; - if (!active || snap<1) { + if (!active || get_snap().x<1 || get_snap().y<1) { if (pixel_snap) { @@ -2014,8 +2031,8 @@ Point2 CanvasItemEditor::snapify(const Point2& p_pos) const { } - pos.x=Math::stepify(pos.x,snap); - pos.y=Math::stepify(pos.y,snap); + pos.x=Math::stepify(pos.x,get_snap().x); + pos.y=Math::stepify(pos.y,get_snap().y); return pos; @@ -2038,15 +2055,46 @@ void CanvasItemEditor::_popup_callback(int p_op) { int idx = edit_menu->get_popup()->get_item_index(SNAP_USE_PIXEL); edit_menu->get_popup()->set_item_checked(idx,pixel_snap); } break; + case SNAP_OBJECT_CENTERS: { + + List &selection = editor_selection->get_selected_node_list(); + + undo_redo->create_action("Snap Object Centers"); + for(List::Element *E=selection.front();E;E=E->next()) { + + CanvasItem *canvas_item = E->get()->cast_to(); + if (!canvas_item) + continue; + if (!canvas_item->is_visible()) + continue; + Node2D* node = canvas_item->cast_to(); + if (!node) + continue; + + Matrix32 gtrans = node->get_global_transform(); + gtrans.elements[2]=snapify(gtrans.elements[2]); + + undo_redo->add_do_method(node,"set_global_transform",gtrans); + undo_redo->add_undo_method(node,"set_global_transform",node->get_global_transform()); + } + + undo_redo->add_do_method(viewport,"update"); + undo_redo->add_undo_method(viewport,"update"); + undo_redo->commit_action(); + + } break; case SNAP_CONFIGURE: { updating_value_dialog=true; + snap_dialog->popup_centered_minsize(); +/* dialog_label->set_text("Snap (Pixels):"); dialog_val->set_min(1); dialog_val->set_step(1); dialog_val->set_max(4096); dialog_val->set_val(snap); value_dialog->popup_centered(Size2(200,85)); + */ updating_value_dialog=false; } break; @@ -2604,6 +2652,7 @@ void CanvasItemEditor::_bind_methods() { ObjectTypeDB::bind_method("_unhandled_key_input",&CanvasItemEditor::_unhandled_key_input); ObjectTypeDB::bind_method("_viewport_draw",&CanvasItemEditor::_viewport_draw); ObjectTypeDB::bind_method("_viewport_input_event",&CanvasItemEditor::_viewport_input_event); + ObjectTypeDB::bind_method("_snap_changed",&CanvasItemEditor::_snap_changed); ADD_SIGNAL( MethodInfo("item_lock_status_changed") ); ADD_SIGNAL( MethodInfo("item_group_status_changed") ); @@ -2812,6 +2861,7 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) { p->add_item("Configure Snap..",SNAP_CONFIGURE); p->add_separator(); p->add_check_item("Use Pixel Snap",SNAP_USE_PIXEL); + p->add_item("Snap Selected Object Centers",SNAP_OBJECT_CENTERS); p->add_separator(); p->add_item("Expand to Parent",EXPAND_TO_PARENT,KEY_MASK_CMD|KEY_P); p->add_separator(); @@ -2918,12 +2968,33 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) { dialog_val->connect("value_changed",this,"_dialog_value_changed"); select_sb = Ref( memnew( StyleBoxTexture) ); + snap_dialog = memnew( AcceptDialog ); + VBoxContainer *snap_vb = memnew( VBoxContainer ); + snap_dialog->add_child(snap_vb); + snap_dialog->set_child_rect(snap_vb); + snap_dialog->set_title("Snap Configuration"); + snap_x = memnew( SpinBox ); + snap_x->set_custom_minimum_size(Size2(250,0)); + snap_y = memnew( SpinBox ); + snap_x->set_min(1); + snap_x->set_max(4096); + snap_x->set_step(1); + snap_x->set_val(10); + snap_y->set_min(1); + snap_y->set_max(4096); + snap_y->set_step(1); + snap_y->set_val(10); + snap_vb->add_margin_child("Snap X",snap_x); + snap_vb->add_margin_child("Snap Y",snap_y); + add_child(snap_dialog); + + key_pos=true; key_rot=true; key_scale=false; zoom=1; - snap=10; + //snap=10; updating_value_dialog=false; box_selecting=false; //zoom=0.5; diff --git a/tools/editor/plugins/canvas_item_editor_plugin.h b/tools/editor/plugins/canvas_item_editor_plugin.h index 6648d486e8..9160742826 100644 --- a/tools/editor/plugins/canvas_item_editor_plugin.h +++ b/tools/editor/plugins/canvas_item_editor_plugin.h @@ -77,6 +77,7 @@ class CanvasItemEditor : public VBoxContainer { SNAP_USE, SNAP_CONFIGURE, SNAP_USE_PIXEL, + SNAP_OBJECT_CENTERS, ZOOM_IN, ZOOM_OUT, ZOOM_RESET, @@ -143,7 +144,6 @@ class CanvasItemEditor : public VBoxContainer { Matrix32 transform; float zoom; - int snap; bool pixel_snap; bool box_selecting; Point2 box_selecting_to; @@ -250,7 +250,11 @@ class CanvasItemEditor : public VBoxContainer { AcceptDialog *value_dialog; Label *dialog_label; SpinBox *dialog_val; - + + AcceptDialog *snap_dialog; + SpinBox *snap_x; + SpinBox *snap_y; + CanvasItem *ref_item; void _add_canvas_item(CanvasItem *p_canvas_item); @@ -289,6 +293,7 @@ class CanvasItemEditor : public VBoxContainer { void _viewport_input_event(const InputEvent& p_event); void _viewport_draw(); + void _snap_changed(double); HSplitContainer *palette_split; VSplitContainer *bottom_split; @@ -335,7 +340,7 @@ protected: public: bool is_snap_active() const; - int get_snap() const { return snap; } + Size2i get_snap() const { return Size2i(snap_x->get_val(),snap_y->get_val()); } Matrix32 get_canvas_transform() const { return transform; } diff --git a/tools/editor/plugins/collision_polygon_2d_editor_plugin.cpp b/tools/editor/plugins/collision_polygon_2d_editor_plugin.cpp index dab6df9a39..9a0d5b4066 100644 --- a/tools/editor/plugins/collision_polygon_2d_editor_plugin.cpp +++ b/tools/editor/plugins/collision_polygon_2d_editor_plugin.cpp @@ -369,6 +369,7 @@ void CollisionPolygon2DEditor::edit(Node *p_collision_polygon) { wip.clear(); wip_active=false; edited_point=-1; + canvas_item_editor->get_viewport_control()->update(); } else { node=NULL; diff --git a/tools/editor/plugins/light_occluder_2d_editor_plugin.cpp b/tools/editor/plugins/light_occluder_2d_editor_plugin.cpp index c1fb81b66a..5fa3d8ac8f 100644 --- a/tools/editor/plugins/light_occluder_2d_editor_plugin.cpp +++ b/tools/editor/plugins/light_occluder_2d_editor_plugin.cpp @@ -96,7 +96,7 @@ bool LightOccluder2DEditor::forward_input_event(const InputEvent& p_event) { create_poly->set_text("No OccluderPolygon2D resource on this node.\nCreate and assign one?"); create_poly->popup_centered_minsize(); } - return false; + return (p_event.type==InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index==1); } switch(p_event.type) { @@ -389,7 +389,7 @@ void LightOccluder2DEditor::edit(Node *p_collision_polygon) { wip.clear(); wip_active=false; edited_point=-1; - + canvas_item_editor->get_viewport_control()->update(); } else { node=NULL; @@ -402,6 +402,8 @@ void LightOccluder2DEditor::edit(Node *p_collision_polygon) { void LightOccluder2DEditor::_create_poly() { + if (!node) + return; undo_redo->create_action("Create Occluder Polygon"); undo_redo->add_do_method(node,"set_occluder_polygon",Ref(memnew( OccluderPolygon2D))); undo_redo->add_undo_method(node,"set_occluder_polygon",Variant(REF())); diff --git a/tools/editor/plugins/navigation_polygon_editor_plugin.cpp b/tools/editor/plugins/navigation_polygon_editor_plugin.cpp index 599d18c8bb..163accfdd3 100644 --- a/tools/editor/plugins/navigation_polygon_editor_plugin.cpp +++ b/tools/editor/plugins/navigation_polygon_editor_plugin.cpp @@ -36,6 +36,9 @@ void NavigationPolygonEditor::_node_removed(Node *p_node) { void NavigationPolygonEditor::_create_nav() { + if (!node) + return; + undo_redo->create_action("Create Navigation Polygon"); undo_redo->add_do_method(node,"set_navigation_polygon",Ref(memnew( NavigationPolygon))); undo_redo->add_undo_method(node,"set_navigation_polygon",Variant(REF())); @@ -107,7 +110,7 @@ bool NavigationPolygonEditor::forward_input_event(const InputEvent& p_event) { create_nav->set_text("No NavigationPolygon resource on this node.\nCreate and assign one?"); create_nav->popup_centered_minsize(); } - return false; + return (p_event.type==InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index==1);; } @@ -445,6 +448,7 @@ void NavigationPolygonEditor::edit(Node *p_collision_polygon) { wip.clear(); wip_active=false; edited_point=-1; + canvas_item_editor->get_viewport_control()->update(); } else { node=NULL; diff --git a/tools/editor/plugins/tile_map_editor_plugin.cpp b/tools/editor/plugins/tile_map_editor_plugin.cpp index 47727a00c2..79e43f9012 100644 --- a/tools/editor/plugins/tile_map_editor_plugin.cpp +++ b/tools/editor/plugins/tile_map_editor_plugin.cpp @@ -640,19 +640,53 @@ void TileMapEditor::_canvas_draw() { Ref t = ts->tile_get_texture(st); if (t.is_valid()) { - Vector2 from = xform.xform(ts->tile_get_texture_offset(st)+node->map_to_world(over_tile)+node->get_cell_draw_offset()); + Vector2 from = node->map_to_world(over_tile)+node->get_cell_draw_offset(); Rect2 r = ts->tile_get_region(st); Size2 sc = xform.get_scale(); if (mirror_x->is_pressed()) sc.x*=-1.0; if (mirror_y->is_pressed()) sc.y*=-1.0; + + Rect2 rect; + if (r==Rect2()) { + rect=Rect2(from,t->get_size()); + } else { + + rect=Rect2(from,r.get_size()); + } + + + if (node->get_tile_origin()==TileMap::TILE_ORIGIN_TOP_LEFT) { + rect.pos+=ts->tile_get_texture_offset(st); + + } else if (node->get_tile_origin()==TileMap::TILE_ORIGIN_CENTER) { + rect.pos+=node->get_cell_size()/2; + Vector2 s = r.size; + + Vector2 center = (s/2) - ts->tile_get_texture_offset(st); + + + if (mirror_x->is_pressed()) + rect.pos.x-=s.x-center.x; + else + rect.pos.x-=center.x; + + if (mirror_y->is_pressed()) + rect.pos.y-=s.y-center.y; + else + rect.pos.y-=center.y; + } + + rect.pos=xform.xform(rect.pos); + rect.size*=sc; + if (r==Rect2()) { - canvas_item_editor->draw_texture_rect(t,Rect2(from,t->get_size()*sc),false,Color(1,1,1,0.5),transpose->is_pressed()); + canvas_item_editor->draw_texture_rect(t,rect,false,Color(1,1,1,0.5),transpose->is_pressed()); } else { - canvas_item_editor->draw_texture_rect_region(t,Rect2(from,r.get_size()*sc),r,Color(1,1,1,0.5),transpose->is_pressed()); + canvas_item_editor->draw_texture_rect_region(t,rect,r,Color(1,1,1,0.5),transpose->is_pressed()); } } } diff --git a/tools/editor/plugins/tile_set_editor_plugin.cpp b/tools/editor/plugins/tile_set_editor_plugin.cpp index a51caf7d54..8ff7720934 100644 --- a/tools/editor/plugins/tile_set_editor_plugin.cpp +++ b/tools/editor/plugins/tile_set_editor_plugin.cpp @@ -37,83 +37,103 @@ void TileSetEditor::edit(const Ref& p_tileset) { void TileSetEditor::_import_scene(Node *scene, Ref p_library, bool p_merge) { if (!p_merge) - p_library->clear(); + p_library->clear(); for(int i=0;iget_child_count();i++) { - Node *child = scene->get_child(i); + Node *child = scene->get_child(i); - if (!child->cast_to()) { - if (child->get_child_count()>0) { - child=child->get_child(0); - if (!child->cast_to()) { - continue; - } + if (!child->cast_to()) { + if (child->get_child_count()>0) { + child=child->get_child(0); + if (!child->cast_to()) { + continue; + } - } else - continue; + } else + continue; - } + } - Sprite *mi = child->cast_to(); - Ref texture=mi->get_texture(); - if (texture.is_null()) + Sprite *mi = child->cast_to(); + Ref texture=mi->get_texture(); + Ref material=mi->get_material(); + + if (texture.is_null()) continue; - int id = p_library->find_tile_by_name(mi->get_name()); - if (id<0) { - - id=p_library->get_last_unused_tile_id(); - p_library->create_tile(id); - p_library->tile_set_name(id,mi->get_name()); - } - - - p_library->tile_set_texture(id,texture); - Vector2 phys_offset; - - if (mi->is_centered()) { - Size2 s; - if (mi->is_region()) { - s=mi->get_region_rect().size; - } else { - s=texture->get_size(); - } - phys_offset+=-s/2; - } - if (mi->is_region()) { - p_library->tile_set_region(id,mi->get_region_rect()); - } - - Vector >collisions; - - for(int j=0;jget_child_count();j++) { - - Node *child2 = mi->get_child(j); - if (!child2->cast_to()) - continue; - StaticBody2D *sb = child2->cast_to(); - if (sb->get_shape_count()==0) - continue; - Ref collision=sb->get_shape(0); - if (collision.is_valid()) { - collisions.push_back(collision); + int id = p_library->find_tile_by_name(mi->get_name()); + if (id<0) { + + id=p_library->get_last_unused_tile_id(); + p_library->create_tile(id); + p_library->tile_set_name(id,mi->get_name()); + } + + + + p_library->tile_set_texture(id,texture); + p_library->tile_set_material(id,material); + + Vector2 phys_offset; + + if (mi->is_centered()) { + Size2 s; + if (mi->is_region()) { + s=mi->get_region_rect().size; + } else { + s=texture->get_size(); + } + phys_offset+=-s/2; + } + if (mi->is_region()) { + p_library->tile_set_region(id,mi->get_region_rect()); + } + + Vector >collisions; + Ref nav_poly; + Ref occluder; + + for(int j=0;jget_child_count();j++) { + + Node *child2 = mi->get_child(j); + + if (child2->cast_to()) + nav_poly=child2->cast_to()->get_navigation_polygon(); + + if (child2->cast_to()) + occluder=child2->cast_to()->get_occluder_polygon(); + + if (!child2->cast_to()) + continue; + StaticBody2D *sb = child2->cast_to(); + if (sb->get_shape_count()==0) + continue; + Ref collision=sb->get_shape(0); + if (collision.is_valid()) { + collisions.push_back(collision); } - } + } - if (collisions.size()) { + if (collisions.size()) { - p_library->tile_set_shapes(id,collisions); - p_library->tile_set_shape_offset(id,-phys_offset); - } else { - p_library->tile_set_shape_offset(id,Vector2()); + p_library->tile_set_shapes(id,collisions); + p_library->tile_set_shape_offset(id,-phys_offset); + } else { + p_library->tile_set_shape_offset(id,Vector2()); + + } + + p_library->tile_set_texture_offset(id,mi->get_offset()); + p_library->tile_set_navigation_polygon(id,nav_poly); + p_library->tile_set_light_occluder(id,occluder); + p_library->tile_set_occluder_offset(id,-phys_offset); + p_library->tile_set_navigation_polygon_offset(id,-phys_offset); - } - p_library->tile_set_texture_offset(id,mi->get_offset()); } } @@ -121,23 +141,23 @@ void TileSetEditor::_menu_confirm() { switch(option) { - case MENU_OPTION_REMOVE_ITEM: { + case MENU_OPTION_REMOVE_ITEM: { - tileset->remove_tile(to_erase); - } break; - case MENU_OPTION_MERGE_FROM_SCENE: - case MENU_OPTION_CREATE_FROM_SCENE: { + tileset->remove_tile(to_erase); + } break; + case MENU_OPTION_MERGE_FROM_SCENE: + case MENU_OPTION_CREATE_FROM_SCENE: { - EditorNode *en = editor; - Node * scene = en->get_edited_scene(); - if (!scene) - break; + EditorNode *en = editor; + Node * scene = en->get_edited_scene(); + if (!scene) + break; - _import_scene(scene,tileset,option==MENU_OPTION_MERGE_FROM_SCENE); + _import_scene(scene,tileset,option==MENU_OPTION_MERGE_FROM_SCENE); - } break; + } break; } } @@ -165,11 +185,11 @@ void TileSetEditor::_menu_cbk(int p_option) { cd->set_text("Create from scene?"); cd->popup_centered(Size2(300,60)); } break; - case MENU_OPTION_MERGE_FROM_SCENE: { + case MENU_OPTION_MERGE_FROM_SCENE: { - cd->set_text("Merge from scene?"); - cd->popup_centered(Size2(300,60)); - } break; + cd->set_text("Merge from scene?"); + cd->popup_centered(Size2(300,60)); + } break; } } diff --git a/tools/editor/plugins/tile_set_editor_plugin.h b/tools/editor/plugins/tile_set_editor_plugin.h index 2531ec55bf..1248b4e007 100644 --- a/tools/editor/plugins/tile_set_editor_plugin.h +++ b/tools/editor/plugins/tile_set_editor_plugin.h @@ -56,7 +56,7 @@ class TileSetEditor : public Control { int option; void _menu_cbk(int p_option); - void _menu_confirm(); + void _menu_confirm(); static void _import_scene(Node *p_scene, Ref p_library, bool p_merge); diff --git a/tools/editor/property_editor.cpp b/tools/editor/property_editor.cpp index 25c39b3173..fb4c134263 100644 --- a/tools/editor/property_editor.cpp +++ b/tools/editor/property_editor.cpp @@ -1860,7 +1860,7 @@ void PropertyEditor::set_item_text(TreeItem *p_item, int p_type, const String& p if (has_icon(res->get_type(),"EditorIcons")) { - p_item->set_icon(1,get_icon(res->get_type(),"EditorIcons")); + p_item->set_icon(0,get_icon(res->get_type(),"EditorIcons")); } else { Dictionary d = p_item->get_metadata(0); @@ -1870,10 +1870,10 @@ void PropertyEditor::set_item_text(TreeItem *p_item, int p_type, const String& p if (has_icon(hint_text,"EditorIcons")) { - p_item->set_icon(1,get_icon(hint_text,"EditorIcons")); + p_item->set_icon(0,get_icon(hint_text,"EditorIcons")); } else { - p_item->set_icon(1,get_icon("Object","EditorIcons")); + p_item->set_icon(0,get_icon("Object","EditorIcons")); } } -- cgit v1.2.3 From 7957709cb162a646ad5c81f81cce62f0f61b5e1c Mon Sep 17 00:00:00 2001 From: marynate Date: Mon, 9 Mar 2015 16:28:08 +0800 Subject: Fix compie error in TileMap::_fix_cell_transform(...) --- scene/2d/tile_map.cpp | 11 ++++++----- scene/2d/tile_map.h | 2 +- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp index b9d87c1224..2b88ee5dba 100644 --- a/scene/2d/tile_map.cpp +++ b/scene/2d/tile_map.cpp @@ -215,23 +215,24 @@ bool TileMap::get_center_y() const { return center_y; } -void TileMap::_fix_cell_transform(Matrix32& xform,const Cell& c,Vector2& offset,const Size2 &sc) { +void TileMap::_fix_cell_transform(Matrix32& xform,const Cell& p_cell, const Vector2& p_offset, const Size2 &p_sc) { - Size2 s=sc; + Size2 s=p_sc; + Vector2 offset = p_offset; - if (c.transpose) { + if (p_cell.transpose) { SWAP(xform.elements[0].x, xform.elements[0].y); SWAP(xform.elements[1].x, xform.elements[1].y); SWAP(offset.x, offset.y); SWAP(s.x, s.y); } - if (c.flip_h) { + if (p_cell.flip_h) { xform.elements[0].x=-xform.elements[0].x; xform.elements[1].x=-xform.elements[1].x; if (tile_origin==TILE_ORIGIN_TOP_LEFT) offset.x=s.x-offset.x; } - if (c.flip_v) { + if (p_cell.flip_v) { xform.elements[0].y=-xform.elements[0].y; xform.elements[1].y=-xform.elements[1].y; if (tile_origin==TILE_ORIGIN_TOP_LEFT) diff --git a/scene/2d/tile_map.h b/scene/2d/tile_map.h index 3facc9e8b7..e02c4ee5bb 100644 --- a/scene/2d/tile_map.h +++ b/scene/2d/tile_map.h @@ -148,7 +148,7 @@ private: uint32_t collision_layer; TileOrigin tile_origin; - void _fix_cell_transform(Matrix32& xform, const Cell& c, Vector2 &offset, const Size2 &s); + void _fix_cell_transform(Matrix32& xform, const Cell& p_cell, const Vector2 &p_offset, const Size2 &p_sc); Map::Element *_create_quadrant(const PosKey& p_qk); void _erase_quadrant(Map::Element *Q); -- cgit v1.2.3 From 91744e9ed3124ca48e0837ee72bfe7182fd31701 Mon Sep 17 00:00:00 2001 From: Juan Linietsky Date: Tue, 10 Mar 2015 00:53:09 -0300 Subject: New Demo, Screen Space Shaders -Fixes to screen space shaders. -Fixes to isometric light demo. --- demos/2d/isometric_light/faceColor.png | Bin 45476 -> 47941 bytes demos/2d/screen_space_shaders/art/burano.jpg | Bin 0 -> 246589 bytes demos/2d/screen_space_shaders/art/burano.png | Bin 0 -> 974437 bytes demos/2d/screen_space_shaders/art/filmgrain.png | Bin 0 -> 290595 bytes .../screen_space_shaders/art/filmgrain.png.flags | 1 + demos/2d/screen_space_shaders/art/forest.png | Bin 0 -> 1199433 bytes demos/2d/screen_space_shaders/art/mountains.png | Bin 0 -> 927435 bytes demos/2d/screen_space_shaders/art/platformer.png | Bin 0 -> 44102 bytes demos/2d/screen_space_shaders/art/vignette.png | Bin 0 -> 4075 bytes demos/2d/screen_space_shaders/art/white.png | Bin 0 -> 174 bytes demos/2d/screen_space_shaders/engine.cfg | 4 +++ demos/2d/screen_space_shaders/screen_shaders.gd | 32 +++++++++++++++++++ demos/2d/screen_space_shaders/screen_shaders.scn | Bin 0 -> 5762 bytes drivers/gles2/shader_compiler_gles2.cpp | 8 +++++ servers/visual/shader_language.cpp | 35 ++++++++++++++++----- servers/visual/shader_language.h | 2 ++ tools/editor/plugins/baked_light_baker.cpp | 2 +- 17 files changed, 76 insertions(+), 8 deletions(-) create mode 100644 demos/2d/screen_space_shaders/art/burano.jpg create mode 100644 demos/2d/screen_space_shaders/art/burano.png create mode 100644 demos/2d/screen_space_shaders/art/filmgrain.png create mode 100644 demos/2d/screen_space_shaders/art/filmgrain.png.flags create mode 100644 demos/2d/screen_space_shaders/art/forest.png create mode 100644 demos/2d/screen_space_shaders/art/mountains.png create mode 100644 demos/2d/screen_space_shaders/art/platformer.png create mode 100644 demos/2d/screen_space_shaders/art/vignette.png create mode 100644 demos/2d/screen_space_shaders/art/white.png create mode 100644 demos/2d/screen_space_shaders/engine.cfg create mode 100644 demos/2d/screen_space_shaders/screen_shaders.gd create mode 100644 demos/2d/screen_space_shaders/screen_shaders.scn diff --git a/demos/2d/isometric_light/faceColor.png b/demos/2d/isometric_light/faceColor.png index b7e3839a78..c6daf73cb7 100644 Binary files a/demos/2d/isometric_light/faceColor.png and b/demos/2d/isometric_light/faceColor.png differ diff --git a/demos/2d/screen_space_shaders/art/burano.jpg b/demos/2d/screen_space_shaders/art/burano.jpg new file mode 100644 index 0000000000..cdab993ec1 Binary files /dev/null and b/demos/2d/screen_space_shaders/art/burano.jpg differ diff --git a/demos/2d/screen_space_shaders/art/burano.png b/demos/2d/screen_space_shaders/art/burano.png new file mode 100644 index 0000000000..6eec09d585 Binary files /dev/null and b/demos/2d/screen_space_shaders/art/burano.png differ diff --git a/demos/2d/screen_space_shaders/art/filmgrain.png b/demos/2d/screen_space_shaders/art/filmgrain.png new file mode 100644 index 0000000000..b8ea89902c Binary files /dev/null and b/demos/2d/screen_space_shaders/art/filmgrain.png differ diff --git a/demos/2d/screen_space_shaders/art/filmgrain.png.flags b/demos/2d/screen_space_shaders/art/filmgrain.png.flags new file mode 100644 index 0000000000..d5476d5499 --- /dev/null +++ b/demos/2d/screen_space_shaders/art/filmgrain.png.flags @@ -0,0 +1 @@ +repeat=true diff --git a/demos/2d/screen_space_shaders/art/forest.png b/demos/2d/screen_space_shaders/art/forest.png new file mode 100644 index 0000000000..f5a2fb9bfb Binary files /dev/null and b/demos/2d/screen_space_shaders/art/forest.png differ diff --git a/demos/2d/screen_space_shaders/art/mountains.png b/demos/2d/screen_space_shaders/art/mountains.png new file mode 100644 index 0000000000..b8435bb1a8 Binary files /dev/null and b/demos/2d/screen_space_shaders/art/mountains.png differ diff --git a/demos/2d/screen_space_shaders/art/platformer.png b/demos/2d/screen_space_shaders/art/platformer.png new file mode 100644 index 0000000000..21c1cb4c4b Binary files /dev/null and b/demos/2d/screen_space_shaders/art/platformer.png differ diff --git a/demos/2d/screen_space_shaders/art/vignette.png b/demos/2d/screen_space_shaders/art/vignette.png new file mode 100644 index 0000000000..8afeb7f9e1 Binary files /dev/null and b/demos/2d/screen_space_shaders/art/vignette.png differ diff --git a/demos/2d/screen_space_shaders/art/white.png b/demos/2d/screen_space_shaders/art/white.png new file mode 100644 index 0000000000..573faa33f2 Binary files /dev/null and b/demos/2d/screen_space_shaders/art/white.png differ diff --git a/demos/2d/screen_space_shaders/engine.cfg b/demos/2d/screen_space_shaders/engine.cfg new file mode 100644 index 0000000000..2a41110886 --- /dev/null +++ b/demos/2d/screen_space_shaders/engine.cfg @@ -0,0 +1,4 @@ +[application] + +name="Screen-Space Shaders" +main_scene="res://screen_shaders.scn" diff --git a/demos/2d/screen_space_shaders/screen_shaders.gd b/demos/2d/screen_space_shaders/screen_shaders.gd new file mode 100644 index 0000000000..4e8a548539 --- /dev/null +++ b/demos/2d/screen_space_shaders/screen_shaders.gd @@ -0,0 +1,32 @@ + +extends Control + +# member variables here, example: +# var a=2 +# var b="textvar" + +func _ready(): + # Initialization here + for c in get_node("pictures").get_children(): + get_node("picture").add_item("PIC: "+c.get_name()) + for c in get_node("effects").get_children(): + get_node("effect").add_item("FX: "+c.get_name()) + pass + + + + +func _on_picture_item_selected( ID ): + for c in range(get_node("pictures").get_child_count()): + if (ID==c): + get_node("pictures").get_child(c).show() + else: + get_node("pictures").get_child(c).hide() + + +func _on_effect_item_selected( ID ): + for c in range(get_node("effects").get_child_count()): + if (ID==c): + get_node("effects").get_child(c).show() + else: + get_node("effects").get_child(c).hide() diff --git a/demos/2d/screen_space_shaders/screen_shaders.scn b/demos/2d/screen_space_shaders/screen_shaders.scn new file mode 100644 index 0000000000..aa359616de Binary files /dev/null and b/demos/2d/screen_space_shaders/screen_shaders.scn differ diff --git a/drivers/gles2/shader_compiler_gles2.cpp b/drivers/gles2/shader_compiler_gles2.cpp index be40043573..8d378ceec1 100644 --- a/drivers/gles2/shader_compiler_gles2.cpp +++ b/drivers/gles2/shader_compiler_gles2.cpp @@ -61,6 +61,7 @@ static String _typestr(SL::DataType p_type) { case SL::TYPE_VEC2: return "vec2"; case SL::TYPE_VEC3: return "vec3"; case SL::TYPE_VEC4: return "vec4"; + case SL::TYPE_MAT2: return "mat2"; case SL::TYPE_MAT3: return "mat3"; case SL::TYPE_MAT4: return "mat4"; case SL::TYPE_TEXTURE: return "sampler2D"; @@ -284,6 +285,7 @@ String ShaderCompilerGLES2::dump_node_code(SL::Node *p_node,int p_level,bool p_a case SL::TYPE_VEC2: { Vector2 v = cnode->value; code="vec2("+_mknum(v.x)+", "+_mknum(v.y)+")"; } break; case SL::TYPE_VEC3: { Vector3 v = cnode->value; code="vec3("+_mknum(v.x)+", "+_mknum(v.y)+", "+_mknum(v.z)+")"; } break; case SL::TYPE_VEC4: { Plane v = cnode->value; code="vec4("+_mknum(v.normal.x)+", "+_mknum(v.normal.y)+", "+_mknum(v.normal.z)+", "+_mknum(v.d)+")"; } break; + case SL::TYPE_MAT2: { Matrix32 x = cnode->value; code="mat2( vec2("+_mknum(x[0][0])+", "+_mknum(x[0][1])+"), vec2("+_mknum(x[1][0])+", "+_mknum(x[1][1])+"))"; } break; case SL::TYPE_MAT3: { Matrix3 x = cnode->value; code="mat3( vec3("+_mknum(x.get_axis(0).x)+", "+_mknum(x.get_axis(0).y)+", "+_mknum(x.get_axis(0).z)+"), vec3("+_mknum(x.get_axis(1).x)+", "+_mknum(x.get_axis(1).y)+", "+_mknum(x.get_axis(1).z)+"), vec3("+_mknum(x.get_axis(2).x)+", "+_mknum(x.get_axis(2).y)+", "+_mknum(x.get_axis(2).z)+"))"; } break; case SL::TYPE_MAT4: { Transform x = cnode->value; code="mat4( vec4("+_mknum(x.basis.get_axis(0).x)+", "+_mknum(x.basis.get_axis(0).y)+", "+_mknum(x.basis.get_axis(0).z)+",0.0), vec4("+_mknum(x.basis.get_axis(1).x)+", "+_mknum(x.basis.get_axis(1).y)+", "+_mknum(x.basis.get_axis(1).z)+",0.0), vec4("+_mknum(x.basis.get_axis(2).x)+", "+_mknum(x.basis.get_axis(2).y)+", "+_mknum(x.basis.get_axis(2).z)+",0.0), vec4("+_mknum(x.origin.x)+", "+_mknum(x.origin.y)+", "+_mknum(x.origin.z)+",1.0))"; } break; default: code="value.get_type())+" ("+itos(cnode->datatype)+">"; @@ -476,6 +478,11 @@ String ShaderCompilerGLES2::dump_node_code(SL::Node *p_node,int p_level,bool p_a m="[2]"; else if (mnode->name=="w") m="[3]"; + } else if (mnode->basetype==SL::TYPE_MAT2) { + if (mnode->name=="x") + m="[0]"; + else if (mnode->name=="y") + m="[1]"; } else if (mnode->basetype==SL::TYPE_MAT3) { if (mnode->name=="x") @@ -657,6 +664,7 @@ ShaderCompilerGLES2::ShaderCompilerGLES2() { replace_table["vec2" ]= "vec2"; replace_table["vec3" ]= "vec3"; replace_table["vec4" ]= "vec4"; + replace_table["mat2" ]= "mat2"; replace_table["mat3" ]= "mat3"; replace_table["mat4" ]= "mat4"; replace_table["texture" ]= "sampler2D"; diff --git a/servers/visual/shader_language.cpp b/servers/visual/shader_language.cpp index e53fe8f82d..af65a7a639 100644 --- a/servers/visual/shader_language.cpp +++ b/servers/visual/shader_language.cpp @@ -56,6 +56,7 @@ const char * ShaderLanguage::token_names[TK_MAX]={ "TYPE_VEC2", "TYPE_VEC3", "TYPE_VEC4", + "TYPE_MAT2", "TYPE_MAT3", "TYPE_MAT4", "TYPE_TEXTURE", @@ -403,9 +404,9 @@ ShaderLanguage::Token ShaderLanguage::read_token(const CharType* p_text,int p_le {TK_TYPE_TEXTURE,"texture"}, {TK_TYPE_CUBEMAP,"cubemap"}, {TK_TYPE_COLOR,"color"}, - /* + {TK_TYPE_MAT2,"mat2"}, - {TK_TYPE_MAT3,"mat3"}, + /*{TK_TYPE_MAT3,"mat3"}, {TK_TYPE_MAT4,"mat3"},*/ {TK_TYPE_MAT3,"mat3"}, {TK_TYPE_MAT4,"mat4"}, @@ -511,6 +512,7 @@ bool ShaderLanguage::is_token_datatype(TokenType p_type) { (p_type==TK_TYPE_VEC3) || (p_type==TK_TYPE_VEC4) || (p_type==TK_TYPE_COLOR) || + (p_type==TK_TYPE_MAT2) || (p_type==TK_TYPE_MAT3) || (p_type==TK_TYPE_MAT4) || (p_type==TK_TYPE_CUBEMAP) || @@ -529,6 +531,7 @@ ShaderLanguage::DataType ShaderLanguage::get_token_datatype(TokenType p_type) { case TK_TYPE_VEC3: return TYPE_VEC3; case TK_TYPE_VEC4: return TYPE_VEC4; case TK_TYPE_COLOR: return TYPE_VEC4; + case TK_TYPE_MAT2: return TYPE_MAT2; case TK_TYPE_MAT3: return TYPE_MAT3; case TK_TYPE_MAT4: return TYPE_MAT4; case TK_TYPE_TEXTURE: return TYPE_TEXTURE; @@ -550,6 +553,7 @@ String ShaderLanguage::get_datatype_name(DataType p_type) { case TYPE_VEC2: return "vec2"; case TYPE_VEC3: return "vec3"; case TYPE_VEC4: return "vec4"; + case TYPE_MAT2: return "mat2"; case TYPE_MAT3: return "mat3"; case TYPE_MAT4: return "mat4"; case TYPE_TEXTURE: return "texture"; @@ -570,6 +574,7 @@ bool ShaderLanguage::is_token_nonvoid_datatype(TokenType p_type) { (p_type==TK_TYPE_VEC3) || (p_type==TK_TYPE_VEC4) || (p_type==TK_TYPE_COLOR) || + (p_type==TK_TYPE_MAT2) || (p_type==TK_TYPE_MAT3) || (p_type==TK_TYPE_MAT4) || (p_type==TK_TYPE_TEXTURE) || @@ -782,6 +787,7 @@ const ShaderLanguage::IntrinsicFuncDef ShaderLanguage::intrinsic_func_defs[]={ {"vec4",TYPE_VEC4,{TYPE_FLOAT,TYPE_VEC3,TYPE_VOID}}, {"vec4",TYPE_VEC4,{TYPE_VEC3,TYPE_FLOAT,TYPE_VOID}}, {"vec4",TYPE_VEC4,{TYPE_VEC2,TYPE_VEC2,TYPE_VOID}}, + {"mat2",TYPE_MAT2,{TYPE_VEC2,TYPE_VEC2,TYPE_VOID}}, {"mat3",TYPE_MAT3,{TYPE_VEC3,TYPE_VEC3,TYPE_VEC3,TYPE_VOID}}, {"mat4",TYPE_MAT4,{TYPE_VEC4,TYPE_VEC4,TYPE_VEC4,TYPE_VEC4,TYPE_VOID}}, //intrinsics - trigonometry @@ -918,6 +924,7 @@ const ShaderLanguage::OperatorDef ShaderLanguage::operator_defs[]={ {OP_ASSIGN,TYPE_VOID,{TYPE_VEC2,TYPE_VEC2}}, {OP_ASSIGN,TYPE_VOID,{TYPE_VEC3,TYPE_VEC3}}, {OP_ASSIGN,TYPE_VOID,{TYPE_VEC4,TYPE_VEC4}}, + {OP_ASSIGN,TYPE_VOID,{TYPE_MAT2,TYPE_MAT2}}, {OP_ASSIGN,TYPE_VOID,{TYPE_MAT3,TYPE_MAT3}}, {OP_ASSIGN,TYPE_VOID,{TYPE_MAT4,TYPE_MAT4}}, {OP_ADD,TYPE_FLOAT,{TYPE_FLOAT,TYPE_FLOAT}}, @@ -933,6 +940,8 @@ const ShaderLanguage::OperatorDef ShaderLanguage::operator_defs[]={ {OP_MUL,TYPE_VEC2,{TYPE_VEC2,TYPE_FLOAT}}, {OP_MUL,TYPE_VEC2,{TYPE_FLOAT,TYPE_VEC2}}, {OP_MUL,TYPE_VEC2,{TYPE_VEC2,TYPE_MAT3}}, + {OP_MUL,TYPE_VEC2,{TYPE_MAT2,TYPE_VEC2}}, + {OP_MUL,TYPE_VEC2,{TYPE_VEC2,TYPE_MAT2}}, {OP_MUL,TYPE_VEC2,{TYPE_MAT3,TYPE_VEC2}}, {OP_MUL,TYPE_VEC2,{TYPE_VEC2,TYPE_MAT4}}, {OP_MUL,TYPE_VEC2,{TYPE_MAT4,TYPE_VEC2}}, @@ -947,6 +956,7 @@ const ShaderLanguage::OperatorDef ShaderLanguage::operator_defs[]={ {OP_MUL,TYPE_VEC4,{TYPE_FLOAT,TYPE_VEC4}}, {OP_MUL,TYPE_VEC4,{TYPE_MAT4,TYPE_VEC4}}, {OP_MUL,TYPE_VEC4,{TYPE_VEC4,TYPE_MAT4}}, + {OP_MUL,TYPE_MAT2,{TYPE_MAT2,TYPE_MAT2}}, {OP_MUL,TYPE_MAT3,{TYPE_MAT3,TYPE_MAT3}}, {OP_MUL,TYPE_MAT4,{TYPE_MAT4,TYPE_MAT4}}, {OP_DIV,TYPE_FLOAT,{TYPE_FLOAT,TYPE_FLOAT}}, @@ -976,15 +986,15 @@ const ShaderLanguage::OperatorDef ShaderLanguage::operator_defs[]={ {OP_ASSIGN_MUL,TYPE_VOID,{TYPE_FLOAT,TYPE_FLOAT}}, {OP_ASSIGN_MUL,TYPE_VOID,{TYPE_VEC2,TYPE_VEC2}}, {OP_ASSIGN_MUL,TYPE_VOID,{TYPE_VEC2,TYPE_FLOAT}}, - {OP_ASSIGN_MUL,TYPE_VOID,{TYPE_MAT3,TYPE_VEC2}}, - {OP_ASSIGN_MUL,TYPE_VOID,{TYPE_MAT4,TYPE_VEC2}}, + {OP_ASSIGN_MUL,TYPE_VOID,{TYPE_VEC2,TYPE_MAT2}}, + {OP_ASSIGN_MUL,TYPE_VOID,{TYPE_MAT2,TYPE_MAT2}}, + {OP_ASSIGN_MUL,TYPE_VOID,{TYPE_VEC3,TYPE_MAT3}}, {OP_ASSIGN_MUL,TYPE_VOID,{TYPE_VEC3,TYPE_VEC3}}, {OP_ASSIGN_MUL,TYPE_VOID,{TYPE_VEC3,TYPE_FLOAT}}, - {OP_ASSIGN_MUL,TYPE_VOID,{TYPE_MAT3,TYPE_VEC3}}, - {OP_ASSIGN_MUL,TYPE_VOID,{TYPE_MAT4,TYPE_VEC3}}, + {OP_ASSIGN_MUL,TYPE_VOID,{TYPE_VEC3,TYPE_MAT4}}, {OP_ASSIGN_MUL,TYPE_VOID,{TYPE_VEC4,TYPE_VEC4}}, {OP_ASSIGN_MUL,TYPE_VOID,{TYPE_VEC4,TYPE_FLOAT}}, - {OP_ASSIGN_MUL,TYPE_VOID,{TYPE_MAT4,TYPE_VEC4}}, + {OP_ASSIGN_MUL,TYPE_VOID,{TYPE_VEC4,TYPE_MAT4}}, {OP_ASSIGN_MUL,TYPE_VOID,{TYPE_MAT3,TYPE_MAT3}}, {OP_ASSIGN_MUL,TYPE_VOID,{TYPE_MAT4,TYPE_MAT4}}, {OP_ASSIGN_DIV,TYPE_VOID,{TYPE_FLOAT,TYPE_FLOAT}}, @@ -1566,6 +1576,7 @@ Error ShaderLanguage::parse_expression(Parser& parser,Node *p_parent,Node **r_ex case TYPE_VEC2: name="vec2"; break; case TYPE_VEC3: name="vec3"; break; case TYPE_VEC4: name="vec4"; break; + case TYPE_MAT2: name="mat2"; break; case TYPE_MAT3: name="mat3"; break; case TYPE_MAT4: name="mat4"; break; default: ERR_FAIL_V(ERR_BUG); @@ -1860,6 +1871,7 @@ Error ShaderLanguage::parse_expression(Parser& parser,Node *p_parent,Node **r_ex } } break; + case TYPE_MAT2: ok=(ident=="x" || ident=="y"); member_type=TYPE_VEC2; break; case TYPE_MAT3: ok=(ident=="x" || ident=="y" || ident=="z" ); member_type=TYPE_VEC3; break; case TYPE_MAT4: ok=(ident=="x" || ident=="y" || ident=="z" || ident=="w"); member_type=TYPE_VEC4; break; default: {} @@ -2246,6 +2258,7 @@ Error ShaderLanguage::parse_variable_declaration(Parser& parser,BlockNode *p_blo case TYPE_VEC2: con->value=Vector2(); break; case TYPE_VEC3: con->value=Vector3(); break; case TYPE_VEC4: con->value=iscolor?Variant(Color()):Variant(Plane()); break; + case TYPE_MAT2: con->value=Matrix32(); break; case TYPE_MAT3: con->value=Matrix3(); break; case TYPE_MAT4: con->value=Transform(); break; case TYPE_TEXTURE: @@ -2628,12 +2641,20 @@ void ShaderLanguage::get_keyword_list(ShaderType p_type, List *p_keyword int idx=0; + p_keywords->push_back("uniform"); + p_keywords->push_back("texture"); + p_keywords->push_back("cubemap"); + p_keywords->push_back("color"); + p_keywords->push_back("if"); + p_keywords->push_back("else"); + while(intrinsic_func_defs[idx].name) { p_keywords->push_back(intrinsic_func_defs[idx].name); idx++; } + switch(p_type) { case SHADER_MATERIAL_VERTEX: { idx=0; diff --git a/servers/visual/shader_language.h b/servers/visual/shader_language.h index f79c219d85..7777c8bcf3 100644 --- a/servers/visual/shader_language.h +++ b/servers/visual/shader_language.h @@ -56,6 +56,7 @@ public: TK_TYPE_VEC2, TK_TYPE_VEC3, TK_TYPE_VEC4, + TK_TYPE_MAT2, TK_TYPE_MAT3, TK_TYPE_MAT4, TK_TYPE_TEXTURE, @@ -118,6 +119,7 @@ public: TYPE_VEC2, TYPE_VEC3, TYPE_VEC4, + TYPE_MAT2, TYPE_MAT3, TYPE_MAT4, TYPE_TEXTURE, diff --git a/tools/editor/plugins/baked_light_baker.cpp b/tools/editor/plugins/baked_light_baker.cpp index 42a185b7c2..184f80a1b7 100644 --- a/tools/editor/plugins/baked_light_baker.cpp +++ b/tools/editor/plugins/baked_light_baker.cpp @@ -1233,7 +1233,7 @@ float BakedLightBaker::_throw_ray(ThreadStack& thread_stack,bool p_bake_direct,c if (dist